IceInst.h revision 41689df2f71c6bcf964248f58824bd6061e7f6c3
1f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth//===- subzero/src/IceInst.h - High-level instructions ----------*- C++ -*-===//
2f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth//
3f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth//                        The Subzero Code Generator
4f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth//
5f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// This file is distributed under the University of Illinois Open Source
6f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// License. See LICENSE.TXT for details.
7f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth//
8f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth//===----------------------------------------------------------------------===//
9f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth//
10f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// This file declares the Inst class and its target-independent
11f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// subclasses, which represent the high-level Vanilla ICE instructions
12f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// and map roughly 1:1 to LLVM instructions.
13f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth//
14f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth//===----------------------------------------------------------------------===//
15f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
16f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth#ifndef SUBZERO_SRC_ICEINST_H
17f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth#define SUBZERO_SRC_ICEINST_H
18f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
19f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth#include "IceDefs.h"
20f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth#include "IceInst.def"
213bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung#include "IceIntrinsics.h"
22f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth#include "IceTypes.h"
23f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
24f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// TODO: The Cfg structure, and instructions in particular, need to be
25f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// validated for things like valid operand types, valid branch
26f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// targets, proper ordering of Phi and non-Phi instructions, etc.
27f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Most of the validity checking will be done in the bitcode reader.
28f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// We need a list of everything that should be validated, and tests
29f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// for each.
30f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
31f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothnamespace Ice {
32f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
33f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothclass Inst {
34f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothpublic:
35f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  enum InstKind {
36f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    // Arbitrary (alphabetical) order, except put Unreachable first.
37f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    Unreachable,
38f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    Alloca,
39f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    Arithmetic,
40f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    Assign, // not part of LLVM/PNaCl bitcode
41f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    Br,
42f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    Call,
43f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    Cast,
4449889239d4c7ab296c7430722d36032d905110b6Matt Wala    ExtractElement,
45f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    Fcmp,
46f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    Icmp,
473bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung    IntrinsicCall,
4849889239d4c7ab296c7430722d36032d905110b6Matt Wala    InsertElement,
49f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    Load,
50f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    Phi,
51f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    Ret,
52f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    Select,
53f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    Store,
545bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth    Switch,
555bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth    FakeDef,  // not part of LLVM/PNaCl bitcode
565bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth    FakeUse,  // not part of LLVM/PNaCl bitcode
575bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth    FakeKill, // not part of LLVM/PNaCl bitcode
585bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth    Target    // target-specific low-level ICE
595bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth              // Anything >= Target is an InstTarget subclass.
60f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  };
61f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstKind getKind() const { return Kind; }
62f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
63d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  InstNumberT getNumber() const { return Number; }
64d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  void renumber(Cfg *Func);
65d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  static const InstNumberT NumberDeleted = -1;
66d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  static const InstNumberT NumberSentinel = 0;
67f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
68f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  bool isDeleted() const { return Deleted; }
69f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  void setDeleted() { Deleted = true; }
70d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  void deleteIfDead();
71f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
72f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  bool hasSideEffects() const { return HasSideEffects; }
73f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
74f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  Variable *getDest() const { return Dest; }
75f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
76f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  SizeT getSrcSize() const { return NumSrcs; }
77f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  Operand *getSrc(SizeT I) const {
78f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    assert(I < getSrcSize());
79f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return Srcs[I];
80f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
81f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
82d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  bool isLastUse(const Operand *Src) const;
83d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth
84f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  // Returns a list of out-edges corresponding to a terminator
85f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  // instruction, which is the last instruction of the block.
86f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual NodeList getTerminatorEdges() const {
87f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    // All valid terminator instructions override this method.  For
88f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    // the default implementation, we assert in case some CfgNode
89f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    // is constructed without a terminator instruction at the end.
90f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    llvm_unreachable(
91f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth        "getTerminatorEdges() called on a non-terminator instruction");
92f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return NodeList();
93f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
94f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
95f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  // Updates the status of the Variables contained within the
96f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  // instruction.  In particular, it marks where the Dest variable is
97f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  // first assigned, and it tracks whether variables are live across
98f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  // basic blocks, i.e. used in a different block from their definition.
99f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  void updateVars(CfgNode *Node);
100f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
101d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  void livenessLightweight(llvm::BitVector &Live);
102d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  void liveness(InstNumberT InstNumber, llvm::BitVector &Live,
103d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth                Liveness *Liveness, const CfgNode *Node);
1045bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  virtual void emit(const Cfg *Func) const;
105f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void dump(const Cfg *Func) const;
106d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  virtual void dumpExtras(const Cfg *Func) const;
107f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  void dumpDecorated(const Cfg *Func) const;
1085bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  void emitSources(const Cfg *Func) const;
109f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  void dumpSources(const Cfg *Func) const;
110f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  void dumpDest(const Cfg *Func) const;
1115bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  virtual bool isRedundantAssign() const { return false; }
112f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
113f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual ~Inst() {}
114f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
115f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothprotected:
116f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  Inst(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest);
117f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  void addSource(Operand *Src) {
118f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    assert(Src);
119f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    assert(NumSrcs < MaxSrcs);
120f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    Srcs[NumSrcs++] = Src;
121f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
122d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  void setLastUse(SizeT VarIndex) {
123d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth    if (VarIndex < CHAR_BIT * sizeof(LiveRangesEnded))
124d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth      LiveRangesEnded |= (((LREndedBits)1u) << VarIndex);
125d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  }
126d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  void resetLastUses() { LiveRangesEnded = 0; }
127f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  // The destroy() method lets the instruction cleanly release any
128f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  // memory that was allocated via the Cfg's allocator.
129f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void destroy(Cfg *Func) { Func->deallocateArrayOf<Operand *>(Srcs); }
130f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
131f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  const InstKind Kind;
132f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  // Number is the instruction number for describing live ranges.
133d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  InstNumberT Number;
134f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  // Deleted means irrevocably deleted.
135f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  bool Deleted;
136d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  // Dead means pending deletion after liveness analysis converges.
137d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  bool Dead;
138f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  // HasSideEffects means the instruction is something like a function
139f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  // call or a volatile load that can't be removed even if its Dest
140f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  // variable is not live.
141f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  bool HasSideEffects;
142f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
143f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  Variable *Dest;
144f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  const SizeT MaxSrcs; // only used for assert
145f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  SizeT NumSrcs;
146f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  Operand **Srcs;
147f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
148d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  // LiveRangesEnded marks which Variables' live ranges end in this
149d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  // instruction.  An instruction can have an arbitrary number of
150d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  // source operands (e.g. a call instruction), and each source
151d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  // operand can contain 0 or 1 Variable (and target-specific operands
152d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  // could contain more than 1 Variable).  All the variables in an
153d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  // instruction are conceptually flattened and each variable is
154d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  // mapped to one bit position of the LiveRangesEnded bit vector.
155d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  // Only the first CHAR_BIT * sizeof(LREndedBits) variables are
156d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  // tracked this way.
157d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  typedef uint32_t LREndedBits; // only first 32 src operands tracked, sorry
158d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  LREndedBits LiveRangesEnded;
159d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth
160f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothprivate:
161f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  Inst(const Inst &) LLVM_DELETED_FUNCTION;
162f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  Inst &operator=(const Inst &) LLVM_DELETED_FUNCTION;
163f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth};
164f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
165f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Alloca instruction.  This captures the size in bytes as getSrc(0),
166f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// and the required alignment in bytes.  The alignment must be either
167f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// 0 (no alignment required) or a power of 2.
168f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothclass InstAlloca : public Inst {
169f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothpublic:
170f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static InstAlloca *create(Cfg *Func, Operand *ByteCount,
171f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth                            uint32_t AlignInBytes, Variable *Dest) {
172f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return new (Func->allocateInst<InstAlloca>())
173f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth        InstAlloca(Func, ByteCount, AlignInBytes, Dest);
174f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
175f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  uint32_t getAlignInBytes() const { return AlignInBytes; }
176f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  Operand *getSizeInBytes() const { return getSrc(0); }
177f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void dump(const Cfg *Func) const;
178f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() == Alloca; }
179f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
180f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothprivate:
181f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstAlloca(Cfg *Func, Operand *ByteCount, uint32_t AlignInBytes,
182f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth             Variable *Dest);
183f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstAlloca(const InstAlloca &) LLVM_DELETED_FUNCTION;
184f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstAlloca &operator=(const InstAlloca &) LLVM_DELETED_FUNCTION;
185f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual ~InstAlloca() {}
186f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  const uint32_t AlignInBytes;
187f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth};
188f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
189f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Binary arithmetic instruction.  The source operands are captured in
190f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// getSrc(0) and getSrc(1).
191f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothclass InstArithmetic : public Inst {
192f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothpublic:
193f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  enum OpKind {
194f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth#define X(tag, str, commutative) tag,
195f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    ICEINSTARITHMETIC_TABLE
196f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth#undef X
1974376d2929a6d09055222f41600b165d3a2130657Jim Stichnoth        _num
198f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  };
1995bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth
200f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static InstArithmetic *create(Cfg *Func, OpKind Op, Variable *Dest,
201f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth                                Operand *Source1, Operand *Source2) {
202f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return new (Func->allocateInst<InstArithmetic>())
203f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth        InstArithmetic(Func, Op, Dest, Source1, Source2);
204f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
205f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  OpKind getOp() const { return Op; }
206d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf  static const char *getOpName(OpKind Op);
207f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  bool isCommutative() const;
208f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void dump(const Cfg *Func) const;
209f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static bool classof(const Inst *Inst) {
210f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return Inst->getKind() == Arithmetic;
211f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
212f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
213f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothprivate:
214f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstArithmetic(Cfg *Func, OpKind Op, Variable *Dest, Operand *Source1,
215f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth                 Operand *Source2);
216f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstArithmetic(const InstArithmetic &) LLVM_DELETED_FUNCTION;
217f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstArithmetic &operator=(const InstArithmetic &) LLVM_DELETED_FUNCTION;
218f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual ~InstArithmetic() {}
219f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
220f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  const OpKind Op;
221f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth};
222f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
223f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Assignment instruction.  The source operand is captured in
224f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// getSrc(0).  This is not part of the LLVM bitcode, but is a useful
225f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// abstraction for some of the lowering.  E.g., if Phi instruction
226f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// lowering happens before target lowering, or for representing an
227f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Inttoptr instruction, or as an intermediate step for lowering a
228f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Load instruction.
229f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothclass InstAssign : public Inst {
230f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothpublic:
231f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static InstAssign *create(Cfg *Func, Variable *Dest, Operand *Source) {
232f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return new (Func->allocateInst<InstAssign>())
233f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth        InstAssign(Func, Dest, Source);
234f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
235f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void dump(const Cfg *Func) const;
236f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() == Assign; }
237f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
238f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothprivate:
239f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstAssign(Cfg *Func, Variable *Dest, Operand *Source);
240f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstAssign(const InstAssign &) LLVM_DELETED_FUNCTION;
241f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstAssign &operator=(const InstAssign &) LLVM_DELETED_FUNCTION;
242f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual ~InstAssign() {}
243f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth};
244f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
245f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Branch instruction.  This represents both conditional and
246f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// unconditional branches.
247f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothclass InstBr : public Inst {
248f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothpublic:
249f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  // Create a conditional branch.  If TargetTrue==TargetFalse, it is
250f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  // optimized to an unconditional branch.
251f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static InstBr *create(Cfg *Func, Operand *Source, CfgNode *TargetTrue,
252f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth                        CfgNode *TargetFalse) {
253f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return new (Func->allocateInst<InstBr>())
254f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth        InstBr(Func, Source, TargetTrue, TargetFalse);
255f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
256f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  // Create an unconditional branch.
257f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static InstBr *create(Cfg *Func, CfgNode *Target) {
258f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return new (Func->allocateInst<InstBr>()) InstBr(Func, Target);
259f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
260f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  bool isUnconditional() const { return getTargetTrue() == NULL; }
261f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  Operand *getCondition() const {
262f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    assert(!isUnconditional());
263f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return getSrc(0);
264f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
265f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  CfgNode *getTargetTrue() const { return TargetTrue; }
266f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  CfgNode *getTargetFalse() const { return TargetFalse; }
267f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  CfgNode *getTargetUnconditional() const {
268f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    assert(isUnconditional());
269f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return getTargetFalse();
270f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
271f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual NodeList getTerminatorEdges() const;
272f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void dump(const Cfg *Func) const;
273f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() == Br; }
274f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
275f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothprivate:
276f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  // Conditional branch
277f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstBr(Cfg *Func, Operand *Source, CfgNode *TargetTrue, CfgNode *TargetFalse);
278f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  // Unconditional branch
279f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstBr(Cfg *Func, CfgNode *Target);
280f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstBr(const InstBr &) LLVM_DELETED_FUNCTION;
281f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstBr &operator=(const InstBr &) LLVM_DELETED_FUNCTION;
282f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual ~InstBr() {}
283f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
284f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  CfgNode *const TargetFalse; // Doubles as unconditional branch target
285f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  CfgNode *const TargetTrue;  // NULL if unconditional branch
286f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth};
287f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
288f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Call instruction.  The call target is captured as getSrc(0), and
289f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// arg I is captured as getSrc(I+1).
290f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothclass InstCall : public Inst {
291f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothpublic:
292f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static InstCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest,
293f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth                          Operand *CallTarget) {
2943bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung    // Set HasSideEffects to true so that the call instruction can't be
2953bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung    // dead-code eliminated. IntrinsicCalls can override this if the
2963bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung    // particular intrinsic is deletable and has no side-effects.
2973bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung    const bool HasSideEffects = true;
2983bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung    const InstKind Kind = Inst::Call;
299f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return new (Func->allocateInst<InstCall>())
3003bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung        InstCall(Func, NumArgs, Dest, CallTarget, HasSideEffects, Kind);
301f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
302f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  void addArg(Operand *Arg) { addSource(Arg); }
303f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  Operand *getCallTarget() const { return getSrc(0); }
304f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  Operand *getArg(SizeT I) const { return getSrc(I + 1); }
305f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  SizeT getNumArgs() const { return getSrcSize() - 1; }
306f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void dump(const Cfg *Func) const;
307f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() == Call; }
308f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
3093bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voungprotected:
3103bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung  InstCall(Cfg *Func, SizeT NumArgs, Variable *Dest, Operand *CallTarget,
3113bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung           bool HasSideEff, InstKind Kind)
3123bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung      : Inst(Func, Kind, NumArgs + 1, Dest) {
3133bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung    HasSideEffects = HasSideEff;
314f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    addSource(CallTarget);
315f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
3163bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung  virtual ~InstCall() {}
3173bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung
3183bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voungprivate:
319f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstCall(const InstCall &) LLVM_DELETED_FUNCTION;
320f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstCall &operator=(const InstCall &) LLVM_DELETED_FUNCTION;
321f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth};
322f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
323f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Cast instruction (a.k.a. conversion operation).
324f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothclass InstCast : public Inst {
325f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothpublic:
326f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  enum OpKind {
327f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth#define X(tag, str) tag,
328f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    ICEINSTCAST_TABLE
329f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth#undef X
3304376d2929a6d09055222f41600b165d3a2130657Jim Stichnoth        _num
331f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  };
3325bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth
333f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static InstCast *create(Cfg *Func, OpKind CastKind, Variable *Dest,
334f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth                          Operand *Source) {
335f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return new (Func->allocateInst<InstCast>())
336f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth        InstCast(Func, CastKind, Dest, Source);
337f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
338f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  OpKind getCastKind() const { return CastKind; }
339f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void dump(const Cfg *Func) const;
340f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() == Cast; }
341f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
342f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothprivate:
343f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstCast(Cfg *Func, OpKind CastKind, Variable *Dest, Operand *Source);
344f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstCast(const InstCast &) LLVM_DELETED_FUNCTION;
345f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstCast &operator=(const InstCast &) LLVM_DELETED_FUNCTION;
346f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual ~InstCast() {}
347f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  const OpKind CastKind;
348f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth};
349f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
35049889239d4c7ab296c7430722d36032d905110b6Matt Wala// ExtractElement instruction.
35149889239d4c7ab296c7430722d36032d905110b6Matt Walaclass InstExtractElement : public Inst {
35249889239d4c7ab296c7430722d36032d905110b6Matt Walapublic:
35349889239d4c7ab296c7430722d36032d905110b6Matt Wala  static InstExtractElement *create(Cfg *Func, Variable *Dest, Operand *Source1,
35449889239d4c7ab296c7430722d36032d905110b6Matt Wala                                    Operand *Source2) {
35549889239d4c7ab296c7430722d36032d905110b6Matt Wala    return new (Func->allocateInst<InstExtractElement>())
35649889239d4c7ab296c7430722d36032d905110b6Matt Wala        InstExtractElement(Func, Dest, Source1, Source2);
35749889239d4c7ab296c7430722d36032d905110b6Matt Wala  }
35849889239d4c7ab296c7430722d36032d905110b6Matt Wala
35949889239d4c7ab296c7430722d36032d905110b6Matt Wala  virtual void dump(const Cfg *Func) const;
36049889239d4c7ab296c7430722d36032d905110b6Matt Wala  static bool classof(const Inst *Inst) {
36149889239d4c7ab296c7430722d36032d905110b6Matt Wala    return Inst->getKind() == ExtractElement;
36249889239d4c7ab296c7430722d36032d905110b6Matt Wala  }
36349889239d4c7ab296c7430722d36032d905110b6Matt Wala
36449889239d4c7ab296c7430722d36032d905110b6Matt Walaprivate:
36549889239d4c7ab296c7430722d36032d905110b6Matt Wala  InstExtractElement(Cfg *Func, Variable *Dest, Operand *Source1,
36649889239d4c7ab296c7430722d36032d905110b6Matt Wala                     Operand *Source2);
36749889239d4c7ab296c7430722d36032d905110b6Matt Wala  InstExtractElement(const InstExtractElement &) LLVM_DELETED_FUNCTION;
36849889239d4c7ab296c7430722d36032d905110b6Matt Wala  InstExtractElement &
36949889239d4c7ab296c7430722d36032d905110b6Matt Wala  operator=(const InstExtractElement &) LLVM_DELETED_FUNCTION;
37049889239d4c7ab296c7430722d36032d905110b6Matt Wala  virtual ~InstExtractElement() {}
37149889239d4c7ab296c7430722d36032d905110b6Matt Wala};
37249889239d4c7ab296c7430722d36032d905110b6Matt Wala
373f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Floating-point comparison instruction.  The source operands are
374f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// captured in getSrc(0) and getSrc(1).
375f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothclass InstFcmp : public Inst {
376f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothpublic:
377f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  enum FCond {
378f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth#define X(tag, str) tag,
379f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    ICEINSTFCMP_TABLE
380f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth#undef X
3814376d2929a6d09055222f41600b165d3a2130657Jim Stichnoth        _num
382f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  };
3835bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth
384f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static InstFcmp *create(Cfg *Func, FCond Condition, Variable *Dest,
385f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth                          Operand *Source1, Operand *Source2) {
386f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return new (Func->allocateInst<InstFcmp>())
387f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth        InstFcmp(Func, Condition, Dest, Source1, Source2);
388f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
389f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  FCond getCondition() const { return Condition; }
390f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void dump(const Cfg *Func) const;
391f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() == Fcmp; }
392f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
393f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothprivate:
394f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstFcmp(Cfg *Func, FCond Condition, Variable *Dest, Operand *Source1,
395f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth           Operand *Source2);
396f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstFcmp(const InstFcmp &) LLVM_DELETED_FUNCTION;
397f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstFcmp &operator=(const InstFcmp &) LLVM_DELETED_FUNCTION;
398f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual ~InstFcmp() {}
399f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  const FCond Condition;
400f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth};
401f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
402f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Integer comparison instruction.  The source operands are captured
403f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// in getSrc(0) and getSrc(1).
404f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothclass InstIcmp : public Inst {
405f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothpublic:
406f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  enum ICond {
407f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth#define X(tag, str) tag,
408f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    ICEINSTICMP_TABLE
409f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth#undef X
4104376d2929a6d09055222f41600b165d3a2130657Jim Stichnoth        _num
411f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  };
4125bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth
413f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static InstIcmp *create(Cfg *Func, ICond Condition, Variable *Dest,
414f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth                          Operand *Source1, Operand *Source2) {
415f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return new (Func->allocateInst<InstIcmp>())
416f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth        InstIcmp(Func, Condition, Dest, Source1, Source2);
417f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
418f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  ICond getCondition() const { return Condition; }
419f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void dump(const Cfg *Func) const;
420f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() == Icmp; }
421f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
422f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothprivate:
423f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstIcmp(Cfg *Func, ICond Condition, Variable *Dest, Operand *Source1,
424f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth           Operand *Source2);
425f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstIcmp(const InstIcmp &) LLVM_DELETED_FUNCTION;
426f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstIcmp &operator=(const InstIcmp &) LLVM_DELETED_FUNCTION;
427f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual ~InstIcmp() {}
428f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  const ICond Condition;
429f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth};
430f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
43149889239d4c7ab296c7430722d36032d905110b6Matt Wala// InsertElement instruction.
43249889239d4c7ab296c7430722d36032d905110b6Matt Walaclass InstInsertElement : public Inst {
43349889239d4c7ab296c7430722d36032d905110b6Matt Walapublic:
43449889239d4c7ab296c7430722d36032d905110b6Matt Wala  static InstInsertElement *create(Cfg *Func, Variable *Dest, Operand *Source1,
43549889239d4c7ab296c7430722d36032d905110b6Matt Wala                                   Operand *Source2, Operand *Source3) {
43649889239d4c7ab296c7430722d36032d905110b6Matt Wala    return new (Func->allocateInst<InstInsertElement>())
43749889239d4c7ab296c7430722d36032d905110b6Matt Wala        InstInsertElement(Func, Dest, Source1, Source2, Source3);
43849889239d4c7ab296c7430722d36032d905110b6Matt Wala  }
43949889239d4c7ab296c7430722d36032d905110b6Matt Wala
44049889239d4c7ab296c7430722d36032d905110b6Matt Wala  virtual void dump(const Cfg *Func) const;
44149889239d4c7ab296c7430722d36032d905110b6Matt Wala  static bool classof(const Inst *Inst) {
44249889239d4c7ab296c7430722d36032d905110b6Matt Wala    return Inst->getKind() == InsertElement;
44349889239d4c7ab296c7430722d36032d905110b6Matt Wala  }
44449889239d4c7ab296c7430722d36032d905110b6Matt Wala
44549889239d4c7ab296c7430722d36032d905110b6Matt Walaprivate:
44649889239d4c7ab296c7430722d36032d905110b6Matt Wala  InstInsertElement(Cfg *Func, Variable *Dest, Operand *Source1,
44749889239d4c7ab296c7430722d36032d905110b6Matt Wala                    Operand *Source2, Operand *Source3);
44849889239d4c7ab296c7430722d36032d905110b6Matt Wala  InstInsertElement(const InstInsertElement &) LLVM_DELETED_FUNCTION;
44949889239d4c7ab296c7430722d36032d905110b6Matt Wala  InstInsertElement &operator=(const InstInsertElement &) LLVM_DELETED_FUNCTION;
45049889239d4c7ab296c7430722d36032d905110b6Matt Wala  virtual ~InstInsertElement() {}
45149889239d4c7ab296c7430722d36032d905110b6Matt Wala};
45249889239d4c7ab296c7430722d36032d905110b6Matt Wala
4533bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung// Call to an intrinsic function.  The call target is captured as getSrc(0),
4543bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung// and arg I is captured as getSrc(I+1).
4553bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voungclass InstIntrinsicCall : public InstCall {
4563bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voungpublic:
4573bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung  static InstIntrinsicCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest,
4583bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung                                   Operand *CallTarget,
4593bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung                                   const Intrinsics::IntrinsicInfo &Info) {
4603bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung    return new (Func->allocateInst<InstIntrinsicCall>())
4613bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung        InstIntrinsicCall(Func, NumArgs, Dest, CallTarget, Info);
4623bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung  }
4633bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung  static bool classof(const Inst *Inst) {
4643bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung    return Inst->getKind() == IntrinsicCall;
4653bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung  }
4663bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung
4673bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung  Intrinsics::IntrinsicInfo getIntrinsicInfo() const { return Info; }
4683bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung
4693bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voungprivate:
4703bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung  InstIntrinsicCall(Cfg *Func, SizeT NumArgs, Variable *Dest,
4713bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung                    Operand *CallTarget, const Intrinsics::IntrinsicInfo &Info)
4723bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung      : InstCall(Func, NumArgs, Dest, CallTarget, Info.HasSideEffects,
4733bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung                 Inst::IntrinsicCall),
4743bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung        Info(Info) {}
4753bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung  InstIntrinsicCall(const InstIntrinsicCall &) LLVM_DELETED_FUNCTION;
4763bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung  InstIntrinsicCall &operator=(const InstIntrinsicCall &) LLVM_DELETED_FUNCTION;
4773bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung  virtual ~InstIntrinsicCall() {}
4783bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung  const Intrinsics::IntrinsicInfo Info;
4793bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung};
4803bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung
481f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Load instruction.  The source address is captured in getSrc(0).
482f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothclass InstLoad : public Inst {
483f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothpublic:
48441689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf  static InstLoad *create(Cfg *Func, Variable *Dest, Operand *SourceAddr,
48541689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf                          uint32_t align = 1) {
48641689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf    // TODO(kschimpf) Stop ignoring alignment specification.
48741689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf    (void)align;
488f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return new (Func->allocateInst<InstLoad>())
489f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth        InstLoad(Func, Dest, SourceAddr);
490f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
491f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  Operand *getSourceAddress() const { return getSrc(0); }
492f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void dump(const Cfg *Func) const;
493f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() == Load; }
494f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
495f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothprivate:
496f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstLoad(Cfg *Func, Variable *Dest, Operand *SourceAddr);
497f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstLoad(const InstLoad &) LLVM_DELETED_FUNCTION;
498f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstLoad &operator=(const InstLoad &) LLVM_DELETED_FUNCTION;
499f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual ~InstLoad() {}
500f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth};
501f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
502f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Phi instruction.  For incoming edge I, the node is Labels[I] and
503f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// the Phi source operand is getSrc(I).
504f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothclass InstPhi : public Inst {
505f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothpublic:
506f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static InstPhi *create(Cfg *Func, SizeT MaxSrcs, Variable *Dest) {
507f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return new (Func->allocateInst<InstPhi>()) InstPhi(Func, MaxSrcs, Dest);
508f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
509f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  void addArgument(Operand *Source, CfgNode *Label);
5105bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  Operand *getOperandForTarget(CfgNode *Target) const;
511d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  void livenessPhiOperand(llvm::BitVector &Live, CfgNode *Target,
512d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth                          Liveness *Liveness);
5135bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  Inst *lower(Cfg *Func, CfgNode *Node);
514f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void dump(const Cfg *Func) const;
515f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() == Phi; }
516f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
517f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothprivate:
518f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstPhi(Cfg *Func, SizeT MaxSrcs, Variable *Dest);
519f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstPhi(const InstPhi &) LLVM_DELETED_FUNCTION;
520f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstPhi &operator=(const InstPhi &) LLVM_DELETED_FUNCTION;
521f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void destroy(Cfg *Func) {
522f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    Func->deallocateArrayOf<CfgNode *>(Labels);
523f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    Inst::destroy(Func);
524f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
525f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual ~InstPhi() {}
526f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
527f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  // Labels[] duplicates the InEdges[] information in the enclosing
528f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  // CfgNode, but the Phi instruction is created before InEdges[]
529f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  // is available, so it's more complicated to share the list.
530f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  CfgNode **Labels;
531f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth};
532f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
533f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Ret instruction.  The return value is captured in getSrc(0), but if
534f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// there is no return value (void-type function), then
535f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// getSrcSize()==0 and hasRetValue()==false.
536f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothclass InstRet : public Inst {
537f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothpublic:
538f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static InstRet *create(Cfg *Func, Operand *RetValue = NULL) {
539f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return new (Func->allocateInst<InstRet>()) InstRet(Func, RetValue);
540f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
541f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  bool hasRetValue() const { return getSrcSize(); }
542f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  Operand *getRetValue() const {
543f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    assert(hasRetValue());
544f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return getSrc(0);
545f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
546f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual NodeList getTerminatorEdges() const { return NodeList(); }
547f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void dump(const Cfg *Func) const;
548f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() == Ret; }
549f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
550f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothprivate:
551f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstRet(Cfg *Func, Operand *RetValue);
552f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstRet(const InstRet &) LLVM_DELETED_FUNCTION;
553f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstRet &operator=(const InstRet &) LLVM_DELETED_FUNCTION;
554f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual ~InstRet() {}
555f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth};
556f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
557f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Select instruction.  The condition, true, and false operands are captured.
558f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothclass InstSelect : public Inst {
559f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothpublic:
560f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static InstSelect *create(Cfg *Func, Variable *Dest, Operand *Condition,
561f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth                            Operand *SourceTrue, Operand *SourceFalse) {
562f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return new (Func->allocateInst<InstSelect>())
563f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth        InstSelect(Func, Dest, Condition, SourceTrue, SourceFalse);
564f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
565f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  Operand *getCondition() const { return getSrc(0); }
566f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  Operand *getTrueOperand() const { return getSrc(1); }
567f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  Operand *getFalseOperand() const { return getSrc(2); }
568f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void dump(const Cfg *Func) const;
569f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() == Select; }
570f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
571f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothprivate:
572f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstSelect(Cfg *Func, Variable *Dest, Operand *Condition, Operand *Source1,
573f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth             Operand *Source2);
574f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstSelect(const InstSelect &) LLVM_DELETED_FUNCTION;
575f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstSelect &operator=(const InstSelect &) LLVM_DELETED_FUNCTION;
576f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual ~InstSelect() {}
577f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth};
578f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
579f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Store instruction.  The address operand is captured, along with the
580f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// data operand to be stored into the address.
581f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothclass InstStore : public Inst {
582f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothpublic:
58341689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf  static InstStore *create(Cfg *Func, Operand *Data, Operand *Addr,
58441689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf                           uint32_t align = 1) {
58541689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf    // TODO(kschimpf) Stop ignoring alignment specification.
58641689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf    (void)align;
587f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return new (Func->allocateInst<InstStore>()) InstStore(Func, Data, Addr);
588f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
589f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  Operand *getAddr() const { return getSrc(1); }
590f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  Operand *getData() const { return getSrc(0); }
591f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void dump(const Cfg *Func) const;
592f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() == Store; }
593f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
594f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothprivate:
595f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstStore(Cfg *Func, Operand *Data, Operand *Addr);
596f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstStore(const InstStore &) LLVM_DELETED_FUNCTION;
597f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstStore &operator=(const InstStore &) LLVM_DELETED_FUNCTION;
598f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual ~InstStore() {}
599f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth};
600f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
601f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Switch instruction.  The single source operand is captured as
602f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// getSrc(0).
603f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothclass InstSwitch : public Inst {
604f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothpublic:
605f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static InstSwitch *create(Cfg *Func, SizeT NumCases, Operand *Source,
606f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth                            CfgNode *LabelDefault) {
607f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return new (Func->allocateInst<InstSwitch>())
608f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth        InstSwitch(Func, NumCases, Source, LabelDefault);
609f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
610f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  Operand *getComparison() const { return getSrc(0); }
611f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  CfgNode *getLabelDefault() const { return LabelDefault; }
612f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  SizeT getNumCases() const { return NumCases; }
613f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  uint64_t getValue(SizeT I) const {
614f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    assert(I < NumCases);
615f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return Values[I];
616f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
617f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  CfgNode *getLabel(SizeT I) const {
618f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    assert(I < NumCases);
619f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return Labels[I];
620f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
621f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  void addBranch(SizeT CaseIndex, uint64_t Value, CfgNode *Label);
622f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual NodeList getTerminatorEdges() const;
623f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void dump(const Cfg *Func) const;
624f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() == Switch; }
625f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
626f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothprivate:
627f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstSwitch(Cfg *Func, SizeT NumCases, Operand *Source, CfgNode *LabelDefault);
628f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstSwitch(const InstSwitch &) LLVM_DELETED_FUNCTION;
629f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstSwitch &operator=(const InstSwitch &) LLVM_DELETED_FUNCTION;
630f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void destroy(Cfg *Func) {
631f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    Func->deallocateArrayOf<uint64_t>(Values);
632f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    Func->deallocateArrayOf<CfgNode *>(Labels);
633f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    Inst::destroy(Func);
634f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
635f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual ~InstSwitch() {}
636f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
637f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  CfgNode *LabelDefault;
638f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  SizeT NumCases;   // not including the default case
639f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  uint64_t *Values; // size is NumCases
640f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  CfgNode **Labels; // size is NumCases
641f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth};
642f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
643f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Unreachable instruction.  This is a terminator instruction with no
644f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// operands.
645f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothclass InstUnreachable : public Inst {
646f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothpublic:
647f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static InstUnreachable *create(Cfg *Func) {
648f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return new (Func->allocateInst<InstUnreachable>()) InstUnreachable(Func);
649f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
650f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual NodeList getTerminatorEdges() const { return NodeList(); }
651f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void dump(const Cfg *Func) const;
652f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static bool classof(const Inst *Inst) {
653f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return Inst->getKind() == Unreachable;
654f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
655f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
656f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothprivate:
657f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstUnreachable(Cfg *Func);
658f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstUnreachable(const InstUnreachable &) LLVM_DELETED_FUNCTION;
659f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstUnreachable &operator=(const InstUnreachable &) LLVM_DELETED_FUNCTION;
660f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual ~InstUnreachable() {}
661f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth};
662f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
6635bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// FakeDef instruction.  This creates a fake definition of a variable,
6645bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// which is how we represent the case when an instruction produces
6655bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// multiple results.  This doesn't happen with high-level ICE
6665bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// instructions, but might with lowered instructions.  For example,
6675bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// this would be a way to represent condition flags being modified by
6685bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// an instruction.
6695bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth//
6705bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// It's generally useful to set the optional source operand to be the
6715bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// dest variable of the instruction that actually produces the FakeDef
6725bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// dest.  Otherwise, the original instruction could be dead-code
6735bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// eliminated if its dest operand is unused, and therefore the FakeDef
6745bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// dest wouldn't be properly initialized.
6755bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnothclass InstFakeDef : public Inst {
6765bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnothpublic:
6775bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  static InstFakeDef *create(Cfg *Func, Variable *Dest, Variable *Src = NULL) {
6785bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth    return new (Func->allocateInst<InstFakeDef>()) InstFakeDef(Func, Dest, Src);
6795bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  }
6805bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  virtual void emit(const Cfg *Func) const;
6815bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  virtual void dump(const Cfg *Func) const;
6825bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() == FakeDef; }
6835bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth
6845bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnothprivate:
6855bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  InstFakeDef(Cfg *Func, Variable *Dest, Variable *Src);
6865bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  InstFakeDef(const InstFakeDef &) LLVM_DELETED_FUNCTION;
6875bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  InstFakeDef &operator=(const InstFakeDef &) LLVM_DELETED_FUNCTION;
6885bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  virtual ~InstFakeDef() {}
6895bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth};
6905bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth
6915bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// FakeUse instruction.  This creates a fake use of a variable, to
6925bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// keep the instruction that produces that variable from being
6935bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// dead-code eliminated.  This is useful in a variety of lowering
6945bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// situations.  The FakeUse instruction has no dest, so it can itself
6955bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// never be dead-code eliminated.
6965bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnothclass InstFakeUse : public Inst {
6975bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnothpublic:
6985bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  static InstFakeUse *create(Cfg *Func, Variable *Src) {
6995bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth    return new (Func->allocateInst<InstFakeUse>()) InstFakeUse(Func, Src);
7005bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  }
7015bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  virtual void emit(const Cfg *Func) const;
7025bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  virtual void dump(const Cfg *Func) const;
7035bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() == FakeUse; }
7045bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth
7055bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnothprivate:
7065bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  InstFakeUse(Cfg *Func, Variable *Src);
7075bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  InstFakeUse(const InstFakeUse &) LLVM_DELETED_FUNCTION;
7085bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  InstFakeUse &operator=(const InstFakeUse &) LLVM_DELETED_FUNCTION;
7095bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  virtual ~InstFakeUse() {}
7105bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth};
7115bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth
7125bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// FakeKill instruction.  This "kills" a set of variables by adding a
7135bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// trivial live range at this instruction to each variable.  The
7145bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// primary use is to indicate that scratch registers are killed after
7155bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// a call, so that the register allocator won't assign a scratch
7165bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// register to a variable whose live range spans a call.
7175bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth//
7185bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// The FakeKill instruction also holds a pointer to the instruction
7195bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// that kills the set of variables, so that if that linked instruction
7205bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// gets dead-code eliminated, the FakeKill instruction will as well.
7215bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnothclass InstFakeKill : public Inst {
7225bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnothpublic:
7235bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  static InstFakeKill *create(Cfg *Func, const VarList &KilledRegs,
7245bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth                              const Inst *Linked) {
7255bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth    return new (Func->allocateInst<InstFakeKill>())
7265bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth        InstFakeKill(Func, KilledRegs, Linked);
7275bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  }
7285bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  const Inst *getLinked() const { return Linked; }
7295bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  virtual void emit(const Cfg *Func) const;
7305bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  virtual void dump(const Cfg *Func) const;
7315bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() == FakeKill; }
7325bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth
7335bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnothprivate:
7345bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  InstFakeKill(Cfg *Func, const VarList &KilledRegs, const Inst *Linked);
7355bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  InstFakeKill(const InstFakeKill &) LLVM_DELETED_FUNCTION;
7365bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  InstFakeKill &operator=(const InstFakeKill &) LLVM_DELETED_FUNCTION;
7375bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  virtual ~InstFakeKill() {}
7385bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth
7395bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  // This instruction is ignored if Linked->isDeleted() is true.
7405bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  const Inst *Linked;
7415bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth};
7425bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth
7435bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// The Target instruction is the base class for all target-specific
7445bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// instructions.
7455bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnothclass InstTarget : public Inst {
7465bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnothpublic:
7475bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  virtual void emit(const Cfg *Func) const = 0;
7485bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  virtual void dump(const Cfg *Func) const;
749d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  virtual void dumpExtras(const Cfg *Func) const;
7505bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() >= Target; }
7515bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth
7525bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnothprotected:
7535bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  InstTarget(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest)
7545bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth      : Inst(Func, Kind, MaxSrcs, Dest) {
7555bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth    assert(Kind >= Target);
7565bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  }
7575bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  InstTarget(const InstTarget &) LLVM_DELETED_FUNCTION;
7585bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  InstTarget &operator=(const InstTarget &) LLVM_DELETED_FUNCTION;
7595bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  virtual ~InstTarget() {}
7605bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth};
7615bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth
762f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth} // end of namespace Ice
763f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
764f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth#endif // SUBZERO_SRC_ICEINST_H
765