Home | History | Annotate | Download | only in src
      1 //===- subzero/src/IceInst.h - High-level instructions ----------*- C++ -*-===//
      2 //
      3 //                        The Subzero Code Generator
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 ///
     10 /// \file
     11 /// \brief Declares the Inst class and its target-independent subclasses.
     12 ///
     13 /// These represent the high-level Vanilla ICE instructions and map roughly 1:1
     14 /// to LLVM instructions.
     15 ///
     16 //===----------------------------------------------------------------------===//
     17 
     18 #ifndef SUBZERO_SRC_ICEINST_H
     19 #define SUBZERO_SRC_ICEINST_H
     20 
     21 #include "IceCfg.h"
     22 #include "IceDefs.h"
     23 #include "IceInst.def"
     24 #include "IceIntrinsics.h"
     25 #include "IceOperand.h"
     26 #include "IceSwitchLowering.h"
     27 #include "IceTypes.h"
     28 
     29 // TODO: The Cfg structure, and instructions in particular, need to be
     30 // validated for things like valid operand types, valid branch targets, proper
     31 // ordering of Phi and non-Phi instructions, etc. Most of the validity checking
     32 // will be done in the bitcode reader. We need a list of everything that should
     33 // be validated, and tests for each.
     34 
     35 namespace Ice {
     36 
     37 /// Base instruction class for ICE. Inst has two subclasses: InstHighLevel and
     38 /// InstTarget. High-level ICE instructions inherit from InstHighLevel, and
     39 /// low-level (target-specific) ICE instructions inherit from InstTarget.
     40 class Inst : public llvm::ilist_node<Inst> {
     41   Inst() = delete;
     42   Inst(const Inst &) = delete;
     43   Inst &operator=(const Inst &) = delete;
     44 
     45 public:
     46   enum InstKind {
     47     // Arbitrary (alphabetical) order, except put Unreachable first.
     48     Unreachable,
     49     Alloca,
     50     Arithmetic,
     51     Br,
     52     Call,
     53     Cast,
     54     ExtractElement,
     55     Fcmp,
     56     Icmp,
     57     IntrinsicCall,
     58     InsertElement,
     59     Load,
     60     Phi,
     61     Ret,
     62     Select,
     63     Store,
     64     Switch,
     65     Assign,        // not part of LLVM/PNaCl bitcode
     66     Breakpoint,    // not part of LLVM/PNaCl bitcode
     67     BundleLock,    // not part of LLVM/PNaCl bitcode
     68     BundleUnlock,  // not part of LLVM/PNaCl bitcode
     69     FakeDef,       // not part of LLVM/PNaCl bitcode
     70     FakeUse,       // not part of LLVM/PNaCl bitcode
     71     FakeKill,      // not part of LLVM/PNaCl bitcode
     72     JumpTable,     // not part of LLVM/PNaCl bitcode
     73     ShuffleVector, // not part of LLVM/PNaCl bitcode
     74     // Anything >= Target is an InstTarget subclass. Note that the value-spaces
     75     // are shared across targets. To avoid confusion over the definition of
     76     // shared values, an object specific to one target should never be passed
     77     // to a different target.
     78     Target,
     79     Target_Max = std::numeric_limits<uint8_t>::max(),
     80   };
     81   static_assert(Target <= Target_Max, "Must not be above max.");
     82   InstKind getKind() const { return Kind; }
     83   virtual const char *getInstName() const;
     84 
     85   InstNumberT getNumber() const { return Number; }
     86   void renumber(Cfg *Func);
     87   enum {
     88     NumberDeleted = -1,
     89     NumberSentinel = 0,
     90     NumberInitial = 2,
     91     NumberExtended = NumberInitial - 1
     92   };
     93 
     94   bool isDeleted() const { return Deleted; }
     95   void setDeleted() { Deleted = true; }
     96   void setDead(bool Value = true) { Dead = Value; }
     97   void deleteIfDead();
     98 
     99   bool hasSideEffects() const { return HasSideEffects; }
    100 
    101   bool isDestRedefined() const { return IsDestRedefined; }
    102   void setDestRedefined() { IsDestRedefined = true; }
    103 
    104   Variable *getDest() const { return Dest; }
    105 
    106   SizeT getSrcSize() const { return Srcs.size(); }
    107   Operand *getSrc(SizeT I) const {
    108     assert(I < getSrcSize());
    109     return Srcs[I];
    110   }
    111   void replaceSource(SizeT Index, Operand *Replacement) {
    112     assert(Index < getSrcSize());
    113     assert(!isDeleted());
    114     Srcs[Index] = Replacement;
    115   }
    116 
    117   bool isLastUse(const Operand *Src) const;
    118   void spliceLivenessInfo(Inst *OrigInst, Inst *SpliceAssn);
    119 
    120   /// Returns a list of out-edges corresponding to a terminator instruction,
    121   /// which is the last instruction of the block. The list must not contain
    122   /// duplicates.
    123   virtual NodeList getTerminatorEdges() const {
    124     // All valid terminator instructions override this method. For the default
    125     // implementation, we assert in case some CfgNode is constructed without a
    126     // terminator instruction at the end.
    127     llvm_unreachable(
    128         "getTerminatorEdges() called on a non-terminator instruction");
    129     return NodeList();
    130   }
    131   virtual bool isUnconditionalBranch() const { return false; }
    132   /// If the instruction is a branch-type instruction with OldNode as a target,
    133   /// repoint it to NewNode and return true, otherwise return false. Repoint all
    134   /// instances of OldNode as a target.
    135   virtual bool repointEdges(CfgNode *OldNode, CfgNode *NewNode) {
    136     (void)OldNode;
    137     (void)NewNode;
    138     return false;
    139   }
    140 
    141   /// Returns true if the instruction is equivalent to a simple
    142   /// "var_dest=var_src" assignment where the dest and src are both variables.
    143   virtual bool isVarAssign() const { return false; }
    144 
    145   /// Returns true if the instruction has a possible side effect of changing
    146   /// memory, in which case a memory load should not be reordered with respect
    147   /// to this instruction.  It should really be pure virtual, but we can't
    148   /// because of g++ and llvm::ilist<>, so we implement it as
    149   /// report_fatal_error().
    150   virtual bool isMemoryWrite() const;
    151 
    152   /// Returns true if the (target-specific) instruction represents an
    153   /// intra-block label, i.e. branch target.  This is meant primarily for
    154   /// Cfg::splitLocalVars().
    155   virtual bool isLabel() const { return false; }
    156   /// If the (target-specific) instruction represents an intra-block branch to
    157   /// some Label instruction, return that Label branch target instruction;
    158   /// otherwise return nullptr.
    159   virtual const Inst *getIntraBlockBranchTarget() const { return nullptr; }
    160 
    161   void livenessLightweight(Cfg *Func, LivenessBV &Live);
    162   /// Calculates liveness for this instruction. Returns true if this instruction
    163   /// is (tentatively) still live and should be retained, and false if this
    164   /// instruction is (tentatively) dead and should be deleted. The decision is
    165   /// tentative until the liveness dataflow algorithm has converged, and then a
    166   /// separate pass permanently deletes dead instructions.
    167   bool liveness(InstNumberT InstNumber, LivenessBV &Live, Liveness *Liveness,
    168                 LiveBeginEndMap *LiveBegin, LiveBeginEndMap *LiveEnd);
    169 
    170   /// Get the number of native instructions that this instruction ultimately
    171   /// emits. By default, high-level instructions don't result in any native
    172   /// instructions, and a target-specific instruction results in a single native
    173   /// instruction.
    174   virtual uint32_t getEmitInstCount() const { return 0; }
    175   // TODO(stichnot): Change Inst back to abstract once the g++ build issue is
    176   // fixed. llvm::ilist<Ice::Inst> doesn't work under g++ because the
    177   // resize(size_t, Ice::Inst) method is incorrectly declared and thus doesn't
    178   // allow the abstract class Ice::Inst. The method should be declared
    179   // resize(size_t, const Ice::Inst &). virtual void emit(const Cfg *Func)
    180   // const = 0; virtual void emitIAS(const Cfg *Func) const = 0;
    181   virtual void emit(const Cfg *) const {
    182     llvm_unreachable("emit on abstract class");
    183   }
    184   virtual void emitIAS(const Cfg *Func) const { emit(Func); }
    185   virtual void dump(const Cfg *Func) const;
    186   virtual void dumpExtras(const Cfg *Func) const;
    187   void dumpDecorated(const Cfg *Func) const;
    188   void emitSources(const Cfg *Func) const;
    189   void dumpSources(const Cfg *Func) const;
    190   void dumpDest(const Cfg *Func) const;
    191   virtual bool isRedundantAssign() const { return false; }
    192 
    193   virtual ~Inst() = default;
    194   void replaceDest(Variable *Var) { Dest = Var; }
    195 
    196   void operator delete(void *Ptr, std::size_t Size) {
    197     assert(CfgAllocatorTraits::current() != nullptr);
    198     CfgAllocatorTraits::current()->Deallocate(Ptr, Size);
    199     llvm::report_fatal_error("Inst unexpectedly deleted");
    200   }
    201 
    202 protected:
    203   Inst(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest);
    204   void addSource(Operand *Src) {
    205     assert(Src);
    206     Srcs.push_back(Src);
    207   }
    208   void setLastUse(SizeT VarIndex) {
    209     if (VarIndex < CHAR_BIT * sizeof(LiveRangesEnded))
    210       LiveRangesEnded |= (((LREndedBits)1u) << VarIndex);
    211   }
    212   void resetLastUses() { LiveRangesEnded = 0; }
    213   /// The destroy() method lets the instruction cleanly release any memory that
    214   /// was allocated via the Cfg's allocator.
    215   virtual void destroy(Cfg *) {}
    216 
    217   const InstKind Kind;
    218   /// Number is the instruction number for describing live ranges.
    219   InstNumberT Number;
    220   /// Deleted means irrevocably deleted.
    221   bool Deleted = false;
    222   /// Dead means one of two things depending on context: (1) pending deletion
    223   /// after liveness analysis converges, or (2) marked for deletion during
    224   /// lowering due to a folded bool operation.
    225   bool Dead = false;
    226   /// HasSideEffects means the instruction is something like a function call or
    227   /// a volatile load that can't be removed even if its Dest variable is not
    228   /// live.
    229   bool HasSideEffects = false;
    230   /// IsDestRedefined indicates that this instruction is not the first
    231   /// definition of Dest in the basic block.  The effect is that liveness
    232   /// analysis shouldn't consider this instruction to be the start of Dest's
    233   /// live range; rather, there is some other instruction earlier in the basic
    234   /// block with the same Dest.  This is maintained because liveness analysis
    235   /// has an invariant (primarily for performance reasons) that any Variable's
    236   /// live range recorded in a basic block has at most one start and at most one
    237   /// end.
    238   bool IsDestRedefined = false;
    239 
    240   Variable *Dest;
    241   const SizeT MaxSrcs; // only used for assert
    242 
    243   CfgVector<Operand *> Srcs;
    244 
    245   /// LiveRangesEnded marks which Variables' live ranges end in this
    246   /// instruction. An instruction can have an arbitrary number of source
    247   /// operands (e.g. a call instruction), and each source operand can contain 0
    248   /// or 1 Variable (and target-specific operands could contain more than 1
    249   /// Variable). All the variables in an instruction are conceptually flattened
    250   /// and each variable is mapped to one bit position of the LiveRangesEnded bit
    251   /// vector. Only the first CHAR_BIT * sizeof(LREndedBits) variables are
    252   /// tracked this way.
    253   using LREndedBits = uint32_t; // only first 32 src operands tracked, sorry
    254   LREndedBits LiveRangesEnded;
    255 };
    256 
    257 class InstHighLevel : public Inst {
    258   InstHighLevel() = delete;
    259   InstHighLevel(const InstHighLevel &) = delete;
    260   InstHighLevel &operator=(const InstHighLevel &) = delete;
    261 
    262 protected:
    263   InstHighLevel(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest)
    264       : Inst(Func, Kind, MaxSrcs, Dest) {}
    265   void emit(const Cfg * /*Func*/) const override {
    266     llvm_unreachable("emit() called on a non-lowered instruction");
    267   }
    268   void emitIAS(const Cfg * /*Func*/) const override {
    269     llvm_unreachable("emitIAS() called on a non-lowered instruction");
    270   }
    271 };
    272 
    273 /// Alloca instruction. This captures the size in bytes as getSrc(0), and the
    274 /// required alignment in bytes. The alignment must be either 0 (no alignment
    275 /// required) or a power of 2.
    276 class InstAlloca : public InstHighLevel {
    277   InstAlloca() = delete;
    278   InstAlloca(const InstAlloca &) = delete;
    279   InstAlloca &operator=(const InstAlloca &) = delete;
    280 
    281 public:
    282   static InstAlloca *create(Cfg *Func, Variable *Dest, Operand *ByteCount,
    283                             uint32_t AlignInBytes) {
    284     return new (Func->allocate<InstAlloca>())
    285         InstAlloca(Func, Dest, ByteCount, AlignInBytes);
    286   }
    287   uint32_t getAlignInBytes() const { return AlignInBytes; }
    288   Operand *getSizeInBytes() const { return getSrc(0); }
    289   bool getKnownFrameOffset() const { return KnownFrameOffset; }
    290   void setKnownFrameOffset() { KnownFrameOffset = true; }
    291   bool isMemoryWrite() const override { return false; }
    292   void dump(const Cfg *Func) const override;
    293   static bool classof(const Inst *Instr) { return Instr->getKind() == Alloca; }
    294 
    295 private:
    296   InstAlloca(Cfg *Func, Variable *Dest, Operand *ByteCount,
    297              uint32_t AlignInBytes);
    298 
    299   const uint32_t AlignInBytes;
    300   bool KnownFrameOffset = false;
    301 };
    302 
    303 /// Binary arithmetic instruction. The source operands are captured in getSrc(0)
    304 /// and getSrc(1).
    305 class InstArithmetic : public InstHighLevel {
    306   InstArithmetic() = delete;
    307   InstArithmetic(const InstArithmetic &) = delete;
    308   InstArithmetic &operator=(const InstArithmetic &) = delete;
    309 
    310 public:
    311   enum OpKind {
    312 #define X(tag, str, commutative) tag,
    313     ICEINSTARITHMETIC_TABLE
    314 #undef X
    315         _num
    316   };
    317 
    318   static InstArithmetic *create(Cfg *Func, OpKind Op, Variable *Dest,
    319                                 Operand *Source1, Operand *Source2) {
    320     return new (Func->allocate<InstArithmetic>())
    321         InstArithmetic(Func, Op, Dest, Source1, Source2);
    322   }
    323   OpKind getOp() const { return Op; }
    324 
    325   virtual const char *getInstName() const override;
    326 
    327   static const char *getOpName(OpKind Op);
    328   bool isCommutative() const;
    329   bool isMemoryWrite() const override { return false; }
    330   void dump(const Cfg *Func) const override;
    331   static bool classof(const Inst *Instr) {
    332     return Instr->getKind() == Arithmetic;
    333   }
    334 
    335 private:
    336   InstArithmetic(Cfg *Func, OpKind Op, Variable *Dest, Operand *Source1,
    337                  Operand *Source2);
    338 
    339   const OpKind Op;
    340 };
    341 
    342 /// Assignment instruction. The source operand is captured in getSrc(0). This is
    343 /// not part of the LLVM bitcode, but is a useful abstraction for some of the
    344 /// lowering. E.g., if Phi instruction lowering happens before target lowering,
    345 /// or for representing an Inttoptr instruction, or as an intermediate step for
    346 /// lowering a Load instruction.
    347 class InstAssign : public InstHighLevel {
    348   InstAssign() = delete;
    349   InstAssign(const InstAssign &) = delete;
    350   InstAssign &operator=(const InstAssign &) = delete;
    351 
    352 public:
    353   static InstAssign *create(Cfg *Func, Variable *Dest, Operand *Source) {
    354     return new (Func->allocate<InstAssign>()) InstAssign(Func, Dest, Source);
    355   }
    356   bool isVarAssign() const override;
    357   bool isMemoryWrite() const override { return false; }
    358   void dump(const Cfg *Func) const override;
    359   static bool classof(const Inst *Instr) { return Instr->getKind() == Assign; }
    360 
    361 private:
    362   InstAssign(Cfg *Func, Variable *Dest, Operand *Source);
    363 };
    364 
    365 /// Branch instruction. This represents both conditional and unconditional
    366 /// branches.
    367 class InstBr : public InstHighLevel {
    368   InstBr() = delete;
    369   InstBr(const InstBr &) = delete;
    370   InstBr &operator=(const InstBr &) = delete;
    371 
    372 public:
    373   /// Create a conditional branch. If TargetTrue==TargetFalse, it is optimized
    374   /// to an unconditional branch.
    375   static InstBr *create(Cfg *Func, Operand *Source, CfgNode *TargetTrue,
    376                         CfgNode *TargetFalse) {
    377     return new (Func->allocate<InstBr>())
    378         InstBr(Func, Source, TargetTrue, TargetFalse);
    379   }
    380   /// Create an unconditional branch.
    381   static InstBr *create(Cfg *Func, CfgNode *Target) {
    382     return new (Func->allocate<InstBr>()) InstBr(Func, Target);
    383   }
    384   bool isUnconditional() const { return getTargetTrue() == nullptr; }
    385   Operand *getCondition() const {
    386     assert(!isUnconditional());
    387     return getSrc(0);
    388   }
    389   CfgNode *getTargetTrue() const { return TargetTrue; }
    390   CfgNode *getTargetFalse() const { return TargetFalse; }
    391   CfgNode *getTargetUnconditional() const {
    392     assert(isUnconditional());
    393     return getTargetFalse();
    394   }
    395   NodeList getTerminatorEdges() const override;
    396   bool isUnconditionalBranch() const override { return isUnconditional(); }
    397   bool repointEdges(CfgNode *OldNode, CfgNode *NewNode) override;
    398   bool isMemoryWrite() const override { return false; }
    399   void dump(const Cfg *Func) const override;
    400   static bool classof(const Inst *Instr) { return Instr->getKind() == Br; }
    401 
    402 private:
    403   /// Conditional branch
    404   InstBr(Cfg *Func, Operand *Source, CfgNode *TargetTrue, CfgNode *TargetFalse);
    405   /// Unconditional branch
    406   InstBr(Cfg *Func, CfgNode *Target);
    407 
    408   CfgNode *TargetFalse; /// Doubles as unconditional branch target
    409   CfgNode *TargetTrue;  /// nullptr if unconditional branch
    410 };
    411 
    412 /// Call instruction. The call target is captured as getSrc(0), and arg I is
    413 /// captured as getSrc(I+1).
    414 class InstCall : public InstHighLevel {
    415   InstCall() = delete;
    416   InstCall(const InstCall &) = delete;
    417   InstCall &operator=(const InstCall &) = delete;
    418 
    419 public:
    420   static InstCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest,
    421                           Operand *CallTarget, bool HasTailCall,
    422                           bool IsTargetHelperCall = false) {
    423     /// Set HasSideEffects to true so that the call instruction can't be
    424     /// dead-code eliminated. IntrinsicCalls can override this if the particular
    425     /// intrinsic is deletable and has no side-effects.
    426     constexpr bool HasSideEffects = true;
    427     constexpr InstKind Kind = Inst::Call;
    428     return new (Func->allocate<InstCall>())
    429         InstCall(Func, NumArgs, Dest, CallTarget, HasTailCall,
    430                  IsTargetHelperCall, HasSideEffects, Kind);
    431   }
    432   void addArg(Operand *Arg) { addSource(Arg); }
    433   Operand *getCallTarget() const { return getSrc(0); }
    434   Operand *getArg(SizeT I) const { return getSrc(I + 1); }
    435   SizeT getNumArgs() const { return getSrcSize() - 1; }
    436   bool isTailcall() const { return HasTailCall; }
    437   bool isTargetHelperCall() const { return IsTargetHelperCall; }
    438   bool isMemoryWrite() const override { return true; }
    439   void dump(const Cfg *Func) const override;
    440   static bool classof(const Inst *Instr) { return Instr->getKind() == Call; }
    441   Type getReturnType() const;
    442 
    443 protected:
    444   InstCall(Cfg *Func, SizeT NumArgs, Variable *Dest, Operand *CallTarget,
    445            bool HasTailCall, bool IsTargetHelperCall, bool HasSideEff,
    446            InstKind Kind)
    447       : InstHighLevel(Func, Kind, NumArgs + 1, Dest), HasTailCall(HasTailCall),
    448         IsTargetHelperCall(IsTargetHelperCall) {
    449     HasSideEffects = HasSideEff;
    450     addSource(CallTarget);
    451   }
    452 
    453 private:
    454   const bool HasTailCall;
    455   const bool IsTargetHelperCall;
    456 };
    457 
    458 /// Cast instruction (a.k.a. conversion operation).
    459 class InstCast : public InstHighLevel {
    460   InstCast() = delete;
    461   InstCast(const InstCast &) = delete;
    462   InstCast &operator=(const InstCast &) = delete;
    463 
    464 public:
    465   enum OpKind {
    466 #define X(tag, str) tag,
    467     ICEINSTCAST_TABLE
    468 #undef X
    469         _num
    470   };
    471 
    472   static const char *getCastName(OpKind Kind);
    473 
    474   static InstCast *create(Cfg *Func, OpKind CastKind, Variable *Dest,
    475                           Operand *Source) {
    476     return new (Func->allocate<InstCast>())
    477         InstCast(Func, CastKind, Dest, Source);
    478   }
    479   OpKind getCastKind() const { return CastKind; }
    480   bool isMemoryWrite() const override { return false; }
    481   void dump(const Cfg *Func) const override;
    482   static bool classof(const Inst *Instr) { return Instr->getKind() == Cast; }
    483 
    484 private:
    485   InstCast(Cfg *Func, OpKind CastKind, Variable *Dest, Operand *Source);
    486 
    487   const OpKind CastKind;
    488 };
    489 
    490 /// ExtractElement instruction.
    491 class InstExtractElement : public InstHighLevel {
    492   InstExtractElement() = delete;
    493   InstExtractElement(const InstExtractElement &) = delete;
    494   InstExtractElement &operator=(const InstExtractElement &) = delete;
    495 
    496 public:
    497   static InstExtractElement *create(Cfg *Func, Variable *Dest, Operand *Source1,
    498                                     Operand *Source2) {
    499     return new (Func->allocate<InstExtractElement>())
    500         InstExtractElement(Func, Dest, Source1, Source2);
    501   }
    502 
    503   bool isMemoryWrite() const override { return false; }
    504   void dump(const Cfg *Func) const override;
    505   static bool classof(const Inst *Instr) {
    506     return Instr->getKind() == ExtractElement;
    507   }
    508 
    509 private:
    510   InstExtractElement(Cfg *Func, Variable *Dest, Operand *Source1,
    511                      Operand *Source2);
    512 };
    513 
    514 /// Floating-point comparison instruction. The source operands are captured in
    515 /// getSrc(0) and getSrc(1).
    516 class InstFcmp : public InstHighLevel {
    517   InstFcmp() = delete;
    518   InstFcmp(const InstFcmp &) = delete;
    519   InstFcmp &operator=(const InstFcmp &) = delete;
    520 
    521 public:
    522   enum FCond {
    523 #define X(tag, str) tag,
    524     ICEINSTFCMP_TABLE
    525 #undef X
    526         _num
    527   };
    528 
    529   static InstFcmp *create(Cfg *Func, FCond Condition, Variable *Dest,
    530                           Operand *Source1, Operand *Source2) {
    531     return new (Func->allocate<InstFcmp>())
    532         InstFcmp(Func, Condition, Dest, Source1, Source2);
    533   }
    534   FCond getCondition() const { return Condition; }
    535   bool isMemoryWrite() const override { return false; }
    536   void dump(const Cfg *Func) const override;
    537   static bool classof(const Inst *Instr) { return Instr->getKind() == Fcmp; }
    538 
    539 private:
    540   InstFcmp(Cfg *Func, FCond Condition, Variable *Dest, Operand *Source1,
    541            Operand *Source2);
    542 
    543   const FCond Condition;
    544 };
    545 
    546 /// Integer comparison instruction. The source operands are captured in
    547 /// getSrc(0) and getSrc(1).
    548 class InstIcmp : public InstHighLevel {
    549   InstIcmp() = delete;
    550   InstIcmp(const InstIcmp &) = delete;
    551   InstIcmp &operator=(const InstIcmp &) = delete;
    552 
    553 public:
    554   enum ICond {
    555 #define X(tag, inverse, str) tag,
    556     ICEINSTICMP_TABLE
    557 #undef X
    558         _num
    559   };
    560 
    561   static InstIcmp *create(Cfg *Func, ICond Condition, Variable *Dest,
    562                           Operand *Source1, Operand *Source2) {
    563     return new (Func->allocate<InstIcmp>())
    564         InstIcmp(Func, Condition, Dest, Source1, Source2);
    565   }
    566   ICond getCondition() const { return Condition; }
    567   void reverseConditionAndOperands();
    568   bool isMemoryWrite() const override { return false; }
    569   void dump(const Cfg *Func) const override;
    570   static bool classof(const Inst *Instr) { return Instr->getKind() == Icmp; }
    571 
    572 private:
    573   InstIcmp(Cfg *Func, ICond Condition, Variable *Dest, Operand *Source1,
    574            Operand *Source2);
    575 
    576   ICond Condition;
    577 };
    578 
    579 /// InsertElement instruction.
    580 class InstInsertElement : public InstHighLevel {
    581   InstInsertElement() = delete;
    582   InstInsertElement(const InstInsertElement &) = delete;
    583   InstInsertElement &operator=(const InstInsertElement &) = delete;
    584 
    585 public:
    586   static InstInsertElement *create(Cfg *Func, Variable *Dest, Operand *Source1,
    587                                    Operand *Source2, Operand *Source3) {
    588     return new (Func->allocate<InstInsertElement>())
    589         InstInsertElement(Func, Dest, Source1, Source2, Source3);
    590   }
    591 
    592   bool isMemoryWrite() const override { return false; }
    593   void dump(const Cfg *Func) const override;
    594   static bool classof(const Inst *Instr) {
    595     return Instr->getKind() == InsertElement;
    596   }
    597 
    598 private:
    599   InstInsertElement(Cfg *Func, Variable *Dest, Operand *Source1,
    600                     Operand *Source2, Operand *Source3);
    601 };
    602 
    603 /// Call to an intrinsic function. The call target is captured as getSrc(0), and
    604 /// arg I is captured as getSrc(I+1).
    605 class InstIntrinsicCall : public InstCall {
    606   InstIntrinsicCall() = delete;
    607   InstIntrinsicCall(const InstIntrinsicCall &) = delete;
    608   InstIntrinsicCall &operator=(const InstIntrinsicCall &) = delete;
    609 
    610 public:
    611   static InstIntrinsicCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest,
    612                                    Operand *CallTarget,
    613                                    const Intrinsics::IntrinsicInfo &Info) {
    614     return new (Func->allocate<InstIntrinsicCall>())
    615         InstIntrinsicCall(Func, NumArgs, Dest, CallTarget, Info);
    616   }
    617   static bool classof(const Inst *Instr) {
    618     return Instr->getKind() == IntrinsicCall;
    619   }
    620 
    621   Intrinsics::IntrinsicInfo getIntrinsicInfo() const { return Info; }
    622   bool isMemoryWrite() const override {
    623     return getIntrinsicInfo().IsMemoryWrite;
    624   }
    625 
    626 private:
    627   InstIntrinsicCall(Cfg *Func, SizeT NumArgs, Variable *Dest,
    628                     Operand *CallTarget, const Intrinsics::IntrinsicInfo &Info)
    629       : InstCall(Func, NumArgs, Dest, CallTarget, false, false,
    630                  Info.HasSideEffects, Inst::IntrinsicCall),
    631         Info(Info) {}
    632 
    633   const Intrinsics::IntrinsicInfo Info;
    634 };
    635 
    636 /// Load instruction. The source address is captured in getSrc(0).
    637 class InstLoad : public InstHighLevel {
    638   InstLoad() = delete;
    639   InstLoad(const InstLoad &) = delete;
    640   InstLoad &operator=(const InstLoad &) = delete;
    641 
    642 public:
    643   static InstLoad *create(Cfg *Func, Variable *Dest, Operand *SourceAddr,
    644                           uint32_t Align = 1) {
    645     // TODO(kschimpf) Stop ignoring alignment specification.
    646     (void)Align;
    647     return new (Func->allocate<InstLoad>()) InstLoad(Func, Dest, SourceAddr);
    648   }
    649   Operand *getSourceAddress() const { return getSrc(0); }
    650   bool isMemoryWrite() const override { return false; }
    651   void dump(const Cfg *Func) const override;
    652   static bool classof(const Inst *Instr) { return Instr->getKind() == Load; }
    653 
    654 private:
    655   InstLoad(Cfg *Func, Variable *Dest, Operand *SourceAddr);
    656 };
    657 
    658 /// Phi instruction. For incoming edge I, the node is Labels[I] and the Phi
    659 /// source operand is getSrc(I).
    660 class InstPhi : public InstHighLevel {
    661   InstPhi() = delete;
    662   InstPhi(const InstPhi &) = delete;
    663   InstPhi &operator=(const InstPhi &) = delete;
    664 
    665 public:
    666   static InstPhi *create(Cfg *Func, SizeT MaxSrcs, Variable *Dest) {
    667     return new (Func->allocate<InstPhi>()) InstPhi(Func, MaxSrcs, Dest);
    668   }
    669   void addArgument(Operand *Source, CfgNode *Label);
    670   Operand *getOperandForTarget(CfgNode *Target) const;
    671   void clearOperandForTarget(CfgNode *Target);
    672   CfgNode *getLabel(SizeT Index) const { return Labels[Index]; }
    673   void setLabel(SizeT Index, CfgNode *Label) { Labels[Index] = Label; }
    674   void livenessPhiOperand(LivenessBV &Live, CfgNode *Target,
    675                           Liveness *Liveness);
    676   Inst *lower(Cfg *Func);
    677   bool isMemoryWrite() const override { return false; }
    678   void dump(const Cfg *Func) const override;
    679   static bool classof(const Inst *Instr) { return Instr->getKind() == Phi; }
    680 
    681 private:
    682   InstPhi(Cfg *Func, SizeT MaxSrcs, Variable *Dest);
    683   void destroy(Cfg *Func) override { Inst::destroy(Func); }
    684 
    685   /// Labels[] duplicates the InEdges[] information in the enclosing CfgNode,
    686   /// but the Phi instruction is created before InEdges[] is available, so it's
    687   /// more complicated to share the list.
    688   CfgVector<CfgNode *> Labels;
    689 };
    690 
    691 /// Ret instruction. The return value is captured in getSrc(0), but if there is
    692 /// no return value (void-type function), then getSrcSize()==0 and
    693 /// hasRetValue()==false.
    694 class InstRet : public InstHighLevel {
    695   InstRet() = delete;
    696   InstRet(const InstRet &) = delete;
    697   InstRet &operator=(const InstRet &) = delete;
    698 
    699 public:
    700   static InstRet *create(Cfg *Func, Operand *RetValue = nullptr) {
    701     return new (Func->allocate<InstRet>()) InstRet(Func, RetValue);
    702   }
    703   bool hasRetValue() const { return getSrcSize(); }
    704   Operand *getRetValue() const {
    705     assert(hasRetValue());
    706     return getSrc(0);
    707   }
    708   NodeList getTerminatorEdges() const override { return NodeList(); }
    709   bool isMemoryWrite() const override { return false; }
    710   void dump(const Cfg *Func) const override;
    711   static bool classof(const Inst *Instr) { return Instr->getKind() == Ret; }
    712 
    713 private:
    714   InstRet(Cfg *Func, Operand *RetValue);
    715 };
    716 
    717 /// Select instruction.  The condition, true, and false operands are captured.
    718 class InstSelect : public InstHighLevel {
    719   InstSelect() = delete;
    720   InstSelect(const InstSelect &) = delete;
    721   InstSelect &operator=(const InstSelect &) = delete;
    722 
    723 public:
    724   static InstSelect *create(Cfg *Func, Variable *Dest, Operand *Condition,
    725                             Operand *SourceTrue, Operand *SourceFalse) {
    726     return new (Func->allocate<InstSelect>())
    727         InstSelect(Func, Dest, Condition, SourceTrue, SourceFalse);
    728   }
    729   Operand *getCondition() const { return getSrc(0); }
    730   Operand *getTrueOperand() const { return getSrc(1); }
    731   Operand *getFalseOperand() const { return getSrc(2); }
    732   bool isMemoryWrite() const override { return false; }
    733   void dump(const Cfg *Func) const override;
    734   static bool classof(const Inst *Instr) { return Instr->getKind() == Select; }
    735 
    736 private:
    737   InstSelect(Cfg *Func, Variable *Dest, Operand *Condition, Operand *Source1,
    738              Operand *Source2);
    739 };
    740 
    741 /// Store instruction. The address operand is captured, along with the data
    742 /// operand to be stored into the address.
    743 class InstStore : public InstHighLevel {
    744   InstStore() = delete;
    745   InstStore(const InstStore &) = delete;
    746   InstStore &operator=(const InstStore &) = delete;
    747 
    748 public:
    749   static InstStore *create(Cfg *Func, Operand *Data, Operand *Addr,
    750                            uint32_t Align = 1) {
    751     // TODO(kschimpf) Stop ignoring alignment specification.
    752     (void)Align;
    753     return new (Func->allocate<InstStore>()) InstStore(Func, Data, Addr);
    754   }
    755   Operand *getAddr() const { return getSrc(1); }
    756   Operand *getData() const { return getSrc(0); }
    757   Variable *getRmwBeacon() const;
    758   void setRmwBeacon(Variable *Beacon);
    759   bool isMemoryWrite() const override { return true; }
    760   void dump(const Cfg *Func) const override;
    761   static bool classof(const Inst *Instr) { return Instr->getKind() == Store; }
    762 
    763 private:
    764   InstStore(Cfg *Func, Operand *Data, Operand *Addr);
    765 };
    766 
    767 /// Switch instruction. The single source operand is captured as getSrc(0).
    768 class InstSwitch : public InstHighLevel {
    769   InstSwitch() = delete;
    770   InstSwitch(const InstSwitch &) = delete;
    771   InstSwitch &operator=(const InstSwitch &) = delete;
    772 
    773 public:
    774   static InstSwitch *create(Cfg *Func, SizeT NumCases, Operand *Source,
    775                             CfgNode *LabelDefault) {
    776     return new (Func->allocate<InstSwitch>())
    777         InstSwitch(Func, NumCases, Source, LabelDefault);
    778   }
    779   Operand *getComparison() const { return getSrc(0); }
    780   CfgNode *getLabelDefault() const { return LabelDefault; }
    781   SizeT getNumCases() const { return NumCases; }
    782   uint64_t getValue(SizeT I) const {
    783     assert(I < NumCases);
    784     return Values[I];
    785   }
    786   CfgNode *getLabel(SizeT I) const {
    787     assert(I < NumCases);
    788     return Labels[I];
    789   }
    790   void addBranch(SizeT CaseIndex, uint64_t Value, CfgNode *Label);
    791   NodeList getTerminatorEdges() const override;
    792   bool repointEdges(CfgNode *OldNode, CfgNode *NewNode) override;
    793   bool isMemoryWrite() const override { return false; }
    794   void dump(const Cfg *Func) const override;
    795   static bool classof(const Inst *Instr) { return Instr->getKind() == Switch; }
    796 
    797 private:
    798   InstSwitch(Cfg *Func, SizeT NumCases, Operand *Source, CfgNode *LabelDefault);
    799   void destroy(Cfg *Func) override {
    800     Func->deallocateArrayOf<uint64_t>(Values);
    801     Func->deallocateArrayOf<CfgNode *>(Labels);
    802     Inst::destroy(Func);
    803   }
    804 
    805   CfgNode *LabelDefault;
    806   SizeT NumCases;   /// not including the default case
    807   uint64_t *Values; /// size is NumCases
    808   CfgNode **Labels; /// size is NumCases
    809 };
    810 
    811 /// Unreachable instruction. This is a terminator instruction with no operands.
    812 class InstUnreachable : public InstHighLevel {
    813   InstUnreachable() = delete;
    814   InstUnreachable(const InstUnreachable &) = delete;
    815   InstUnreachable &operator=(const InstUnreachable &) = delete;
    816 
    817 public:
    818   static InstUnreachable *create(Cfg *Func) {
    819     return new (Func->allocate<InstUnreachable>()) InstUnreachable(Func);
    820   }
    821   NodeList getTerminatorEdges() const override { return NodeList(); }
    822   bool isMemoryWrite() const override { return false; }
    823   void dump(const Cfg *Func) const override;
    824   static bool classof(const Inst *Instr) {
    825     return Instr->getKind() == Unreachable;
    826   }
    827 
    828 private:
    829   explicit InstUnreachable(Cfg *Func);
    830 };
    831 
    832 /// BundleLock instruction.  There are no operands. Contains an option
    833 /// indicating whether align_to_end is specified.
    834 class InstBundleLock : public InstHighLevel {
    835   InstBundleLock() = delete;
    836   InstBundleLock(const InstBundleLock &) = delete;
    837   InstBundleLock &operator=(const InstBundleLock &) = delete;
    838 
    839 public:
    840   enum Option { Opt_None, Opt_AlignToEnd, Opt_PadToEnd };
    841   static InstBundleLock *create(Cfg *Func, Option BundleOption) {
    842     return new (Func->allocate<InstBundleLock>())
    843         InstBundleLock(Func, BundleOption);
    844   }
    845   void emit(const Cfg *Func) const override;
    846   void emitIAS(const Cfg * /* Func */) const override {}
    847   bool isMemoryWrite() const override { return false; }
    848   void dump(const Cfg *Func) const override;
    849   Option getOption() const { return BundleOption; }
    850   static bool classof(const Inst *Instr) {
    851     return Instr->getKind() == BundleLock;
    852   }
    853 
    854 private:
    855   Option BundleOption;
    856   InstBundleLock(Cfg *Func, Option BundleOption);
    857 };
    858 
    859 /// BundleUnlock instruction. There are no operands.
    860 class InstBundleUnlock : public InstHighLevel {
    861   InstBundleUnlock() = delete;
    862   InstBundleUnlock(const InstBundleUnlock &) = delete;
    863   InstBundleUnlock &operator=(const InstBundleUnlock &) = delete;
    864 
    865 public:
    866   static InstBundleUnlock *create(Cfg *Func) {
    867     return new (Func->allocate<InstBundleUnlock>()) InstBundleUnlock(Func);
    868   }
    869   void emit(const Cfg *Func) const override;
    870   void emitIAS(const Cfg * /* Func */) const override {}
    871   bool isMemoryWrite() const override { return false; }
    872   void dump(const Cfg *Func) const override;
    873   static bool classof(const Inst *Instr) {
    874     return Instr->getKind() == BundleUnlock;
    875   }
    876 
    877 private:
    878   explicit InstBundleUnlock(Cfg *Func);
    879 };
    880 
    881 /// FakeDef instruction. This creates a fake definition of a variable, which is
    882 /// how we represent the case when an instruction produces multiple results.
    883 /// This doesn't happen with high-level ICE instructions, but might with lowered
    884 /// instructions. For example, this would be a way to represent condition flags
    885 /// being modified by an instruction.
    886 ///
    887 /// It's generally useful to set the optional source operand to be the dest
    888 /// variable of the instruction that actually produces the FakeDef dest.
    889 /// Otherwise, the original instruction could be dead-code eliminated if its
    890 /// dest operand is unused, and therefore the FakeDef dest wouldn't be properly
    891 /// initialized.
    892 class InstFakeDef : public InstHighLevel {
    893   InstFakeDef() = delete;
    894   InstFakeDef(const InstFakeDef &) = delete;
    895   InstFakeDef &operator=(const InstFakeDef &) = delete;
    896 
    897 public:
    898   static InstFakeDef *create(Cfg *Func, Variable *Dest,
    899                              Variable *Src = nullptr) {
    900     return new (Func->allocate<InstFakeDef>()) InstFakeDef(Func, Dest, Src);
    901   }
    902   void emit(const Cfg *Func) const override;
    903   void emitIAS(const Cfg * /* Func */) const override {}
    904   bool isMemoryWrite() const override { return false; }
    905   void dump(const Cfg *Func) const override;
    906   static bool classof(const Inst *Instr) { return Instr->getKind() == FakeDef; }
    907 
    908 private:
    909   InstFakeDef(Cfg *Func, Variable *Dest, Variable *Src);
    910 };
    911 
    912 /// FakeUse instruction. This creates a fake use of a variable, to keep the
    913 /// instruction that produces that variable from being dead-code eliminated.
    914 /// This is useful in a variety of lowering situations. The FakeUse instruction
    915 /// has no dest, so it can itself never be dead-code eliminated.  A weight can
    916 /// be provided to provide extra bias to the register allocator - for simplicity
    917 /// of implementation, weight=N is handled by holding N copies of the variable
    918 /// as source operands.
    919 class InstFakeUse : public InstHighLevel {
    920   InstFakeUse() = delete;
    921   InstFakeUse(const InstFakeUse &) = delete;
    922   InstFakeUse &operator=(const InstFakeUse &) = delete;
    923 
    924 public:
    925   static InstFakeUse *create(Cfg *Func, Variable *Src, uint32_t Weight = 1) {
    926     return new (Func->allocate<InstFakeUse>()) InstFakeUse(Func, Src, Weight);
    927   }
    928   void emit(const Cfg *Func) const override;
    929   void emitIAS(const Cfg * /* Func */) const override {}
    930   bool isMemoryWrite() const override { return false; }
    931   void dump(const Cfg *Func) const override;
    932   static bool classof(const Inst *Instr) { return Instr->getKind() == FakeUse; }
    933 
    934 private:
    935   InstFakeUse(Cfg *Func, Variable *Src, uint32_t Weight);
    936 };
    937 
    938 /// FakeKill instruction. This "kills" a set of variables by modeling a trivial
    939 /// live range at this instruction for each (implicit) variable. The primary use
    940 /// is to indicate that scratch registers are killed after a call, so that the
    941 /// register allocator won't assign a scratch register to a variable whose live
    942 /// range spans a call.
    943 ///
    944 /// The FakeKill instruction also holds a pointer to the instruction that kills
    945 /// the set of variables, so that if that linked instruction gets dead-code
    946 /// eliminated, the FakeKill instruction will as well.
    947 class InstFakeKill : public InstHighLevel {
    948   InstFakeKill() = delete;
    949   InstFakeKill(const InstFakeKill &) = delete;
    950   InstFakeKill &operator=(const InstFakeKill &) = delete;
    951 
    952 public:
    953   static InstFakeKill *create(Cfg *Func, const Inst *Linked) {
    954     return new (Func->allocate<InstFakeKill>()) InstFakeKill(Func, Linked);
    955   }
    956   const Inst *getLinked() const { return Linked; }
    957   void emit(const Cfg *Func) const override;
    958   void emitIAS(const Cfg * /* Func */) const override {}
    959   bool isMemoryWrite() const override { return false; }
    960   void dump(const Cfg *Func) const override;
    961   static bool classof(const Inst *Instr) {
    962     return Instr->getKind() == FakeKill;
    963   }
    964 
    965 private:
    966   InstFakeKill(Cfg *Func, const Inst *Linked);
    967 
    968   /// This instruction is ignored if Linked->isDeleted() is true.
    969   const Inst *Linked;
    970 };
    971 
    972 /// ShuffleVector instruction. This represents a shuffle operation on vector
    973 /// types. This instruction is not part of the PNaCl bitcode: it is generated
    974 /// by Subzero when it matches the pattern used by pnacl-clang when compiling
    975 /// to bitcode.
    976 class InstShuffleVector : public InstHighLevel {
    977   InstShuffleVector() = delete;
    978   InstShuffleVector(const InstShuffleVector &) = delete;
    979   InstShuffleVector &operator=(const InstShuffleVector &) = delete;
    980 
    981 public:
    982   static InstShuffleVector *create(Cfg *Func, Variable *Dest, Operand *Src0,
    983                                    Operand *Src1) {
    984     return new (Func->allocate<InstShuffleVector>())
    985         InstShuffleVector(Func, Dest, Src0, Src1);
    986   }
    987 
    988   SizeT getNumIndexes() const { return NumIndexes; }
    989 
    990   void addIndex(ConstantInteger32 *Index) {
    991     assert(CurrentIndex < NumIndexes);
    992     Indexes[CurrentIndex++] = Index;
    993   }
    994 
    995   ConstantInteger32 *getIndex(SizeT Pos) const {
    996     assert(Pos < NumIndexes);
    997     return Indexes[Pos];
    998   }
    999 
   1000   int32_t getIndexValue(SizeT Pos) const { return getIndex(Pos)->getValue(); }
   1001 
   1002   bool indexesAre(int32_t i0, int32_t i1, int32_t i2, int32_t i3) const {
   1003     static constexpr SizeT ExpectedNumElements = 4;
   1004     assert(ExpectedNumElements == getNumIndexes());
   1005     (void)ExpectedNumElements;
   1006 
   1007     return getIndexValue(0) == i0 && getIndexValue(1) == i1 &&
   1008            getIndexValue(2) == i2 && getIndexValue(3) == i3;
   1009   }
   1010 
   1011   bool indexesAre(int32_t i0, int32_t i1, int32_t i2, int32_t i3, int32_t i4,
   1012                   int32_t i5, int32_t i6, int32_t i7) const {
   1013     static constexpr SizeT ExpectedNumElements = 8;
   1014     assert(ExpectedNumElements == getNumIndexes());
   1015     (void)ExpectedNumElements;
   1016 
   1017     return getIndexValue(0) == i0 && getIndexValue(1) == i1 &&
   1018            getIndexValue(2) == i2 && getIndexValue(3) == i3 &&
   1019            getIndexValue(4) == i4 && getIndexValue(5) == i5 &&
   1020            getIndexValue(6) == i6 && getIndexValue(7) == i7;
   1021   }
   1022 
   1023   bool indexesAre(int32_t i0, int32_t i1, int32_t i2, int32_t i3, int32_t i4,
   1024                   int32_t i5, int32_t i6, int32_t i7, int32_t i8, int32_t i9,
   1025                   int32_t i10, int32_t i11, int32_t i12, int32_t i13,
   1026                   int32_t i14, int32_t i15) const {
   1027     static constexpr SizeT ExpectedNumElements = 16;
   1028     assert(ExpectedNumElements == getNumIndexes());
   1029     (void)ExpectedNumElements;
   1030 
   1031     return getIndexValue(0) == i0 && getIndexValue(1) == i1 &&
   1032            getIndexValue(2) == i2 && getIndexValue(3) == i3 &&
   1033            getIndexValue(4) == i4 && getIndexValue(5) == i5 &&
   1034            getIndexValue(6) == i6 && getIndexValue(7) == i7 &&
   1035            getIndexValue(8) == i8 && getIndexValue(9) == i9 &&
   1036            getIndexValue(10) == i10 && getIndexValue(11) == i11 &&
   1037            getIndexValue(12) == i12 && getIndexValue(13) == i13 &&
   1038            getIndexValue(14) == i14 && getIndexValue(15) == i15;
   1039   }
   1040 
   1041   bool isMemoryWrite() const override { return false; }
   1042   void dump(const Cfg *Func) const override;
   1043   static bool classof(const Inst *Instr) {
   1044     return Instr->getKind() == ShuffleVector;
   1045   }
   1046 
   1047 private:
   1048   InstShuffleVector(Cfg *Func, Variable *Dest, Operand *Src0, Operand *Src1);
   1049 
   1050   void destroy(Cfg *Func) override {
   1051     Func->deallocateArrayOf<ConstantInteger32 *>(Indexes);
   1052     Inst::destroy(Func);
   1053   }
   1054 
   1055   ConstantInteger32 **Indexes;
   1056   SizeT CurrentIndex = 0;
   1057   const SizeT NumIndexes;
   1058 };
   1059 
   1060 /// JumpTable instruction. This represents a jump table that will be stored in
   1061 /// the .rodata section. This is used to track and repoint the target CfgNodes
   1062 /// which may change, for example due to splitting for phi lowering.
   1063 class InstJumpTable : public InstHighLevel {
   1064   InstJumpTable() = delete;
   1065   InstJumpTable(const InstJumpTable &) = delete;
   1066   InstJumpTable &operator=(const InstJumpTable &) = delete;
   1067 
   1068 public:
   1069   static InstJumpTable *create(Cfg *Func, SizeT NumTargets, CfgNode *Default) {
   1070     return new (Func->allocate<InstJumpTable>())
   1071         InstJumpTable(Func, NumTargets, Default);
   1072   }
   1073   void addTarget(SizeT TargetIndex, CfgNode *Target) {
   1074     assert(TargetIndex < NumTargets);
   1075     Targets[TargetIndex] = Target;
   1076   }
   1077   bool repointEdges(CfgNode *OldNode, CfgNode *NewNode) override;
   1078   SizeT getId() const { return Id; }
   1079   SizeT getNumTargets() const { return NumTargets; }
   1080   CfgNode *getTarget(SizeT I) const {
   1081     assert(I < NumTargets);
   1082     return Targets[I];
   1083   }
   1084   bool isMemoryWrite() const override { return false; }
   1085   void dump(const Cfg *Func) const override;
   1086   static bool classof(const Inst *Instr) {
   1087     return Instr->getKind() == JumpTable;
   1088   }
   1089   // Creates a JumpTableData struct (used for ELF emission) that represents this
   1090   // InstJumpTable.
   1091   JumpTableData toJumpTableData(Assembler *Asm) const;
   1092 
   1093   // InstJumpTable is just a placeholder for the switch targets, and it does not
   1094   // need to emit any code, so we redefine emit and emitIAS to do nothing.
   1095   void emit(const Cfg *) const override {}
   1096   void emitIAS(const Cfg * /* Func */) const override {}
   1097 
   1098   const std::string getName() const {
   1099     assert(Name.hasStdString());
   1100     return Name.toString();
   1101   }
   1102 
   1103   std::string getSectionName() const {
   1104     return JumpTableData::createSectionName(FuncName);
   1105   }
   1106 
   1107 private:
   1108   InstJumpTable(Cfg *Func, SizeT NumTargets, CfgNode *Default);
   1109   void destroy(Cfg *Func) override {
   1110     Func->deallocateArrayOf<CfgNode *>(Targets);
   1111     Inst::destroy(Func);
   1112   }
   1113 
   1114   const SizeT Id;
   1115   const SizeT NumTargets;
   1116   CfgNode **Targets;
   1117   GlobalString Name; // This JumpTable's name in the output.
   1118   GlobalString FuncName;
   1119 };
   1120 
   1121 /// This instruction inserts an unconditional breakpoint.
   1122 ///
   1123 /// On x86, this assembles into an INT 3 instruction.
   1124 ///
   1125 /// This instruction is primarily meant for debugging the code generator.
   1126 class InstBreakpoint : public InstHighLevel {
   1127 public:
   1128   InstBreakpoint() = delete;
   1129   InstBreakpoint(const InstBreakpoint &) = delete;
   1130   InstBreakpoint &operator=(const InstBreakpoint &) = delete;
   1131 
   1132   explicit InstBreakpoint(Cfg *Func);
   1133   bool isMemoryWrite() const override { return false; }
   1134 
   1135 public:
   1136   static InstBreakpoint *create(Cfg *Func) {
   1137     return new (Func->allocate<InstBreakpoint>()) InstBreakpoint(Func);
   1138   }
   1139 
   1140   static bool classof(const Inst *Instr) {
   1141     return Instr->getKind() == Breakpoint;
   1142   }
   1143 };
   1144 
   1145 /// The Target instruction is the base class for all target-specific
   1146 /// instructions.
   1147 class InstTarget : public Inst {
   1148   InstTarget() = delete;
   1149   InstTarget(const InstTarget &) = delete;
   1150   InstTarget &operator=(const InstTarget &) = delete;
   1151 
   1152 public:
   1153   uint32_t getEmitInstCount() const override { return 1; }
   1154   bool isMemoryWrite() const override {
   1155     return true; // conservative answer
   1156   }
   1157   void dump(const Cfg *Func) const override;
   1158   static bool classof(const Inst *Instr) { return Instr->getKind() >= Target; }
   1159 
   1160 protected:
   1161   InstTarget(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest)
   1162       : Inst(Func, Kind, MaxSrcs, Dest) {
   1163     assert(Kind >= Target);
   1164     assert(Kind <= Target_Max);
   1165   }
   1166 };
   1167 
   1168 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source);
   1169 
   1170 } // end of namespace Ice
   1171 
   1172 #ifdef PNACL_LLVM
   1173 namespace llvm {
   1174 
   1175 /// Override the default ilist traits so that Inst's private ctor and deleted
   1176 /// dtor aren't invoked.
   1177 template <>
   1178 struct ilist_traits<Ice::Inst> : public ilist_default_traits<Ice::Inst> {
   1179   Ice::Inst *createSentinel() const {
   1180     return static_cast<Ice::Inst *>(&Sentinel);
   1181   }
   1182   static void destroySentinel(Ice::Inst *) {}
   1183   Ice::Inst *provideInitialHead() const { return createSentinel(); }
   1184   Ice::Inst *ensureHead(Ice::Inst *) const { return createSentinel(); }
   1185   static void noteHead(Ice::Inst *, Ice::Inst *) {}
   1186   void deleteNode(Ice::Inst *) {}
   1187 
   1188 private:
   1189   mutable ilist_half_node<Ice::Inst> Sentinel;
   1190 };
   1191 
   1192 } // end of namespace llvm
   1193 #endif // PNACL_LLVM
   1194 
   1195 namespace Ice {
   1196 
   1197 inline InstList::iterator instToIterator(Inst *Instr) {
   1198 #ifdef PNACL_LLVM
   1199   return Instr;
   1200 #else  // !PNACL_LLVM
   1201   return Instr->getIterator();
   1202 #endif // !PNACL_LLVM
   1203 }
   1204 
   1205 inline Inst *iteratorToInst(InstList::iterator Iter) { return &*Iter; }
   1206 
   1207 inline const Inst *iteratorToInst(InstList::const_iterator Iter) {
   1208   return &*Iter;
   1209 }
   1210 
   1211 inline InstList::iterator
   1212 reverseToForwardIterator(InstList::reverse_iterator RI) {
   1213 #ifdef PNACL_LLVM
   1214   return RI.base();
   1215 #else  // !PNACL_LLVM
   1216   return ++RI.getReverse();
   1217 #endif // !PNACL_LLVM
   1218 }
   1219 
   1220 } // end of namespace Ice
   1221 
   1222 #endif // SUBZERO_SRC_ICEINST_H
   1223