blob: 15751d3da0a0336e8b9d7359508f6b23d4efc41a [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 Stichnoth7b451a92014-10-15 14:39:23 -070038 Inst(const Inst &) = delete;
39 Inst &operator=(const Inst &) = delete;
40
Jim Stichnothf7c9a142014-04-29 10:52:43 -070041public:
42 enum InstKind {
43 // Arbitrary (alphabetical) order, except put Unreachable first.
44 Unreachable,
45 Alloca,
46 Arithmetic,
47 Assign, // not part of LLVM/PNaCl bitcode
48 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,
62 FakeDef, // not part of LLVM/PNaCl bitcode
63 FakeUse, // not part of LLVM/PNaCl bitcode
64 FakeKill, // not part of LLVM/PNaCl bitcode
65 Target // target-specific low-level ICE
66 // Anything >= Target is an InstTarget subclass.
Jim Stichnothf7c9a142014-04-29 10:52:43 -070067 };
68 InstKind getKind() const { return Kind; }
69
Jim Stichnothd97c7df2014-06-04 11:57:08 -070070 InstNumberT getNumber() const { return Number; }
71 void renumber(Cfg *Func);
Jim Stichnoth47752552014-10-13 17:15:08 -070072 enum { NumberDeleted = -1, NumberSentinel = 0 };
Jim Stichnothf7c9a142014-04-29 10:52:43 -070073
74 bool isDeleted() const { return Deleted; }
75 void setDeleted() { Deleted = true; }
Jim Stichnothd97c7df2014-06-04 11:57:08 -070076 void deleteIfDead();
Jim Stichnothf7c9a142014-04-29 10:52:43 -070077
78 bool hasSideEffects() const { return HasSideEffects; }
79
Jim Stichnoth47752552014-10-13 17:15:08 -070080 bool isDestNonKillable() const { return IsDestNonKillable; }
81 void setDestNonKillable() { IsDestNonKillable = true; }
82
Jim Stichnothf7c9a142014-04-29 10:52:43 -070083 Variable *getDest() const { return Dest; }
84
85 SizeT getSrcSize() const { return NumSrcs; }
86 Operand *getSrc(SizeT I) const {
87 assert(I < getSrcSize());
88 return Srcs[I];
89 }
90
Jim Stichnothd97c7df2014-06-04 11:57:08 -070091 bool isLastUse(const Operand *Src) const;
92
Jim Stichnothf7c9a142014-04-29 10:52:43 -070093 // Returns a list of out-edges corresponding to a terminator
94 // instruction, which is the last instruction of the block.
95 virtual NodeList getTerminatorEdges() const {
96 // All valid terminator instructions override this method. For
97 // the default implementation, we assert in case some CfgNode
98 // is constructed without a terminator instruction at the end.
99 llvm_unreachable(
100 "getTerminatorEdges() called on a non-terminator instruction");
101 return NodeList();
102 }
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700103 virtual bool isUnconditionalBranch() const { return false; }
104 // If the instruction is a branch-type instruction with OldNode as a
105 // target, repoint it to NewNode and return true, otherwise return
106 // false. Only repoint one instance, even if the instruction has
107 // multiple instances of OldNode as a target.
108 virtual bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) {
109 (void)OldNode;
110 (void)NewNode;
111 return false;
112 }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700113
Jim Stichnothad403532014-09-25 12:44:17 -0700114 virtual bool isSimpleAssign() const { return false; }
115
Jim Stichnoth47752552014-10-13 17:15:08 -0700116 void livenessLightweight(Cfg *Func, LivenessBV &Live);
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700117 // Calculates liveness for this instruction. Returns true if this
118 // instruction is (tentatively) still live and should be retained,
119 // and false if this instruction is (tentatively) dead and should be
120 // deleted. The decision is tentative until the liveness dataflow
121 // algorithm has converged, and then a separate pass permanently
122 // deletes dead instructions.
123 bool liveness(InstNumberT InstNumber, LivenessBV &Live, Liveness *Liveness,
Jim Stichnoth47752552014-10-13 17:15:08 -0700124 LiveBeginEndMap *LiveBegin, LiveBeginEndMap *LiveEnd);
Jim Stichnoth18735602014-09-16 19:59:35 -0700125
126 // Get the number of native instructions that this instruction
127 // ultimately emits. By default, high-level instructions don't
128 // result in any native instructions, and a target-specific
129 // instruction results in a single native instruction.
130 virtual uint32_t getEmitInstCount() const { return 0; }
Jim Stichnothdddaf9c2014-12-04 14:09:21 -0800131 // TODO(stichnot): Change Inst back to abstract once the g++ build
132 // issue is fixed. llvm::ilist<Ice::Inst> doesn't work under g++
133 // because the resize(size_t, Ice::Inst) method is incorrectly
134 // declared and thus doesn't allow the abstract class Ice::Inst.
135 // The method should be declared resize(size_t, const Ice::Inst &).
136 // virtual void emit(const Cfg *Func) const = 0;
137 // virtual void emitIAS(const Cfg *Func) const = 0;
138 virtual void emit(const Cfg *) const {
139 llvm_unreachable("emit on abstract class");
140 }
141 virtual void emitIAS(const Cfg *Func) const { emit(Func); }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700142 virtual void dump(const Cfg *Func) const;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700143 virtual void dumpExtras(const Cfg *Func) const;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700144 void dumpDecorated(const Cfg *Func) const;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700145 void emitSources(const Cfg *Func) const;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700146 void dumpSources(const Cfg *Func) const;
147 void dumpDest(const Cfg *Func) const;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700148 virtual bool isRedundantAssign() const { return false; }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700149
150 virtual ~Inst() {}
151
152protected:
153 Inst(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest);
154 void addSource(Operand *Src) {
155 assert(Src);
156 assert(NumSrcs < MaxSrcs);
157 Srcs[NumSrcs++] = Src;
158 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700159 void setLastUse(SizeT VarIndex) {
160 if (VarIndex < CHAR_BIT * sizeof(LiveRangesEnded))
161 LiveRangesEnded |= (((LREndedBits)1u) << VarIndex);
162 }
163 void resetLastUses() { LiveRangesEnded = 0; }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700164 // The destroy() method lets the instruction cleanly release any
165 // memory that was allocated via the Cfg's allocator.
166 virtual void destroy(Cfg *Func) { Func->deallocateArrayOf<Operand *>(Srcs); }
167
168 const InstKind Kind;
169 // Number is the instruction number for describing live ranges.
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700170 InstNumberT Number;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700171 // Deleted means irrevocably deleted.
172 bool Deleted;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700173 // Dead means pending deletion after liveness analysis converges.
174 bool Dead;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700175 // HasSideEffects means the instruction is something like a function
176 // call or a volatile load that can't be removed even if its Dest
177 // variable is not live.
178 bool HasSideEffects;
Jim Stichnoth47752552014-10-13 17:15:08 -0700179 // IsDestNonKillable means that liveness analysis shouldn't consider
180 // this instruction to kill the Dest variable. This is used when
181 // lowering produces two assignments to the same variable.
182 bool IsDestNonKillable;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700183
184 Variable *Dest;
185 const SizeT MaxSrcs; // only used for assert
186 SizeT NumSrcs;
187 Operand **Srcs;
188
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700189 // LiveRangesEnded marks which Variables' live ranges end in this
190 // instruction. An instruction can have an arbitrary number of
191 // source operands (e.g. a call instruction), and each source
192 // operand can contain 0 or 1 Variable (and target-specific operands
193 // could contain more than 1 Variable). All the variables in an
194 // instruction are conceptually flattened and each variable is
195 // mapped to one bit position of the LiveRangesEnded bit vector.
196 // Only the first CHAR_BIT * sizeof(LREndedBits) variables are
197 // tracked this way.
198 typedef uint32_t LREndedBits; // only first 32 src operands tracked, sorry
199 LREndedBits LiveRangesEnded;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700200};
201
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700202class InstHighLevel : public Inst {
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700203 InstHighLevel(const InstHighLevel &) = delete;
204 InstHighLevel &operator=(const InstHighLevel &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700205
206protected:
207 InstHighLevel(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest)
208 : Inst(Func, Kind, MaxSrcs, Dest) {}
209 void emit(const Cfg * /*Func*/) const override {
210 llvm_unreachable("emit() called on a non-lowered instruction");
211 }
212 void emitIAS(const Cfg * /*Func*/) const override {
213 llvm_unreachable("emitIAS() called on a non-lowered instruction");
214 }
215 ~InstHighLevel() override {}
216};
217
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700218// Alloca instruction. This captures the size in bytes as getSrc(0),
219// and the required alignment in bytes. The alignment must be either
220// 0 (no alignment required) or a power of 2.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700221class InstAlloca : public InstHighLevel {
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700222 InstAlloca(const InstAlloca &) = delete;
223 InstAlloca &operator=(const InstAlloca &) = delete;
224
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700225public:
226 static InstAlloca *create(Cfg *Func, Operand *ByteCount,
227 uint32_t AlignInBytes, Variable *Dest) {
228 return new (Func->allocateInst<InstAlloca>())
229 InstAlloca(Func, ByteCount, AlignInBytes, Dest);
230 }
231 uint32_t getAlignInBytes() const { return AlignInBytes; }
232 Operand *getSizeInBytes() const { return getSrc(0); }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700233 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700234 static bool classof(const Inst *Inst) { return Inst->getKind() == Alloca; }
235
236private:
237 InstAlloca(Cfg *Func, Operand *ByteCount, uint32_t AlignInBytes,
238 Variable *Dest);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700239 ~InstAlloca() override {}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700240 const uint32_t AlignInBytes;
241};
242
243// Binary arithmetic instruction. The source operands are captured in
244// getSrc(0) and getSrc(1).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700245class InstArithmetic : public InstHighLevel {
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700246 InstArithmetic(const InstArithmetic &) = delete;
247 InstArithmetic &operator=(const InstArithmetic &) = delete;
248
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700249public:
250 enum OpKind {
251#define X(tag, str, commutative) tag,
252 ICEINSTARITHMETIC_TABLE
253#undef X
Jim Stichnoth4376d292014-05-23 13:39:02 -0700254 _num
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700255 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700256
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700257 static InstArithmetic *create(Cfg *Func, OpKind Op, Variable *Dest,
258 Operand *Source1, Operand *Source2) {
259 return new (Func->allocateInst<InstArithmetic>())
260 InstArithmetic(Func, Op, Dest, Source1, Source2);
261 }
262 OpKind getOp() const { return Op; }
Karl Schimpfd6064a12014-08-27 15:34:58 -0700263 static const char *getOpName(OpKind Op);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700264 bool isCommutative() const;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700265 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700266 static bool classof(const Inst *Inst) {
267 return Inst->getKind() == Arithmetic;
268 }
269
270private:
271 InstArithmetic(Cfg *Func, OpKind Op, Variable *Dest, Operand *Source1,
272 Operand *Source2);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700273 ~InstArithmetic() override {}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700274
275 const OpKind Op;
276};
277
278// Assignment instruction. The source operand is captured in
279// getSrc(0). This is not part of the LLVM bitcode, but is a useful
280// abstraction for some of the lowering. E.g., if Phi instruction
281// lowering happens before target lowering, or for representing an
282// Inttoptr instruction, or as an intermediate step for lowering a
283// Load instruction.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700284class InstAssign : public InstHighLevel {
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700285 InstAssign(const InstAssign &) = delete;
286 InstAssign &operator=(const InstAssign &) = delete;
287
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700288public:
289 static InstAssign *create(Cfg *Func, Variable *Dest, Operand *Source) {
290 return new (Func->allocateInst<InstAssign>())
291 InstAssign(Func, Dest, Source);
292 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700293 bool isSimpleAssign() const override { return true; }
294 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700295 static bool classof(const Inst *Inst) { return Inst->getKind() == Assign; }
296
297private:
298 InstAssign(Cfg *Func, Variable *Dest, Operand *Source);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700299 ~InstAssign() override {}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700300};
301
302// Branch instruction. This represents both conditional and
303// unconditional branches.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700304class InstBr : public InstHighLevel {
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700305 InstBr(const InstBr &) = delete;
306 InstBr &operator=(const InstBr &) = delete;
307
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700308public:
309 // Create a conditional branch. If TargetTrue==TargetFalse, it is
310 // optimized to an unconditional branch.
311 static InstBr *create(Cfg *Func, Operand *Source, CfgNode *TargetTrue,
312 CfgNode *TargetFalse) {
313 return new (Func->allocateInst<InstBr>())
314 InstBr(Func, Source, TargetTrue, TargetFalse);
315 }
316 // Create an unconditional branch.
317 static InstBr *create(Cfg *Func, CfgNode *Target) {
318 return new (Func->allocateInst<InstBr>()) InstBr(Func, Target);
319 }
320 bool isUnconditional() const { return getTargetTrue() == NULL; }
321 Operand *getCondition() const {
322 assert(!isUnconditional());
323 return getSrc(0);
324 }
325 CfgNode *getTargetTrue() const { return TargetTrue; }
326 CfgNode *getTargetFalse() const { return TargetFalse; }
327 CfgNode *getTargetUnconditional() const {
328 assert(isUnconditional());
329 return getTargetFalse();
330 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700331 NodeList getTerminatorEdges() const override;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700332 bool isUnconditionalBranch() const override { return isUnconditional(); }
333 bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700334 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700335 static bool classof(const Inst *Inst) { return Inst->getKind() == Br; }
336
337private:
338 // Conditional branch
339 InstBr(Cfg *Func, Operand *Source, CfgNode *TargetTrue, CfgNode *TargetFalse);
340 // Unconditional branch
341 InstBr(Cfg *Func, CfgNode *Target);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700342 ~InstBr() override {}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700343
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700344 CfgNode *TargetFalse; // Doubles as unconditional branch target
345 CfgNode *TargetTrue; // NULL if unconditional branch
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700346};
347
348// Call instruction. The call target is captured as getSrc(0), and
349// arg I is captured as getSrc(I+1).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700350class InstCall : public InstHighLevel {
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700351 InstCall(const InstCall &) = delete;
352 InstCall &operator=(const InstCall &) = delete;
353
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700354public:
355 static InstCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest,
Karl Schimpf8df26f32014-09-19 09:33:26 -0700356 Operand *CallTarget, bool HasTailCall) {
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700357 // Set HasSideEffects to true so that the call instruction can't be
358 // dead-code eliminated. IntrinsicCalls can override this if the
359 // particular intrinsic is deletable and has no side-effects.
360 const bool HasSideEffects = true;
361 const InstKind Kind = Inst::Call;
Karl Schimpf8df26f32014-09-19 09:33:26 -0700362 return new (Func->allocateInst<InstCall>()) InstCall(
363 Func, NumArgs, Dest, CallTarget, HasTailCall, HasSideEffects, Kind);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700364 }
365 void addArg(Operand *Arg) { addSource(Arg); }
366 Operand *getCallTarget() const { return getSrc(0); }
367 Operand *getArg(SizeT I) const { return getSrc(I + 1); }
368 SizeT getNumArgs() const { return getSrcSize() - 1; }
Karl Schimpf8df26f32014-09-19 09:33:26 -0700369 bool isTailcall() const { return HasTailCall; }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700370 void dump(const Cfg *Func) const;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700371 static bool classof(const Inst *Inst) { return Inst->getKind() == Call; }
Karl Schimpf8df26f32014-09-19 09:33:26 -0700372 Type getReturnType() const;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700373
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700374protected:
375 InstCall(Cfg *Func, SizeT NumArgs, Variable *Dest, Operand *CallTarget,
Karl Schimpf8df26f32014-09-19 09:33:26 -0700376 bool HasTailCall, bool HasSideEff, InstKind Kind)
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700377 : InstHighLevel(Func, Kind, NumArgs + 1, Dest), HasTailCall(HasTailCall) {
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700378 HasSideEffects = HasSideEff;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700379 addSource(CallTarget);
380 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700381 ~InstCall() override {}
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700382
383private:
Karl Schimpf8df26f32014-09-19 09:33:26 -0700384 bool HasTailCall;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700385};
386
387// Cast instruction (a.k.a. conversion operation).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700388class InstCast : public InstHighLevel {
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700389 InstCast(const InstCast &) = delete;
390 InstCast &operator=(const InstCast &) = delete;
391
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700392public:
393 enum OpKind {
394#define X(tag, str) tag,
395 ICEINSTCAST_TABLE
396#undef X
Jim Stichnoth4376d292014-05-23 13:39:02 -0700397 _num
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700398 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700399
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700400 static InstCast *create(Cfg *Func, OpKind CastKind, Variable *Dest,
401 Operand *Source) {
402 return new (Func->allocateInst<InstCast>())
403 InstCast(Func, CastKind, Dest, Source);
404 }
405 OpKind getCastKind() const { return CastKind; }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700406 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700407 static bool classof(const Inst *Inst) { return Inst->getKind() == Cast; }
408
409private:
410 InstCast(Cfg *Func, OpKind CastKind, Variable *Dest, Operand *Source);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700411 ~InstCast() override {}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700412 const OpKind CastKind;
413};
414
Matt Wala49889232014-07-18 12:45:09 -0700415// ExtractElement instruction.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700416class InstExtractElement : public InstHighLevel {
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700417 InstExtractElement(const InstExtractElement &) = delete;
418 InstExtractElement &operator=(const InstExtractElement &) = delete;
419
Matt Wala49889232014-07-18 12:45:09 -0700420public:
421 static InstExtractElement *create(Cfg *Func, Variable *Dest, Operand *Source1,
422 Operand *Source2) {
423 return new (Func->allocateInst<InstExtractElement>())
424 InstExtractElement(Func, Dest, Source1, Source2);
425 }
426
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700427 void dump(const Cfg *Func) const override;
Matt Wala49889232014-07-18 12:45:09 -0700428 static bool classof(const Inst *Inst) {
429 return Inst->getKind() == ExtractElement;
430 }
431
432private:
433 InstExtractElement(Cfg *Func, Variable *Dest, Operand *Source1,
434 Operand *Source2);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700435 ~InstExtractElement() override {}
Matt Wala49889232014-07-18 12:45:09 -0700436};
437
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700438// Floating-point comparison instruction. The source operands are
439// captured in getSrc(0) and getSrc(1).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700440class InstFcmp : public InstHighLevel {
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700441 InstFcmp(const InstFcmp &) = delete;
442 InstFcmp &operator=(const InstFcmp &) = delete;
443
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700444public:
445 enum FCond {
446#define X(tag, str) tag,
447 ICEINSTFCMP_TABLE
448#undef X
Jim Stichnoth4376d292014-05-23 13:39:02 -0700449 _num
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700450 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700451
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700452 static InstFcmp *create(Cfg *Func, FCond Condition, Variable *Dest,
453 Operand *Source1, Operand *Source2) {
454 return new (Func->allocateInst<InstFcmp>())
455 InstFcmp(Func, Condition, Dest, Source1, Source2);
456 }
457 FCond getCondition() const { return Condition; }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700458 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700459 static bool classof(const Inst *Inst) { return Inst->getKind() == Fcmp; }
460
461private:
462 InstFcmp(Cfg *Func, FCond Condition, Variable *Dest, Operand *Source1,
463 Operand *Source2);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700464 ~InstFcmp() override {}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700465 const FCond Condition;
466};
467
468// Integer comparison instruction. The source operands are captured
469// in getSrc(0) and getSrc(1).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700470class InstIcmp : public InstHighLevel {
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700471 InstIcmp(const InstIcmp &) = delete;
472 InstIcmp &operator=(const InstIcmp &) = delete;
473
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700474public:
475 enum ICond {
476#define X(tag, str) tag,
477 ICEINSTICMP_TABLE
478#undef X
Jim Stichnoth4376d292014-05-23 13:39:02 -0700479 _num
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700480 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700481
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700482 static InstIcmp *create(Cfg *Func, ICond Condition, Variable *Dest,
483 Operand *Source1, Operand *Source2) {
484 return new (Func->allocateInst<InstIcmp>())
485 InstIcmp(Func, Condition, Dest, Source1, Source2);
486 }
487 ICond getCondition() const { return Condition; }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700488 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700489 static bool classof(const Inst *Inst) { return Inst->getKind() == Icmp; }
490
491private:
492 InstIcmp(Cfg *Func, ICond Condition, Variable *Dest, Operand *Source1,
493 Operand *Source2);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700494 ~InstIcmp() override {}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700495 const ICond Condition;
496};
497
Matt Wala49889232014-07-18 12:45:09 -0700498// InsertElement instruction.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700499class InstInsertElement : public InstHighLevel {
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700500 InstInsertElement(const InstInsertElement &) = delete;
501 InstInsertElement &operator=(const InstInsertElement &) = delete;
502
Matt Wala49889232014-07-18 12:45:09 -0700503public:
504 static InstInsertElement *create(Cfg *Func, Variable *Dest, Operand *Source1,
505 Operand *Source2, Operand *Source3) {
506 return new (Func->allocateInst<InstInsertElement>())
507 InstInsertElement(Func, Dest, Source1, Source2, Source3);
508 }
509
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700510 void dump(const Cfg *Func) const override;
Matt Wala49889232014-07-18 12:45:09 -0700511 static bool classof(const Inst *Inst) {
512 return Inst->getKind() == InsertElement;
513 }
514
515private:
516 InstInsertElement(Cfg *Func, Variable *Dest, Operand *Source1,
517 Operand *Source2, Operand *Source3);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700518 ~InstInsertElement() override {}
Matt Wala49889232014-07-18 12:45:09 -0700519};
520
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700521// Call to an intrinsic function. The call target is captured as getSrc(0),
522// and arg I is captured as getSrc(I+1).
523class InstIntrinsicCall : public InstCall {
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700524 InstIntrinsicCall(const InstIntrinsicCall &) = delete;
525 InstIntrinsicCall &operator=(const InstIntrinsicCall &) = delete;
526
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700527public:
528 static InstIntrinsicCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest,
529 Operand *CallTarget,
530 const Intrinsics::IntrinsicInfo &Info) {
531 return new (Func->allocateInst<InstIntrinsicCall>())
532 InstIntrinsicCall(Func, NumArgs, Dest, CallTarget, Info);
533 }
534 static bool classof(const Inst *Inst) {
535 return Inst->getKind() == IntrinsicCall;
536 }
537
538 Intrinsics::IntrinsicInfo getIntrinsicInfo() const { return Info; }
539
540private:
541 InstIntrinsicCall(Cfg *Func, SizeT NumArgs, Variable *Dest,
542 Operand *CallTarget, const Intrinsics::IntrinsicInfo &Info)
Karl Schimpf8df26f32014-09-19 09:33:26 -0700543 : InstCall(Func, NumArgs, Dest, CallTarget, false, Info.HasSideEffects,
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700544 Inst::IntrinsicCall),
545 Info(Info) {}
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700546 ~InstIntrinsicCall() override {}
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700547 const Intrinsics::IntrinsicInfo Info;
548};
549
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700550// Load instruction. The source address is captured in getSrc(0).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700551class InstLoad : public InstHighLevel {
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700552 InstLoad(const InstLoad &) = delete;
553 InstLoad &operator=(const InstLoad &) = delete;
554
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700555public:
Karl Schimpf41689df2014-09-10 14:36:07 -0700556 static InstLoad *create(Cfg *Func, Variable *Dest, Operand *SourceAddr,
Jim Stichnothc4554d72014-09-30 16:49:38 -0700557 uint32_t Align = 1) {
Karl Schimpf41689df2014-09-10 14:36:07 -0700558 // TODO(kschimpf) Stop ignoring alignment specification.
Jim Stichnothc4554d72014-09-30 16:49:38 -0700559 (void)Align;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700560 return new (Func->allocateInst<InstLoad>())
561 InstLoad(Func, Dest, SourceAddr);
562 }
563 Operand *getSourceAddress() const { return getSrc(0); }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700564 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700565 static bool classof(const Inst *Inst) { return Inst->getKind() == Load; }
566
567private:
568 InstLoad(Cfg *Func, Variable *Dest, Operand *SourceAddr);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700569 ~InstLoad() override {}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700570};
571
572// Phi instruction. For incoming edge I, the node is Labels[I] and
573// the Phi source operand is getSrc(I).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700574class InstPhi : public InstHighLevel {
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700575 InstPhi(const InstPhi &) = delete;
576 InstPhi &operator=(const InstPhi &) = delete;
577
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700578public:
579 static InstPhi *create(Cfg *Func, SizeT MaxSrcs, Variable *Dest) {
580 return new (Func->allocateInst<InstPhi>()) InstPhi(Func, MaxSrcs, Dest);
581 }
582 void addArgument(Operand *Source, CfgNode *Label);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700583 Operand *getOperandForTarget(CfgNode *Target) const;
Jim Stichnoth98712a32014-10-24 10:59:02 -0700584 CfgNode *getLabel(SizeT Index) const { return Labels[Index]; }
Jim Stichnoth47752552014-10-13 17:15:08 -0700585 void livenessPhiOperand(LivenessBV &Live, CfgNode *Target,
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700586 Liveness *Liveness);
Jim Stichnoth144cdce2014-09-22 16:02:59 -0700587 Inst *lower(Cfg *Func);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700588 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700589 static bool classof(const Inst *Inst) { return Inst->getKind() == Phi; }
590
591private:
592 InstPhi(Cfg *Func, SizeT MaxSrcs, Variable *Dest);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700593 void destroy(Cfg *Func) override {
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700594 Func->deallocateArrayOf<CfgNode *>(Labels);
595 Inst::destroy(Func);
596 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700597 ~InstPhi() override {}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700598
599 // Labels[] duplicates the InEdges[] information in the enclosing
600 // CfgNode, but the Phi instruction is created before InEdges[]
601 // is available, so it's more complicated to share the list.
602 CfgNode **Labels;
603};
604
605// Ret instruction. The return value is captured in getSrc(0), but if
606// there is no return value (void-type function), then
607// getSrcSize()==0 and hasRetValue()==false.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700608class InstRet : public InstHighLevel {
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700609 InstRet(const InstRet &) = delete;
610 InstRet &operator=(const InstRet &) = delete;
611
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700612public:
613 static InstRet *create(Cfg *Func, Operand *RetValue = NULL) {
614 return new (Func->allocateInst<InstRet>()) InstRet(Func, RetValue);
615 }
616 bool hasRetValue() const { return getSrcSize(); }
617 Operand *getRetValue() const {
618 assert(hasRetValue());
619 return getSrc(0);
620 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700621 NodeList getTerminatorEdges() const override { return NodeList(); }
622 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700623 static bool classof(const Inst *Inst) { return Inst->getKind() == Ret; }
624
625private:
626 InstRet(Cfg *Func, Operand *RetValue);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700627 ~InstRet() override {}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700628};
629
630// Select instruction. The condition, true, and false operands are captured.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700631class InstSelect : public InstHighLevel {
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700632 InstSelect(const InstSelect &) = delete;
633 InstSelect &operator=(const InstSelect &) = delete;
634
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700635public:
636 static InstSelect *create(Cfg *Func, Variable *Dest, Operand *Condition,
637 Operand *SourceTrue, Operand *SourceFalse) {
638 return new (Func->allocateInst<InstSelect>())
639 InstSelect(Func, Dest, Condition, SourceTrue, SourceFalse);
640 }
641 Operand *getCondition() const { return getSrc(0); }
642 Operand *getTrueOperand() const { return getSrc(1); }
643 Operand *getFalseOperand() const { return getSrc(2); }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700644 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700645 static bool classof(const Inst *Inst) { return Inst->getKind() == Select; }
646
647private:
648 InstSelect(Cfg *Func, Variable *Dest, Operand *Condition, Operand *Source1,
649 Operand *Source2);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700650 ~InstSelect() override {}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700651};
652
653// Store instruction. The address operand is captured, along with the
654// data operand to be stored into the address.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700655class InstStore : public InstHighLevel {
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700656 InstStore(const InstStore &) = delete;
657 InstStore &operator=(const InstStore &) = delete;
658
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700659public:
Karl Schimpf41689df2014-09-10 14:36:07 -0700660 static InstStore *create(Cfg *Func, Operand *Data, Operand *Addr,
661 uint32_t align = 1) {
662 // TODO(kschimpf) Stop ignoring alignment specification.
663 (void)align;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700664 return new (Func->allocateInst<InstStore>()) InstStore(Func, Data, Addr);
665 }
666 Operand *getAddr() const { return getSrc(1); }
667 Operand *getData() const { return getSrc(0); }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700668 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700669 static bool classof(const Inst *Inst) { return Inst->getKind() == Store; }
670
671private:
672 InstStore(Cfg *Func, Operand *Data, Operand *Addr);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700673 ~InstStore() override {}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700674};
675
676// Switch instruction. The single source operand is captured as
677// getSrc(0).
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700678class InstSwitch : public InstHighLevel {
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700679 InstSwitch(const InstSwitch &) = delete;
680 InstSwitch &operator=(const InstSwitch &) = delete;
681
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700682public:
683 static InstSwitch *create(Cfg *Func, SizeT NumCases, Operand *Source,
684 CfgNode *LabelDefault) {
685 return new (Func->allocateInst<InstSwitch>())
686 InstSwitch(Func, NumCases, Source, LabelDefault);
687 }
688 Operand *getComparison() const { return getSrc(0); }
689 CfgNode *getLabelDefault() const { return LabelDefault; }
690 SizeT getNumCases() const { return NumCases; }
691 uint64_t getValue(SizeT I) const {
692 assert(I < NumCases);
693 return Values[I];
694 }
695 CfgNode *getLabel(SizeT I) const {
696 assert(I < NumCases);
697 return Labels[I];
698 }
699 void addBranch(SizeT CaseIndex, uint64_t Value, CfgNode *Label);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700700 NodeList getTerminatorEdges() const override;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700701 bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) override;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700702 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700703 static bool classof(const Inst *Inst) { return Inst->getKind() == Switch; }
704
705private:
706 InstSwitch(Cfg *Func, SizeT NumCases, Operand *Source, CfgNode *LabelDefault);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700707 void destroy(Cfg *Func) override {
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700708 Func->deallocateArrayOf<uint64_t>(Values);
709 Func->deallocateArrayOf<CfgNode *>(Labels);
710 Inst::destroy(Func);
711 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700712 ~InstSwitch() override {}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700713
714 CfgNode *LabelDefault;
715 SizeT NumCases; // not including the default case
716 uint64_t *Values; // size is NumCases
717 CfgNode **Labels; // size is NumCases
718};
719
720// Unreachable instruction. This is a terminator instruction with no
721// operands.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700722class InstUnreachable : public InstHighLevel {
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700723 InstUnreachable(const InstUnreachable &) = delete;
724 InstUnreachable &operator=(const InstUnreachable &) = delete;
725
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700726public:
727 static InstUnreachable *create(Cfg *Func) {
728 return new (Func->allocateInst<InstUnreachable>()) InstUnreachable(Func);
729 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700730 NodeList getTerminatorEdges() const override { return NodeList(); }
731 void dump(const Cfg *Func) const override;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700732 static bool classof(const Inst *Inst) {
733 return Inst->getKind() == Unreachable;
734 }
735
736private:
737 InstUnreachable(Cfg *Func);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700738 ~InstUnreachable() override {}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700739};
740
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700741// FakeDef instruction. This creates a fake definition of a variable,
742// which is how we represent the case when an instruction produces
743// multiple results. This doesn't happen with high-level ICE
744// instructions, but might with lowered instructions. For example,
745// this would be a way to represent condition flags being modified by
746// an instruction.
747//
748// It's generally useful to set the optional source operand to be the
749// dest variable of the instruction that actually produces the FakeDef
750// dest. Otherwise, the original instruction could be dead-code
751// eliminated if its dest operand is unused, and therefore the FakeDef
752// dest wouldn't be properly initialized.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700753class InstFakeDef : public InstHighLevel {
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700754 InstFakeDef(const InstFakeDef &) = delete;
755 InstFakeDef &operator=(const InstFakeDef &) = delete;
756
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700757public:
758 static InstFakeDef *create(Cfg *Func, Variable *Dest, Variable *Src = NULL) {
759 return new (Func->allocateInst<InstFakeDef>()) InstFakeDef(Func, Dest, Src);
760 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700761 void emit(const Cfg *Func) const override;
Jan Voung198b2942014-10-16 09:40:02 -0700762 void emitIAS(const Cfg * /* Func */) const override {}
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700763 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700764 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeDef; }
765
766private:
767 InstFakeDef(Cfg *Func, Variable *Dest, Variable *Src);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700768 ~InstFakeDef() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700769};
770
771// FakeUse instruction. This creates a fake use of a variable, to
772// keep the instruction that produces that variable from being
773// dead-code eliminated. This is useful in a variety of lowering
774// situations. The FakeUse instruction has no dest, so it can itself
775// never be dead-code eliminated.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700776class InstFakeUse : public InstHighLevel {
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700777 InstFakeUse(const InstFakeUse &) = delete;
778 InstFakeUse &operator=(const InstFakeUse &) = delete;
779
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700780public:
781 static InstFakeUse *create(Cfg *Func, Variable *Src) {
782 return new (Func->allocateInst<InstFakeUse>()) InstFakeUse(Func, Src);
783 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700784 void emit(const Cfg *Func) const override;
Jan Voung198b2942014-10-16 09:40:02 -0700785 void emitIAS(const Cfg * /* Func */) const override {}
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700786 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700787 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeUse; }
788
789private:
790 InstFakeUse(Cfg *Func, Variable *Src);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700791 ~InstFakeUse() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700792};
793
Jim Stichnoth87ff3a12014-11-14 10:27:29 -0800794// FakeKill instruction. This "kills" a set of variables by modeling
795// a trivial live range at this instruction for each (implicit)
796// variable. The primary use is to indicate that scratch registers
797// are killed after a call, so that the register allocator won't
798// assign a scratch register to a variable whose live range spans a
799// call.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700800//
801// The FakeKill instruction also holds a pointer to the instruction
802// that kills the set of variables, so that if that linked instruction
803// gets dead-code eliminated, the FakeKill instruction will as well.
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700804class InstFakeKill : public InstHighLevel {
Jim Stichnoth7b451a92014-10-15 14:39:23 -0700805 InstFakeKill(const InstFakeKill &) = delete;
806 InstFakeKill &operator=(const InstFakeKill &) = delete;
807
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700808public:
Jim Stichnoth87ff3a12014-11-14 10:27:29 -0800809 static InstFakeKill *create(Cfg *Func, const Inst *Linked) {
810 return new (Func->allocateInst<InstFakeKill>()) InstFakeKill(Func, Linked);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700811 }
812 const Inst *getLinked() const { return Linked; }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700813 void emit(const Cfg *Func) const override;
Jan Voung198b2942014-10-16 09:40:02 -0700814 void emitIAS(const Cfg * /* Func */) const override {}
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700815 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700816 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeKill; }
817
818private:
Jim Stichnoth87ff3a12014-11-14 10:27:29 -0800819 InstFakeKill(Cfg *Func, const Inst *Linked);
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700820 ~InstFakeKill() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700821
822 // This instruction is ignored if Linked->isDeleted() is true.
823 const Inst *Linked;
824};
825
826// The Target instruction is the base class for all target-specific
827// instructions.
828class InstTarget : public Inst {
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700829 InstTarget(const InstTarget &) = delete;
830 InstTarget &operator=(const InstTarget &) = delete;
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700831
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700832public:
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700833 uint32_t getEmitInstCount() const override { return 1; }
834 void dump(const Cfg *Func) const override;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700835 static bool classof(const Inst *Inst) { return Inst->getKind() >= Target; }
836
837protected:
838 InstTarget(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest)
839 : Inst(Func, Kind, MaxSrcs, Dest) {
840 assert(Kind >= Target);
841 }
Jim Stichnothb56c8f42014-09-26 09:28:46 -0700842 ~InstTarget() override {}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700843};
844
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700845} // end of namespace Ice
846
Jim Stichnothdddaf9c2014-12-04 14:09:21 -0800847namespace llvm {
848
Jim Stichnoth607e9f02014-11-06 13:32:05 -0800849// Override the default ilist traits so that Inst's private ctor and
850// deleted dtor aren't invoked.
851template <>
Jim Stichnothdddaf9c2014-12-04 14:09:21 -0800852struct ilist_traits<Ice::Inst> : public ilist_default_traits<Ice::Inst> {
Jim Stichnoth607e9f02014-11-06 13:32:05 -0800853 Ice::Inst *createSentinel() const {
854 return static_cast<Ice::Inst *>(&Sentinel);
855 }
856 static void destroySentinel(Ice::Inst *) {}
857 Ice::Inst *provideInitialHead() const { return createSentinel(); }
858 Ice::Inst *ensureHead(Ice::Inst *) const { return createSentinel(); }
859 static void noteHead(Ice::Inst *, Ice::Inst *) {}
860 void deleteNode(Ice::Inst *) {}
861
862private:
863 mutable ilist_half_node<Ice::Inst> Sentinel;
864};
865
Jim Stichnothdddaf9c2014-12-04 14:09:21 -0800866} // end of namespace llvm
867
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700868#endif // SUBZERO_SRC_ICEINST_H