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