diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/JavaScriptCore/b3/air/AirInst.h | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/JavaScriptCore/b3/air/AirInst.h')
-rw-r--r-- | Source/JavaScriptCore/b3/air/AirInst.h | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/Source/JavaScriptCore/b3/air/AirInst.h b/Source/JavaScriptCore/b3/air/AirInst.h new file mode 100644 index 000000000..f38c21df8 --- /dev/null +++ b/Source/JavaScriptCore/b3/air/AirInst.h @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2015-2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#if ENABLE(B3_JIT) + +#include "AirArg.h" +#include "AirKind.h" +#include "CCallHelpers.h" + +namespace JSC { + +class CCallHelpers; +class RegisterSet; + +namespace B3 { + +class Value; + +namespace Air { + +struct GenerationContext; + +struct Inst { +public: + typedef Vector<Arg, 3> ArgList; + + Inst() + : origin(nullptr) + { + } + + Inst(Kind kind, Value* origin) + : origin(origin) + , kind(kind) + { + } + + template<typename... Arguments> + Inst(Kind kind, Value* origin, Arg arg, Arguments... arguments) + : args{ arg, arguments... } + , origin(origin) + , kind(kind) + { + } + + Inst(Kind kind, Value* origin, const ArgList& arguments) + : args(arguments) + , origin(origin) + , kind(kind) + { + } + + Inst(Kind kind, Value* origin, ArgList&& arguments) + : args(WTFMove(arguments)) + , origin(origin) + , kind(kind) + { + } + + explicit operator bool() const { return origin || kind || args.size(); } + + void append() { } + + template<typename... Arguments> + void append(Arg arg, Arguments... arguments) + { + args.append(arg); + append(arguments...); + } + + // Note that these functors all avoid using "const" because we want to use them for things that + // edit IR. IR is meant to be edited; if you're carrying around a "const Inst&" then you're + // probably doing it wrong. + + // This only walks those Tmps that are explicitly mentioned, and it doesn't tell you their role + // or type. + template<typename Functor> + void forEachTmpFast(const Functor& functor) + { + for (Arg& arg : args) + arg.forEachTmpFast(functor); + } + + typedef void EachArgCallback(Arg&, Arg::Role, Arg::Type, Arg::Width); + + // Calls the functor with (arg, role, type, width). This function is auto-generated by + // opcode_generator.rb. + template<typename Functor> + void forEachArg(const Functor&); + + // Calls the functor with (tmp, role, type, width). + template<typename Functor> + void forEachTmp(const Functor& functor) + { + forEachArg( + [&] (Arg& arg, Arg::Role role, Arg::Type type, Arg::Width width) { + arg.forEachTmp(role, type, width, functor); + }); + } + + // Thing can be either Arg, Tmp, or StackSlot*. + template<typename Thing, typename Functor> + void forEach(const Functor&); + + // Reports any additional registers clobbered by this operation. Note that for efficiency, + // extraClobberedRegs() only works for the Patch opcode. + RegisterSet extraClobberedRegs(); + RegisterSet extraEarlyClobberedRegs(); + + // Iterate over all Def's that happen at the end of an instruction. You supply a pair + // instructions. The instructions must appear next to each other, in that order, in some basic + // block. You can pass null for the first instruction when analyzing what happens at the top of + // a basic block. You can pass null for the second instruction when analyzing what happens at the + // bottom of a basic block. + template<typename Thing, typename Functor> + static void forEachDef(Inst* prevInst, Inst* nextInst, const Functor&); + + // Iterate over all Def's that happen at the end of this instruction, including extra clobbered + // registers. Note that Thing can only be Arg or Tmp when you use this functor. + template<typename Thing, typename Functor> + static void forEachDefWithExtraClobberedRegs(Inst* prevInst, Inst* nextInst, const Functor&); + + // Use this to report which registers are live. This should be done just before codegen. Note + // that for efficiency, reportUsedRegisters() only works for the Patch opcode. + void reportUsedRegisters(const RegisterSet&); + + // Is this instruction in one of the valid forms right now? This function is auto-generated by + // opcode_generator.rb. + bool isValidForm(); + + // Assuming this instruction is in a valid form right now, will it still be in one of the valid + // forms if we put an Addr referencing the stack (or a StackSlot or CallArg, of course) in the + // given index? Spilling uses this: it walks the args by index to find Tmps that need spilling; + // if it finds one, it calls this to see if it can replace the Arg::Tmp with an Arg::Addr. If it + // finds a non-Tmp Arg, then it calls that Arg's forEachTmp to do a replacement that way. + // + // This function is auto-generated by opcode_generator.rb. + bool admitsStack(unsigned argIndex); + bool admitsStack(Arg&); + + // Defined by opcode_generator.rb. + bool isTerminal(); + + // Returns true if this instruction can have any effects other than control flow or arguments. + bool hasNonArgNonControlEffects(); + + // Returns true if this instruction can have any effects other than what is implied by arguments. + // For example, "Move $42, (%rax)" will return false because the effect of storing to (%rax) is + // implied by the second argument. + bool hasNonArgEffects(); + + // Tells you if this operation has arg effects. + bool hasArgEffects(); + + // Tells you if this operation has non-control effects. + bool hasNonControlEffects() { return hasNonArgNonControlEffects() || hasArgEffects(); } + + // Generate some code for this instruction. This is, like, literally our backend. If this is the + // terminal, it returns the jump that needs to be linked for the "then" case, with the "else" + // case being fall-through. This function is auto-generated by opcode_generator.rb. + CCallHelpers::Jump generate(CCallHelpers&, GenerationContext&); + + // If source arguments benefits from being aliased to a destination argument, + // this return the index of the destination argument. + // The source are assumed to be at (index - 1) and (index - 2) + // For example, + // Add Tmp1, Tmp2, Tmp3 + // returns 2 if 0 and 1 benefit from aliasing to Tmp3. + std::optional<unsigned> shouldTryAliasingDef(); + + // This computes a hash for comparing this to JSAir's Inst. + unsigned jsHash() const; + + void dump(PrintStream&) const; + + ArgList args; + Value* origin; // The B3::Value that this originated from. + Kind kind; +}; + +} } } // namespace JSC::B3::Air + +#endif // ENABLE(B3_JIT) |