blob: 7aad05455aa7d7519f671eb99ee7c38334324861 [file] [log] [blame]
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001//===- subzero/src/IceInst.h - High-level instructions ----------*- C++ -*-===//
2//
3// The Subzero Code Generator
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file declares the Inst class and its target-independent
11// subclasses, which represent the high-level Vanilla ICE instructions
12// and map roughly 1:1 to LLVM instructions.
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef SUBZERO_SRC_ICEINST_H
17#define SUBZERO_SRC_ICEINST_H
18
John Porto7e93c622015-06-23 10:58:57 -070019#include "IceCfg.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070020#include "IceDefs.h"
21#include "IceInst.def"
Jan Voung3bd9f1a2014-06-18 10:50:57 -070022#include "IceIntrinsics.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070023#include "IceTypes.h"
24
25// TODO: The Cfg structure, and instructions in particular, need to be
26// validated for things like valid operand types, valid branch
27// targets, proper ordering of Phi and non-Phi instructions, etc.
28// Most of the validity checking will be done in the bitcode reader.
29// We need a list of everything that should be validated, and tests
30// for each.
31
32namespace Ice {
33
Jim Stichnothb56c8f42014-09-26 09:28:46 -070034// Base instruction class for ICE. Inst has two subclasses:
35// InstHighLevel and InstTarget. High-level ICE instructions inherit
36// from InstHighLevel, and low-level (target-specific) ICE
37// instructions inherit from InstTarget.
Jim Stichnoth607e9f02014-11-06 13:32:05 -080038class Inst : public llvm::ilist_node<Inst> {
Jim Stichnothc6ead202015-02-24 09:30:30 -080039 Inst() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -070040 Inst(const Inst &) = delete;
41 Inst &operator=(const Inst &) = delete;
42
Jim Stichnothf7c9a142014-04-29 10:52:43 -070043public:
44 enum InstKind {
45 // Arbitrary (alphabetical) order, except put Unreachable first.
46 Unreachable,
47 Alloca,
48 Arithmetic,
Jim Stichnothf7c9a142014-04-29 10:52:43 -070049 Br,
50 Call,
51 Cast,
Matt Wala49889232014-07-18 12:45:09 -070052 ExtractElement,
Jim Stichnothf7c9a142014-04-29 10:52:43 -070053 Fcmp,
54 Icmp,
Jan Voung3bd9f1a2014-06-18 10:50:57 -070055 IntrinsicCall,
Matt Wala49889232014-07-18 12:45:09 -070056 InsertElement,
Jim Stichnothf7c9a142014-04-29 10:52:43 -070057 Load,
58 Phi,
59 Ret,
60 Select,
61 Store,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070062 Switch,
Jim Stichnothc6ead202015-02-24 09:30:30 -080063 Assign, // not part of LLVM/PNaCl bitcode
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -080064 BundleLock, // not part of LLVM/PNaCl bitcode
65 BundleUnlock, // not part of LLVM/PNaCl bitcode
66 FakeDef, // not part of LLVM/PNaCl bitcode
67 FakeUse, // not part of LLVM/PNaCl bitcode
68 FakeKill, // not part of LLVM/PNaCl bitcode
69 Target // target-specific low-level ICE
70 // Anything >= Target is an InstTarget subclass.
Jan Voungb3401d22015-05-18 09:38:21 -070071 // Note that the value-spaces are shared across targets.
72 // To avoid confusion over the definition of shared values,
73 // an object specific to one target should never be passed
74 // to a different target.
Jim Stichnothf7c9a142014-04-29 10:52:43 -070075 };
76 InstKind getKind() const { return Kind; }
77
Jim Stichnothd97c7df2014-06-04 11:57:08 -070078 InstNumberT getNumber() const { return Number; }
79 void renumber(Cfg *Func);
Jim Stichnothe5b73e62014-12-15 09:58:51 -080080 enum {
81 NumberDeleted = -1,
82 NumberSentinel = 0,
83 NumberInitial = 2,
84 NumberExtended = NumberInitial - 1
85 };
Jim Stichnothf7c9a142014-04-29 10:52:43 -070086
87 bool isDeleted() const { return Deleted; }
88 void setDeleted() { Deleted = true; }
Jim Stichnotha59ae6f2015-05-17 10:11:41 -070089 void setDead(bool Value = true) { Dead = Value; }
Jim Stichnothd97c7df2014-06-04 11:57:08 -070090 void deleteIfDead();
Jim Stichnothf7c9a142014-04-29 10:52:43 -070091
92 bool hasSideEffects() const { return HasSideEffects; }
93
Jim Stichnoth47752552014-10-13 17:15:08 -070094 bool isDestNonKillable() const { return IsDestNonKillable; }
95 void setDestNonKillable() { IsDestNonKillable = true; }
96
Jim Stichnothf7c9a142014-04-29 10:52:43 -070097 Variable *getDest() const { return Dest; }
98
99 SizeT getSrcSize() const { return NumSrcs; }
100 Operand *getSrc(SizeT I) const {
101 assert(I < getSrcSize());
102 return Srcs[I];
103 }
104
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700105 bool isLastUse(const Operand *Src) const;
Jim Stichnoth8e6bf6e2015-06-03 15:58:12 -0700106 void spliceLivenessInfo(Inst *OrigInst, Inst *SpliceAssn);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700107
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700108 // Returns a list of out-edges corresponding to a terminator
109 // instruction, which is the last instruction of the block.
110 virtual NodeList getTerminatorEdges() const {
111 // All valid terminator instructions override this method. For
112 // the default implementation, we assert in case some CfgNode
113 // is constructed without a terminator instruction at the end.
114 llvm_unreachable(
115 "getTerminatorEdges() called on a non-terminator instruction");
116 return NodeList();
117 }
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700118 virtual bool isUnconditionalBranch() const { return false; }
119 // If the instruction is a branch-type instruction with OldNode as a
120 // target, repoint it to NewNode and return true, otherwise return
121 // false. Only repoint one instance, even if the instruction has
122 // multiple instances of OldNode as a target.
123 virtual bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) {
124 (void)OldNode;
125 (void)NewNode;
126 return false;
127 }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700128
Jim Stichnothad403532014-09-25 12:44:17 -0700129 virtual bool isSimpleAssign() const { return false; }
130
Jim Stichnoth47752552014-10-13 17:15:08 -0700131 void livenessLightweight(Cfg *Func, LivenessBV &Live);
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700132 // Calculates liveness for this instruction. Returns true if this
133 // instruction is (tentatively) still live and should be retained,
134 // and false if this instruction is (tentatively) dead and should be
135 // deleted. The decision is tentative until the liveness dataflow
136 // algorithm has converged, and then a separate pass permanently
137 // deletes dead instructions.
138 bool liveness(InstNumberT InstNumber, LivenessBV &Live, Liveness *Liveness,
Jim Stichnoth47752552014-10-13 17:15:08 -0700139 LiveBeginEndMap *LiveBegin, LiveBeginEndMap *LiveEnd);
Jim Stichnoth18735602014-09-16 19:59:35 -0700140
141 // Get the number of native instructions that this instruction
142 // ultimately emits. By default, high-level instructions don't
143 // result in any native instructions, and a target-specific
144 // instruction results in a single native instruction.
145 virtual uint32_t getEmitInstCount() const { return 0; }
Jim Stichnothdddaf9c2014-12-04 14:09:21 -0800146 // TODO(stichnot): Change Inst back to abstract once the g++ build
147 // issue is fixed. llvm::ilist<Ice::Inst> doesn't work under g++
148 // because the resize(size_t, Ice::Inst) method is incorrectly
149 // declared and thus doesn't allow the abstract class Ice::Inst.
150 // The method should be declared resize(size_t, const Ice::Inst &).
151 // virtual void emit(const Cfg *Func) const = 0;
152 // virtual void emitIAS(const Cfg *Func) const = 0;
153 virtual void emit(const Cfg *) const {
154 llvm_unreachable("emit on abstract class");
155 }
156 virtual void emitIAS(const Cfg *Func) const { emit(Func); }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700157 virtual void dump(const Cfg *Func) const;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700158 virtual void dumpExtras(const Cfg *Func) const;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700159 void dumpDecorated(const Cfg *Func) const;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700160 void emitSources(const Cfg *Func) const;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700161 void dumpSources(const Cfg *Func) const;
162 void dumpDest(const Cfg *Func) const;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700163 virtual bool isRedundantAssign() const { return false; }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700164
John Porto1bec8bc2015-06-22 10:51:13 -0700165 // TODO(jpp): Insts should not have non-trivial destructors, but they
166 // currently do. This dtor is marked final as a multi-step refactor that
167 // will eventually fix this problem.
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700168 virtual ~Inst() = default;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700169
170protected:
171 Inst(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest);
172 void addSource(Operand *Src) {
173 assert(Src);
174 assert(NumSrcs < MaxSrcs);
175 Srcs[NumSrcs++] = Src;
176 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700177 void setLastUse(SizeT VarIndex) {
178 if (VarIndex < CHAR_BIT * sizeof(LiveRangesEnded))
179 LiveRangesEnded |= (((LREndedBits)1u) << VarIndex);
180 }
181 void resetLastUses() { LiveRangesEnded = 0; }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700182 // The destroy() method lets the instruction cleanly release any
183 // memory that was allocated via the Cfg's allocator.
184 virtual void destroy(Cfg *Func) { Func->deallocateArrayOf<Operand *>(Srcs); }
185
186 const InstKind Kind;
187 // Number is the instruction number for describing live ranges.
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700188 InstNumberT Number;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700189 // Deleted means irrevocably deleted.
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700190 bool Deleted = false;
Jim Stichnotha59ae6f2015-05-17 10:11:41 -0700191 // Dead means one of two things depending on context: (1) pending
192 // deletion after liveness analysis converges, or (2) marked for
193 // deletion during lowering due to a folded bool operation.
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700194 bool Dead = false;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700195 // HasSideEffects means the instruction is something like a function
196 // call or a volatile load that can't be removed even if its Dest
197 // variable is not live.
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700198 bool HasSideEffects = false;
Jim Stichnoth47752552014-10-13 17:15:08 -0700199 // IsDestNonKillable means that liveness analysis shouldn't consider
200 // this instruction to kill the Dest variable. This is used when
201 // lowering produces two assignments to the same variable.
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700202 bool IsDestNonKillable = false;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700203
204 Variable *Dest;
205 const SizeT MaxSrcs; // only used for assert
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700206 SizeT NumSrcs = 0;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700207 Operand **Srcs;
208
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700209 // LiveRangesEnded marks which Variables' live ranges end in this
210 // instruction. An instruction can have an arbitrary number of
211 // source operands (e.g. a call instruction), and each source
212 // operand can contain 0 or 1 Variable (and target-specific operands
213 // could contain more than 1 Variable). All the variables in an
214 // instruction are conceptually flattened and each variable is
215 // mapped to one bit position of the LiveRangesEnded bit vector.
216 // Only the first CHAR_BIT * sizeof(LREndedBits) variables are
217 // tracked this way.
218 typedef uint32_t LREndedBits; // only first 32 src operands tracked, sorry
219 LREndedBits LiveRangesEnded;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700220};
221
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700222class InstHighLevel : public Inst {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800223 InstHighLevel() = delete;
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700224 InstHighLevel(const InstHighLevel &) = delete;
225 InstHighLevel &operator=(const InstHighLevel &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700226
227protected:
228 InstHighLevel(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest)
229 : Inst(Func, Kind, MaxSrcs, Dest) {}
230 void emit(const Cfg * /*Func*/) const override {
231 llvm_unreachable("emit() called on a non-lowered instruction");
232 }
233 void emitIAS(const Cfg * /*Func*/) const override {
234 llvm_unreachable("emitIAS() called on a non-lowered instruction");
235 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700236};
237
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700238// Alloca instruction. This captures the size in bytes as getSrc(0),
239// and the required alignment in bytes. The alignment must be either
240// 0 (no alignment required) or a power of 2.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700241class InstAlloca : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800242 InstAlloca() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700243 InstAlloca(const InstAlloca &) = delete;
244 InstAlloca &operator=(const InstAlloca &) = delete;
245
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700246public:
247 static InstAlloca *create(Cfg *Func, Operand *ByteCount,
248 uint32_t AlignInBytes, Variable *Dest) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800249 return new (Func->allocate<InstAlloca>())
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700250 InstAlloca(Func, ByteCount, AlignInBytes, Dest);
251 }
252 uint32_t getAlignInBytes() const { return AlignInBytes; }
253 Operand *getSizeInBytes() const { return getSrc(0); }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700254 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700255 static bool classof(const Inst *Inst) { return Inst->getKind() == Alloca; }
256
257private:
258 InstAlloca(Cfg *Func, Operand *ByteCount, uint32_t AlignInBytes,
259 Variable *Dest);
John Porto1bec8bc2015-06-22 10:51:13 -0700260
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700261 const uint32_t AlignInBytes;
262};
263
264// Binary arithmetic instruction. The source operands are captured in
265// getSrc(0) and getSrc(1).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700266class InstArithmetic : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800267 InstArithmetic() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700268 InstArithmetic(const InstArithmetic &) = delete;
269 InstArithmetic &operator=(const InstArithmetic &) = delete;
270
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700271public:
272 enum OpKind {
273#define X(tag, str, commutative) tag,
274 ICEINSTARITHMETIC_TABLE
275#undef X
Jim Stichnoth4376d292014-05-23 13:39:02 -0700276 _num
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700277 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700278
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700279 static InstArithmetic *create(Cfg *Func, OpKind Op, Variable *Dest,
280 Operand *Source1, Operand *Source2) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800281 return new (Func->allocate<InstArithmetic>())
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700282 InstArithmetic(Func, Op, Dest, Source1, Source2);
283 }
284 OpKind getOp() const { return Op; }
Karl Schimpfd6064a12014-08-27 15:34:58 -0700285 static const char *getOpName(OpKind Op);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700286 bool isCommutative() const;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700287 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700288 static bool classof(const Inst *Inst) {
289 return Inst->getKind() == Arithmetic;
290 }
291
292private:
293 InstArithmetic(Cfg *Func, OpKind Op, Variable *Dest, Operand *Source1,
294 Operand *Source2);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700295
296 const OpKind Op;
297};
298
299// Assignment instruction. The source operand is captured in
300// getSrc(0). This is not part of the LLVM bitcode, but is a useful
301// abstraction for some of the lowering. E.g., if Phi instruction
302// lowering happens before target lowering, or for representing an
303// Inttoptr instruction, or as an intermediate step for lowering a
304// Load instruction.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700305class InstAssign : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800306 InstAssign() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700307 InstAssign(const InstAssign &) = delete;
308 InstAssign &operator=(const InstAssign &) = delete;
309
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700310public:
311 static InstAssign *create(Cfg *Func, Variable *Dest, Operand *Source) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800312 return new (Func->allocate<InstAssign>()) InstAssign(Func, Dest, Source);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700313 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700314 bool isSimpleAssign() const override { return true; }
315 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700316 static bool classof(const Inst *Inst) { return Inst->getKind() == Assign; }
317
318private:
319 InstAssign(Cfg *Func, Variable *Dest, Operand *Source);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700320};
321
322// Branch instruction. This represents both conditional and
323// unconditional branches.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700324class InstBr : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800325 InstBr() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700326 InstBr(const InstBr &) = delete;
327 InstBr &operator=(const InstBr &) = delete;
328
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700329public:
330 // Create a conditional branch. If TargetTrue==TargetFalse, it is
331 // optimized to an unconditional branch.
332 static InstBr *create(Cfg *Func, Operand *Source, CfgNode *TargetTrue,
333 CfgNode *TargetFalse) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800334 return new (Func->allocate<InstBr>())
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700335 InstBr(Func, Source, TargetTrue, TargetFalse);
336 }
337 // Create an unconditional branch.
338 static InstBr *create(Cfg *Func, CfgNode *Target) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800339 return new (Func->allocate<InstBr>()) InstBr(Func, Target);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700340 }
Jim Stichnothae953202014-12-20 06:17:49 -0800341 bool isUnconditional() const { return getTargetTrue() == nullptr; }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700342 Operand *getCondition() const {
343 assert(!isUnconditional());
344 return getSrc(0);
345 }
346 CfgNode *getTargetTrue() const { return TargetTrue; }
347 CfgNode *getTargetFalse() const { return TargetFalse; }
348 CfgNode *getTargetUnconditional() const {
349 assert(isUnconditional());
350 return getTargetFalse();
351 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700352 NodeList getTerminatorEdges() const override;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700353 bool isUnconditionalBranch() const override { return isUnconditional(); }
354 bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700355 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700356 static bool classof(const Inst *Inst) { return Inst->getKind() == Br; }
357
358private:
359 // Conditional branch
360 InstBr(Cfg *Func, Operand *Source, CfgNode *TargetTrue, CfgNode *TargetFalse);
361 // Unconditional branch
362 InstBr(Cfg *Func, CfgNode *Target);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700363
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700364 CfgNode *TargetFalse; // Doubles as unconditional branch target
Jim Stichnothae953202014-12-20 06:17:49 -0800365 CfgNode *TargetTrue; // nullptr if unconditional branch
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700366};
367
368// Call instruction. The call target is captured as getSrc(0), and
369// arg I is captured as getSrc(I+1).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700370class InstCall : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800371 InstCall() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700372 InstCall(const InstCall &) = delete;
373 InstCall &operator=(const InstCall &) = delete;
374
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700375public:
376 static InstCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest,
Karl Schimpf8df26f32014-09-19 09:33:26 -0700377 Operand *CallTarget, bool HasTailCall) {
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700378 // Set HasSideEffects to true so that the call instruction can't be
379 // dead-code eliminated. IntrinsicCalls can override this if the
380 // particular intrinsic is deletable and has no side-effects.
381 const bool HasSideEffects = true;
382 const InstKind Kind = Inst::Call;
Jim Stichnoth31c95592014-12-19 12:51:35 -0800383 return new (Func->allocate<InstCall>()) InstCall(
Karl Schimpf8df26f32014-09-19 09:33:26 -0700384 Func, NumArgs, Dest, CallTarget, HasTailCall, HasSideEffects, Kind);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700385 }
386 void addArg(Operand *Arg) { addSource(Arg); }
387 Operand *getCallTarget() const { return getSrc(0); }
388 Operand *getArg(SizeT I) const { return getSrc(I + 1); }
389 SizeT getNumArgs() const { return getSrcSize() - 1; }
Karl Schimpf8df26f32014-09-19 09:33:26 -0700390 bool isTailcall() const { return HasTailCall; }
Jan Voung3ce1a992015-02-03 08:27:44 -0800391 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700392 static bool classof(const Inst *Inst) { return Inst->getKind() == Call; }
Karl Schimpf8df26f32014-09-19 09:33:26 -0700393 Type getReturnType() const;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700394
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700395protected:
396 InstCall(Cfg *Func, SizeT NumArgs, Variable *Dest, Operand *CallTarget,
Karl Schimpf8df26f32014-09-19 09:33:26 -0700397 bool HasTailCall, bool HasSideEff, InstKind Kind)
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700398 : InstHighLevel(Func, Kind, NumArgs + 1, Dest), HasTailCall(HasTailCall) {
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700399 HasSideEffects = HasSideEff;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700400 addSource(CallTarget);
401 }
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700402
403private:
Karl Schimpf8df26f32014-09-19 09:33:26 -0700404 bool HasTailCall;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700405};
406
407// Cast instruction (a.k.a. conversion operation).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700408class InstCast : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800409 InstCast() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700410 InstCast(const InstCast &) = delete;
411 InstCast &operator=(const InstCast &) = delete;
412
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700413public:
414 enum OpKind {
415#define X(tag, str) tag,
416 ICEINSTCAST_TABLE
417#undef X
Jim Stichnoth4376d292014-05-23 13:39:02 -0700418 _num
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700419 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700420
Karl Schimpfbf170372014-12-15 10:16:31 -0800421 static const char *getCastName(OpKind Kind);
422
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700423 static InstCast *create(Cfg *Func, OpKind CastKind, Variable *Dest,
424 Operand *Source) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800425 return new (Func->allocate<InstCast>())
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700426 InstCast(Func, CastKind, Dest, Source);
427 }
428 OpKind getCastKind() const { return CastKind; }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700429 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700430 static bool classof(const Inst *Inst) { return Inst->getKind() == Cast; }
431
432private:
433 InstCast(Cfg *Func, OpKind CastKind, Variable *Dest, Operand *Source);
John Porto1bec8bc2015-06-22 10:51:13 -0700434
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700435 const OpKind CastKind;
436};
437
Matt Wala49889232014-07-18 12:45:09 -0700438// ExtractElement instruction.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700439class InstExtractElement : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800440 InstExtractElement() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700441 InstExtractElement(const InstExtractElement &) = delete;
442 InstExtractElement &operator=(const InstExtractElement &) = delete;
443
Matt Wala49889232014-07-18 12:45:09 -0700444public:
445 static InstExtractElement *create(Cfg *Func, Variable *Dest, Operand *Source1,
446 Operand *Source2) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800447 return new (Func->allocate<InstExtractElement>())
Matt Wala49889232014-07-18 12:45:09 -0700448 InstExtractElement(Func, Dest, Source1, Source2);
449 }
450
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700451 void dump(const Cfg *Func) const override;
Matt Wala49889232014-07-18 12:45:09 -0700452 static bool classof(const Inst *Inst) {
453 return Inst->getKind() == ExtractElement;
454 }
455
456private:
457 InstExtractElement(Cfg *Func, Variable *Dest, Operand *Source1,
458 Operand *Source2);
Matt Wala49889232014-07-18 12:45:09 -0700459};
460
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700461// Floating-point comparison instruction. The source operands are
462// captured in getSrc(0) and getSrc(1).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700463class InstFcmp : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800464 InstFcmp() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700465 InstFcmp(const InstFcmp &) = delete;
466 InstFcmp &operator=(const InstFcmp &) = delete;
467
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700468public:
469 enum FCond {
470#define X(tag, str) tag,
471 ICEINSTFCMP_TABLE
472#undef X
Jim Stichnoth4376d292014-05-23 13:39:02 -0700473 _num
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700474 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700475
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700476 static InstFcmp *create(Cfg *Func, FCond Condition, Variable *Dest,
477 Operand *Source1, Operand *Source2) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800478 return new (Func->allocate<InstFcmp>())
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700479 InstFcmp(Func, Condition, Dest, Source1, Source2);
480 }
481 FCond getCondition() const { return Condition; }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700482 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700483 static bool classof(const Inst *Inst) { return Inst->getKind() == Fcmp; }
484
485private:
486 InstFcmp(Cfg *Func, FCond Condition, Variable *Dest, Operand *Source1,
487 Operand *Source2);
John Porto1bec8bc2015-06-22 10:51:13 -0700488
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700489 const FCond Condition;
490};
491
492// Integer comparison instruction. The source operands are captured
493// in getSrc(0) and getSrc(1).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700494class InstIcmp : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800495 InstIcmp() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700496 InstIcmp(const InstIcmp &) = delete;
497 InstIcmp &operator=(const InstIcmp &) = delete;
498
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700499public:
500 enum ICond {
501#define X(tag, str) tag,
502 ICEINSTICMP_TABLE
503#undef X
Jim Stichnoth4376d292014-05-23 13:39:02 -0700504 _num
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700505 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700506
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700507 static InstIcmp *create(Cfg *Func, ICond Condition, Variable *Dest,
508 Operand *Source1, Operand *Source2) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800509 return new (Func->allocate<InstIcmp>())
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700510 InstIcmp(Func, Condition, Dest, Source1, Source2);
511 }
512 ICond getCondition() const { return Condition; }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700513 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700514 static bool classof(const Inst *Inst) { return Inst->getKind() == Icmp; }
515
516private:
517 InstIcmp(Cfg *Func, ICond Condition, Variable *Dest, Operand *Source1,
518 Operand *Source2);
John Porto1bec8bc2015-06-22 10:51:13 -0700519
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700520 const ICond Condition;
521};
522
Matt Wala49889232014-07-18 12:45:09 -0700523// InsertElement instruction.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700524class InstInsertElement : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800525 InstInsertElement() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700526 InstInsertElement(const InstInsertElement &) = delete;
527 InstInsertElement &operator=(const InstInsertElement &) = delete;
528
Matt Wala49889232014-07-18 12:45:09 -0700529public:
530 static InstInsertElement *create(Cfg *Func, Variable *Dest, Operand *Source1,
531 Operand *Source2, Operand *Source3) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800532 return new (Func->allocate<InstInsertElement>())
Matt Wala49889232014-07-18 12:45:09 -0700533 InstInsertElement(Func, Dest, Source1, Source2, Source3);
534 }
535
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700536 void dump(const Cfg *Func) const override;
Matt Wala49889232014-07-18 12:45:09 -0700537 static bool classof(const Inst *Inst) {
538 return Inst->getKind() == InsertElement;
539 }
540
541private:
542 InstInsertElement(Cfg *Func, Variable *Dest, Operand *Source1,
543 Operand *Source2, Operand *Source3);
Matt Wala49889232014-07-18 12:45:09 -0700544};
545
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700546// Call to an intrinsic function. The call target is captured as getSrc(0),
547// and arg I is captured as getSrc(I+1).
548class InstIntrinsicCall : public InstCall {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800549 InstIntrinsicCall() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700550 InstIntrinsicCall(const InstIntrinsicCall &) = delete;
551 InstIntrinsicCall &operator=(const InstIntrinsicCall &) = delete;
552
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700553public:
554 static InstIntrinsicCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest,
555 Operand *CallTarget,
556 const Intrinsics::IntrinsicInfo &Info) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800557 return new (Func->allocate<InstIntrinsicCall>())
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700558 InstIntrinsicCall(Func, NumArgs, Dest, CallTarget, Info);
559 }
560 static bool classof(const Inst *Inst) {
561 return Inst->getKind() == IntrinsicCall;
562 }
563
564 Intrinsics::IntrinsicInfo getIntrinsicInfo() const { return Info; }
565
566private:
567 InstIntrinsicCall(Cfg *Func, SizeT NumArgs, Variable *Dest,
568 Operand *CallTarget, const Intrinsics::IntrinsicInfo &Info)
Karl Schimpf8df26f32014-09-19 09:33:26 -0700569 : InstCall(Func, NumArgs, Dest, CallTarget, false, Info.HasSideEffects,
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700570 Inst::IntrinsicCall),
571 Info(Info) {}
John Porto1bec8bc2015-06-22 10:51:13 -0700572
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700573 const Intrinsics::IntrinsicInfo Info;
574};
575
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700576// Load instruction. The source address is captured in getSrc(0).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700577class InstLoad : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800578 InstLoad() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700579 InstLoad(const InstLoad &) = delete;
580 InstLoad &operator=(const InstLoad &) = delete;
581
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700582public:
Karl Schimpf41689df2014-09-10 14:36:07 -0700583 static InstLoad *create(Cfg *Func, Variable *Dest, Operand *SourceAddr,
Jim Stichnothc4554d72014-09-30 16:49:38 -0700584 uint32_t Align = 1) {
Karl Schimpf41689df2014-09-10 14:36:07 -0700585 // TODO(kschimpf) Stop ignoring alignment specification.
Jim Stichnothc4554d72014-09-30 16:49:38 -0700586 (void)Align;
Jim Stichnoth31c95592014-12-19 12:51:35 -0800587 return new (Func->allocate<InstLoad>()) InstLoad(Func, Dest, SourceAddr);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700588 }
589 Operand *getSourceAddress() const { return getSrc(0); }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700590 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700591 static bool classof(const Inst *Inst) { return Inst->getKind() == Load; }
592
593private:
594 InstLoad(Cfg *Func, Variable *Dest, Operand *SourceAddr);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700595};
596
597// Phi instruction. For incoming edge I, the node is Labels[I] and
598// the Phi source operand is getSrc(I).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700599class InstPhi : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800600 InstPhi() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700601 InstPhi(const InstPhi &) = delete;
602 InstPhi &operator=(const InstPhi &) = delete;
603
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700604public:
605 static InstPhi *create(Cfg *Func, SizeT MaxSrcs, Variable *Dest) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800606 return new (Func->allocate<InstPhi>()) InstPhi(Func, MaxSrcs, Dest);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700607 }
608 void addArgument(Operand *Source, CfgNode *Label);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700609 Operand *getOperandForTarget(CfgNode *Target) const;
Jim Stichnoth98712a32014-10-24 10:59:02 -0700610 CfgNode *getLabel(SizeT Index) const { return Labels[Index]; }
Jim Stichnoth47752552014-10-13 17:15:08 -0700611 void livenessPhiOperand(LivenessBV &Live, CfgNode *Target,
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700612 Liveness *Liveness);
Jim Stichnoth144cdce2014-09-22 16:02:59 -0700613 Inst *lower(Cfg *Func);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700614 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700615 static bool classof(const Inst *Inst) { return Inst->getKind() == Phi; }
616
617private:
618 InstPhi(Cfg *Func, SizeT MaxSrcs, Variable *Dest);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700619 void destroy(Cfg *Func) override {
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700620 Func->deallocateArrayOf<CfgNode *>(Labels);
621 Inst::destroy(Func);
622 }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700623
624 // Labels[] duplicates the InEdges[] information in the enclosing
625 // CfgNode, but the Phi instruction is created before InEdges[]
626 // is available, so it's more complicated to share the list.
627 CfgNode **Labels;
628};
629
630// Ret instruction. The return value is captured in getSrc(0), but if
631// there is no return value (void-type function), then
632// getSrcSize()==0 and hasRetValue()==false.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700633class InstRet : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800634 InstRet() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700635 InstRet(const InstRet &) = delete;
636 InstRet &operator=(const InstRet &) = delete;
637
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700638public:
Jim Stichnothae953202014-12-20 06:17:49 -0800639 static InstRet *create(Cfg *Func, Operand *RetValue = nullptr) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800640 return new (Func->allocate<InstRet>()) InstRet(Func, RetValue);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700641 }
642 bool hasRetValue() const { return getSrcSize(); }
643 Operand *getRetValue() const {
644 assert(hasRetValue());
645 return getSrc(0);
646 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700647 NodeList getTerminatorEdges() const override { return NodeList(); }
648 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700649 static bool classof(const Inst *Inst) { return Inst->getKind() == Ret; }
650
651private:
652 InstRet(Cfg *Func, Operand *RetValue);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700653};
654
655// Select instruction. The condition, true, and false operands are captured.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700656class InstSelect : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800657 InstSelect() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700658 InstSelect(const InstSelect &) = delete;
659 InstSelect &operator=(const InstSelect &) = delete;
660
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700661public:
662 static InstSelect *create(Cfg *Func, Variable *Dest, Operand *Condition,
663 Operand *SourceTrue, Operand *SourceFalse) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800664 return new (Func->allocate<InstSelect>())
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700665 InstSelect(Func, Dest, Condition, SourceTrue, SourceFalse);
666 }
667 Operand *getCondition() const { return getSrc(0); }
668 Operand *getTrueOperand() const { return getSrc(1); }
669 Operand *getFalseOperand() const { return getSrc(2); }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700670 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700671 static bool classof(const Inst *Inst) { return Inst->getKind() == Select; }
672
673private:
674 InstSelect(Cfg *Func, Variable *Dest, Operand *Condition, Operand *Source1,
675 Operand *Source2);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700676};
677
678// Store instruction. The address operand is captured, along with the
679// data operand to be stored into the address.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700680class InstStore : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800681 InstStore() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700682 InstStore(const InstStore &) = delete;
683 InstStore &operator=(const InstStore &) = delete;
684
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700685public:
Karl Schimpf41689df2014-09-10 14:36:07 -0700686 static InstStore *create(Cfg *Func, Operand *Data, Operand *Addr,
Jim Stichnothe4f65d82015-06-17 22:16:02 -0700687 uint32_t Align = 1) {
Karl Schimpf41689df2014-09-10 14:36:07 -0700688 // TODO(kschimpf) Stop ignoring alignment specification.
Jim Stichnothe4f65d82015-06-17 22:16:02 -0700689 (void)Align;
Jim Stichnoth31c95592014-12-19 12:51:35 -0800690 return new (Func->allocate<InstStore>()) InstStore(Func, Data, Addr);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700691 }
692 Operand *getAddr() const { return getSrc(1); }
693 Operand *getData() const { return getSrc(0); }
Jim Stichnothe4f65d82015-06-17 22:16:02 -0700694 Variable *getRmwBeacon() const { return llvm::dyn_cast<Variable>(getSrc(2)); }
695 void setRmwBeacon(Variable *Beacon);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700696 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700697 static bool classof(const Inst *Inst) { return Inst->getKind() == Store; }
698
699private:
700 InstStore(Cfg *Func, Operand *Data, Operand *Addr);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700701};
702
703// Switch instruction. The single source operand is captured as
704// getSrc(0).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700705class InstSwitch : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800706 InstSwitch() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700707 InstSwitch(const InstSwitch &) = delete;
708 InstSwitch &operator=(const InstSwitch &) = delete;
709
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700710public:
711 static InstSwitch *create(Cfg *Func, SizeT NumCases, Operand *Source,
712 CfgNode *LabelDefault) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800713 return new (Func->allocate<InstSwitch>())
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700714 InstSwitch(Func, NumCases, Source, LabelDefault);
715 }
716 Operand *getComparison() const { return getSrc(0); }
717 CfgNode *getLabelDefault() const { return LabelDefault; }
718 SizeT getNumCases() const { return NumCases; }
719 uint64_t getValue(SizeT I) const {
720 assert(I < NumCases);
721 return Values[I];
722 }
723 CfgNode *getLabel(SizeT I) const {
724 assert(I < NumCases);
725 return Labels[I];
726 }
727 void addBranch(SizeT CaseIndex, uint64_t Value, CfgNode *Label);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700728 NodeList getTerminatorEdges() const override;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700729 bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700730 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700731 static bool classof(const Inst *Inst) { return Inst->getKind() == Switch; }
732
733private:
734 InstSwitch(Cfg *Func, SizeT NumCases, Operand *Source, CfgNode *LabelDefault);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700735 void destroy(Cfg *Func) override {
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700736 Func->deallocateArrayOf<uint64_t>(Values);
737 Func->deallocateArrayOf<CfgNode *>(Labels);
738 Inst::destroy(Func);
739 }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700740
741 CfgNode *LabelDefault;
742 SizeT NumCases; // not including the default case
743 uint64_t *Values; // size is NumCases
744 CfgNode **Labels; // size is NumCases
745};
746
747// Unreachable instruction. This is a terminator instruction with no
748// operands.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700749class InstUnreachable : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800750 InstUnreachable() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700751 InstUnreachable(const InstUnreachable &) = delete;
752 InstUnreachable &operator=(const InstUnreachable &) = delete;
753
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700754public:
755 static InstUnreachable *create(Cfg *Func) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800756 return new (Func->allocate<InstUnreachable>()) InstUnreachable(Func);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700757 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700758 NodeList getTerminatorEdges() const override { return NodeList(); }
759 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700760 static bool classof(const Inst *Inst) {
761 return Inst->getKind() == Unreachable;
762 }
763
764private:
Jim Stichnothc6ead202015-02-24 09:30:30 -0800765 explicit InstUnreachable(Cfg *Func);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700766};
767
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -0800768// BundleLock instruction. There are no operands. Contains an option
769// indicating whether align_to_end is specified.
770class InstBundleLock : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800771 InstBundleLock() = delete;
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -0800772 InstBundleLock(const InstBundleLock &) = delete;
773 InstBundleLock &operator=(const InstBundleLock &) = delete;
774
775public:
776 enum Option { Opt_None, Opt_AlignToEnd };
777 static InstBundleLock *create(Cfg *Func, Option BundleOption) {
778 return new (Func->allocate<InstBundleLock>())
779 InstBundleLock(Func, BundleOption);
780 }
781 void emit(const Cfg *Func) const override;
782 void emitIAS(const Cfg * /* Func */) const override {}
783 void dump(const Cfg *Func) const override;
784 Option getOption() const { return BundleOption; }
785 static bool classof(const Inst *Inst) {
786 return Inst->getKind() == BundleLock;
787 }
788
789private:
790 Option BundleOption;
791 InstBundleLock(Cfg *Func, Option BundleOption);
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -0800792};
793
794// BundleUnlock instruction. There are no operands.
795class InstBundleUnlock : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800796 InstBundleUnlock() = delete;
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -0800797 InstBundleUnlock(const InstBundleUnlock &) = delete;
798 InstBundleUnlock &operator=(const InstBundleUnlock &) = delete;
799
800public:
801 static InstBundleUnlock *create(Cfg *Func) {
802 return new (Func->allocate<InstBundleUnlock>()) InstBundleUnlock(Func);
803 }
804 void emit(const Cfg *Func) const override;
805 void emitIAS(const Cfg * /* Func */) const override {}
806 void dump(const Cfg *Func) const override;
807 static bool classof(const Inst *Inst) {
808 return Inst->getKind() == BundleUnlock;
809 }
810
811private:
812 explicit InstBundleUnlock(Cfg *Func);
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -0800813};
814
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700815// FakeDef instruction. This creates a fake definition of a variable,
816// which is how we represent the case when an instruction produces
817// multiple results. This doesn't happen with high-level ICE
818// instructions, but might with lowered instructions. For example,
819// this would be a way to represent condition flags being modified by
820// an instruction.
821//
822// It's generally useful to set the optional source operand to be the
823// dest variable of the instruction that actually produces the FakeDef
824// dest. Otherwise, the original instruction could be dead-code
825// eliminated if its dest operand is unused, and therefore the FakeDef
826// dest wouldn't be properly initialized.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700827class InstFakeDef : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800828 InstFakeDef() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700829 InstFakeDef(const InstFakeDef &) = delete;
830 InstFakeDef &operator=(const InstFakeDef &) = delete;
831
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700832public:
Jim Stichnothae953202014-12-20 06:17:49 -0800833 static InstFakeDef *create(Cfg *Func, Variable *Dest,
834 Variable *Src = nullptr) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800835 return new (Func->allocate<InstFakeDef>()) InstFakeDef(Func, Dest, Src);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700836 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700837 void emit(const Cfg *Func) const override;
Jan Voung198b2942014-10-16 09:40:02 -0700838 void emitIAS(const Cfg * /* Func */) const override {}
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700839 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700840 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeDef; }
841
842private:
843 InstFakeDef(Cfg *Func, Variable *Dest, Variable *Src);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700844};
845
846// FakeUse instruction. This creates a fake use of a variable, to
847// keep the instruction that produces that variable from being
848// dead-code eliminated. This is useful in a variety of lowering
849// situations. The FakeUse instruction has no dest, so it can itself
850// never be dead-code eliminated.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700851class InstFakeUse : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800852 InstFakeUse() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700853 InstFakeUse(const InstFakeUse &) = delete;
854 InstFakeUse &operator=(const InstFakeUse &) = delete;
855
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700856public:
857 static InstFakeUse *create(Cfg *Func, Variable *Src) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800858 return new (Func->allocate<InstFakeUse>()) InstFakeUse(Func, Src);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700859 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700860 void emit(const Cfg *Func) const override;
Jan Voung198b2942014-10-16 09:40:02 -0700861 void emitIAS(const Cfg * /* Func */) const override {}
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700862 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700863 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeUse; }
864
865private:
866 InstFakeUse(Cfg *Func, Variable *Src);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700867};
868
Jim Stichnoth87ff3a12014-11-14 10:27:29 -0800869// FakeKill instruction. This "kills" a set of variables by modeling
870// a trivial live range at this instruction for each (implicit)
871// variable. The primary use is to indicate that scratch registers
872// are killed after a call, so that the register allocator won't
873// assign a scratch register to a variable whose live range spans a
874// call.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700875//
876// The FakeKill instruction also holds a pointer to the instruction
877// that kills the set of variables, so that if that linked instruction
878// gets dead-code eliminated, the FakeKill instruction will as well.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700879class InstFakeKill : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800880 InstFakeKill() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700881 InstFakeKill(const InstFakeKill &) = delete;
882 InstFakeKill &operator=(const InstFakeKill &) = delete;
883
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700884public:
Jim Stichnoth87ff3a12014-11-14 10:27:29 -0800885 static InstFakeKill *create(Cfg *Func, const Inst *Linked) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800886 return new (Func->allocate<InstFakeKill>()) InstFakeKill(Func, Linked);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700887 }
888 const Inst *getLinked() const { return Linked; }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700889 void emit(const Cfg *Func) const override;
Jan Voung198b2942014-10-16 09:40:02 -0700890 void emitIAS(const Cfg * /* Func */) const override {}
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700891 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700892 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeKill; }
893
894private:
Jim Stichnoth87ff3a12014-11-14 10:27:29 -0800895 InstFakeKill(Cfg *Func, const Inst *Linked);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700896
897 // This instruction is ignored if Linked->isDeleted() is true.
898 const Inst *Linked;
899};
900
901// The Target instruction is the base class for all target-specific
902// instructions.
903class InstTarget : public Inst {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800904 InstTarget() = delete;
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700905 InstTarget(const InstTarget &) = delete;
906 InstTarget &operator=(const InstTarget &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700907
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700908public:
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700909 uint32_t getEmitInstCount() const override { return 1; }
910 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700911 static bool classof(const Inst *Inst) { return Inst->getKind() >= Target; }
912
913protected:
914 InstTarget(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest)
915 : Inst(Func, Kind, MaxSrcs, Dest) {
916 assert(Kind >= Target);
917 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700918};
919
Jan Voungb3401d22015-05-18 09:38:21 -0700920bool checkForRedundantAssign(const Variable *Dest, const Operand *Source);
921
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700922} // end of namespace Ice
923
Jim Stichnothdddaf9c2014-12-04 14:09:21 -0800924namespace llvm {
925
Jim Stichnoth607e9f02014-11-06 13:32:05 -0800926// Override the default ilist traits so that Inst's private ctor and
927// deleted dtor aren't invoked.
928template <>
Jim Stichnothdddaf9c2014-12-04 14:09:21 -0800929struct ilist_traits<Ice::Inst> : public ilist_default_traits<Ice::Inst> {
Jim Stichnoth607e9f02014-11-06 13:32:05 -0800930 Ice::Inst *createSentinel() const {
931 return static_cast<Ice::Inst *>(&Sentinel);
932 }
933 static void destroySentinel(Ice::Inst *) {}
934 Ice::Inst *provideInitialHead() const { return createSentinel(); }
935 Ice::Inst *ensureHead(Ice::Inst *) const { return createSentinel(); }
936 static void noteHead(Ice::Inst *, Ice::Inst *) {}
937 void deleteNode(Ice::Inst *) {}
938
939private:
940 mutable ilist_half_node<Ice::Inst> Sentinel;
941};
942
Jim Stichnothdddaf9c2014-12-04 14:09:21 -0800943} // end of namespace llvm
944
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700945#endif // SUBZERO_SRC_ICEINST_H