blob: cf507e67cc0ef83bf5c3cbe8c34ac3a2c8d81625 [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,
Matt Wala49889232014-07-18 12:45:09 -070044 ExtractElement,
Jim Stichnothf7c9a142014-04-29 10:52:43 -070045 Fcmp,
46 Icmp,
Jan Voung3bd9f1a2014-06-18 10:50:57 -070047 IntrinsicCall,
Matt Wala49889232014-07-18 12:45:09 -070048 InsertElement,
Jim Stichnothf7c9a142014-04-29 10:52:43 -070049 Load,
50 Phi,
51 Ret,
52 Select,
53 Store,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070054 Switch,
55 FakeDef, // not part of LLVM/PNaCl bitcode
56 FakeUse, // not part of LLVM/PNaCl bitcode
57 FakeKill, // not part of LLVM/PNaCl bitcode
58 Target // target-specific low-level ICE
59 // Anything >= Target is an InstTarget subclass.
Jim Stichnothf7c9a142014-04-29 10:52:43 -070060 };
61 InstKind getKind() const { return Kind; }
62
Jim Stichnothd97c7df2014-06-04 11:57:08 -070063 InstNumberT getNumber() const { return Number; }
64 void renumber(Cfg *Func);
65 static const InstNumberT NumberDeleted = -1;
66 static const InstNumberT NumberSentinel = 0;
Jim Stichnothf7c9a142014-04-29 10:52:43 -070067
68 bool isDeleted() const { return Deleted; }
69 void setDeleted() { Deleted = true; }
Jim Stichnothd97c7df2014-06-04 11:57:08 -070070 void deleteIfDead();
Jim Stichnothf7c9a142014-04-29 10:52:43 -070071
72 bool hasSideEffects() const { return HasSideEffects; }
73
74 Variable *getDest() const { return Dest; }
75
76 SizeT getSrcSize() const { return NumSrcs; }
77 Operand *getSrc(SizeT I) const {
78 assert(I < getSrcSize());
79 return Srcs[I];
80 }
81
Jim Stichnothd97c7df2014-06-04 11:57:08 -070082 bool isLastUse(const Operand *Src) const;
83
Jim Stichnothf7c9a142014-04-29 10:52:43 -070084 // Returns a list of out-edges corresponding to a terminator
85 // instruction, which is the last instruction of the block.
86 virtual NodeList getTerminatorEdges() const {
87 // All valid terminator instructions override this method. For
88 // the default implementation, we assert in case some CfgNode
89 // is constructed without a terminator instruction at the end.
90 llvm_unreachable(
91 "getTerminatorEdges() called on a non-terminator instruction");
92 return NodeList();
93 }
94
95 // Updates the status of the Variables contained within the
96 // instruction. In particular, it marks where the Dest variable is
97 // first assigned, and it tracks whether variables are live across
98 // basic blocks, i.e. used in a different block from their definition.
99 void updateVars(CfgNode *Node);
100
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700101 void livenessLightweight(llvm::BitVector &Live);
102 void liveness(InstNumberT InstNumber, llvm::BitVector &Live,
103 Liveness *Liveness, const CfgNode *Node);
Jim Stichnoth18735602014-09-16 19:59:35 -0700104
105 // Get the number of native instructions that this instruction
106 // ultimately emits. By default, high-level instructions don't
107 // result in any native instructions, and a target-specific
108 // instruction results in a single native instruction.
109 virtual uint32_t getEmitInstCount() const { return 0; }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700110 virtual void emit(const Cfg *Func) const;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700111 virtual void dump(const Cfg *Func) const;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700112 virtual void dumpExtras(const Cfg *Func) const;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700113 void dumpDecorated(const Cfg *Func) const;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700114 void emitSources(const Cfg *Func) const;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700115 void dumpSources(const Cfg *Func) const;
116 void dumpDest(const Cfg *Func) const;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700117 virtual bool isRedundantAssign() const { return false; }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700118
119 virtual ~Inst() {}
120
121protected:
122 Inst(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest);
123 void addSource(Operand *Src) {
124 assert(Src);
125 assert(NumSrcs < MaxSrcs);
126 Srcs[NumSrcs++] = Src;
127 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700128 void setLastUse(SizeT VarIndex) {
129 if (VarIndex < CHAR_BIT * sizeof(LiveRangesEnded))
130 LiveRangesEnded |= (((LREndedBits)1u) << VarIndex);
131 }
132 void resetLastUses() { LiveRangesEnded = 0; }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700133 // The destroy() method lets the instruction cleanly release any
134 // memory that was allocated via the Cfg's allocator.
135 virtual void destroy(Cfg *Func) { Func->deallocateArrayOf<Operand *>(Srcs); }
136
137 const InstKind Kind;
138 // Number is the instruction number for describing live ranges.
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700139 InstNumberT Number;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700140 // Deleted means irrevocably deleted.
141 bool Deleted;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700142 // Dead means pending deletion after liveness analysis converges.
143 bool Dead;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700144 // HasSideEffects means the instruction is something like a function
145 // call or a volatile load that can't be removed even if its Dest
146 // variable is not live.
147 bool HasSideEffects;
148
149 Variable *Dest;
150 const SizeT MaxSrcs; // only used for assert
151 SizeT NumSrcs;
152 Operand **Srcs;
153
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700154 // LiveRangesEnded marks which Variables' live ranges end in this
155 // instruction. An instruction can have an arbitrary number of
156 // source operands (e.g. a call instruction), and each source
157 // operand can contain 0 or 1 Variable (and target-specific operands
158 // could contain more than 1 Variable). All the variables in an
159 // instruction are conceptually flattened and each variable is
160 // mapped to one bit position of the LiveRangesEnded bit vector.
161 // Only the first CHAR_BIT * sizeof(LREndedBits) variables are
162 // tracked this way.
163 typedef uint32_t LREndedBits; // only first 32 src operands tracked, sorry
164 LREndedBits LiveRangesEnded;
165
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700166private:
167 Inst(const Inst &) LLVM_DELETED_FUNCTION;
168 Inst &operator=(const Inst &) LLVM_DELETED_FUNCTION;
169};
170
171// Alloca instruction. This captures the size in bytes as getSrc(0),
172// and the required alignment in bytes. The alignment must be either
173// 0 (no alignment required) or a power of 2.
174class InstAlloca : public Inst {
175public:
176 static InstAlloca *create(Cfg *Func, Operand *ByteCount,
177 uint32_t AlignInBytes, Variable *Dest) {
178 return new (Func->allocateInst<InstAlloca>())
179 InstAlloca(Func, ByteCount, AlignInBytes, Dest);
180 }
181 uint32_t getAlignInBytes() const { return AlignInBytes; }
182 Operand *getSizeInBytes() const { return getSrc(0); }
183 virtual void dump(const Cfg *Func) const;
184 static bool classof(const Inst *Inst) { return Inst->getKind() == Alloca; }
185
186private:
187 InstAlloca(Cfg *Func, Operand *ByteCount, uint32_t AlignInBytes,
188 Variable *Dest);
189 InstAlloca(const InstAlloca &) LLVM_DELETED_FUNCTION;
190 InstAlloca &operator=(const InstAlloca &) LLVM_DELETED_FUNCTION;
191 virtual ~InstAlloca() {}
192 const uint32_t AlignInBytes;
193};
194
195// Binary arithmetic instruction. The source operands are captured in
196// getSrc(0) and getSrc(1).
197class InstArithmetic : public Inst {
198public:
199 enum OpKind {
200#define X(tag, str, commutative) tag,
201 ICEINSTARITHMETIC_TABLE
202#undef X
Jim Stichnoth4376d292014-05-23 13:39:02 -0700203 _num
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700204 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700205
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700206 static InstArithmetic *create(Cfg *Func, OpKind Op, Variable *Dest,
207 Operand *Source1, Operand *Source2) {
208 return new (Func->allocateInst<InstArithmetic>())
209 InstArithmetic(Func, Op, Dest, Source1, Source2);
210 }
211 OpKind getOp() const { return Op; }
Karl Schimpfd6064a12014-08-27 15:34:58 -0700212 static const char *getOpName(OpKind Op);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700213 bool isCommutative() const;
214 virtual void dump(const Cfg *Func) const;
215 static bool classof(const Inst *Inst) {
216 return Inst->getKind() == Arithmetic;
217 }
218
219private:
220 InstArithmetic(Cfg *Func, OpKind Op, Variable *Dest, Operand *Source1,
221 Operand *Source2);
222 InstArithmetic(const InstArithmetic &) LLVM_DELETED_FUNCTION;
223 InstArithmetic &operator=(const InstArithmetic &) LLVM_DELETED_FUNCTION;
224 virtual ~InstArithmetic() {}
225
226 const OpKind Op;
227};
228
229// Assignment instruction. The source operand is captured in
230// getSrc(0). This is not part of the LLVM bitcode, but is a useful
231// abstraction for some of the lowering. E.g., if Phi instruction
232// lowering happens before target lowering, or for representing an
233// Inttoptr instruction, or as an intermediate step for lowering a
234// Load instruction.
235class InstAssign : public Inst {
236public:
237 static InstAssign *create(Cfg *Func, Variable *Dest, Operand *Source) {
238 return new (Func->allocateInst<InstAssign>())
239 InstAssign(Func, Dest, Source);
240 }
241 virtual void dump(const Cfg *Func) const;
242 static bool classof(const Inst *Inst) { return Inst->getKind() == Assign; }
243
244private:
245 InstAssign(Cfg *Func, Variable *Dest, Operand *Source);
246 InstAssign(const InstAssign &) LLVM_DELETED_FUNCTION;
247 InstAssign &operator=(const InstAssign &) LLVM_DELETED_FUNCTION;
248 virtual ~InstAssign() {}
249};
250
251// Branch instruction. This represents both conditional and
252// unconditional branches.
253class InstBr : public Inst {
254public:
255 // Create a conditional branch. If TargetTrue==TargetFalse, it is
256 // optimized to an unconditional branch.
257 static InstBr *create(Cfg *Func, Operand *Source, CfgNode *TargetTrue,
258 CfgNode *TargetFalse) {
259 return new (Func->allocateInst<InstBr>())
260 InstBr(Func, Source, TargetTrue, TargetFalse);
261 }
262 // Create an unconditional branch.
263 static InstBr *create(Cfg *Func, CfgNode *Target) {
264 return new (Func->allocateInst<InstBr>()) InstBr(Func, Target);
265 }
266 bool isUnconditional() const { return getTargetTrue() == NULL; }
267 Operand *getCondition() const {
268 assert(!isUnconditional());
269 return getSrc(0);
270 }
271 CfgNode *getTargetTrue() const { return TargetTrue; }
272 CfgNode *getTargetFalse() const { return TargetFalse; }
273 CfgNode *getTargetUnconditional() const {
274 assert(isUnconditional());
275 return getTargetFalse();
276 }
277 virtual NodeList getTerminatorEdges() const;
278 virtual void dump(const Cfg *Func) const;
279 static bool classof(const Inst *Inst) { return Inst->getKind() == Br; }
280
281private:
282 // Conditional branch
283 InstBr(Cfg *Func, Operand *Source, CfgNode *TargetTrue, CfgNode *TargetFalse);
284 // Unconditional branch
285 InstBr(Cfg *Func, CfgNode *Target);
286 InstBr(const InstBr &) LLVM_DELETED_FUNCTION;
287 InstBr &operator=(const InstBr &) LLVM_DELETED_FUNCTION;
288 virtual ~InstBr() {}
289
290 CfgNode *const TargetFalse; // Doubles as unconditional branch target
291 CfgNode *const TargetTrue; // NULL if unconditional branch
292};
293
294// Call instruction. The call target is captured as getSrc(0), and
295// arg I is captured as getSrc(I+1).
296class InstCall : public Inst {
297public:
298 static InstCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest,
Karl Schimpf8df26f32014-09-19 09:33:26 -0700299 Operand *CallTarget, bool HasTailCall) {
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700300 // Set HasSideEffects to true so that the call instruction can't be
301 // dead-code eliminated. IntrinsicCalls can override this if the
302 // particular intrinsic is deletable and has no side-effects.
303 const bool HasSideEffects = true;
304 const InstKind Kind = Inst::Call;
Karl Schimpf8df26f32014-09-19 09:33:26 -0700305 return new (Func->allocateInst<InstCall>()) InstCall(
306 Func, NumArgs, Dest, CallTarget, HasTailCall, HasSideEffects, Kind);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700307 }
308 void addArg(Operand *Arg) { addSource(Arg); }
309 Operand *getCallTarget() const { return getSrc(0); }
310 Operand *getArg(SizeT I) const { return getSrc(I + 1); }
311 SizeT getNumArgs() const { return getSrcSize() - 1; }
Karl Schimpf8df26f32014-09-19 09:33:26 -0700312 bool isTailcall() const { return HasTailCall; }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700313 virtual void dump(const Cfg *Func) const;
314 static bool classof(const Inst *Inst) { return Inst->getKind() == Call; }
Karl Schimpf8df26f32014-09-19 09:33:26 -0700315 Type getReturnType() const;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700316
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700317protected:
318 InstCall(Cfg *Func, SizeT NumArgs, Variable *Dest, Operand *CallTarget,
Karl Schimpf8df26f32014-09-19 09:33:26 -0700319 bool HasTailCall, bool HasSideEff, InstKind Kind)
320 : Inst(Func, Kind, NumArgs + 1, Dest),
321 HasTailCall(HasTailCall) {
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700322 HasSideEffects = HasSideEff;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700323 addSource(CallTarget);
324 }
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700325 virtual ~InstCall() {}
326
327private:
Karl Schimpf8df26f32014-09-19 09:33:26 -0700328 bool HasTailCall;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700329 InstCall(const InstCall &) LLVM_DELETED_FUNCTION;
330 InstCall &operator=(const InstCall &) LLVM_DELETED_FUNCTION;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700331};
332
333// Cast instruction (a.k.a. conversion operation).
334class InstCast : public Inst {
335public:
336 enum OpKind {
337#define X(tag, str) tag,
338 ICEINSTCAST_TABLE
339#undef X
Jim Stichnoth4376d292014-05-23 13:39:02 -0700340 _num
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700341 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700342
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700343 static InstCast *create(Cfg *Func, OpKind CastKind, Variable *Dest,
344 Operand *Source) {
345 return new (Func->allocateInst<InstCast>())
346 InstCast(Func, CastKind, Dest, Source);
347 }
348 OpKind getCastKind() const { return CastKind; }
349 virtual void dump(const Cfg *Func) const;
350 static bool classof(const Inst *Inst) { return Inst->getKind() == Cast; }
351
352private:
353 InstCast(Cfg *Func, OpKind CastKind, Variable *Dest, Operand *Source);
354 InstCast(const InstCast &) LLVM_DELETED_FUNCTION;
355 InstCast &operator=(const InstCast &) LLVM_DELETED_FUNCTION;
356 virtual ~InstCast() {}
357 const OpKind CastKind;
358};
359
Matt Wala49889232014-07-18 12:45:09 -0700360// ExtractElement instruction.
361class InstExtractElement : public Inst {
362public:
363 static InstExtractElement *create(Cfg *Func, Variable *Dest, Operand *Source1,
364 Operand *Source2) {
365 return new (Func->allocateInst<InstExtractElement>())
366 InstExtractElement(Func, Dest, Source1, Source2);
367 }
368
369 virtual void dump(const Cfg *Func) const;
370 static bool classof(const Inst *Inst) {
371 return Inst->getKind() == ExtractElement;
372 }
373
374private:
375 InstExtractElement(Cfg *Func, Variable *Dest, Operand *Source1,
376 Operand *Source2);
377 InstExtractElement(const InstExtractElement &) LLVM_DELETED_FUNCTION;
378 InstExtractElement &
379 operator=(const InstExtractElement &) LLVM_DELETED_FUNCTION;
380 virtual ~InstExtractElement() {}
381};
382
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700383// Floating-point comparison instruction. The source operands are
384// captured in getSrc(0) and getSrc(1).
385class InstFcmp : public Inst {
386public:
387 enum FCond {
388#define X(tag, str) tag,
389 ICEINSTFCMP_TABLE
390#undef X
Jim Stichnoth4376d292014-05-23 13:39:02 -0700391 _num
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700392 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700393
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700394 static InstFcmp *create(Cfg *Func, FCond Condition, Variable *Dest,
395 Operand *Source1, Operand *Source2) {
396 return new (Func->allocateInst<InstFcmp>())
397 InstFcmp(Func, Condition, Dest, Source1, Source2);
398 }
399 FCond getCondition() const { return Condition; }
400 virtual void dump(const Cfg *Func) const;
401 static bool classof(const Inst *Inst) { return Inst->getKind() == Fcmp; }
402
403private:
404 InstFcmp(Cfg *Func, FCond Condition, Variable *Dest, Operand *Source1,
405 Operand *Source2);
406 InstFcmp(const InstFcmp &) LLVM_DELETED_FUNCTION;
407 InstFcmp &operator=(const InstFcmp &) LLVM_DELETED_FUNCTION;
408 virtual ~InstFcmp() {}
409 const FCond Condition;
410};
411
412// Integer comparison instruction. The source operands are captured
413// in getSrc(0) and getSrc(1).
414class InstIcmp : public Inst {
415public:
416 enum ICond {
417#define X(tag, str) tag,
418 ICEINSTICMP_TABLE
419#undef X
Jim Stichnoth4376d292014-05-23 13:39:02 -0700420 _num
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700421 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700422
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700423 static InstIcmp *create(Cfg *Func, ICond Condition, Variable *Dest,
424 Operand *Source1, Operand *Source2) {
425 return new (Func->allocateInst<InstIcmp>())
426 InstIcmp(Func, Condition, Dest, Source1, Source2);
427 }
428 ICond getCondition() const { return Condition; }
429 virtual void dump(const Cfg *Func) const;
430 static bool classof(const Inst *Inst) { return Inst->getKind() == Icmp; }
431
432private:
433 InstIcmp(Cfg *Func, ICond Condition, Variable *Dest, Operand *Source1,
434 Operand *Source2);
435 InstIcmp(const InstIcmp &) LLVM_DELETED_FUNCTION;
436 InstIcmp &operator=(const InstIcmp &) LLVM_DELETED_FUNCTION;
437 virtual ~InstIcmp() {}
438 const ICond Condition;
439};
440
Matt Wala49889232014-07-18 12:45:09 -0700441// InsertElement instruction.
442class InstInsertElement : public Inst {
443public:
444 static InstInsertElement *create(Cfg *Func, Variable *Dest, Operand *Source1,
445 Operand *Source2, Operand *Source3) {
446 return new (Func->allocateInst<InstInsertElement>())
447 InstInsertElement(Func, Dest, Source1, Source2, Source3);
448 }
449
450 virtual void dump(const Cfg *Func) const;
451 static bool classof(const Inst *Inst) {
452 return Inst->getKind() == InsertElement;
453 }
454
455private:
456 InstInsertElement(Cfg *Func, Variable *Dest, Operand *Source1,
457 Operand *Source2, Operand *Source3);
458 InstInsertElement(const InstInsertElement &) LLVM_DELETED_FUNCTION;
459 InstInsertElement &operator=(const InstInsertElement &) LLVM_DELETED_FUNCTION;
460 virtual ~InstInsertElement() {}
461};
462
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700463// Call to an intrinsic function. The call target is captured as getSrc(0),
464// and arg I is captured as getSrc(I+1).
465class InstIntrinsicCall : public InstCall {
466public:
467 static InstIntrinsicCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest,
468 Operand *CallTarget,
469 const Intrinsics::IntrinsicInfo &Info) {
470 return new (Func->allocateInst<InstIntrinsicCall>())
471 InstIntrinsicCall(Func, NumArgs, Dest, CallTarget, Info);
472 }
473 static bool classof(const Inst *Inst) {
474 return Inst->getKind() == IntrinsicCall;
475 }
476
477 Intrinsics::IntrinsicInfo getIntrinsicInfo() const { return Info; }
478
479private:
480 InstIntrinsicCall(Cfg *Func, SizeT NumArgs, Variable *Dest,
481 Operand *CallTarget, const Intrinsics::IntrinsicInfo &Info)
Karl Schimpf8df26f32014-09-19 09:33:26 -0700482 : InstCall(Func, NumArgs, Dest, CallTarget, false, Info.HasSideEffects,
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700483 Inst::IntrinsicCall),
484 Info(Info) {}
485 InstIntrinsicCall(const InstIntrinsicCall &) LLVM_DELETED_FUNCTION;
486 InstIntrinsicCall &operator=(const InstIntrinsicCall &) LLVM_DELETED_FUNCTION;
487 virtual ~InstIntrinsicCall() {}
488 const Intrinsics::IntrinsicInfo Info;
489};
490
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700491// Load instruction. The source address is captured in getSrc(0).
492class InstLoad : public Inst {
493public:
Karl Schimpf41689df2014-09-10 14:36:07 -0700494 static InstLoad *create(Cfg *Func, Variable *Dest, Operand *SourceAddr,
495 uint32_t align = 1) {
496 // TODO(kschimpf) Stop ignoring alignment specification.
497 (void)align;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700498 return new (Func->allocateInst<InstLoad>())
499 InstLoad(Func, Dest, SourceAddr);
500 }
501 Operand *getSourceAddress() const { return getSrc(0); }
502 virtual void dump(const Cfg *Func) const;
503 static bool classof(const Inst *Inst) { return Inst->getKind() == Load; }
504
505private:
506 InstLoad(Cfg *Func, Variable *Dest, Operand *SourceAddr);
507 InstLoad(const InstLoad &) LLVM_DELETED_FUNCTION;
508 InstLoad &operator=(const InstLoad &) LLVM_DELETED_FUNCTION;
509 virtual ~InstLoad() {}
510};
511
512// Phi instruction. For incoming edge I, the node is Labels[I] and
513// the Phi source operand is getSrc(I).
514class InstPhi : public Inst {
515public:
516 static InstPhi *create(Cfg *Func, SizeT MaxSrcs, Variable *Dest) {
517 return new (Func->allocateInst<InstPhi>()) InstPhi(Func, MaxSrcs, Dest);
518 }
519 void addArgument(Operand *Source, CfgNode *Label);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700520 Operand *getOperandForTarget(CfgNode *Target) const;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700521 void livenessPhiOperand(llvm::BitVector &Live, CfgNode *Target,
522 Liveness *Liveness);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700523 Inst *lower(Cfg *Func, CfgNode *Node);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700524 virtual void dump(const Cfg *Func) const;
525 static bool classof(const Inst *Inst) { return Inst->getKind() == Phi; }
526
527private:
528 InstPhi(Cfg *Func, SizeT MaxSrcs, Variable *Dest);
529 InstPhi(const InstPhi &) LLVM_DELETED_FUNCTION;
530 InstPhi &operator=(const InstPhi &) LLVM_DELETED_FUNCTION;
531 virtual void destroy(Cfg *Func) {
532 Func->deallocateArrayOf<CfgNode *>(Labels);
533 Inst::destroy(Func);
534 }
535 virtual ~InstPhi() {}
536
537 // Labels[] duplicates the InEdges[] information in the enclosing
538 // CfgNode, but the Phi instruction is created before InEdges[]
539 // is available, so it's more complicated to share the list.
540 CfgNode **Labels;
541};
542
543// Ret instruction. The return value is captured in getSrc(0), but if
544// there is no return value (void-type function), then
545// getSrcSize()==0 and hasRetValue()==false.
546class InstRet : public Inst {
547public:
548 static InstRet *create(Cfg *Func, Operand *RetValue = NULL) {
549 return new (Func->allocateInst<InstRet>()) InstRet(Func, RetValue);
550 }
551 bool hasRetValue() const { return getSrcSize(); }
552 Operand *getRetValue() const {
553 assert(hasRetValue());
554 return getSrc(0);
555 }
556 virtual NodeList getTerminatorEdges() const { return NodeList(); }
557 virtual void dump(const Cfg *Func) const;
558 static bool classof(const Inst *Inst) { return Inst->getKind() == Ret; }
559
560private:
561 InstRet(Cfg *Func, Operand *RetValue);
562 InstRet(const InstRet &) LLVM_DELETED_FUNCTION;
563 InstRet &operator=(const InstRet &) LLVM_DELETED_FUNCTION;
564 virtual ~InstRet() {}
565};
566
567// Select instruction. The condition, true, and false operands are captured.
568class InstSelect : public Inst {
569public:
570 static InstSelect *create(Cfg *Func, Variable *Dest, Operand *Condition,
571 Operand *SourceTrue, Operand *SourceFalse) {
572 return new (Func->allocateInst<InstSelect>())
573 InstSelect(Func, Dest, Condition, SourceTrue, SourceFalse);
574 }
575 Operand *getCondition() const { return getSrc(0); }
576 Operand *getTrueOperand() const { return getSrc(1); }
577 Operand *getFalseOperand() const { return getSrc(2); }
578 virtual void dump(const Cfg *Func) const;
579 static bool classof(const Inst *Inst) { return Inst->getKind() == Select; }
580
581private:
582 InstSelect(Cfg *Func, Variable *Dest, Operand *Condition, Operand *Source1,
583 Operand *Source2);
584 InstSelect(const InstSelect &) LLVM_DELETED_FUNCTION;
585 InstSelect &operator=(const InstSelect &) LLVM_DELETED_FUNCTION;
586 virtual ~InstSelect() {}
587};
588
589// Store instruction. The address operand is captured, along with the
590// data operand to be stored into the address.
591class InstStore : public Inst {
592public:
Karl Schimpf41689df2014-09-10 14:36:07 -0700593 static InstStore *create(Cfg *Func, Operand *Data, Operand *Addr,
594 uint32_t align = 1) {
595 // TODO(kschimpf) Stop ignoring alignment specification.
596 (void)align;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700597 return new (Func->allocateInst<InstStore>()) InstStore(Func, Data, Addr);
598 }
599 Operand *getAddr() const { return getSrc(1); }
600 Operand *getData() const { return getSrc(0); }
601 virtual void dump(const Cfg *Func) const;
602 static bool classof(const Inst *Inst) { return Inst->getKind() == Store; }
603
604private:
605 InstStore(Cfg *Func, Operand *Data, Operand *Addr);
606 InstStore(const InstStore &) LLVM_DELETED_FUNCTION;
607 InstStore &operator=(const InstStore &) LLVM_DELETED_FUNCTION;
608 virtual ~InstStore() {}
609};
610
611// Switch instruction. The single source operand is captured as
612// getSrc(0).
613class InstSwitch : public Inst {
614public:
615 static InstSwitch *create(Cfg *Func, SizeT NumCases, Operand *Source,
616 CfgNode *LabelDefault) {
617 return new (Func->allocateInst<InstSwitch>())
618 InstSwitch(Func, NumCases, Source, LabelDefault);
619 }
620 Operand *getComparison() const { return getSrc(0); }
621 CfgNode *getLabelDefault() const { return LabelDefault; }
622 SizeT getNumCases() const { return NumCases; }
623 uint64_t getValue(SizeT I) const {
624 assert(I < NumCases);
625 return Values[I];
626 }
627 CfgNode *getLabel(SizeT I) const {
628 assert(I < NumCases);
629 return Labels[I];
630 }
631 void addBranch(SizeT CaseIndex, uint64_t Value, CfgNode *Label);
632 virtual NodeList getTerminatorEdges() const;
633 virtual void dump(const Cfg *Func) const;
634 static bool classof(const Inst *Inst) { return Inst->getKind() == Switch; }
635
636private:
637 InstSwitch(Cfg *Func, SizeT NumCases, Operand *Source, CfgNode *LabelDefault);
638 InstSwitch(const InstSwitch &) LLVM_DELETED_FUNCTION;
639 InstSwitch &operator=(const InstSwitch &) LLVM_DELETED_FUNCTION;
640 virtual void destroy(Cfg *Func) {
641 Func->deallocateArrayOf<uint64_t>(Values);
642 Func->deallocateArrayOf<CfgNode *>(Labels);
643 Inst::destroy(Func);
644 }
645 virtual ~InstSwitch() {}
646
647 CfgNode *LabelDefault;
648 SizeT NumCases; // not including the default case
649 uint64_t *Values; // size is NumCases
650 CfgNode **Labels; // size is NumCases
651};
652
653// Unreachable instruction. This is a terminator instruction with no
654// operands.
655class InstUnreachable : public Inst {
656public:
657 static InstUnreachable *create(Cfg *Func) {
658 return new (Func->allocateInst<InstUnreachable>()) InstUnreachable(Func);
659 }
660 virtual NodeList getTerminatorEdges() const { return NodeList(); }
661 virtual void dump(const Cfg *Func) const;
662 static bool classof(const Inst *Inst) {
663 return Inst->getKind() == Unreachable;
664 }
665
666private:
667 InstUnreachable(Cfg *Func);
668 InstUnreachable(const InstUnreachable &) LLVM_DELETED_FUNCTION;
669 InstUnreachable &operator=(const InstUnreachable &) LLVM_DELETED_FUNCTION;
670 virtual ~InstUnreachable() {}
671};
672
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700673// FakeDef instruction. This creates a fake definition of a variable,
674// which is how we represent the case when an instruction produces
675// multiple results. This doesn't happen with high-level ICE
676// instructions, but might with lowered instructions. For example,
677// this would be a way to represent condition flags being modified by
678// an instruction.
679//
680// It's generally useful to set the optional source operand to be the
681// dest variable of the instruction that actually produces the FakeDef
682// dest. Otherwise, the original instruction could be dead-code
683// eliminated if its dest operand is unused, and therefore the FakeDef
684// dest wouldn't be properly initialized.
685class InstFakeDef : public Inst {
686public:
687 static InstFakeDef *create(Cfg *Func, Variable *Dest, Variable *Src = NULL) {
688 return new (Func->allocateInst<InstFakeDef>()) InstFakeDef(Func, Dest, Src);
689 }
690 virtual void emit(const Cfg *Func) const;
691 virtual void dump(const Cfg *Func) const;
692 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeDef; }
693
694private:
695 InstFakeDef(Cfg *Func, Variable *Dest, Variable *Src);
696 InstFakeDef(const InstFakeDef &) LLVM_DELETED_FUNCTION;
697 InstFakeDef &operator=(const InstFakeDef &) LLVM_DELETED_FUNCTION;
698 virtual ~InstFakeDef() {}
699};
700
701// FakeUse instruction. This creates a fake use of a variable, to
702// keep the instruction that produces that variable from being
703// dead-code eliminated. This is useful in a variety of lowering
704// situations. The FakeUse instruction has no dest, so it can itself
705// never be dead-code eliminated.
706class InstFakeUse : public Inst {
707public:
708 static InstFakeUse *create(Cfg *Func, Variable *Src) {
709 return new (Func->allocateInst<InstFakeUse>()) InstFakeUse(Func, Src);
710 }
711 virtual void emit(const Cfg *Func) const;
712 virtual void dump(const Cfg *Func) const;
713 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeUse; }
714
715private:
716 InstFakeUse(Cfg *Func, Variable *Src);
717 InstFakeUse(const InstFakeUse &) LLVM_DELETED_FUNCTION;
718 InstFakeUse &operator=(const InstFakeUse &) LLVM_DELETED_FUNCTION;
719 virtual ~InstFakeUse() {}
720};
721
722// FakeKill instruction. This "kills" a set of variables by adding a
723// trivial live range at this instruction to each variable. The
724// primary use is to indicate that scratch registers are killed after
725// a call, so that the register allocator won't assign a scratch
726// register to a variable whose live range spans a call.
727//
728// The FakeKill instruction also holds a pointer to the instruction
729// that kills the set of variables, so that if that linked instruction
730// gets dead-code eliminated, the FakeKill instruction will as well.
731class InstFakeKill : public Inst {
732public:
733 static InstFakeKill *create(Cfg *Func, const VarList &KilledRegs,
734 const Inst *Linked) {
735 return new (Func->allocateInst<InstFakeKill>())
736 InstFakeKill(Func, KilledRegs, Linked);
737 }
738 const Inst *getLinked() const { return Linked; }
739 virtual void emit(const Cfg *Func) const;
740 virtual void dump(const Cfg *Func) const;
741 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeKill; }
742
743private:
744 InstFakeKill(Cfg *Func, const VarList &KilledRegs, const Inst *Linked);
745 InstFakeKill(const InstFakeKill &) LLVM_DELETED_FUNCTION;
746 InstFakeKill &operator=(const InstFakeKill &) LLVM_DELETED_FUNCTION;
747 virtual ~InstFakeKill() {}
748
749 // This instruction is ignored if Linked->isDeleted() is true.
750 const Inst *Linked;
751};
752
753// The Target instruction is the base class for all target-specific
754// instructions.
755class InstTarget : public Inst {
756public:
Jim Stichnoth18735602014-09-16 19:59:35 -0700757 virtual uint32_t getEmitInstCount() const { return 1; }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700758 virtual void emit(const Cfg *Func) const = 0;
759 virtual void dump(const Cfg *Func) const;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700760 virtual void dumpExtras(const Cfg *Func) const;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700761 static bool classof(const Inst *Inst) { return Inst->getKind() >= Target; }
762
763protected:
764 InstTarget(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest)
765 : Inst(Func, Kind, MaxSrcs, Dest) {
766 assert(Kind >= Target);
767 }
768 InstTarget(const InstTarget &) LLVM_DELETED_FUNCTION;
769 InstTarget &operator=(const InstTarget &) LLVM_DELETED_FUNCTION;
770 virtual ~InstTarget() {}
771};
772
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700773} // end of namespace Ice
774
775#endif // SUBZERO_SRC_ICEINST_H