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   inline bool indexesAre(int32_t i0, int32_t i1, int32_t i2, int32_t i3,
   1001                          int32_t i4, int32_t i5, int32_t i6, int32_t i7) const {
   1002     static constexpr SizeT ExpectedNumElements = 8;
   1003     assert(ExpectedNumElements == getNumIndexes());
   1004     (void)ExpectedNumElements;
   1005 
   1006     return getIndex(0)->getValue() == i0 && getIndex(1)->getValue() == i1 &&
   1007            getIndex(2)->getValue() == i2 && getIndex(3)->getValue() == i3 &&
   1008            getIndex(4)->getValue() == i4 && getIndex(5)->getValue() == i5 &&
   1009            getIndex(6)->getValue() == i6 && getIndex(7)->getValue() == i7;
   1010   }
   1011 
   1012   inline bool indexesAre(int32_t i0, int32_t i1, int32_t i2, int32_t i3,
   1013                          int32_t i4, int32_t i5, int32_t i6, int32_t i7,
   1014                          int32_t i8, int32_t i9, int32_t i10, int32_t i11,
   1015                          int32_t i12, int32_t i13, int32_t i14,
   1016                          int32_t i15) const {
   1017     static constexpr SizeT ExpectedNumElements = 16;
   1018     assert(ExpectedNumElements == getNumIndexes());
   1019     (void)ExpectedNumElements;
   1020 
   1021     return getIndex(0)->getValue() == i0 && getIndex(1)->getValue() == i1 &&
   1022            getIndex(2)->getValue() == i2 && getIndex(3)->getValue() == i3 &&
   1023            getIndex(4)->getValue() == i4 && getIndex(5)->getValue() == i5 &&
   1024            getIndex(6)->getValue() == i6 && getIndex(7)->getValue() == i7 &&
   1025            getIndex(8)->getValue() == i8 && getIndex(9)->getValue() == i9 &&
   1026            getIndex(10)->getValue() == i10 && getIndex(11)->getValue() == i11 &&
   1027            getIndex(12)->getValue() == i12 && getIndex(13)->getValue() == i13 &&
   1028            getIndex(14)->getValue() == i14 && getIndex(15)->getValue() == i15;
   1029   }
   1030 
   1031   bool isMemoryWrite() const override { return false; }
   1032   void dump(const Cfg *Func) const override;
   1033   static bool classof(const Inst *Instr) {
   1034     return Instr->getKind() == ShuffleVector;
   1035   }
   1036 
   1037 private:
   1038   InstShuffleVector(Cfg *Func, Variable *Dest, Operand *Src0, Operand *Src1);
   1039 
   1040   void destroy(Cfg *Func) override {
   1041     Func->deallocateArrayOf<ConstantInteger32 *>(Indexes);
   1042     Inst::destroy(Func);
   1043   }
   1044 
   1045   ConstantInteger32 **Indexes;
   1046   SizeT CurrentIndex = 0;
   1047   const SizeT NumIndexes;
   1048 };
   1049 
   1050 /// JumpTable instruction. This represents a jump table that will be stored in
   1051 /// the .rodata section. This is used to track and repoint the target CfgNodes
   1052 /// which may change, for example due to splitting for phi lowering.
   1053 class InstJumpTable : public InstHighLevel {
   1054   InstJumpTable() = delete;
   1055   InstJumpTable(const InstJumpTable &) = delete;
   1056   InstJumpTable &operator=(const InstJumpTable &) = delete;
   1057 
   1058 public:
   1059   static InstJumpTable *create(Cfg *Func, SizeT NumTargets, CfgNode *Default) {
   1060     return new (Func->allocate<InstJumpTable>())
   1061         InstJumpTable(Func, NumTargets, Default);
   1062   }
   1063   void addTarget(SizeT TargetIndex, CfgNode *Target) {
   1064     assert(TargetIndex < NumTargets);
   1065     Targets[TargetIndex] = Target;
   1066   }
   1067   bool repointEdges(CfgNode *OldNode, CfgNode *NewNode) override;
   1068   SizeT getId() const { return Id; }
   1069   SizeT getNumTargets() const { return NumTargets; }
   1070   CfgNode *getTarget(SizeT I) const {
   1071     assert(I < NumTargets);
   1072     return Targets[I];
   1073   }
   1074   bool isMemoryWrite() const override { return false; }
   1075   void dump(const Cfg *Func) const override;
   1076   static bool classof(const Inst *Instr) {
   1077     return Instr->getKind() == JumpTable;
   1078   }
   1079   // Creates a JumpTableData struct (used for ELF emission) that represents this
   1080   // InstJumpTable.
   1081   JumpTableData toJumpTableData(Assembler *Asm) const;
   1082 
   1083   // InstJumpTable is just a placeholder for the switch targets, and it does not
   1084   // need to emit any code, so we redefine emit and emitIAS to do nothing.
   1085   void emit(const Cfg *) const override {}
   1086   void emitIAS(const Cfg * /* Func */) const override {}
   1087 
   1088   const std::string getName() const {
   1089     assert(Name.hasStdString());
   1090     return Name.toString();
   1091   }
   1092 
   1093   std::string getSectionName() const {
   1094     return JumpTableData::createSectionName(FuncName);
   1095   }
   1096 
   1097 private:
   1098   InstJumpTable(Cfg *Func, SizeT NumTargets, CfgNode *Default);
   1099   void destroy(Cfg *Func) override {
   1100     Func->deallocateArrayOf<CfgNode *>(Targets);
   1101     Inst::destroy(Func);
   1102   }
   1103 
   1104   const SizeT Id;
   1105   const SizeT NumTargets;
   1106   CfgNode **Targets;
   1107   GlobalString Name; // This JumpTable's name in the output.
   1108   GlobalString FuncName;
   1109 };
   1110 
   1111 /// This instruction inserts an unconditional breakpoint.
   1112 ///
   1113 /// On x86, this assembles into an INT 3 instruction.
   1114 ///
   1115 /// This instruction is primarily meant for debugging the code generator.
   1116 class InstBreakpoint : public InstHighLevel {
   1117 public:
   1118   InstBreakpoint() = delete;
   1119   InstBreakpoint(const InstBreakpoint &) = delete;
   1120   InstBreakpoint &operator=(const InstBreakpoint &) = delete;
   1121 
   1122   explicit InstBreakpoint(Cfg *Func);
   1123   bool isMemoryWrite() const override { return false; }
   1124 
   1125 public:
   1126   static InstBreakpoint *create(Cfg *Func) {
   1127     return new (Func->allocate<InstBreakpoint>()) InstBreakpoint(Func);
   1128   }
   1129 
   1130   static bool classof(const Inst *Instr) {
   1131     return Instr->getKind() == Breakpoint;
   1132   }
   1133 };
   1134 
   1135 /// The Target instruction is the base class for all target-specific
   1136 /// instructions.
   1137 class InstTarget : public Inst {
   1138   InstTarget() = delete;
   1139   InstTarget(const InstTarget &) = delete;
   1140   InstTarget &operator=(const InstTarget &) = delete;
   1141 
   1142 public:
   1143   uint32_t getEmitInstCount() const override { return 1; }
   1144   bool isMemoryWrite() const override {
   1145     return true; // conservative answer
   1146   }
   1147   void dump(const Cfg *Func) const override;
   1148   static bool classof(const Inst *Instr) { return Instr->getKind() >= Target; }
   1149 
   1150 protected:
   1151   InstTarget(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest)
   1152       : Inst(Func, Kind, MaxSrcs, Dest) {
   1153     assert(Kind >= Target);
   1154     assert(Kind <= Target_Max);
   1155   }
   1156 };
   1157 
   1158 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source);
   1159 
   1160 } // end of namespace Ice
   1161 
   1162 #ifdef PNACL_LLVM
   1163 namespace llvm {
   1164 
   1165 /// Override the default ilist traits so that Inst's private ctor and deleted
   1166 /// dtor aren't invoked.
   1167 template <>
   1168 struct ilist_traits<Ice::Inst> : public ilist_default_traits<Ice::Inst> {
   1169   Ice::Inst *createSentinel() const {
   1170     return static_cast<Ice::Inst *>(&Sentinel);
   1171   }
   1172   static void destroySentinel(Ice::Inst *) {}
   1173   Ice::Inst *provideInitialHead() const { return createSentinel(); }
   1174   Ice::Inst *ensureHead(Ice::Inst *) const { return createSentinel(); }
   1175   static void noteHead(Ice::Inst *, Ice::Inst *) {}
   1176   void deleteNode(Ice::Inst *) {}
   1177 
   1178 private:
   1179   mutable ilist_half_node<Ice::Inst> Sentinel;
   1180 };
   1181 
   1182 } // end of namespace llvm
   1183 #endif // PNACL_LLVM
   1184 
   1185 namespace Ice {
   1186 
   1187 inline InstList::iterator instToIterator(Inst *Instr) {
   1188 #ifdef PNACL_LLVM
   1189   return Instr;
   1190 #else  // !PNACL_LLVM
   1191   return Instr->getIterator();
   1192 #endif // !PNACL_LLVM
   1193 }
   1194 
   1195 inline Inst *iteratorToInst(InstList::iterator Iter) { return &*Iter; }
   1196 
   1197 inline const Inst *iteratorToInst(InstList::const_iterator Iter) {
   1198   return &*Iter;
   1199 }
   1200 
   1201 inline InstList::iterator
   1202 reverseToForwardIterator(InstList::reverse_iterator RI) {
   1203 #ifdef PNACL_LLVM
   1204   return RI.base();
   1205 #else  // !PNACL_LLVM
   1206   return ++RI.getReverse();
   1207 #endif // !PNACL_LLVM
   1208 }
   1209 
   1210 } // end of namespace Ice
   1211 
   1212 #endif // SUBZERO_SRC_ICEINST_H
   1213