blob: 18c38dd29da78b01b7038ecb9672fcf325b9a789 [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,
299 Operand *CallTarget) {
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;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700305 return new (Func->allocateInst<InstCall>())
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700306 InstCall(Func, NumArgs, Dest, CallTarget, 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; }
312 virtual void dump(const Cfg *Func) const;
313 static bool classof(const Inst *Inst) { return Inst->getKind() == Call; }
314
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700315protected:
316 InstCall(Cfg *Func, SizeT NumArgs, Variable *Dest, Operand *CallTarget,
317 bool HasSideEff, InstKind Kind)
318 : Inst(Func, Kind, NumArgs + 1, Dest) {
319 HasSideEffects = HasSideEff;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700320 addSource(CallTarget);
321 }
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700322 virtual ~InstCall() {}
323
324private:
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700325 InstCall(const InstCall &) LLVM_DELETED_FUNCTION;
326 InstCall &operator=(const InstCall &) LLVM_DELETED_FUNCTION;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700327};
328
329// Cast instruction (a.k.a. conversion operation).
330class InstCast : public Inst {
331public:
332 enum OpKind {
333#define X(tag, str) tag,
334 ICEINSTCAST_TABLE
335#undef X
Jim Stichnoth4376d292014-05-23 13:39:02 -0700336 _num
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700337 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700338
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700339 static InstCast *create(Cfg *Func, OpKind CastKind, Variable *Dest,
340 Operand *Source) {
341 return new (Func->allocateInst<InstCast>())
342 InstCast(Func, CastKind, Dest, Source);
343 }
344 OpKind getCastKind() const { return CastKind; }
345 virtual void dump(const Cfg *Func) const;
346 static bool classof(const Inst *Inst) { return Inst->getKind() == Cast; }
347
348private:
349 InstCast(Cfg *Func, OpKind CastKind, Variable *Dest, Operand *Source);
350 InstCast(const InstCast &) LLVM_DELETED_FUNCTION;
351 InstCast &operator=(const InstCast &) LLVM_DELETED_FUNCTION;
352 virtual ~InstCast() {}
353 const OpKind CastKind;
354};
355
Matt Wala49889232014-07-18 12:45:09 -0700356// ExtractElement instruction.
357class InstExtractElement : public Inst {
358public:
359 static InstExtractElement *create(Cfg *Func, Variable *Dest, Operand *Source1,
360 Operand *Source2) {
361 return new (Func->allocateInst<InstExtractElement>())
362 InstExtractElement(Func, Dest, Source1, Source2);
363 }
364
365 virtual void dump(const Cfg *Func) const;
366 static bool classof(const Inst *Inst) {
367 return Inst->getKind() == ExtractElement;
368 }
369
370private:
371 InstExtractElement(Cfg *Func, Variable *Dest, Operand *Source1,
372 Operand *Source2);
373 InstExtractElement(const InstExtractElement &) LLVM_DELETED_FUNCTION;
374 InstExtractElement &
375 operator=(const InstExtractElement &) LLVM_DELETED_FUNCTION;
376 virtual ~InstExtractElement() {}
377};
378
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700379// Floating-point comparison instruction. The source operands are
380// captured in getSrc(0) and getSrc(1).
381class InstFcmp : public Inst {
382public:
383 enum FCond {
384#define X(tag, str) tag,
385 ICEINSTFCMP_TABLE
386#undef X
Jim Stichnoth4376d292014-05-23 13:39:02 -0700387 _num
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700388 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700389
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700390 static InstFcmp *create(Cfg *Func, FCond Condition, Variable *Dest,
391 Operand *Source1, Operand *Source2) {
392 return new (Func->allocateInst<InstFcmp>())
393 InstFcmp(Func, Condition, Dest, Source1, Source2);
394 }
395 FCond getCondition() const { return Condition; }
396 virtual void dump(const Cfg *Func) const;
397 static bool classof(const Inst *Inst) { return Inst->getKind() == Fcmp; }
398
399private:
400 InstFcmp(Cfg *Func, FCond Condition, Variable *Dest, Operand *Source1,
401 Operand *Source2);
402 InstFcmp(const InstFcmp &) LLVM_DELETED_FUNCTION;
403 InstFcmp &operator=(const InstFcmp &) LLVM_DELETED_FUNCTION;
404 virtual ~InstFcmp() {}
405 const FCond Condition;
406};
407
408// Integer comparison instruction. The source operands are captured
409// in getSrc(0) and getSrc(1).
410class InstIcmp : public Inst {
411public:
412 enum ICond {
413#define X(tag, str) tag,
414 ICEINSTICMP_TABLE
415#undef X
Jim Stichnoth4376d292014-05-23 13:39:02 -0700416 _num
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700417 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700418
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700419 static InstIcmp *create(Cfg *Func, ICond Condition, Variable *Dest,
420 Operand *Source1, Operand *Source2) {
421 return new (Func->allocateInst<InstIcmp>())
422 InstIcmp(Func, Condition, Dest, Source1, Source2);
423 }
424 ICond getCondition() const { return Condition; }
425 virtual void dump(const Cfg *Func) const;
426 static bool classof(const Inst *Inst) { return Inst->getKind() == Icmp; }
427
428private:
429 InstIcmp(Cfg *Func, ICond Condition, Variable *Dest, Operand *Source1,
430 Operand *Source2);
431 InstIcmp(const InstIcmp &) LLVM_DELETED_FUNCTION;
432 InstIcmp &operator=(const InstIcmp &) LLVM_DELETED_FUNCTION;
433 virtual ~InstIcmp() {}
434 const ICond Condition;
435};
436
Matt Wala49889232014-07-18 12:45:09 -0700437// InsertElement instruction.
438class InstInsertElement : public Inst {
439public:
440 static InstInsertElement *create(Cfg *Func, Variable *Dest, Operand *Source1,
441 Operand *Source2, Operand *Source3) {
442 return new (Func->allocateInst<InstInsertElement>())
443 InstInsertElement(Func, Dest, Source1, Source2, Source3);
444 }
445
446 virtual void dump(const Cfg *Func) const;
447 static bool classof(const Inst *Inst) {
448 return Inst->getKind() == InsertElement;
449 }
450
451private:
452 InstInsertElement(Cfg *Func, Variable *Dest, Operand *Source1,
453 Operand *Source2, Operand *Source3);
454 InstInsertElement(const InstInsertElement &) LLVM_DELETED_FUNCTION;
455 InstInsertElement &operator=(const InstInsertElement &) LLVM_DELETED_FUNCTION;
456 virtual ~InstInsertElement() {}
457};
458
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700459// Call to an intrinsic function. The call target is captured as getSrc(0),
460// and arg I is captured as getSrc(I+1).
461class InstIntrinsicCall : public InstCall {
462public:
463 static InstIntrinsicCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest,
464 Operand *CallTarget,
465 const Intrinsics::IntrinsicInfo &Info) {
466 return new (Func->allocateInst<InstIntrinsicCall>())
467 InstIntrinsicCall(Func, NumArgs, Dest, CallTarget, Info);
468 }
469 static bool classof(const Inst *Inst) {
470 return Inst->getKind() == IntrinsicCall;
471 }
472
473 Intrinsics::IntrinsicInfo getIntrinsicInfo() const { return Info; }
474
475private:
476 InstIntrinsicCall(Cfg *Func, SizeT NumArgs, Variable *Dest,
477 Operand *CallTarget, const Intrinsics::IntrinsicInfo &Info)
478 : InstCall(Func, NumArgs, Dest, CallTarget, Info.HasSideEffects,
479 Inst::IntrinsicCall),
480 Info(Info) {}
481 InstIntrinsicCall(const InstIntrinsicCall &) LLVM_DELETED_FUNCTION;
482 InstIntrinsicCall &operator=(const InstIntrinsicCall &) LLVM_DELETED_FUNCTION;
483 virtual ~InstIntrinsicCall() {}
484 const Intrinsics::IntrinsicInfo Info;
485};
486
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700487// Load instruction. The source address is captured in getSrc(0).
488class InstLoad : public Inst {
489public:
Karl Schimpf41689df2014-09-10 14:36:07 -0700490 static InstLoad *create(Cfg *Func, Variable *Dest, Operand *SourceAddr,
491 uint32_t align = 1) {
492 // TODO(kschimpf) Stop ignoring alignment specification.
493 (void)align;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700494 return new (Func->allocateInst<InstLoad>())
495 InstLoad(Func, Dest, SourceAddr);
496 }
497 Operand *getSourceAddress() const { return getSrc(0); }
498 virtual void dump(const Cfg *Func) const;
499 static bool classof(const Inst *Inst) { return Inst->getKind() == Load; }
500
501private:
502 InstLoad(Cfg *Func, Variable *Dest, Operand *SourceAddr);
503 InstLoad(const InstLoad &) LLVM_DELETED_FUNCTION;
504 InstLoad &operator=(const InstLoad &) LLVM_DELETED_FUNCTION;
505 virtual ~InstLoad() {}
506};
507
508// Phi instruction. For incoming edge I, the node is Labels[I] and
509// the Phi source operand is getSrc(I).
510class InstPhi : public Inst {
511public:
512 static InstPhi *create(Cfg *Func, SizeT MaxSrcs, Variable *Dest) {
513 return new (Func->allocateInst<InstPhi>()) InstPhi(Func, MaxSrcs, Dest);
514 }
515 void addArgument(Operand *Source, CfgNode *Label);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700516 Operand *getOperandForTarget(CfgNode *Target) const;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700517 void livenessPhiOperand(llvm::BitVector &Live, CfgNode *Target,
518 Liveness *Liveness);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700519 Inst *lower(Cfg *Func, CfgNode *Node);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700520 virtual void dump(const Cfg *Func) const;
521 static bool classof(const Inst *Inst) { return Inst->getKind() == Phi; }
522
523private:
524 InstPhi(Cfg *Func, SizeT MaxSrcs, Variable *Dest);
525 InstPhi(const InstPhi &) LLVM_DELETED_FUNCTION;
526 InstPhi &operator=(const InstPhi &) LLVM_DELETED_FUNCTION;
527 virtual void destroy(Cfg *Func) {
528 Func->deallocateArrayOf<CfgNode *>(Labels);
529 Inst::destroy(Func);
530 }
531 virtual ~InstPhi() {}
532
533 // Labels[] duplicates the InEdges[] information in the enclosing
534 // CfgNode, but the Phi instruction is created before InEdges[]
535 // is available, so it's more complicated to share the list.
536 CfgNode **Labels;
537};
538
539// Ret instruction. The return value is captured in getSrc(0), but if
540// there is no return value (void-type function), then
541// getSrcSize()==0 and hasRetValue()==false.
542class InstRet : public Inst {
543public:
544 static InstRet *create(Cfg *Func, Operand *RetValue = NULL) {
545 return new (Func->allocateInst<InstRet>()) InstRet(Func, RetValue);
546 }
547 bool hasRetValue() const { return getSrcSize(); }
548 Operand *getRetValue() const {
549 assert(hasRetValue());
550 return getSrc(0);
551 }
552 virtual NodeList getTerminatorEdges() const { return NodeList(); }
553 virtual void dump(const Cfg *Func) const;
554 static bool classof(const Inst *Inst) { return Inst->getKind() == Ret; }
555
556private:
557 InstRet(Cfg *Func, Operand *RetValue);
558 InstRet(const InstRet &) LLVM_DELETED_FUNCTION;
559 InstRet &operator=(const InstRet &) LLVM_DELETED_FUNCTION;
560 virtual ~InstRet() {}
561};
562
563// Select instruction. The condition, true, and false operands are captured.
564class InstSelect : public Inst {
565public:
566 static InstSelect *create(Cfg *Func, Variable *Dest, Operand *Condition,
567 Operand *SourceTrue, Operand *SourceFalse) {
568 return new (Func->allocateInst<InstSelect>())
569 InstSelect(Func, Dest, Condition, SourceTrue, SourceFalse);
570 }
571 Operand *getCondition() const { return getSrc(0); }
572 Operand *getTrueOperand() const { return getSrc(1); }
573 Operand *getFalseOperand() const { return getSrc(2); }
574 virtual void dump(const Cfg *Func) const;
575 static bool classof(const Inst *Inst) { return Inst->getKind() == Select; }
576
577private:
578 InstSelect(Cfg *Func, Variable *Dest, Operand *Condition, Operand *Source1,
579 Operand *Source2);
580 InstSelect(const InstSelect &) LLVM_DELETED_FUNCTION;
581 InstSelect &operator=(const InstSelect &) LLVM_DELETED_FUNCTION;
582 virtual ~InstSelect() {}
583};
584
585// Store instruction. The address operand is captured, along with the
586// data operand to be stored into the address.
587class InstStore : public Inst {
588public:
Karl Schimpf41689df2014-09-10 14:36:07 -0700589 static InstStore *create(Cfg *Func, Operand *Data, Operand *Addr,
590 uint32_t align = 1) {
591 // TODO(kschimpf) Stop ignoring alignment specification.
592 (void)align;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700593 return new (Func->allocateInst<InstStore>()) InstStore(Func, Data, Addr);
594 }
595 Operand *getAddr() const { return getSrc(1); }
596 Operand *getData() const { return getSrc(0); }
597 virtual void dump(const Cfg *Func) const;
598 static bool classof(const Inst *Inst) { return Inst->getKind() == Store; }
599
600private:
601 InstStore(Cfg *Func, Operand *Data, Operand *Addr);
602 InstStore(const InstStore &) LLVM_DELETED_FUNCTION;
603 InstStore &operator=(const InstStore &) LLVM_DELETED_FUNCTION;
604 virtual ~InstStore() {}
605};
606
607// Switch instruction. The single source operand is captured as
608// getSrc(0).
609class InstSwitch : public Inst {
610public:
611 static InstSwitch *create(Cfg *Func, SizeT NumCases, Operand *Source,
612 CfgNode *LabelDefault) {
613 return new (Func->allocateInst<InstSwitch>())
614 InstSwitch(Func, NumCases, Source, LabelDefault);
615 }
616 Operand *getComparison() const { return getSrc(0); }
617 CfgNode *getLabelDefault() const { return LabelDefault; }
618 SizeT getNumCases() const { return NumCases; }
619 uint64_t getValue(SizeT I) const {
620 assert(I < NumCases);
621 return Values[I];
622 }
623 CfgNode *getLabel(SizeT I) const {
624 assert(I < NumCases);
625 return Labels[I];
626 }
627 void addBranch(SizeT CaseIndex, uint64_t Value, CfgNode *Label);
628 virtual NodeList getTerminatorEdges() const;
629 virtual void dump(const Cfg *Func) const;
630 static bool classof(const Inst *Inst) { return Inst->getKind() == Switch; }
631
632private:
633 InstSwitch(Cfg *Func, SizeT NumCases, Operand *Source, CfgNode *LabelDefault);
634 InstSwitch(const InstSwitch &) LLVM_DELETED_FUNCTION;
635 InstSwitch &operator=(const InstSwitch &) LLVM_DELETED_FUNCTION;
636 virtual void destroy(Cfg *Func) {
637 Func->deallocateArrayOf<uint64_t>(Values);
638 Func->deallocateArrayOf<CfgNode *>(Labels);
639 Inst::destroy(Func);
640 }
641 virtual ~InstSwitch() {}
642
643 CfgNode *LabelDefault;
644 SizeT NumCases; // not including the default case
645 uint64_t *Values; // size is NumCases
646 CfgNode **Labels; // size is NumCases
647};
648
649// Unreachable instruction. This is a terminator instruction with no
650// operands.
651class InstUnreachable : public Inst {
652public:
653 static InstUnreachable *create(Cfg *Func) {
654 return new (Func->allocateInst<InstUnreachable>()) InstUnreachable(Func);
655 }
656 virtual NodeList getTerminatorEdges() const { return NodeList(); }
657 virtual void dump(const Cfg *Func) const;
658 static bool classof(const Inst *Inst) {
659 return Inst->getKind() == Unreachable;
660 }
661
662private:
663 InstUnreachable(Cfg *Func);
664 InstUnreachable(const InstUnreachable &) LLVM_DELETED_FUNCTION;
665 InstUnreachable &operator=(const InstUnreachable &) LLVM_DELETED_FUNCTION;
666 virtual ~InstUnreachable() {}
667};
668
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700669// FakeDef instruction. This creates a fake definition of a variable,
670// which is how we represent the case when an instruction produces
671// multiple results. This doesn't happen with high-level ICE
672// instructions, but might with lowered instructions. For example,
673// this would be a way to represent condition flags being modified by
674// an instruction.
675//
676// It's generally useful to set the optional source operand to be the
677// dest variable of the instruction that actually produces the FakeDef
678// dest. Otherwise, the original instruction could be dead-code
679// eliminated if its dest operand is unused, and therefore the FakeDef
680// dest wouldn't be properly initialized.
681class InstFakeDef : public Inst {
682public:
683 static InstFakeDef *create(Cfg *Func, Variable *Dest, Variable *Src = NULL) {
684 return new (Func->allocateInst<InstFakeDef>()) InstFakeDef(Func, Dest, Src);
685 }
686 virtual void emit(const Cfg *Func) const;
687 virtual void dump(const Cfg *Func) const;
688 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeDef; }
689
690private:
691 InstFakeDef(Cfg *Func, Variable *Dest, Variable *Src);
692 InstFakeDef(const InstFakeDef &) LLVM_DELETED_FUNCTION;
693 InstFakeDef &operator=(const InstFakeDef &) LLVM_DELETED_FUNCTION;
694 virtual ~InstFakeDef() {}
695};
696
697// FakeUse instruction. This creates a fake use of a variable, to
698// keep the instruction that produces that variable from being
699// dead-code eliminated. This is useful in a variety of lowering
700// situations. The FakeUse instruction has no dest, so it can itself
701// never be dead-code eliminated.
702class InstFakeUse : public Inst {
703public:
704 static InstFakeUse *create(Cfg *Func, Variable *Src) {
705 return new (Func->allocateInst<InstFakeUse>()) InstFakeUse(Func, Src);
706 }
707 virtual void emit(const Cfg *Func) const;
708 virtual void dump(const Cfg *Func) const;
709 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeUse; }
710
711private:
712 InstFakeUse(Cfg *Func, Variable *Src);
713 InstFakeUse(const InstFakeUse &) LLVM_DELETED_FUNCTION;
714 InstFakeUse &operator=(const InstFakeUse &) LLVM_DELETED_FUNCTION;
715 virtual ~InstFakeUse() {}
716};
717
718// FakeKill instruction. This "kills" a set of variables by adding a
719// trivial live range at this instruction to each variable. The
720// primary use is to indicate that scratch registers are killed after
721// a call, so that the register allocator won't assign a scratch
722// register to a variable whose live range spans a call.
723//
724// The FakeKill instruction also holds a pointer to the instruction
725// that kills the set of variables, so that if that linked instruction
726// gets dead-code eliminated, the FakeKill instruction will as well.
727class InstFakeKill : public Inst {
728public:
729 static InstFakeKill *create(Cfg *Func, const VarList &KilledRegs,
730 const Inst *Linked) {
731 return new (Func->allocateInst<InstFakeKill>())
732 InstFakeKill(Func, KilledRegs, Linked);
733 }
734 const Inst *getLinked() const { return Linked; }
735 virtual void emit(const Cfg *Func) const;
736 virtual void dump(const Cfg *Func) const;
737 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeKill; }
738
739private:
740 InstFakeKill(Cfg *Func, const VarList &KilledRegs, const Inst *Linked);
741 InstFakeKill(const InstFakeKill &) LLVM_DELETED_FUNCTION;
742 InstFakeKill &operator=(const InstFakeKill &) LLVM_DELETED_FUNCTION;
743 virtual ~InstFakeKill() {}
744
745 // This instruction is ignored if Linked->isDeleted() is true.
746 const Inst *Linked;
747};
748
749// The Target instruction is the base class for all target-specific
750// instructions.
751class InstTarget : public Inst {
752public:
Jim Stichnoth18735602014-09-16 19:59:35 -0700753 virtual uint32_t getEmitInstCount() const { return 1; }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700754 virtual void emit(const Cfg *Func) const = 0;
755 virtual void dump(const Cfg *Func) const;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700756 virtual void dumpExtras(const Cfg *Func) const;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700757 static bool classof(const Inst *Inst) { return Inst->getKind() >= Target; }
758
759protected:
760 InstTarget(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest)
761 : Inst(Func, Kind, MaxSrcs, Dest) {
762 assert(Kind >= Target);
763 }
764 InstTarget(const InstTarget &) LLVM_DELETED_FUNCTION;
765 InstTarget &operator=(const InstTarget &) LLVM_DELETED_FUNCTION;
766 virtual ~InstTarget() {}
767};
768
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700769} // end of namespace Ice
770
771#endif // SUBZERO_SRC_ICEINST_H