IceInst.h revision 49889239d4c7ab296c7430722d36032d905110b6
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; }
206f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  bool isCommutative() const;
207f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void dump(const Cfg *Func) const;
208f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static bool classof(const Inst *Inst) {
209f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return Inst->getKind() == Arithmetic;
210f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
211f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
212f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothprivate:
213f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstArithmetic(Cfg *Func, OpKind Op, Variable *Dest, Operand *Source1,
214f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth                 Operand *Source2);
215f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstArithmetic(const InstArithmetic &) LLVM_DELETED_FUNCTION;
216f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstArithmetic &operator=(const InstArithmetic &) LLVM_DELETED_FUNCTION;
217f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual ~InstArithmetic() {}
218f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
219f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  const OpKind Op;
220f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth};
221f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
222f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Assignment instruction.  The source operand is captured in
223f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// getSrc(0).  This is not part of the LLVM bitcode, but is a useful
224f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// abstraction for some of the lowering.  E.g., if Phi instruction
225f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// lowering happens before target lowering, or for representing an
226f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Inttoptr instruction, or as an intermediate step for lowering a
227f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Load instruction.
228f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothclass InstAssign : public Inst {
229f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothpublic:
230f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static InstAssign *create(Cfg *Func, Variable *Dest, Operand *Source) {
231f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return new (Func->allocateInst<InstAssign>())
232f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth        InstAssign(Func, Dest, Source);
233f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
234f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void dump(const Cfg *Func) const;
235f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() == Assign; }
236f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
237f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothprivate:
238f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstAssign(Cfg *Func, Variable *Dest, Operand *Source);
239f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstAssign(const InstAssign &) LLVM_DELETED_FUNCTION;
240f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstAssign &operator=(const InstAssign &) LLVM_DELETED_FUNCTION;
241f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual ~InstAssign() {}
242f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth};
243f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
244f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Branch instruction.  This represents both conditional and
245f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// unconditional branches.
246f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothclass InstBr : public Inst {
247f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothpublic:
248f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  // Create a conditional branch.  If TargetTrue==TargetFalse, it is
249f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  // optimized to an unconditional branch.
250f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static InstBr *create(Cfg *Func, Operand *Source, CfgNode *TargetTrue,
251f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth                        CfgNode *TargetFalse) {
252f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return new (Func->allocateInst<InstBr>())
253f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth        InstBr(Func, Source, TargetTrue, TargetFalse);
254f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
255f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  // Create an unconditional branch.
256f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static InstBr *create(Cfg *Func, CfgNode *Target) {
257f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return new (Func->allocateInst<InstBr>()) InstBr(Func, Target);
258f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
259f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  bool isUnconditional() const { return getTargetTrue() == NULL; }
260f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  Operand *getCondition() const {
261f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    assert(!isUnconditional());
262f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return getSrc(0);
263f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
264f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  CfgNode *getTargetTrue() const { return TargetTrue; }
265f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  CfgNode *getTargetFalse() const { return TargetFalse; }
266f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  CfgNode *getTargetUnconditional() const {
267f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    assert(isUnconditional());
268f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return getTargetFalse();
269f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
270f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual NodeList getTerminatorEdges() const;
271f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void dump(const Cfg *Func) const;
272f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() == Br; }
273f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
274f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothprivate:
275f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  // Conditional branch
276f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstBr(Cfg *Func, Operand *Source, CfgNode *TargetTrue, CfgNode *TargetFalse);
277f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  // Unconditional branch
278f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstBr(Cfg *Func, CfgNode *Target);
279f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstBr(const InstBr &) LLVM_DELETED_FUNCTION;
280f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstBr &operator=(const InstBr &) LLVM_DELETED_FUNCTION;
281f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual ~InstBr() {}
282f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
283f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  CfgNode *const TargetFalse; // Doubles as unconditional branch target
284f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  CfgNode *const TargetTrue;  // NULL if unconditional branch
285f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth};
286f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
287f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Call instruction.  The call target is captured as getSrc(0), and
288f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// arg I is captured as getSrc(I+1).
289f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothclass InstCall : public Inst {
290f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothpublic:
291f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static InstCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest,
292f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth                          Operand *CallTarget) {
2933bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung    // Set HasSideEffects to true so that the call instruction can't be
2943bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung    // dead-code eliminated. IntrinsicCalls can override this if the
2953bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung    // particular intrinsic is deletable and has no side-effects.
2963bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung    const bool HasSideEffects = true;
2973bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung    const InstKind Kind = Inst::Call;
298f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return new (Func->allocateInst<InstCall>())
2993bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung        InstCall(Func, NumArgs, Dest, CallTarget, HasSideEffects, Kind);
300f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
301f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  void addArg(Operand *Arg) { addSource(Arg); }
302f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  Operand *getCallTarget() const { return getSrc(0); }
303f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  Operand *getArg(SizeT I) const { return getSrc(I + 1); }
304f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  SizeT getNumArgs() const { return getSrcSize() - 1; }
305f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void dump(const Cfg *Func) const;
306f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() == Call; }
307f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
3083bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voungprotected:
3093bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung  InstCall(Cfg *Func, SizeT NumArgs, Variable *Dest, Operand *CallTarget,
3103bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung           bool HasSideEff, InstKind Kind)
3113bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung      : Inst(Func, Kind, NumArgs + 1, Dest) {
3123bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung    HasSideEffects = HasSideEff;
313f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    addSource(CallTarget);
314f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
3153bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung  virtual ~InstCall() {}
3163bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung
3173bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voungprivate:
318f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstCall(const InstCall &) LLVM_DELETED_FUNCTION;
319f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstCall &operator=(const InstCall &) LLVM_DELETED_FUNCTION;
320f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth};
321f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
322f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Cast instruction (a.k.a. conversion operation).
323f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothclass InstCast : public Inst {
324f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothpublic:
325f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  enum OpKind {
326f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth#define X(tag, str) tag,
327f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    ICEINSTCAST_TABLE
328f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth#undef X
3294376d2929a6d09055222f41600b165d3a2130657Jim Stichnoth        _num
330f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  };
3315bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth
332f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static InstCast *create(Cfg *Func, OpKind CastKind, Variable *Dest,
333f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth                          Operand *Source) {
334f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return new (Func->allocateInst<InstCast>())
335f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth        InstCast(Func, CastKind, Dest, Source);
336f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
337f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  OpKind getCastKind() const { return CastKind; }
338f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void dump(const Cfg *Func) const;
339f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() == Cast; }
340f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
341f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothprivate:
342f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstCast(Cfg *Func, OpKind CastKind, Variable *Dest, Operand *Source);
343f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstCast(const InstCast &) LLVM_DELETED_FUNCTION;
344f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstCast &operator=(const InstCast &) LLVM_DELETED_FUNCTION;
345f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual ~InstCast() {}
346f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  const OpKind CastKind;
347f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth};
348f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
34949889239d4c7ab296c7430722d36032d905110b6Matt Wala// ExtractElement instruction.
35049889239d4c7ab296c7430722d36032d905110b6Matt Walaclass InstExtractElement : public Inst {
35149889239d4c7ab296c7430722d36032d905110b6Matt Walapublic:
35249889239d4c7ab296c7430722d36032d905110b6Matt Wala  static InstExtractElement *create(Cfg *Func, Variable *Dest, Operand *Source1,
35349889239d4c7ab296c7430722d36032d905110b6Matt Wala                                    Operand *Source2) {
35449889239d4c7ab296c7430722d36032d905110b6Matt Wala    return new (Func->allocateInst<InstExtractElement>())
35549889239d4c7ab296c7430722d36032d905110b6Matt Wala        InstExtractElement(Func, Dest, Source1, Source2);
35649889239d4c7ab296c7430722d36032d905110b6Matt Wala  }
35749889239d4c7ab296c7430722d36032d905110b6Matt Wala
35849889239d4c7ab296c7430722d36032d905110b6Matt Wala  virtual void dump(const Cfg *Func) const;
35949889239d4c7ab296c7430722d36032d905110b6Matt Wala  static bool classof(const Inst *Inst) {
36049889239d4c7ab296c7430722d36032d905110b6Matt Wala    return Inst->getKind() == ExtractElement;
36149889239d4c7ab296c7430722d36032d905110b6Matt Wala  }
36249889239d4c7ab296c7430722d36032d905110b6Matt Wala
36349889239d4c7ab296c7430722d36032d905110b6Matt Walaprivate:
36449889239d4c7ab296c7430722d36032d905110b6Matt Wala  InstExtractElement(Cfg *Func, Variable *Dest, Operand *Source1,
36549889239d4c7ab296c7430722d36032d905110b6Matt Wala                     Operand *Source2);
36649889239d4c7ab296c7430722d36032d905110b6Matt Wala  InstExtractElement(const InstExtractElement &) LLVM_DELETED_FUNCTION;
36749889239d4c7ab296c7430722d36032d905110b6Matt Wala  InstExtractElement &
36849889239d4c7ab296c7430722d36032d905110b6Matt Wala  operator=(const InstExtractElement &) LLVM_DELETED_FUNCTION;
36949889239d4c7ab296c7430722d36032d905110b6Matt Wala  virtual ~InstExtractElement() {}
37049889239d4c7ab296c7430722d36032d905110b6Matt Wala};
37149889239d4c7ab296c7430722d36032d905110b6Matt Wala
372f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Floating-point comparison instruction.  The source operands are
373f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// captured in getSrc(0) and getSrc(1).
374f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothclass InstFcmp : public Inst {
375f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothpublic:
376f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  enum FCond {
377f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth#define X(tag, str) tag,
378f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    ICEINSTFCMP_TABLE
379f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth#undef X
3804376d2929a6d09055222f41600b165d3a2130657Jim Stichnoth        _num
381f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  };
3825bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth
383f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static InstFcmp *create(Cfg *Func, FCond Condition, Variable *Dest,
384f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth                          Operand *Source1, Operand *Source2) {
385f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return new (Func->allocateInst<InstFcmp>())
386f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth        InstFcmp(Func, Condition, Dest, Source1, Source2);
387f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
388f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  FCond getCondition() const { return Condition; }
389f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void dump(const Cfg *Func) const;
390f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() == Fcmp; }
391f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
392f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothprivate:
393f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstFcmp(Cfg *Func, FCond Condition, Variable *Dest, Operand *Source1,
394f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth           Operand *Source2);
395f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstFcmp(const InstFcmp &) LLVM_DELETED_FUNCTION;
396f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstFcmp &operator=(const InstFcmp &) LLVM_DELETED_FUNCTION;
397f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual ~InstFcmp() {}
398f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  const FCond Condition;
399f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth};
400f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
401f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Integer comparison instruction.  The source operands are captured
402f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// in getSrc(0) and getSrc(1).
403f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothclass InstIcmp : public Inst {
404f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothpublic:
405f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  enum ICond {
406f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth#define X(tag, str) tag,
407f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    ICEINSTICMP_TABLE
408f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth#undef X
4094376d2929a6d09055222f41600b165d3a2130657Jim Stichnoth        _num
410f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  };
4115bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth
412f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static InstIcmp *create(Cfg *Func, ICond Condition, Variable *Dest,
413f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth                          Operand *Source1, Operand *Source2) {
414f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return new (Func->allocateInst<InstIcmp>())
415f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth        InstIcmp(Func, Condition, Dest, Source1, Source2);
416f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
417f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  ICond getCondition() const { return Condition; }
418f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void dump(const Cfg *Func) const;
419f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() == Icmp; }
420f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
421f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothprivate:
422f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstIcmp(Cfg *Func, ICond Condition, Variable *Dest, Operand *Source1,
423f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth           Operand *Source2);
424f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstIcmp(const InstIcmp &) LLVM_DELETED_FUNCTION;
425f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstIcmp &operator=(const InstIcmp &) LLVM_DELETED_FUNCTION;
426f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual ~InstIcmp() {}
427f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  const ICond Condition;
428f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth};
429f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
43049889239d4c7ab296c7430722d36032d905110b6Matt Wala// InsertElement instruction.
43149889239d4c7ab296c7430722d36032d905110b6Matt Walaclass InstInsertElement : public Inst {
43249889239d4c7ab296c7430722d36032d905110b6Matt Walapublic:
43349889239d4c7ab296c7430722d36032d905110b6Matt Wala  static InstInsertElement *create(Cfg *Func, Variable *Dest, Operand *Source1,
43449889239d4c7ab296c7430722d36032d905110b6Matt Wala                                   Operand *Source2, Operand *Source3) {
43549889239d4c7ab296c7430722d36032d905110b6Matt Wala    return new (Func->allocateInst<InstInsertElement>())
43649889239d4c7ab296c7430722d36032d905110b6Matt Wala        InstInsertElement(Func, Dest, Source1, Source2, Source3);
43749889239d4c7ab296c7430722d36032d905110b6Matt Wala  }
43849889239d4c7ab296c7430722d36032d905110b6Matt Wala
43949889239d4c7ab296c7430722d36032d905110b6Matt Wala  virtual void dump(const Cfg *Func) const;
44049889239d4c7ab296c7430722d36032d905110b6Matt Wala  static bool classof(const Inst *Inst) {
44149889239d4c7ab296c7430722d36032d905110b6Matt Wala    return Inst->getKind() == InsertElement;
44249889239d4c7ab296c7430722d36032d905110b6Matt Wala  }
44349889239d4c7ab296c7430722d36032d905110b6Matt Wala
44449889239d4c7ab296c7430722d36032d905110b6Matt Walaprivate:
44549889239d4c7ab296c7430722d36032d905110b6Matt Wala  InstInsertElement(Cfg *Func, Variable *Dest, Operand *Source1,
44649889239d4c7ab296c7430722d36032d905110b6Matt Wala                    Operand *Source2, Operand *Source3);
44749889239d4c7ab296c7430722d36032d905110b6Matt Wala  InstInsertElement(const InstInsertElement &) LLVM_DELETED_FUNCTION;
44849889239d4c7ab296c7430722d36032d905110b6Matt Wala  InstInsertElement &operator=(const InstInsertElement &) LLVM_DELETED_FUNCTION;
44949889239d4c7ab296c7430722d36032d905110b6Matt Wala  virtual ~InstInsertElement() {}
45049889239d4c7ab296c7430722d36032d905110b6Matt Wala};
45149889239d4c7ab296c7430722d36032d905110b6Matt Wala
4523bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung// Call to an intrinsic function.  The call target is captured as getSrc(0),
4533bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung// and arg I is captured as getSrc(I+1).
4543bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voungclass InstIntrinsicCall : public InstCall {
4553bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voungpublic:
4563bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung  static InstIntrinsicCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest,
4573bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung                                   Operand *CallTarget,
4583bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung                                   const Intrinsics::IntrinsicInfo &Info) {
4593bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung    return new (Func->allocateInst<InstIntrinsicCall>())
4603bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung        InstIntrinsicCall(Func, NumArgs, Dest, CallTarget, Info);
4613bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung  }
4623bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung  static bool classof(const Inst *Inst) {
4633bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung    return Inst->getKind() == IntrinsicCall;
4643bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung  }
4653bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung
4663bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung  Intrinsics::IntrinsicInfo getIntrinsicInfo() const { return Info; }
4673bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung
4683bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voungprivate:
4693bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung  InstIntrinsicCall(Cfg *Func, SizeT NumArgs, Variable *Dest,
4703bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung                    Operand *CallTarget, const Intrinsics::IntrinsicInfo &Info)
4713bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung      : InstCall(Func, NumArgs, Dest, CallTarget, Info.HasSideEffects,
4723bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung                 Inst::IntrinsicCall),
4733bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung        Info(Info) {}
4743bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung  InstIntrinsicCall(const InstIntrinsicCall &) LLVM_DELETED_FUNCTION;
4753bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung  InstIntrinsicCall &operator=(const InstIntrinsicCall &) LLVM_DELETED_FUNCTION;
4763bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung  virtual ~InstIntrinsicCall() {}
4773bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung  const Intrinsics::IntrinsicInfo Info;
4783bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung};
4793bd9f1af8fd8ff81857ae79adec01ae56fb3413fJan Voung
480f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Load instruction.  The source address is captured in getSrc(0).
481f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothclass InstLoad : public Inst {
482f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothpublic:
483f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static InstLoad *create(Cfg *Func, Variable *Dest, Operand *SourceAddr) {
484f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return new (Func->allocateInst<InstLoad>())
485f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth        InstLoad(Func, Dest, SourceAddr);
486f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
487f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  Operand *getSourceAddress() const { return getSrc(0); }
488f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void dump(const Cfg *Func) const;
489f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() == Load; }
490f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
491f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothprivate:
492f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstLoad(Cfg *Func, Variable *Dest, Operand *SourceAddr);
493f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstLoad(const InstLoad &) LLVM_DELETED_FUNCTION;
494f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstLoad &operator=(const InstLoad &) LLVM_DELETED_FUNCTION;
495f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual ~InstLoad() {}
496f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth};
497f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
498f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Phi instruction.  For incoming edge I, the node is Labels[I] and
499f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// the Phi source operand is getSrc(I).
500f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothclass InstPhi : public Inst {
501f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothpublic:
502f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static InstPhi *create(Cfg *Func, SizeT MaxSrcs, Variable *Dest) {
503f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return new (Func->allocateInst<InstPhi>()) InstPhi(Func, MaxSrcs, Dest);
504f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
505f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  void addArgument(Operand *Source, CfgNode *Label);
5065bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  Operand *getOperandForTarget(CfgNode *Target) const;
507d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  void livenessPhiOperand(llvm::BitVector &Live, CfgNode *Target,
508d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth                          Liveness *Liveness);
5095bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  Inst *lower(Cfg *Func, CfgNode *Node);
510f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void dump(const Cfg *Func) const;
511f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() == Phi; }
512f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
513f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothprivate:
514f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstPhi(Cfg *Func, SizeT MaxSrcs, Variable *Dest);
515f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstPhi(const InstPhi &) LLVM_DELETED_FUNCTION;
516f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstPhi &operator=(const InstPhi &) LLVM_DELETED_FUNCTION;
517f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void destroy(Cfg *Func) {
518f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    Func->deallocateArrayOf<CfgNode *>(Labels);
519f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    Inst::destroy(Func);
520f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
521f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual ~InstPhi() {}
522f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
523f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  // Labels[] duplicates the InEdges[] information in the enclosing
524f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  // CfgNode, but the Phi instruction is created before InEdges[]
525f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  // is available, so it's more complicated to share the list.
526f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  CfgNode **Labels;
527f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth};
528f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
529f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Ret instruction.  The return value is captured in getSrc(0), but if
530f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// there is no return value (void-type function), then
531f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// getSrcSize()==0 and hasRetValue()==false.
532f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothclass InstRet : public Inst {
533f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothpublic:
534f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static InstRet *create(Cfg *Func, Operand *RetValue = NULL) {
535f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return new (Func->allocateInst<InstRet>()) InstRet(Func, RetValue);
536f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
537f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  bool hasRetValue() const { return getSrcSize(); }
538f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  Operand *getRetValue() const {
539f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    assert(hasRetValue());
540f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return getSrc(0);
541f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
542f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual NodeList getTerminatorEdges() const { return NodeList(); }
543f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void dump(const Cfg *Func) const;
544f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() == Ret; }
545f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
546f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothprivate:
547f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstRet(Cfg *Func, Operand *RetValue);
548f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstRet(const InstRet &) LLVM_DELETED_FUNCTION;
549f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstRet &operator=(const InstRet &) LLVM_DELETED_FUNCTION;
550f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual ~InstRet() {}
551f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth};
552f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
553f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Select instruction.  The condition, true, and false operands are captured.
554f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothclass InstSelect : public Inst {
555f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothpublic:
556f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static InstSelect *create(Cfg *Func, Variable *Dest, Operand *Condition,
557f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth                            Operand *SourceTrue, Operand *SourceFalse) {
558f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return new (Func->allocateInst<InstSelect>())
559f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth        InstSelect(Func, Dest, Condition, SourceTrue, SourceFalse);
560f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
561f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  Operand *getCondition() const { return getSrc(0); }
562f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  Operand *getTrueOperand() const { return getSrc(1); }
563f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  Operand *getFalseOperand() const { return getSrc(2); }
564f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void dump(const Cfg *Func) const;
565f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() == Select; }
566f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
567f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothprivate:
568f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstSelect(Cfg *Func, Variable *Dest, Operand *Condition, Operand *Source1,
569f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth             Operand *Source2);
570f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstSelect(const InstSelect &) LLVM_DELETED_FUNCTION;
571f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstSelect &operator=(const InstSelect &) LLVM_DELETED_FUNCTION;
572f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual ~InstSelect() {}
573f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth};
574f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
575f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Store instruction.  The address operand is captured, along with the
576f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// data operand to be stored into the address.
577f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothclass InstStore : public Inst {
578f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothpublic:
579f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static InstStore *create(Cfg *Func, Operand *Data, Operand *Addr) {
580f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return new (Func->allocateInst<InstStore>()) InstStore(Func, Data, Addr);
581f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
582f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  Operand *getAddr() const { return getSrc(1); }
583f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  Operand *getData() const { return getSrc(0); }
584f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void dump(const Cfg *Func) const;
585f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() == Store; }
586f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
587f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothprivate:
588f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstStore(Cfg *Func, Operand *Data, Operand *Addr);
589f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstStore(const InstStore &) LLVM_DELETED_FUNCTION;
590f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstStore &operator=(const InstStore &) LLVM_DELETED_FUNCTION;
591f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual ~InstStore() {}
592f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth};
593f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
594f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Switch instruction.  The single source operand is captured as
595f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// getSrc(0).
596f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothclass InstSwitch : public Inst {
597f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothpublic:
598f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static InstSwitch *create(Cfg *Func, SizeT NumCases, Operand *Source,
599f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth                            CfgNode *LabelDefault) {
600f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return new (Func->allocateInst<InstSwitch>())
601f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth        InstSwitch(Func, NumCases, Source, LabelDefault);
602f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
603f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  Operand *getComparison() const { return getSrc(0); }
604f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  CfgNode *getLabelDefault() const { return LabelDefault; }
605f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  SizeT getNumCases() const { return NumCases; }
606f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  uint64_t getValue(SizeT I) const {
607f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    assert(I < NumCases);
608f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return Values[I];
609f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
610f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  CfgNode *getLabel(SizeT I) const {
611f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    assert(I < NumCases);
612f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return Labels[I];
613f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
614f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  void addBranch(SizeT CaseIndex, uint64_t Value, CfgNode *Label);
615f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual NodeList getTerminatorEdges() const;
616f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void dump(const Cfg *Func) const;
617f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() == Switch; }
618f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
619f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothprivate:
620f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstSwitch(Cfg *Func, SizeT NumCases, Operand *Source, CfgNode *LabelDefault);
621f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstSwitch(const InstSwitch &) LLVM_DELETED_FUNCTION;
622f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstSwitch &operator=(const InstSwitch &) LLVM_DELETED_FUNCTION;
623f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void destroy(Cfg *Func) {
624f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    Func->deallocateArrayOf<uint64_t>(Values);
625f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    Func->deallocateArrayOf<CfgNode *>(Labels);
626f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    Inst::destroy(Func);
627f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
628f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual ~InstSwitch() {}
629f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
630f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  CfgNode *LabelDefault;
631f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  SizeT NumCases;   // not including the default case
632f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  uint64_t *Values; // size is NumCases
633f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  CfgNode **Labels; // size is NumCases
634f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth};
635f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
636f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// Unreachable instruction.  This is a terminator instruction with no
637f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// operands.
638f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothclass InstUnreachable : public Inst {
639f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothpublic:
640f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static InstUnreachable *create(Cfg *Func) {
641f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return new (Func->allocateInst<InstUnreachable>()) InstUnreachable(Func);
642f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
643f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual NodeList getTerminatorEdges() const { return NodeList(); }
644f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual void dump(const Cfg *Func) const;
645f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  static bool classof(const Inst *Inst) {
646f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth    return Inst->getKind() == Unreachable;
647f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  }
648f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
649f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothprivate:
650f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstUnreachable(Cfg *Func);
651f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstUnreachable(const InstUnreachable &) LLVM_DELETED_FUNCTION;
652f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  InstUnreachable &operator=(const InstUnreachable &) LLVM_DELETED_FUNCTION;
653f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth  virtual ~InstUnreachable() {}
654f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth};
655f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
6565bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// FakeDef instruction.  This creates a fake definition of a variable,
6575bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// which is how we represent the case when an instruction produces
6585bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// multiple results.  This doesn't happen with high-level ICE
6595bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// instructions, but might with lowered instructions.  For example,
6605bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// this would be a way to represent condition flags being modified by
6615bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// an instruction.
6625bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth//
6635bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// It's generally useful to set the optional source operand to be the
6645bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// dest variable of the instruction that actually produces the FakeDef
6655bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// dest.  Otherwise, the original instruction could be dead-code
6665bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// eliminated if its dest operand is unused, and therefore the FakeDef
6675bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// dest wouldn't be properly initialized.
6685bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnothclass InstFakeDef : public Inst {
6695bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnothpublic:
6705bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  static InstFakeDef *create(Cfg *Func, Variable *Dest, Variable *Src = NULL) {
6715bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth    return new (Func->allocateInst<InstFakeDef>()) InstFakeDef(Func, Dest, Src);
6725bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  }
6735bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  virtual void emit(const Cfg *Func) const;
6745bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  virtual void dump(const Cfg *Func) const;
6755bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() == FakeDef; }
6765bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth
6775bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnothprivate:
6785bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  InstFakeDef(Cfg *Func, Variable *Dest, Variable *Src);
6795bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  InstFakeDef(const InstFakeDef &) LLVM_DELETED_FUNCTION;
6805bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  InstFakeDef &operator=(const InstFakeDef &) LLVM_DELETED_FUNCTION;
6815bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  virtual ~InstFakeDef() {}
6825bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth};
6835bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth
6845bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// FakeUse instruction.  This creates a fake use of a variable, to
6855bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// keep the instruction that produces that variable from being
6865bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// dead-code eliminated.  This is useful in a variety of lowering
6875bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// situations.  The FakeUse instruction has no dest, so it can itself
6885bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// never be dead-code eliminated.
6895bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnothclass InstFakeUse : public Inst {
6905bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnothpublic:
6915bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  static InstFakeUse *create(Cfg *Func, Variable *Src) {
6925bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth    return new (Func->allocateInst<InstFakeUse>()) InstFakeUse(Func, Src);
6935bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  }
6945bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  virtual void emit(const Cfg *Func) const;
6955bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  virtual void dump(const Cfg *Func) const;
6965bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() == FakeUse; }
6975bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth
6985bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnothprivate:
6995bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  InstFakeUse(Cfg *Func, Variable *Src);
7005bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  InstFakeUse(const InstFakeUse &) LLVM_DELETED_FUNCTION;
7015bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  InstFakeUse &operator=(const InstFakeUse &) LLVM_DELETED_FUNCTION;
7025bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  virtual ~InstFakeUse() {}
7035bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth};
7045bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth
7055bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// FakeKill instruction.  This "kills" a set of variables by adding a
7065bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// trivial live range at this instruction to each variable.  The
7075bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// primary use is to indicate that scratch registers are killed after
7085bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// a call, so that the register allocator won't assign a scratch
7095bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// register to a variable whose live range spans a call.
7105bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth//
7115bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// The FakeKill instruction also holds a pointer to the instruction
7125bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// that kills the set of variables, so that if that linked instruction
7135bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// gets dead-code eliminated, the FakeKill instruction will as well.
7145bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnothclass InstFakeKill : public Inst {
7155bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnothpublic:
7165bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  static InstFakeKill *create(Cfg *Func, const VarList &KilledRegs,
7175bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth                              const Inst *Linked) {
7185bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth    return new (Func->allocateInst<InstFakeKill>())
7195bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth        InstFakeKill(Func, KilledRegs, Linked);
7205bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  }
7215bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  const Inst *getLinked() const { return Linked; }
7225bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  virtual void emit(const Cfg *Func) const;
7235bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  virtual void dump(const Cfg *Func) const;
7245bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() == FakeKill; }
7255bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth
7265bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnothprivate:
7275bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  InstFakeKill(Cfg *Func, const VarList &KilledRegs, const Inst *Linked);
7285bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  InstFakeKill(const InstFakeKill &) LLVM_DELETED_FUNCTION;
7295bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  InstFakeKill &operator=(const InstFakeKill &) LLVM_DELETED_FUNCTION;
7305bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  virtual ~InstFakeKill() {}
7315bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth
7325bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  // This instruction is ignored if Linked->isDeleted() is true.
7335bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  const Inst *Linked;
7345bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth};
7355bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth
7365bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// The Target instruction is the base class for all target-specific
7375bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth// instructions.
7385bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnothclass InstTarget : public Inst {
7395bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnothpublic:
7405bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  virtual void emit(const Cfg *Func) const = 0;
7415bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  virtual void dump(const Cfg *Func) const;
742d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  virtual void dumpExtras(const Cfg *Func) const;
7435bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  static bool classof(const Inst *Inst) { return Inst->getKind() >= Target; }
7445bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth
7455bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnothprotected:
7465bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  InstTarget(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest)
7475bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth      : Inst(Func, Kind, MaxSrcs, Dest) {
7485bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth    assert(Kind >= Target);
7495bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  }
7505bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  InstTarget(const InstTarget &) LLVM_DELETED_FUNCTION;
7515bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  InstTarget &operator=(const InstTarget &) LLVM_DELETED_FUNCTION;
7525bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  virtual ~InstTarget() {}
7535bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth};
7545bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth
755f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth} // end of namespace Ice
756f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
757f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth#endif // SUBZERO_SRC_ICEINST_H
758