blob: 2b5adc6aa8d3cb01bd26a693d3bc0aaec90ec0b6 [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
19#include "IceDefs.h"
20#include "IceInst.def"
Jan Voung3bd9f1a2014-06-18 10:50:57 -070021#include "IceIntrinsics.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070022#include "IceTypes.h"
23
24// TODO: The Cfg structure, and instructions in particular, need to be
25// validated for things like valid operand types, valid branch
26// targets, proper ordering of Phi and non-Phi instructions, etc.
27// Most of the validity checking will be done in the bitcode reader.
28// We need a list of everything that should be validated, and tests
29// for each.
30
31namespace Ice {
32
Jim Stichnothb56c8f42014-09-26 09:28:46 -070033// Base instruction class for ICE. Inst has two subclasses:
34// InstHighLevel and InstTarget. High-level ICE instructions inherit
35// from InstHighLevel, and low-level (target-specific) ICE
36// instructions inherit from InstTarget.
Jim Stichnoth607e9f02014-11-06 13:32:05 -080037class Inst : public llvm::ilist_node<Inst> {
Jim Stichnothc6ead202015-02-24 09:30:30 -080038 Inst() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -070039 Inst(const Inst &) = delete;
40 Inst &operator=(const Inst &) = delete;
41
Jim Stichnothf7c9a142014-04-29 10:52:43 -070042public:
43 enum InstKind {
44 // Arbitrary (alphabetical) order, except put Unreachable first.
45 Unreachable,
46 Alloca,
47 Arithmetic,
Jim Stichnothf7c9a142014-04-29 10:52:43 -070048 Br,
49 Call,
50 Cast,
Matt Wala49889232014-07-18 12:45:09 -070051 ExtractElement,
Jim Stichnothf7c9a142014-04-29 10:52:43 -070052 Fcmp,
53 Icmp,
Jan Voung3bd9f1a2014-06-18 10:50:57 -070054 IntrinsicCall,
Matt Wala49889232014-07-18 12:45:09 -070055 InsertElement,
Jim Stichnothf7c9a142014-04-29 10:52:43 -070056 Load,
57 Phi,
58 Ret,
59 Select,
60 Store,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070061 Switch,
Jim Stichnothc6ead202015-02-24 09:30:30 -080062 Assign, // not part of LLVM/PNaCl bitcode
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -080063 BundleLock, // not part of LLVM/PNaCl bitcode
64 BundleUnlock, // not part of LLVM/PNaCl bitcode
65 FakeDef, // not part of LLVM/PNaCl bitcode
66 FakeUse, // not part of LLVM/PNaCl bitcode
67 FakeKill, // not part of LLVM/PNaCl bitcode
68 Target // target-specific low-level ICE
69 // Anything >= Target is an InstTarget subclass.
Jan Voungb3401d22015-05-18 09:38:21 -070070 // Note that the value-spaces are shared across targets.
71 // To avoid confusion over the definition of shared values,
72 // an object specific to one target should never be passed
73 // to a different target.
Jim Stichnothf7c9a142014-04-29 10:52:43 -070074 };
75 InstKind getKind() const { return Kind; }
76
Jim Stichnothd97c7df2014-06-04 11:57:08 -070077 InstNumberT getNumber() const { return Number; }
78 void renumber(Cfg *Func);
Jim Stichnothe5b73e62014-12-15 09:58:51 -080079 enum {
80 NumberDeleted = -1,
81 NumberSentinel = 0,
82 NumberInitial = 2,
83 NumberExtended = NumberInitial - 1
84 };
Jim Stichnothf7c9a142014-04-29 10:52:43 -070085
86 bool isDeleted() const { return Deleted; }
87 void setDeleted() { Deleted = true; }
Jim Stichnotha59ae6f2015-05-17 10:11:41 -070088 void setDead(bool Value = true) { Dead = Value; }
Jim Stichnothd97c7df2014-06-04 11:57:08 -070089 void deleteIfDead();
Jim Stichnothf7c9a142014-04-29 10:52:43 -070090
91 bool hasSideEffects() const { return HasSideEffects; }
92
Jim Stichnoth47752552014-10-13 17:15:08 -070093 bool isDestNonKillable() const { return IsDestNonKillable; }
94 void setDestNonKillable() { IsDestNonKillable = true; }
95
Jim Stichnothf7c9a142014-04-29 10:52:43 -070096 Variable *getDest() const { return Dest; }
97
98 SizeT getSrcSize() const { return NumSrcs; }
99 Operand *getSrc(SizeT I) const {
100 assert(I < getSrcSize());
101 return Srcs[I];
102 }
103
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700104 bool isLastUse(const Operand *Src) const;
Jim Stichnoth8e6bf6e2015-06-03 15:58:12 -0700105 void spliceLivenessInfo(Inst *OrigInst, Inst *SpliceAssn);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700106
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700107 // Returns a list of out-edges corresponding to a terminator
108 // instruction, which is the last instruction of the block.
109 virtual NodeList getTerminatorEdges() const {
110 // All valid terminator instructions override this method. For
111 // the default implementation, we assert in case some CfgNode
112 // is constructed without a terminator instruction at the end.
113 llvm_unreachable(
114 "getTerminatorEdges() called on a non-terminator instruction");
115 return NodeList();
116 }
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700117 virtual bool isUnconditionalBranch() const { return false; }
118 // If the instruction is a branch-type instruction with OldNode as a
119 // target, repoint it to NewNode and return true, otherwise return
120 // false. Only repoint one instance, even if the instruction has
121 // multiple instances of OldNode as a target.
122 virtual bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) {
123 (void)OldNode;
124 (void)NewNode;
125 return false;
126 }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700127
Jim Stichnothad403532014-09-25 12:44:17 -0700128 virtual bool isSimpleAssign() const { return false; }
129
Jim Stichnoth47752552014-10-13 17:15:08 -0700130 void livenessLightweight(Cfg *Func, LivenessBV &Live);
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700131 // Calculates liveness for this instruction. Returns true if this
132 // instruction is (tentatively) still live and should be retained,
133 // and false if this instruction is (tentatively) dead and should be
134 // deleted. The decision is tentative until the liveness dataflow
135 // algorithm has converged, and then a separate pass permanently
136 // deletes dead instructions.
137 bool liveness(InstNumberT InstNumber, LivenessBV &Live, Liveness *Liveness,
Jim Stichnoth47752552014-10-13 17:15:08 -0700138 LiveBeginEndMap *LiveBegin, LiveBeginEndMap *LiveEnd);
Jim Stichnoth18735602014-09-16 19:59:35 -0700139
140 // Get the number of native instructions that this instruction
141 // ultimately emits. By default, high-level instructions don't
142 // result in any native instructions, and a target-specific
143 // instruction results in a single native instruction.
144 virtual uint32_t getEmitInstCount() const { return 0; }
Jim Stichnothdddaf9c2014-12-04 14:09:21 -0800145 // TODO(stichnot): Change Inst back to abstract once the g++ build
146 // issue is fixed. llvm::ilist<Ice::Inst> doesn't work under g++
147 // because the resize(size_t, Ice::Inst) method is incorrectly
148 // declared and thus doesn't allow the abstract class Ice::Inst.
149 // The method should be declared resize(size_t, const Ice::Inst &).
150 // virtual void emit(const Cfg *Func) const = 0;
151 // virtual void emitIAS(const Cfg *Func) const = 0;
152 virtual void emit(const Cfg *) const {
153 llvm_unreachable("emit on abstract class");
154 }
155 virtual void emitIAS(const Cfg *Func) const { emit(Func); }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700156 virtual void dump(const Cfg *Func) const;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700157 virtual void dumpExtras(const Cfg *Func) const;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700158 void dumpDecorated(const Cfg *Func) const;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700159 void emitSources(const Cfg *Func) const;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700160 void dumpSources(const Cfg *Func) const;
161 void dumpDest(const Cfg *Func) const;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700162 virtual bool isRedundantAssign() const { return false; }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700163
John Porto1bec8bc2015-06-22 10:51:13 -0700164 // TODO(jpp): Insts should not have non-trivial destructors, but they
165 // currently do. This dtor is marked final as a multi-step refactor that
166 // will eventually fix this problem.
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700167 virtual ~Inst() = default;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700168
169protected:
170 Inst(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest);
171 void addSource(Operand *Src) {
172 assert(Src);
173 assert(NumSrcs < MaxSrcs);
174 Srcs[NumSrcs++] = Src;
175 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700176 void setLastUse(SizeT VarIndex) {
177 if (VarIndex < CHAR_BIT * sizeof(LiveRangesEnded))
178 LiveRangesEnded |= (((LREndedBits)1u) << VarIndex);
179 }
180 void resetLastUses() { LiveRangesEnded = 0; }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700181 // The destroy() method lets the instruction cleanly release any
182 // memory that was allocated via the Cfg's allocator.
183 virtual void destroy(Cfg *Func) { Func->deallocateArrayOf<Operand *>(Srcs); }
184
185 const InstKind Kind;
186 // Number is the instruction number for describing live ranges.
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700187 InstNumberT Number;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700188 // Deleted means irrevocably deleted.
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700189 bool Deleted = false;
Jim Stichnotha59ae6f2015-05-17 10:11:41 -0700190 // Dead means one of two things depending on context: (1) pending
191 // deletion after liveness analysis converges, or (2) marked for
192 // deletion during lowering due to a folded bool operation.
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700193 bool Dead = false;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700194 // HasSideEffects means the instruction is something like a function
195 // call or a volatile load that can't be removed even if its Dest
196 // variable is not live.
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700197 bool HasSideEffects = false;
Jim Stichnoth47752552014-10-13 17:15:08 -0700198 // IsDestNonKillable means that liveness analysis shouldn't consider
199 // this instruction to kill the Dest variable. This is used when
200 // lowering produces two assignments to the same variable.
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700201 bool IsDestNonKillable = false;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700202
203 Variable *Dest;
204 const SizeT MaxSrcs; // only used for assert
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700205 SizeT NumSrcs = 0;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700206 Operand **Srcs;
207
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700208 // LiveRangesEnded marks which Variables' live ranges end in this
209 // instruction. An instruction can have an arbitrary number of
210 // source operands (e.g. a call instruction), and each source
211 // operand can contain 0 or 1 Variable (and target-specific operands
212 // could contain more than 1 Variable). All the variables in an
213 // instruction are conceptually flattened and each variable is
214 // mapped to one bit position of the LiveRangesEnded bit vector.
215 // Only the first CHAR_BIT * sizeof(LREndedBits) variables are
216 // tracked this way.
217 typedef uint32_t LREndedBits; // only first 32 src operands tracked, sorry
218 LREndedBits LiveRangesEnded;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700219};
220
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700221class InstHighLevel : public Inst {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800222 InstHighLevel() = delete;
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700223 InstHighLevel(const InstHighLevel &) = delete;
224 InstHighLevel &operator=(const InstHighLevel &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700225
226protected:
227 InstHighLevel(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest)
228 : Inst(Func, Kind, MaxSrcs, Dest) {}
229 void emit(const Cfg * /*Func*/) const override {
230 llvm_unreachable("emit() called on a non-lowered instruction");
231 }
232 void emitIAS(const Cfg * /*Func*/) const override {
233 llvm_unreachable("emitIAS() called on a non-lowered instruction");
234 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700235};
236
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700237// Alloca instruction. This captures the size in bytes as getSrc(0),
238// and the required alignment in bytes. The alignment must be either
239// 0 (no alignment required) or a power of 2.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700240class InstAlloca : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800241 InstAlloca() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700242 InstAlloca(const InstAlloca &) = delete;
243 InstAlloca &operator=(const InstAlloca &) = delete;
244
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700245public:
246 static InstAlloca *create(Cfg *Func, Operand *ByteCount,
247 uint32_t AlignInBytes, Variable *Dest) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800248 return new (Func->allocate<InstAlloca>())
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700249 InstAlloca(Func, ByteCount, AlignInBytes, Dest);
250 }
251 uint32_t getAlignInBytes() const { return AlignInBytes; }
252 Operand *getSizeInBytes() const { return getSrc(0); }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700253 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700254 static bool classof(const Inst *Inst) { return Inst->getKind() == Alloca; }
255
256private:
257 InstAlloca(Cfg *Func, Operand *ByteCount, uint32_t AlignInBytes,
258 Variable *Dest);
John Porto1bec8bc2015-06-22 10:51:13 -0700259
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700260 const uint32_t AlignInBytes;
261};
262
263// Binary arithmetic instruction. The source operands are captured in
264// getSrc(0) and getSrc(1).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700265class InstArithmetic : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800266 InstArithmetic() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700267 InstArithmetic(const InstArithmetic &) = delete;
268 InstArithmetic &operator=(const InstArithmetic &) = delete;
269
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700270public:
271 enum OpKind {
272#define X(tag, str, commutative) tag,
273 ICEINSTARITHMETIC_TABLE
274#undef X
Jim Stichnoth4376d292014-05-23 13:39:02 -0700275 _num
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700276 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700277
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700278 static InstArithmetic *create(Cfg *Func, OpKind Op, Variable *Dest,
279 Operand *Source1, Operand *Source2) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800280 return new (Func->allocate<InstArithmetic>())
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700281 InstArithmetic(Func, Op, Dest, Source1, Source2);
282 }
283 OpKind getOp() const { return Op; }
Karl Schimpfd6064a12014-08-27 15:34:58 -0700284 static const char *getOpName(OpKind Op);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700285 bool isCommutative() const;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700286 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700287 static bool classof(const Inst *Inst) {
288 return Inst->getKind() == Arithmetic;
289 }
290
291private:
292 InstArithmetic(Cfg *Func, OpKind Op, Variable *Dest, Operand *Source1,
293 Operand *Source2);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700294
295 const OpKind Op;
296};
297
298// Assignment instruction. The source operand is captured in
299// getSrc(0). This is not part of the LLVM bitcode, but is a useful
300// abstraction for some of the lowering. E.g., if Phi instruction
301// lowering happens before target lowering, or for representing an
302// Inttoptr instruction, or as an intermediate step for lowering a
303// Load instruction.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700304class InstAssign : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800305 InstAssign() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700306 InstAssign(const InstAssign &) = delete;
307 InstAssign &operator=(const InstAssign &) = delete;
308
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700309public:
310 static InstAssign *create(Cfg *Func, Variable *Dest, Operand *Source) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800311 return new (Func->allocate<InstAssign>()) InstAssign(Func, Dest, Source);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700312 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700313 bool isSimpleAssign() const override { return true; }
314 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700315 static bool classof(const Inst *Inst) { return Inst->getKind() == Assign; }
316
317private:
318 InstAssign(Cfg *Func, Variable *Dest, Operand *Source);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700319};
320
321// Branch instruction. This represents both conditional and
322// unconditional branches.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700323class InstBr : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800324 InstBr() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700325 InstBr(const InstBr &) = delete;
326 InstBr &operator=(const InstBr &) = delete;
327
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700328public:
329 // Create a conditional branch. If TargetTrue==TargetFalse, it is
330 // optimized to an unconditional branch.
331 static InstBr *create(Cfg *Func, Operand *Source, CfgNode *TargetTrue,
332 CfgNode *TargetFalse) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800333 return new (Func->allocate<InstBr>())
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700334 InstBr(Func, Source, TargetTrue, TargetFalse);
335 }
336 // Create an unconditional branch.
337 static InstBr *create(Cfg *Func, CfgNode *Target) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800338 return new (Func->allocate<InstBr>()) InstBr(Func, Target);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700339 }
Jim Stichnothae953202014-12-20 06:17:49 -0800340 bool isUnconditional() const { return getTargetTrue() == nullptr; }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700341 Operand *getCondition() const {
342 assert(!isUnconditional());
343 return getSrc(0);
344 }
345 CfgNode *getTargetTrue() const { return TargetTrue; }
346 CfgNode *getTargetFalse() const { return TargetFalse; }
347 CfgNode *getTargetUnconditional() const {
348 assert(isUnconditional());
349 return getTargetFalse();
350 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700351 NodeList getTerminatorEdges() const override;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700352 bool isUnconditionalBranch() const override { return isUnconditional(); }
353 bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700354 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700355 static bool classof(const Inst *Inst) { return Inst->getKind() == Br; }
356
357private:
358 // Conditional branch
359 InstBr(Cfg *Func, Operand *Source, CfgNode *TargetTrue, CfgNode *TargetFalse);
360 // Unconditional branch
361 InstBr(Cfg *Func, CfgNode *Target);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700362
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700363 CfgNode *TargetFalse; // Doubles as unconditional branch target
Jim Stichnothae953202014-12-20 06:17:49 -0800364 CfgNode *TargetTrue; // nullptr if unconditional branch
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700365};
366
367// Call instruction. The call target is captured as getSrc(0), and
368// arg I is captured as getSrc(I+1).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700369class InstCall : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800370 InstCall() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700371 InstCall(const InstCall &) = delete;
372 InstCall &operator=(const InstCall &) = delete;
373
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700374public:
375 static InstCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest,
Karl Schimpf8df26f32014-09-19 09:33:26 -0700376 Operand *CallTarget, bool HasTailCall) {
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700377 // Set HasSideEffects to true so that the call instruction can't be
378 // dead-code eliminated. IntrinsicCalls can override this if the
379 // particular intrinsic is deletable and has no side-effects.
380 const bool HasSideEffects = true;
381 const InstKind Kind = Inst::Call;
Jim Stichnoth31c95592014-12-19 12:51:35 -0800382 return new (Func->allocate<InstCall>()) InstCall(
Karl Schimpf8df26f32014-09-19 09:33:26 -0700383 Func, NumArgs, Dest, CallTarget, HasTailCall, HasSideEffects, Kind);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700384 }
385 void addArg(Operand *Arg) { addSource(Arg); }
386 Operand *getCallTarget() const { return getSrc(0); }
387 Operand *getArg(SizeT I) const { return getSrc(I + 1); }
388 SizeT getNumArgs() const { return getSrcSize() - 1; }
Karl Schimpf8df26f32014-09-19 09:33:26 -0700389 bool isTailcall() const { return HasTailCall; }
Jan Voung3ce1a992015-02-03 08:27:44 -0800390 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700391 static bool classof(const Inst *Inst) { return Inst->getKind() == Call; }
Karl Schimpf8df26f32014-09-19 09:33:26 -0700392 Type getReturnType() const;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700393
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700394protected:
395 InstCall(Cfg *Func, SizeT NumArgs, Variable *Dest, Operand *CallTarget,
Karl Schimpf8df26f32014-09-19 09:33:26 -0700396 bool HasTailCall, bool HasSideEff, InstKind Kind)
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700397 : InstHighLevel(Func, Kind, NumArgs + 1, Dest), HasTailCall(HasTailCall) {
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700398 HasSideEffects = HasSideEff;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700399 addSource(CallTarget);
400 }
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700401
402private:
Karl Schimpf8df26f32014-09-19 09:33:26 -0700403 bool HasTailCall;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700404};
405
406// Cast instruction (a.k.a. conversion operation).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700407class InstCast : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800408 InstCast() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700409 InstCast(const InstCast &) = delete;
410 InstCast &operator=(const InstCast &) = delete;
411
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700412public:
413 enum OpKind {
414#define X(tag, str) tag,
415 ICEINSTCAST_TABLE
416#undef X
Jim Stichnoth4376d292014-05-23 13:39:02 -0700417 _num
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700418 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700419
Karl Schimpfbf170372014-12-15 10:16:31 -0800420 static const char *getCastName(OpKind Kind);
421
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700422 static InstCast *create(Cfg *Func, OpKind CastKind, Variable *Dest,
423 Operand *Source) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800424 return new (Func->allocate<InstCast>())
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700425 InstCast(Func, CastKind, Dest, Source);
426 }
427 OpKind getCastKind() const { return CastKind; }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700428 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700429 static bool classof(const Inst *Inst) { return Inst->getKind() == Cast; }
430
431private:
432 InstCast(Cfg *Func, OpKind CastKind, Variable *Dest, Operand *Source);
John Porto1bec8bc2015-06-22 10:51:13 -0700433
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700434 const OpKind CastKind;
435};
436
Matt Wala49889232014-07-18 12:45:09 -0700437// ExtractElement instruction.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700438class InstExtractElement : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800439 InstExtractElement() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700440 InstExtractElement(const InstExtractElement &) = delete;
441 InstExtractElement &operator=(const InstExtractElement &) = delete;
442
Matt Wala49889232014-07-18 12:45:09 -0700443public:
444 static InstExtractElement *create(Cfg *Func, Variable *Dest, Operand *Source1,
445 Operand *Source2) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800446 return new (Func->allocate<InstExtractElement>())
Matt Wala49889232014-07-18 12:45:09 -0700447 InstExtractElement(Func, Dest, Source1, Source2);
448 }
449
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700450 void dump(const Cfg *Func) const override;
Matt Wala49889232014-07-18 12:45:09 -0700451 static bool classof(const Inst *Inst) {
452 return Inst->getKind() == ExtractElement;
453 }
454
455private:
456 InstExtractElement(Cfg *Func, Variable *Dest, Operand *Source1,
457 Operand *Source2);
Matt Wala49889232014-07-18 12:45:09 -0700458};
459
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700460// Floating-point comparison instruction. The source operands are
461// captured in getSrc(0) and getSrc(1).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700462class InstFcmp : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800463 InstFcmp() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700464 InstFcmp(const InstFcmp &) = delete;
465 InstFcmp &operator=(const InstFcmp &) = delete;
466
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700467public:
468 enum FCond {
469#define X(tag, str) tag,
470 ICEINSTFCMP_TABLE
471#undef X
Jim Stichnoth4376d292014-05-23 13:39:02 -0700472 _num
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700473 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700474
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700475 static InstFcmp *create(Cfg *Func, FCond Condition, Variable *Dest,
476 Operand *Source1, Operand *Source2) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800477 return new (Func->allocate<InstFcmp>())
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700478 InstFcmp(Func, Condition, Dest, Source1, Source2);
479 }
480 FCond getCondition() const { return Condition; }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700481 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700482 static bool classof(const Inst *Inst) { return Inst->getKind() == Fcmp; }
483
484private:
485 InstFcmp(Cfg *Func, FCond Condition, Variable *Dest, Operand *Source1,
486 Operand *Source2);
John Porto1bec8bc2015-06-22 10:51:13 -0700487
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700488 const FCond Condition;
489};
490
491// Integer comparison instruction. The source operands are captured
492// in getSrc(0) and getSrc(1).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700493class InstIcmp : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800494 InstIcmp() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700495 InstIcmp(const InstIcmp &) = delete;
496 InstIcmp &operator=(const InstIcmp &) = delete;
497
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700498public:
499 enum ICond {
500#define X(tag, str) tag,
501 ICEINSTICMP_TABLE
502#undef X
Jim Stichnoth4376d292014-05-23 13:39:02 -0700503 _num
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700504 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700505
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700506 static InstIcmp *create(Cfg *Func, ICond Condition, Variable *Dest,
507 Operand *Source1, Operand *Source2) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800508 return new (Func->allocate<InstIcmp>())
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700509 InstIcmp(Func, Condition, Dest, Source1, Source2);
510 }
511 ICond getCondition() const { return Condition; }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700512 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700513 static bool classof(const Inst *Inst) { return Inst->getKind() == Icmp; }
514
515private:
516 InstIcmp(Cfg *Func, ICond Condition, Variable *Dest, Operand *Source1,
517 Operand *Source2);
John Porto1bec8bc2015-06-22 10:51:13 -0700518
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700519 const ICond Condition;
520};
521
Matt Wala49889232014-07-18 12:45:09 -0700522// InsertElement instruction.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700523class InstInsertElement : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800524 InstInsertElement() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700525 InstInsertElement(const InstInsertElement &) = delete;
526 InstInsertElement &operator=(const InstInsertElement &) = delete;
527
Matt Wala49889232014-07-18 12:45:09 -0700528public:
529 static InstInsertElement *create(Cfg *Func, Variable *Dest, Operand *Source1,
530 Operand *Source2, Operand *Source3) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800531 return new (Func->allocate<InstInsertElement>())
Matt Wala49889232014-07-18 12:45:09 -0700532 InstInsertElement(Func, Dest, Source1, Source2, Source3);
533 }
534
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700535 void dump(const Cfg *Func) const override;
Matt Wala49889232014-07-18 12:45:09 -0700536 static bool classof(const Inst *Inst) {
537 return Inst->getKind() == InsertElement;
538 }
539
540private:
541 InstInsertElement(Cfg *Func, Variable *Dest, Operand *Source1,
542 Operand *Source2, Operand *Source3);
Matt Wala49889232014-07-18 12:45:09 -0700543};
544
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700545// Call to an intrinsic function. The call target is captured as getSrc(0),
546// and arg I is captured as getSrc(I+1).
547class InstIntrinsicCall : public InstCall {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800548 InstIntrinsicCall() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700549 InstIntrinsicCall(const InstIntrinsicCall &) = delete;
550 InstIntrinsicCall &operator=(const InstIntrinsicCall &) = delete;
551
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700552public:
553 static InstIntrinsicCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest,
554 Operand *CallTarget,
555 const Intrinsics::IntrinsicInfo &Info) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800556 return new (Func->allocate<InstIntrinsicCall>())
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700557 InstIntrinsicCall(Func, NumArgs, Dest, CallTarget, Info);
558 }
559 static bool classof(const Inst *Inst) {
560 return Inst->getKind() == IntrinsicCall;
561 }
562
563 Intrinsics::IntrinsicInfo getIntrinsicInfo() const { return Info; }
564
565private:
566 InstIntrinsicCall(Cfg *Func, SizeT NumArgs, Variable *Dest,
567 Operand *CallTarget, const Intrinsics::IntrinsicInfo &Info)
Karl Schimpf8df26f32014-09-19 09:33:26 -0700568 : InstCall(Func, NumArgs, Dest, CallTarget, false, Info.HasSideEffects,
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700569 Inst::IntrinsicCall),
570 Info(Info) {}
John Porto1bec8bc2015-06-22 10:51:13 -0700571
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700572 const Intrinsics::IntrinsicInfo Info;
573};
574
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700575// Load instruction. The source address is captured in getSrc(0).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700576class InstLoad : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800577 InstLoad() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700578 InstLoad(const InstLoad &) = delete;
579 InstLoad &operator=(const InstLoad &) = delete;
580
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700581public:
Karl Schimpf41689df2014-09-10 14:36:07 -0700582 static InstLoad *create(Cfg *Func, Variable *Dest, Operand *SourceAddr,
Jim Stichnothc4554d72014-09-30 16:49:38 -0700583 uint32_t Align = 1) {
Karl Schimpf41689df2014-09-10 14:36:07 -0700584 // TODO(kschimpf) Stop ignoring alignment specification.
Jim Stichnothc4554d72014-09-30 16:49:38 -0700585 (void)Align;
Jim Stichnoth31c95592014-12-19 12:51:35 -0800586 return new (Func->allocate<InstLoad>()) InstLoad(Func, Dest, SourceAddr);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700587 }
588 Operand *getSourceAddress() const { return getSrc(0); }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700589 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700590 static bool classof(const Inst *Inst) { return Inst->getKind() == Load; }
591
592private:
593 InstLoad(Cfg *Func, Variable *Dest, Operand *SourceAddr);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700594};
595
596// Phi instruction. For incoming edge I, the node is Labels[I] and
597// the Phi source operand is getSrc(I).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700598class InstPhi : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800599 InstPhi() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700600 InstPhi(const InstPhi &) = delete;
601 InstPhi &operator=(const InstPhi &) = delete;
602
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700603public:
604 static InstPhi *create(Cfg *Func, SizeT MaxSrcs, Variable *Dest) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800605 return new (Func->allocate<InstPhi>()) InstPhi(Func, MaxSrcs, Dest);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700606 }
607 void addArgument(Operand *Source, CfgNode *Label);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700608 Operand *getOperandForTarget(CfgNode *Target) const;
Jim Stichnoth98712a32014-10-24 10:59:02 -0700609 CfgNode *getLabel(SizeT Index) const { return Labels[Index]; }
Jim Stichnoth47752552014-10-13 17:15:08 -0700610 void livenessPhiOperand(LivenessBV &Live, CfgNode *Target,
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700611 Liveness *Liveness);
Jim Stichnoth144cdce2014-09-22 16:02:59 -0700612 Inst *lower(Cfg *Func);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700613 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700614 static bool classof(const Inst *Inst) { return Inst->getKind() == Phi; }
615
616private:
617 InstPhi(Cfg *Func, SizeT MaxSrcs, Variable *Dest);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700618 void destroy(Cfg *Func) override {
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700619 Func->deallocateArrayOf<CfgNode *>(Labels);
620 Inst::destroy(Func);
621 }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700622
623 // Labels[] duplicates the InEdges[] information in the enclosing
624 // CfgNode, but the Phi instruction is created before InEdges[]
625 // is available, so it's more complicated to share the list.
626 CfgNode **Labels;
627};
628
629// Ret instruction. The return value is captured in getSrc(0), but if
630// there is no return value (void-type function), then
631// getSrcSize()==0 and hasRetValue()==false.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700632class InstRet : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800633 InstRet() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700634 InstRet(const InstRet &) = delete;
635 InstRet &operator=(const InstRet &) = delete;
636
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700637public:
Jim Stichnothae953202014-12-20 06:17:49 -0800638 static InstRet *create(Cfg *Func, Operand *RetValue = nullptr) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800639 return new (Func->allocate<InstRet>()) InstRet(Func, RetValue);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700640 }
641 bool hasRetValue() const { return getSrcSize(); }
642 Operand *getRetValue() const {
643 assert(hasRetValue());
644 return getSrc(0);
645 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700646 NodeList getTerminatorEdges() const override { return NodeList(); }
647 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700648 static bool classof(const Inst *Inst) { return Inst->getKind() == Ret; }
649
650private:
651 InstRet(Cfg *Func, Operand *RetValue);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700652};
653
654// Select instruction. The condition, true, and false operands are captured.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700655class InstSelect : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800656 InstSelect() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700657 InstSelect(const InstSelect &) = delete;
658 InstSelect &operator=(const InstSelect &) = delete;
659
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700660public:
661 static InstSelect *create(Cfg *Func, Variable *Dest, Operand *Condition,
662 Operand *SourceTrue, Operand *SourceFalse) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800663 return new (Func->allocate<InstSelect>())
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700664 InstSelect(Func, Dest, Condition, SourceTrue, SourceFalse);
665 }
666 Operand *getCondition() const { return getSrc(0); }
667 Operand *getTrueOperand() const { return getSrc(1); }
668 Operand *getFalseOperand() const { return getSrc(2); }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700669 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700670 static bool classof(const Inst *Inst) { return Inst->getKind() == Select; }
671
672private:
673 InstSelect(Cfg *Func, Variable *Dest, Operand *Condition, Operand *Source1,
674 Operand *Source2);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700675};
676
677// Store instruction. The address operand is captured, along with the
678// data operand to be stored into the address.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700679class InstStore : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800680 InstStore() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700681 InstStore(const InstStore &) = delete;
682 InstStore &operator=(const InstStore &) = delete;
683
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700684public:
Karl Schimpf41689df2014-09-10 14:36:07 -0700685 static InstStore *create(Cfg *Func, Operand *Data, Operand *Addr,
Jim Stichnothe4f65d82015-06-17 22:16:02 -0700686 uint32_t Align = 1) {
Karl Schimpf41689df2014-09-10 14:36:07 -0700687 // TODO(kschimpf) Stop ignoring alignment specification.
Jim Stichnothe4f65d82015-06-17 22:16:02 -0700688 (void)Align;
Jim Stichnoth31c95592014-12-19 12:51:35 -0800689 return new (Func->allocate<InstStore>()) InstStore(Func, Data, Addr);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700690 }
691 Operand *getAddr() const { return getSrc(1); }
692 Operand *getData() const { return getSrc(0); }
Jim Stichnothe4f65d82015-06-17 22:16:02 -0700693 Variable *getRmwBeacon() const { return llvm::dyn_cast<Variable>(getSrc(2)); }
694 void setRmwBeacon(Variable *Beacon);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700695 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700696 static bool classof(const Inst *Inst) { return Inst->getKind() == Store; }
697
698private:
699 InstStore(Cfg *Func, Operand *Data, Operand *Addr);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700700};
701
702// Switch instruction. The single source operand is captured as
703// getSrc(0).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700704class InstSwitch : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800705 InstSwitch() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700706 InstSwitch(const InstSwitch &) = delete;
707 InstSwitch &operator=(const InstSwitch &) = delete;
708
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700709public:
710 static InstSwitch *create(Cfg *Func, SizeT NumCases, Operand *Source,
711 CfgNode *LabelDefault) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800712 return new (Func->allocate<InstSwitch>())
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700713 InstSwitch(Func, NumCases, Source, LabelDefault);
714 }
715 Operand *getComparison() const { return getSrc(0); }
716 CfgNode *getLabelDefault() const { return LabelDefault; }
717 SizeT getNumCases() const { return NumCases; }
718 uint64_t getValue(SizeT I) const {
719 assert(I < NumCases);
720 return Values[I];
721 }
722 CfgNode *getLabel(SizeT I) const {
723 assert(I < NumCases);
724 return Labels[I];
725 }
726 void addBranch(SizeT CaseIndex, uint64_t Value, CfgNode *Label);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700727 NodeList getTerminatorEdges() const override;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700728 bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700729 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700730 static bool classof(const Inst *Inst) { return Inst->getKind() == Switch; }
731
732private:
733 InstSwitch(Cfg *Func, SizeT NumCases, Operand *Source, CfgNode *LabelDefault);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700734 void destroy(Cfg *Func) override {
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700735 Func->deallocateArrayOf<uint64_t>(Values);
736 Func->deallocateArrayOf<CfgNode *>(Labels);
737 Inst::destroy(Func);
738 }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700739
740 CfgNode *LabelDefault;
741 SizeT NumCases; // not including the default case
742 uint64_t *Values; // size is NumCases
743 CfgNode **Labels; // size is NumCases
744};
745
746// Unreachable instruction. This is a terminator instruction with no
747// operands.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700748class InstUnreachable : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800749 InstUnreachable() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700750 InstUnreachable(const InstUnreachable &) = delete;
751 InstUnreachable &operator=(const InstUnreachable &) = delete;
752
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700753public:
754 static InstUnreachable *create(Cfg *Func) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800755 return new (Func->allocate<InstUnreachable>()) InstUnreachable(Func);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700756 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700757 NodeList getTerminatorEdges() const override { return NodeList(); }
758 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700759 static bool classof(const Inst *Inst) {
760 return Inst->getKind() == Unreachable;
761 }
762
763private:
Jim Stichnothc6ead202015-02-24 09:30:30 -0800764 explicit InstUnreachable(Cfg *Func);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700765};
766
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -0800767// BundleLock instruction. There are no operands. Contains an option
768// indicating whether align_to_end is specified.
769class InstBundleLock : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800770 InstBundleLock() = delete;
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -0800771 InstBundleLock(const InstBundleLock &) = delete;
772 InstBundleLock &operator=(const InstBundleLock &) = delete;
773
774public:
775 enum Option { Opt_None, Opt_AlignToEnd };
776 static InstBundleLock *create(Cfg *Func, Option BundleOption) {
777 return new (Func->allocate<InstBundleLock>())
778 InstBundleLock(Func, BundleOption);
779 }
780 void emit(const Cfg *Func) const override;
781 void emitIAS(const Cfg * /* Func */) const override {}
782 void dump(const Cfg *Func) const override;
783 Option getOption() const { return BundleOption; }
784 static bool classof(const Inst *Inst) {
785 return Inst->getKind() == BundleLock;
786 }
787
788private:
789 Option BundleOption;
790 InstBundleLock(Cfg *Func, Option BundleOption);
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -0800791};
792
793// BundleUnlock instruction. There are no operands.
794class InstBundleUnlock : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800795 InstBundleUnlock() = delete;
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -0800796 InstBundleUnlock(const InstBundleUnlock &) = delete;
797 InstBundleUnlock &operator=(const InstBundleUnlock &) = delete;
798
799public:
800 static InstBundleUnlock *create(Cfg *Func) {
801 return new (Func->allocate<InstBundleUnlock>()) InstBundleUnlock(Func);
802 }
803 void emit(const Cfg *Func) const override;
804 void emitIAS(const Cfg * /* Func */) const override {}
805 void dump(const Cfg *Func) const override;
806 static bool classof(const Inst *Inst) {
807 return Inst->getKind() == BundleUnlock;
808 }
809
810private:
811 explicit InstBundleUnlock(Cfg *Func);
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -0800812};
813
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700814// FakeDef instruction. This creates a fake definition of a variable,
815// which is how we represent the case when an instruction produces
816// multiple results. This doesn't happen with high-level ICE
817// instructions, but might with lowered instructions. For example,
818// this would be a way to represent condition flags being modified by
819// an instruction.
820//
821// It's generally useful to set the optional source operand to be the
822// dest variable of the instruction that actually produces the FakeDef
823// dest. Otherwise, the original instruction could be dead-code
824// eliminated if its dest operand is unused, and therefore the FakeDef
825// dest wouldn't be properly initialized.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700826class InstFakeDef : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800827 InstFakeDef() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700828 InstFakeDef(const InstFakeDef &) = delete;
829 InstFakeDef &operator=(const InstFakeDef &) = delete;
830
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700831public:
Jim Stichnothae953202014-12-20 06:17:49 -0800832 static InstFakeDef *create(Cfg *Func, Variable *Dest,
833 Variable *Src = nullptr) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800834 return new (Func->allocate<InstFakeDef>()) InstFakeDef(Func, Dest, Src);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700835 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700836 void emit(const Cfg *Func) const override;
Jan Voung198b2942014-10-16 09:40:02 -0700837 void emitIAS(const Cfg * /* Func */) const override {}
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700838 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700839 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeDef; }
840
841private:
842 InstFakeDef(Cfg *Func, Variable *Dest, Variable *Src);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700843};
844
845// FakeUse instruction. This creates a fake use of a variable, to
846// keep the instruction that produces that variable from being
847// dead-code eliminated. This is useful in a variety of lowering
848// situations. The FakeUse instruction has no dest, so it can itself
849// never be dead-code eliminated.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700850class InstFakeUse : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800851 InstFakeUse() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700852 InstFakeUse(const InstFakeUse &) = delete;
853 InstFakeUse &operator=(const InstFakeUse &) = delete;
854
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700855public:
856 static InstFakeUse *create(Cfg *Func, Variable *Src) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800857 return new (Func->allocate<InstFakeUse>()) InstFakeUse(Func, Src);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700858 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700859 void emit(const Cfg *Func) const override;
Jan Voung198b2942014-10-16 09:40:02 -0700860 void emitIAS(const Cfg * /* Func */) const override {}
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700861 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700862 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeUse; }
863
864private:
865 InstFakeUse(Cfg *Func, Variable *Src);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700866};
867
Jim Stichnoth87ff3a12014-11-14 10:27:29 -0800868// FakeKill instruction. This "kills" a set of variables by modeling
869// a trivial live range at this instruction for each (implicit)
870// variable. The primary use is to indicate that scratch registers
871// are killed after a call, so that the register allocator won't
872// assign a scratch register to a variable whose live range spans a
873// call.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700874//
875// The FakeKill instruction also holds a pointer to the instruction
876// that kills the set of variables, so that if that linked instruction
877// gets dead-code eliminated, the FakeKill instruction will as well.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700878class InstFakeKill : public InstHighLevel {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800879 InstFakeKill() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700880 InstFakeKill(const InstFakeKill &) = delete;
881 InstFakeKill &operator=(const InstFakeKill &) = delete;
882
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700883public:
Jim Stichnoth87ff3a12014-11-14 10:27:29 -0800884 static InstFakeKill *create(Cfg *Func, const Inst *Linked) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800885 return new (Func->allocate<InstFakeKill>()) InstFakeKill(Func, Linked);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700886 }
887 const Inst *getLinked() const { return Linked; }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700888 void emit(const Cfg *Func) const override;
Jan Voung198b2942014-10-16 09:40:02 -0700889 void emitIAS(const Cfg * /* Func */) const override {}
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700890 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700891 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeKill; }
892
893private:
Jim Stichnoth87ff3a12014-11-14 10:27:29 -0800894 InstFakeKill(Cfg *Func, const Inst *Linked);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700895
896 // This instruction is ignored if Linked->isDeleted() is true.
897 const Inst *Linked;
898};
899
900// The Target instruction is the base class for all target-specific
901// instructions.
902class InstTarget : public Inst {
Jim Stichnothc6ead202015-02-24 09:30:30 -0800903 InstTarget() = delete;
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700904 InstTarget(const InstTarget &) = delete;
905 InstTarget &operator=(const InstTarget &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700906
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700907public:
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700908 uint32_t getEmitInstCount() const override { return 1; }
909 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700910 static bool classof(const Inst *Inst) { return Inst->getKind() >= Target; }
911
912protected:
913 InstTarget(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest)
914 : Inst(Func, Kind, MaxSrcs, Dest) {
915 assert(Kind >= Target);
916 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700917};
918
Jan Voungb3401d22015-05-18 09:38:21 -0700919bool checkForRedundantAssign(const Variable *Dest, const Operand *Source);
920
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700921} // end of namespace Ice
922
Jim Stichnothdddaf9c2014-12-04 14:09:21 -0800923namespace llvm {
924
Jim Stichnoth607e9f02014-11-06 13:32:05 -0800925// Override the default ilist traits so that Inst's private ctor and
926// deleted dtor aren't invoked.
927template <>
Jim Stichnothdddaf9c2014-12-04 14:09:21 -0800928struct ilist_traits<Ice::Inst> : public ilist_default_traits<Ice::Inst> {
Jim Stichnoth607e9f02014-11-06 13:32:05 -0800929 Ice::Inst *createSentinel() const {
930 return static_cast<Ice::Inst *>(&Sentinel);
931 }
932 static void destroySentinel(Ice::Inst *) {}
933 Ice::Inst *provideInitialHead() const { return createSentinel(); }
934 Ice::Inst *ensureHead(Ice::Inst *) const { return createSentinel(); }
935 static void noteHead(Ice::Inst *, Ice::Inst *) {}
936 void deleteNode(Ice::Inst *) {}
937
938private:
939 mutable ilist_half_node<Ice::Inst> Sentinel;
940};
941
Jim Stichnothdddaf9c2014-12-04 14:09:21 -0800942} // end of namespace llvm
943
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700944#endif // SUBZERO_SRC_ICEINST_H