blob: 0397e02a7e54d4743b0f7b3c5d42bf3c7ede4e82 [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
33class Inst {
34public:
35 enum InstKind {
36 // Arbitrary (alphabetical) order, except put Unreachable first.
37 Unreachable,
38 Alloca,
39 Arithmetic,
40 Assign, // not part of LLVM/PNaCl bitcode
41 Br,
42 Call,
43 Cast,
44 Fcmp,
45 Icmp,
Jan Voung3bd9f1a2014-06-18 10:50:57 -070046 IntrinsicCall,
Jim Stichnothf7c9a142014-04-29 10:52:43 -070047 Load,
48 Phi,
49 Ret,
50 Select,
51 Store,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070052 Switch,
53 FakeDef, // not part of LLVM/PNaCl bitcode
54 FakeUse, // not part of LLVM/PNaCl bitcode
55 FakeKill, // not part of LLVM/PNaCl bitcode
56 Target // target-specific low-level ICE
57 // Anything >= Target is an InstTarget subclass.
Jim Stichnothf7c9a142014-04-29 10:52:43 -070058 };
59 InstKind getKind() const { return Kind; }
60
Jim Stichnothd97c7df2014-06-04 11:57:08 -070061 InstNumberT getNumber() const { return Number; }
62 void renumber(Cfg *Func);
63 static const InstNumberT NumberDeleted = -1;
64 static const InstNumberT NumberSentinel = 0;
Jim Stichnothf7c9a142014-04-29 10:52:43 -070065
66 bool isDeleted() const { return Deleted; }
67 void setDeleted() { Deleted = true; }
Jim Stichnothd97c7df2014-06-04 11:57:08 -070068 void deleteIfDead();
Jim Stichnothf7c9a142014-04-29 10:52:43 -070069
70 bool hasSideEffects() const { return HasSideEffects; }
71
72 Variable *getDest() const { return Dest; }
73
74 SizeT getSrcSize() const { return NumSrcs; }
75 Operand *getSrc(SizeT I) const {
76 assert(I < getSrcSize());
77 return Srcs[I];
78 }
79
Jim Stichnothd97c7df2014-06-04 11:57:08 -070080 bool isLastUse(const Operand *Src) const;
81
Jim Stichnothf7c9a142014-04-29 10:52:43 -070082 // Returns a list of out-edges corresponding to a terminator
83 // instruction, which is the last instruction of the block.
84 virtual NodeList getTerminatorEdges() const {
85 // All valid terminator instructions override this method. For
86 // the default implementation, we assert in case some CfgNode
87 // is constructed without a terminator instruction at the end.
88 llvm_unreachable(
89 "getTerminatorEdges() called on a non-terminator instruction");
90 return NodeList();
91 }
92
93 // Updates the status of the Variables contained within the
94 // instruction. In particular, it marks where the Dest variable is
95 // first assigned, and it tracks whether variables are live across
96 // basic blocks, i.e. used in a different block from their definition.
97 void updateVars(CfgNode *Node);
98
Jim Stichnothd97c7df2014-06-04 11:57:08 -070099 void livenessLightweight(llvm::BitVector &Live);
100 void liveness(InstNumberT InstNumber, llvm::BitVector &Live,
101 Liveness *Liveness, const CfgNode *Node);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700102 virtual void emit(const Cfg *Func) const;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700103 virtual void dump(const Cfg *Func) const;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700104 virtual void dumpExtras(const Cfg *Func) const;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700105 void dumpDecorated(const Cfg *Func) const;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700106 void emitSources(const Cfg *Func) const;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700107 void dumpSources(const Cfg *Func) const;
108 void dumpDest(const Cfg *Func) const;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700109 virtual bool isRedundantAssign() const { return false; }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700110
111 virtual ~Inst() {}
112
113protected:
114 Inst(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest);
115 void addSource(Operand *Src) {
116 assert(Src);
117 assert(NumSrcs < MaxSrcs);
118 Srcs[NumSrcs++] = Src;
119 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700120 void setLastUse(SizeT VarIndex) {
121 if (VarIndex < CHAR_BIT * sizeof(LiveRangesEnded))
122 LiveRangesEnded |= (((LREndedBits)1u) << VarIndex);
123 }
124 void resetLastUses() { LiveRangesEnded = 0; }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700125 // The destroy() method lets the instruction cleanly release any
126 // memory that was allocated via the Cfg's allocator.
127 virtual void destroy(Cfg *Func) { Func->deallocateArrayOf<Operand *>(Srcs); }
128
129 const InstKind Kind;
130 // Number is the instruction number for describing live ranges.
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700131 InstNumberT Number;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700132 // Deleted means irrevocably deleted.
133 bool Deleted;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700134 // Dead means pending deletion after liveness analysis converges.
135 bool Dead;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700136 // HasSideEffects means the instruction is something like a function
137 // call or a volatile load that can't be removed even if its Dest
138 // variable is not live.
139 bool HasSideEffects;
140
141 Variable *Dest;
142 const SizeT MaxSrcs; // only used for assert
143 SizeT NumSrcs;
144 Operand **Srcs;
145
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700146 // LiveRangesEnded marks which Variables' live ranges end in this
147 // instruction. An instruction can have an arbitrary number of
148 // source operands (e.g. a call instruction), and each source
149 // operand can contain 0 or 1 Variable (and target-specific operands
150 // could contain more than 1 Variable). All the variables in an
151 // instruction are conceptually flattened and each variable is
152 // mapped to one bit position of the LiveRangesEnded bit vector.
153 // Only the first CHAR_BIT * sizeof(LREndedBits) variables are
154 // tracked this way.
155 typedef uint32_t LREndedBits; // only first 32 src operands tracked, sorry
156 LREndedBits LiveRangesEnded;
157
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700158private:
159 Inst(const Inst &) LLVM_DELETED_FUNCTION;
160 Inst &operator=(const Inst &) LLVM_DELETED_FUNCTION;
161};
162
163// Alloca instruction. This captures the size in bytes as getSrc(0),
164// and the required alignment in bytes. The alignment must be either
165// 0 (no alignment required) or a power of 2.
166class InstAlloca : public Inst {
167public:
168 static InstAlloca *create(Cfg *Func, Operand *ByteCount,
169 uint32_t AlignInBytes, Variable *Dest) {
170 return new (Func->allocateInst<InstAlloca>())
171 InstAlloca(Func, ByteCount, AlignInBytes, Dest);
172 }
173 uint32_t getAlignInBytes() const { return AlignInBytes; }
174 Operand *getSizeInBytes() const { return getSrc(0); }
175 virtual void dump(const Cfg *Func) const;
176 static bool classof(const Inst *Inst) { return Inst->getKind() == Alloca; }
177
178private:
179 InstAlloca(Cfg *Func, Operand *ByteCount, uint32_t AlignInBytes,
180 Variable *Dest);
181 InstAlloca(const InstAlloca &) LLVM_DELETED_FUNCTION;
182 InstAlloca &operator=(const InstAlloca &) LLVM_DELETED_FUNCTION;
183 virtual ~InstAlloca() {}
184 const uint32_t AlignInBytes;
185};
186
187// Binary arithmetic instruction. The source operands are captured in
188// getSrc(0) and getSrc(1).
189class InstArithmetic : public Inst {
190public:
191 enum OpKind {
192#define X(tag, str, commutative) tag,
193 ICEINSTARITHMETIC_TABLE
194#undef X
Jim Stichnoth4376d292014-05-23 13:39:02 -0700195 _num
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700196 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700197
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700198 static InstArithmetic *create(Cfg *Func, OpKind Op, Variable *Dest,
199 Operand *Source1, Operand *Source2) {
200 return new (Func->allocateInst<InstArithmetic>())
201 InstArithmetic(Func, Op, Dest, Source1, Source2);
202 }
203 OpKind getOp() const { return Op; }
204 bool isCommutative() const;
205 virtual void dump(const Cfg *Func) const;
206 static bool classof(const Inst *Inst) {
207 return Inst->getKind() == Arithmetic;
208 }
209
210private:
211 InstArithmetic(Cfg *Func, OpKind Op, Variable *Dest, Operand *Source1,
212 Operand *Source2);
213 InstArithmetic(const InstArithmetic &) LLVM_DELETED_FUNCTION;
214 InstArithmetic &operator=(const InstArithmetic &) LLVM_DELETED_FUNCTION;
215 virtual ~InstArithmetic() {}
216
217 const OpKind Op;
218};
219
220// Assignment instruction. The source operand is captured in
221// getSrc(0). This is not part of the LLVM bitcode, but is a useful
222// abstraction for some of the lowering. E.g., if Phi instruction
223// lowering happens before target lowering, or for representing an
224// Inttoptr instruction, or as an intermediate step for lowering a
225// Load instruction.
226class InstAssign : public Inst {
227public:
228 static InstAssign *create(Cfg *Func, Variable *Dest, Operand *Source) {
229 return new (Func->allocateInst<InstAssign>())
230 InstAssign(Func, Dest, Source);
231 }
232 virtual void dump(const Cfg *Func) const;
233 static bool classof(const Inst *Inst) { return Inst->getKind() == Assign; }
234
235private:
236 InstAssign(Cfg *Func, Variable *Dest, Operand *Source);
237 InstAssign(const InstAssign &) LLVM_DELETED_FUNCTION;
238 InstAssign &operator=(const InstAssign &) LLVM_DELETED_FUNCTION;
239 virtual ~InstAssign() {}
240};
241
242// Branch instruction. This represents both conditional and
243// unconditional branches.
244class InstBr : public Inst {
245public:
246 // Create a conditional branch. If TargetTrue==TargetFalse, it is
247 // optimized to an unconditional branch.
248 static InstBr *create(Cfg *Func, Operand *Source, CfgNode *TargetTrue,
249 CfgNode *TargetFalse) {
250 return new (Func->allocateInst<InstBr>())
251 InstBr(Func, Source, TargetTrue, TargetFalse);
252 }
253 // Create an unconditional branch.
254 static InstBr *create(Cfg *Func, CfgNode *Target) {
255 return new (Func->allocateInst<InstBr>()) InstBr(Func, Target);
256 }
257 bool isUnconditional() const { return getTargetTrue() == NULL; }
258 Operand *getCondition() const {
259 assert(!isUnconditional());
260 return getSrc(0);
261 }
262 CfgNode *getTargetTrue() const { return TargetTrue; }
263 CfgNode *getTargetFalse() const { return TargetFalse; }
264 CfgNode *getTargetUnconditional() const {
265 assert(isUnconditional());
266 return getTargetFalse();
267 }
268 virtual NodeList getTerminatorEdges() const;
269 virtual void dump(const Cfg *Func) const;
270 static bool classof(const Inst *Inst) { return Inst->getKind() == Br; }
271
272private:
273 // Conditional branch
274 InstBr(Cfg *Func, Operand *Source, CfgNode *TargetTrue, CfgNode *TargetFalse);
275 // Unconditional branch
276 InstBr(Cfg *Func, CfgNode *Target);
277 InstBr(const InstBr &) LLVM_DELETED_FUNCTION;
278 InstBr &operator=(const InstBr &) LLVM_DELETED_FUNCTION;
279 virtual ~InstBr() {}
280
281 CfgNode *const TargetFalse; // Doubles as unconditional branch target
282 CfgNode *const TargetTrue; // NULL if unconditional branch
283};
284
285// Call instruction. The call target is captured as getSrc(0), and
286// arg I is captured as getSrc(I+1).
287class InstCall : public Inst {
288public:
289 static InstCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest,
290 Operand *CallTarget) {
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700291 // Set HasSideEffects to true so that the call instruction can't be
292 // dead-code eliminated. IntrinsicCalls can override this if the
293 // particular intrinsic is deletable and has no side-effects.
294 const bool HasSideEffects = true;
295 const InstKind Kind = Inst::Call;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700296 return new (Func->allocateInst<InstCall>())
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700297 InstCall(Func, NumArgs, Dest, CallTarget, HasSideEffects, Kind);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700298 }
299 void addArg(Operand *Arg) { addSource(Arg); }
300 Operand *getCallTarget() const { return getSrc(0); }
301 Operand *getArg(SizeT I) const { return getSrc(I + 1); }
302 SizeT getNumArgs() const { return getSrcSize() - 1; }
303 virtual void dump(const Cfg *Func) const;
304 static bool classof(const Inst *Inst) { return Inst->getKind() == Call; }
305
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700306protected:
307 InstCall(Cfg *Func, SizeT NumArgs, Variable *Dest, Operand *CallTarget,
308 bool HasSideEff, InstKind Kind)
309 : Inst(Func, Kind, NumArgs + 1, Dest) {
310 HasSideEffects = HasSideEff;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700311 addSource(CallTarget);
312 }
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700313 virtual ~InstCall() {}
314
315private:
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700316 InstCall(const InstCall &) LLVM_DELETED_FUNCTION;
317 InstCall &operator=(const InstCall &) LLVM_DELETED_FUNCTION;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700318};
319
320// Cast instruction (a.k.a. conversion operation).
321class InstCast : public Inst {
322public:
323 enum OpKind {
324#define X(tag, str) tag,
325 ICEINSTCAST_TABLE
326#undef X
Jim Stichnoth4376d292014-05-23 13:39:02 -0700327 _num
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700328 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700329
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700330 static InstCast *create(Cfg *Func, OpKind CastKind, Variable *Dest,
331 Operand *Source) {
332 return new (Func->allocateInst<InstCast>())
333 InstCast(Func, CastKind, Dest, Source);
334 }
335 OpKind getCastKind() const { return CastKind; }
336 virtual void dump(const Cfg *Func) const;
337 static bool classof(const Inst *Inst) { return Inst->getKind() == Cast; }
338
339private:
340 InstCast(Cfg *Func, OpKind CastKind, Variable *Dest, Operand *Source);
341 InstCast(const InstCast &) LLVM_DELETED_FUNCTION;
342 InstCast &operator=(const InstCast &) LLVM_DELETED_FUNCTION;
343 virtual ~InstCast() {}
344 const OpKind CastKind;
345};
346
347// Floating-point comparison instruction. The source operands are
348// captured in getSrc(0) and getSrc(1).
349class InstFcmp : public Inst {
350public:
351 enum FCond {
352#define X(tag, str) tag,
353 ICEINSTFCMP_TABLE
354#undef X
Jim Stichnoth4376d292014-05-23 13:39:02 -0700355 _num
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700356 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700357
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700358 static InstFcmp *create(Cfg *Func, FCond Condition, Variable *Dest,
359 Operand *Source1, Operand *Source2) {
360 return new (Func->allocateInst<InstFcmp>())
361 InstFcmp(Func, Condition, Dest, Source1, Source2);
362 }
363 FCond getCondition() const { return Condition; }
364 virtual void dump(const Cfg *Func) const;
365 static bool classof(const Inst *Inst) { return Inst->getKind() == Fcmp; }
366
367private:
368 InstFcmp(Cfg *Func, FCond Condition, Variable *Dest, Operand *Source1,
369 Operand *Source2);
370 InstFcmp(const InstFcmp &) LLVM_DELETED_FUNCTION;
371 InstFcmp &operator=(const InstFcmp &) LLVM_DELETED_FUNCTION;
372 virtual ~InstFcmp() {}
373 const FCond Condition;
374};
375
376// Integer comparison instruction. The source operands are captured
377// in getSrc(0) and getSrc(1).
378class InstIcmp : public Inst {
379public:
380 enum ICond {
381#define X(tag, str) tag,
382 ICEINSTICMP_TABLE
383#undef X
Jim Stichnoth4376d292014-05-23 13:39:02 -0700384 _num
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700385 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700386
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700387 static InstIcmp *create(Cfg *Func, ICond Condition, Variable *Dest,
388 Operand *Source1, Operand *Source2) {
389 return new (Func->allocateInst<InstIcmp>())
390 InstIcmp(Func, Condition, Dest, Source1, Source2);
391 }
392 ICond getCondition() const { return Condition; }
393 virtual void dump(const Cfg *Func) const;
394 static bool classof(const Inst *Inst) { return Inst->getKind() == Icmp; }
395
396private:
397 InstIcmp(Cfg *Func, ICond Condition, Variable *Dest, Operand *Source1,
398 Operand *Source2);
399 InstIcmp(const InstIcmp &) LLVM_DELETED_FUNCTION;
400 InstIcmp &operator=(const InstIcmp &) LLVM_DELETED_FUNCTION;
401 virtual ~InstIcmp() {}
402 const ICond Condition;
403};
404
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700405// Call to an intrinsic function. The call target is captured as getSrc(0),
406// and arg I is captured as getSrc(I+1).
407class InstIntrinsicCall : public InstCall {
408public:
409 static InstIntrinsicCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest,
410 Operand *CallTarget,
411 const Intrinsics::IntrinsicInfo &Info) {
412 return new (Func->allocateInst<InstIntrinsicCall>())
413 InstIntrinsicCall(Func, NumArgs, Dest, CallTarget, Info);
414 }
415 static bool classof(const Inst *Inst) {
416 return Inst->getKind() == IntrinsicCall;
417 }
418
419 Intrinsics::IntrinsicInfo getIntrinsicInfo() const { return Info; }
420
421private:
422 InstIntrinsicCall(Cfg *Func, SizeT NumArgs, Variable *Dest,
423 Operand *CallTarget, const Intrinsics::IntrinsicInfo &Info)
424 : InstCall(Func, NumArgs, Dest, CallTarget, Info.HasSideEffects,
425 Inst::IntrinsicCall),
426 Info(Info) {}
427 InstIntrinsicCall(const InstIntrinsicCall &) LLVM_DELETED_FUNCTION;
428 InstIntrinsicCall &operator=(const InstIntrinsicCall &) LLVM_DELETED_FUNCTION;
429 virtual ~InstIntrinsicCall() {}
430 const Intrinsics::IntrinsicInfo Info;
431};
432
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700433// Load instruction. The source address is captured in getSrc(0).
434class InstLoad : public Inst {
435public:
436 static InstLoad *create(Cfg *Func, Variable *Dest, Operand *SourceAddr) {
437 return new (Func->allocateInst<InstLoad>())
438 InstLoad(Func, Dest, SourceAddr);
439 }
440 Operand *getSourceAddress() const { return getSrc(0); }
441 virtual void dump(const Cfg *Func) const;
442 static bool classof(const Inst *Inst) { return Inst->getKind() == Load; }
443
444private:
445 InstLoad(Cfg *Func, Variable *Dest, Operand *SourceAddr);
446 InstLoad(const InstLoad &) LLVM_DELETED_FUNCTION;
447 InstLoad &operator=(const InstLoad &) LLVM_DELETED_FUNCTION;
448 virtual ~InstLoad() {}
449};
450
451// Phi instruction. For incoming edge I, the node is Labels[I] and
452// the Phi source operand is getSrc(I).
453class InstPhi : public Inst {
454public:
455 static InstPhi *create(Cfg *Func, SizeT MaxSrcs, Variable *Dest) {
456 return new (Func->allocateInst<InstPhi>()) InstPhi(Func, MaxSrcs, Dest);
457 }
458 void addArgument(Operand *Source, CfgNode *Label);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700459 Operand *getOperandForTarget(CfgNode *Target) const;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700460 void livenessPhiOperand(llvm::BitVector &Live, CfgNode *Target,
461 Liveness *Liveness);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700462 Inst *lower(Cfg *Func, CfgNode *Node);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700463 virtual void dump(const Cfg *Func) const;
464 static bool classof(const Inst *Inst) { return Inst->getKind() == Phi; }
465
466private:
467 InstPhi(Cfg *Func, SizeT MaxSrcs, Variable *Dest);
468 InstPhi(const InstPhi &) LLVM_DELETED_FUNCTION;
469 InstPhi &operator=(const InstPhi &) LLVM_DELETED_FUNCTION;
470 virtual void destroy(Cfg *Func) {
471 Func->deallocateArrayOf<CfgNode *>(Labels);
472 Inst::destroy(Func);
473 }
474 virtual ~InstPhi() {}
475
476 // Labels[] duplicates the InEdges[] information in the enclosing
477 // CfgNode, but the Phi instruction is created before InEdges[]
478 // is available, so it's more complicated to share the list.
479 CfgNode **Labels;
480};
481
482// Ret instruction. The return value is captured in getSrc(0), but if
483// there is no return value (void-type function), then
484// getSrcSize()==0 and hasRetValue()==false.
485class InstRet : public Inst {
486public:
487 static InstRet *create(Cfg *Func, Operand *RetValue = NULL) {
488 return new (Func->allocateInst<InstRet>()) InstRet(Func, RetValue);
489 }
490 bool hasRetValue() const { return getSrcSize(); }
491 Operand *getRetValue() const {
492 assert(hasRetValue());
493 return getSrc(0);
494 }
495 virtual NodeList getTerminatorEdges() const { return NodeList(); }
496 virtual void dump(const Cfg *Func) const;
497 static bool classof(const Inst *Inst) { return Inst->getKind() == Ret; }
498
499private:
500 InstRet(Cfg *Func, Operand *RetValue);
501 InstRet(const InstRet &) LLVM_DELETED_FUNCTION;
502 InstRet &operator=(const InstRet &) LLVM_DELETED_FUNCTION;
503 virtual ~InstRet() {}
504};
505
506// Select instruction. The condition, true, and false operands are captured.
507class InstSelect : public Inst {
508public:
509 static InstSelect *create(Cfg *Func, Variable *Dest, Operand *Condition,
510 Operand *SourceTrue, Operand *SourceFalse) {
511 return new (Func->allocateInst<InstSelect>())
512 InstSelect(Func, Dest, Condition, SourceTrue, SourceFalse);
513 }
514 Operand *getCondition() const { return getSrc(0); }
515 Operand *getTrueOperand() const { return getSrc(1); }
516 Operand *getFalseOperand() const { return getSrc(2); }
517 virtual void dump(const Cfg *Func) const;
518 static bool classof(const Inst *Inst) { return Inst->getKind() == Select; }
519
520private:
521 InstSelect(Cfg *Func, Variable *Dest, Operand *Condition, Operand *Source1,
522 Operand *Source2);
523 InstSelect(const InstSelect &) LLVM_DELETED_FUNCTION;
524 InstSelect &operator=(const InstSelect &) LLVM_DELETED_FUNCTION;
525 virtual ~InstSelect() {}
526};
527
528// Store instruction. The address operand is captured, along with the
529// data operand to be stored into the address.
530class InstStore : public Inst {
531public:
532 static InstStore *create(Cfg *Func, Operand *Data, Operand *Addr) {
533 return new (Func->allocateInst<InstStore>()) InstStore(Func, Data, Addr);
534 }
535 Operand *getAddr() const { return getSrc(1); }
536 Operand *getData() const { return getSrc(0); }
537 virtual void dump(const Cfg *Func) const;
538 static bool classof(const Inst *Inst) { return Inst->getKind() == Store; }
539
540private:
541 InstStore(Cfg *Func, Operand *Data, Operand *Addr);
542 InstStore(const InstStore &) LLVM_DELETED_FUNCTION;
543 InstStore &operator=(const InstStore &) LLVM_DELETED_FUNCTION;
544 virtual ~InstStore() {}
545};
546
547// Switch instruction. The single source operand is captured as
548// getSrc(0).
549class InstSwitch : public Inst {
550public:
551 static InstSwitch *create(Cfg *Func, SizeT NumCases, Operand *Source,
552 CfgNode *LabelDefault) {
553 return new (Func->allocateInst<InstSwitch>())
554 InstSwitch(Func, NumCases, Source, LabelDefault);
555 }
556 Operand *getComparison() const { return getSrc(0); }
557 CfgNode *getLabelDefault() const { return LabelDefault; }
558 SizeT getNumCases() const { return NumCases; }
559 uint64_t getValue(SizeT I) const {
560 assert(I < NumCases);
561 return Values[I];
562 }
563 CfgNode *getLabel(SizeT I) const {
564 assert(I < NumCases);
565 return Labels[I];
566 }
567 void addBranch(SizeT CaseIndex, uint64_t Value, CfgNode *Label);
568 virtual NodeList getTerminatorEdges() const;
569 virtual void dump(const Cfg *Func) const;
570 static bool classof(const Inst *Inst) { return Inst->getKind() == Switch; }
571
572private:
573 InstSwitch(Cfg *Func, SizeT NumCases, Operand *Source, CfgNode *LabelDefault);
574 InstSwitch(const InstSwitch &) LLVM_DELETED_FUNCTION;
575 InstSwitch &operator=(const InstSwitch &) LLVM_DELETED_FUNCTION;
576 virtual void destroy(Cfg *Func) {
577 Func->deallocateArrayOf<uint64_t>(Values);
578 Func->deallocateArrayOf<CfgNode *>(Labels);
579 Inst::destroy(Func);
580 }
581 virtual ~InstSwitch() {}
582
583 CfgNode *LabelDefault;
584 SizeT NumCases; // not including the default case
585 uint64_t *Values; // size is NumCases
586 CfgNode **Labels; // size is NumCases
587};
588
589// Unreachable instruction. This is a terminator instruction with no
590// operands.
591class InstUnreachable : public Inst {
592public:
593 static InstUnreachable *create(Cfg *Func) {
594 return new (Func->allocateInst<InstUnreachable>()) InstUnreachable(Func);
595 }
596 virtual NodeList getTerminatorEdges() const { return NodeList(); }
597 virtual void dump(const Cfg *Func) const;
598 static bool classof(const Inst *Inst) {
599 return Inst->getKind() == Unreachable;
600 }
601
602private:
603 InstUnreachable(Cfg *Func);
604 InstUnreachable(const InstUnreachable &) LLVM_DELETED_FUNCTION;
605 InstUnreachable &operator=(const InstUnreachable &) LLVM_DELETED_FUNCTION;
606 virtual ~InstUnreachable() {}
607};
608
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700609// FakeDef instruction. This creates a fake definition of a variable,
610// which is how we represent the case when an instruction produces
611// multiple results. This doesn't happen with high-level ICE
612// instructions, but might with lowered instructions. For example,
613// this would be a way to represent condition flags being modified by
614// an instruction.
615//
616// It's generally useful to set the optional source operand to be the
617// dest variable of the instruction that actually produces the FakeDef
618// dest. Otherwise, the original instruction could be dead-code
619// eliminated if its dest operand is unused, and therefore the FakeDef
620// dest wouldn't be properly initialized.
621class InstFakeDef : public Inst {
622public:
623 static InstFakeDef *create(Cfg *Func, Variable *Dest, Variable *Src = NULL) {
624 return new (Func->allocateInst<InstFakeDef>()) InstFakeDef(Func, Dest, Src);
625 }
626 virtual void emit(const Cfg *Func) const;
627 virtual void dump(const Cfg *Func) const;
628 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeDef; }
629
630private:
631 InstFakeDef(Cfg *Func, Variable *Dest, Variable *Src);
632 InstFakeDef(const InstFakeDef &) LLVM_DELETED_FUNCTION;
633 InstFakeDef &operator=(const InstFakeDef &) LLVM_DELETED_FUNCTION;
634 virtual ~InstFakeDef() {}
635};
636
637// FakeUse instruction. This creates a fake use of a variable, to
638// keep the instruction that produces that variable from being
639// dead-code eliminated. This is useful in a variety of lowering
640// situations. The FakeUse instruction has no dest, so it can itself
641// never be dead-code eliminated.
642class InstFakeUse : public Inst {
643public:
644 static InstFakeUse *create(Cfg *Func, Variable *Src) {
645 return new (Func->allocateInst<InstFakeUse>()) InstFakeUse(Func, Src);
646 }
647 virtual void emit(const Cfg *Func) const;
648 virtual void dump(const Cfg *Func) const;
649 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeUse; }
650
651private:
652 InstFakeUse(Cfg *Func, Variable *Src);
653 InstFakeUse(const InstFakeUse &) LLVM_DELETED_FUNCTION;
654 InstFakeUse &operator=(const InstFakeUse &) LLVM_DELETED_FUNCTION;
655 virtual ~InstFakeUse() {}
656};
657
658// FakeKill instruction. This "kills" a set of variables by adding a
659// trivial live range at this instruction to each variable. The
660// primary use is to indicate that scratch registers are killed after
661// a call, so that the register allocator won't assign a scratch
662// register to a variable whose live range spans a call.
663//
664// The FakeKill instruction also holds a pointer to the instruction
665// that kills the set of variables, so that if that linked instruction
666// gets dead-code eliminated, the FakeKill instruction will as well.
667class InstFakeKill : public Inst {
668public:
669 static InstFakeKill *create(Cfg *Func, const VarList &KilledRegs,
670 const Inst *Linked) {
671 return new (Func->allocateInst<InstFakeKill>())
672 InstFakeKill(Func, KilledRegs, Linked);
673 }
674 const Inst *getLinked() const { return Linked; }
675 virtual void emit(const Cfg *Func) const;
676 virtual void dump(const Cfg *Func) const;
677 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeKill; }
678
679private:
680 InstFakeKill(Cfg *Func, const VarList &KilledRegs, const Inst *Linked);
681 InstFakeKill(const InstFakeKill &) LLVM_DELETED_FUNCTION;
682 InstFakeKill &operator=(const InstFakeKill &) LLVM_DELETED_FUNCTION;
683 virtual ~InstFakeKill() {}
684
685 // This instruction is ignored if Linked->isDeleted() is true.
686 const Inst *Linked;
687};
688
689// The Target instruction is the base class for all target-specific
690// instructions.
691class InstTarget : public Inst {
692public:
693 virtual void emit(const Cfg *Func) const = 0;
694 virtual void dump(const Cfg *Func) const;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700695 virtual void dumpExtras(const Cfg *Func) const;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700696 static bool classof(const Inst *Inst) { return Inst->getKind() >= Target; }
697
698protected:
699 InstTarget(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest)
700 : Inst(Func, Kind, MaxSrcs, Dest) {
701 assert(Kind >= Target);
702 }
703 InstTarget(const InstTarget &) LLVM_DELETED_FUNCTION;
704 InstTarget &operator=(const InstTarget &) LLVM_DELETED_FUNCTION;
705 virtual ~InstTarget() {}
706};
707
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700708} // end of namespace Ice
709
710#endif // SUBZERO_SRC_ICEINST_H