OLD | NEW |
---|---|
(Empty) | |
1 //===- 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 "IceTypes.h" | |
21 | |
22 namespace Ice { | |
23 | |
24 class Inst { | |
25 public: | |
26 enum InstKind { | |
27 // Arbitrary (alphabetical) order, except put Unreachable first. | |
28 Unreachable, | |
29 Alloca, | |
30 Arithmetic, | |
31 Assign, // not part of LLVM/PNaCl bitcode | |
32 Br, | |
33 Call, | |
34 Cast, | |
35 Fcmp, | |
36 Icmp, | |
37 Load, | |
38 Phi, | |
39 Ret, | |
40 Select, | |
41 Store, | |
42 Switch | |
43 }; | |
44 InstKind getKind() const { return Kind; } | |
45 | |
46 int32_t getNumber() const { return Number; } | |
47 | |
48 bool isDeleted() const { return Deleted; } | |
49 void setDeleted() { Deleted = true; } | |
50 | |
51 bool hasSideEffects() const { return HasSideEffects; } | |
52 | |
53 Variable *getDest() const { return Dest; } | |
54 | |
55 IceSize_t getSrcSize() const { return NumSrcs; } | |
56 Operand *getSrc(IceSize_t I) const { | |
57 assert(I < getSrcSize()); | |
58 return Srcs[I]; | |
59 } | |
60 | |
61 // Returns a list of out-edges corresponding to a terminator | |
62 // instruction, which is the last instruction of the block. | |
63 virtual NodeList getTerminatorEdges() const { | |
64 // All valid terminator instructions override this method. For | |
65 // the default implementation, we assert in case some CfgNode | |
66 // is constructed without a terminator instruction at the end. | |
67 assert(0); | |
68 return NodeList(); | |
69 } | |
70 | |
71 // Updates the status of the Variables contained within the | |
72 // instruction. In particular, it marks where the Dest variable is | |
73 // first assigned, and it tracks whether variables are live across | |
74 // basic blocks, i.e. used in a different block from their definition. | |
75 void updateVars(CfgNode *Node); | |
76 | |
77 virtual void dump(const IceCfg *Cfg) const; | |
78 void dumpDecorated(const IceCfg *Cfg) const; | |
79 void dumpSources(const IceCfg *Cfg) const; | |
80 void dumpDest(const IceCfg *Cfg) const; | |
81 | |
82 virtual ~Inst(); | |
83 | |
84 protected: | |
85 Inst(IceCfg *Cfg, InstKind Kind, IceSize_t MaxSrcs, Variable *Dest); | |
86 void addSource(Operand *Src) { | |
87 assert(Src); | |
88 assert(NumSrcs < MaxSrcs); | |
89 Srcs[NumSrcs++] = Src; | |
90 } | |
91 | |
92 const InstKind Kind; | |
93 // Number is the instruction number for describing live ranges. | |
94 int32_t Number; | |
95 // Deleted means irrevocably deleted. | |
96 bool Deleted; | |
97 // HasSideEffects means the instruction is something like a function | |
98 // call or a volatile load that can't be removed even if its Dest | |
99 // variable is not live. | |
100 bool HasSideEffects; | |
101 | |
102 Variable *Dest; | |
103 const IceSize_t MaxSrcs; // only used for assert | |
104 IceSize_t NumSrcs; | |
105 Operand **Srcs; | |
106 | |
107 private: | |
108 Inst(const Inst &) LLVM_DELETED_FUNCTION; | |
109 Inst &operator=(const Inst &) LLVM_DELETED_FUNCTION; | |
110 }; | |
111 | |
112 // Alloca instruction. This captures the size in bytes as getSrc(0), | |
113 // and the alignment. | |
114 class InstAlloca : public Inst { | |
115 public: | |
116 static InstAlloca *create(IceCfg *Cfg, Operand *ByteCount, uint32_t Align, | |
117 Variable *Dest) { | |
118 return new (Cfg->allocateInst<InstAlloca>()) | |
119 InstAlloca(Cfg, ByteCount, Align, Dest); | |
120 } | |
121 uint32_t getAlign() const { return Align; } | |
122 Operand *getSizeInBytes() const { return getSrc(0); } | |
123 virtual void dump(const IceCfg *Cfg) const; | |
124 static bool classof(const Inst *Inst) { return Inst->getKind() == Alloca; } | |
125 | |
126 private: | |
127 InstAlloca(IceCfg *Cfg, Operand *ByteCount, uint32_t Align, Variable *Dest); | |
128 InstAlloca(const InstAlloca &) LLVM_DELETED_FUNCTION; | |
129 InstAlloca &operator=(const InstAlloca &) LLVM_DELETED_FUNCTION; | |
130 virtual ~InstAlloca() {} | |
131 const uint32_t Align; | |
132 }; | |
133 | |
134 #define ICEINSTARITHMETIC_TABLE \ | |
135 /* enum value, printable string, commutative */ \ | |
136 X(Add, "add", true) X(Fadd, "fadd", false) X(Sub, "sub", false) \ | |
137 X(Fsub, "fsub", false) X(Mul, "mul", true) X(Fmul, "fmul", false) \ | |
138 X(Udiv, "udiv", false) X(Sdiv, "sdiv", false) X(Fdiv, "fdiv", false) \ | |
139 X(Urem, "urem", false) X(Srem, "srem", false) X(Frem, "frem", false) \ | |
140 X(Shl, "shl", false) X(Lshr, "lshr", false) X(Ashr, "ashr", false) \ | |
141 X(And, "and", true) X(Or, "or", true) X(Xor, "xor", true) | |
JF
2014/04/23 03:51:28
Yeah, un-clang-formatting this would be nice.
Jim Stichnoth
2014/04/26 15:02:11
Done.
| |
142 | |
143 // Binary arithmetic instruction. The source operands are captured in | |
144 // getSrc(0) and getSrc(1). | |
145 class InstArithmetic : public Inst { | |
146 public: | |
147 #define X(tag, str, commutative) tag, | |
148 | |
149 enum OpKind { | |
150 ICEINSTARITHMETIC_TABLE | |
151 }; | |
152 #undef X | |
153 static InstArithmetic *create(IceCfg *Cfg, OpKind Op, Variable *Dest, | |
154 Operand *Source1, Operand *Source2) { | |
155 return new (Cfg->allocateInst<InstArithmetic>()) | |
156 InstArithmetic(Cfg, Op, Dest, Source1, Source2); | |
157 } | |
158 OpKind getOp() const { return Op; } | |
159 bool isCommutative() const; | |
160 virtual void dump(const IceCfg *Cfg) const; | |
161 static bool classof(const Inst *Inst) { | |
162 return Inst->getKind() == Arithmetic; | |
163 } | |
164 | |
165 private: | |
166 InstArithmetic(IceCfg *Cfg, OpKind Op, Variable *Dest, Operand *Source1, | |
167 Operand *Source2); | |
168 InstArithmetic(const InstArithmetic &) LLVM_DELETED_FUNCTION; | |
169 InstArithmetic &operator=(const InstArithmetic &) LLVM_DELETED_FUNCTION; | |
170 virtual ~InstArithmetic() {} | |
171 | |
172 const OpKind Op; | |
173 }; | |
174 | |
175 // Assignment instruction. The source operand is captured in | |
176 // getSrc(0). This is not part of the LLVM bitcode, but is a useful | |
177 // abstraction for some of the lowering. E.g., if Phi instruction | |
178 // lowering happens before target lowering, or for representing an | |
179 // Inttoptr instruction, or as an intermediate step for lowering a | |
180 // Load instruction. | |
181 class InstAssign : public Inst { | |
182 public: | |
183 static InstAssign *create(IceCfg *Cfg, Variable *Dest, Operand *Source) { | |
184 return new (Cfg->allocateInst<InstAssign>()) InstAssign(Cfg, Dest, Source); | |
185 } | |
186 virtual void dump(const IceCfg *Cfg) const; | |
187 static bool classof(const Inst *Inst) { return Inst->getKind() == Assign; } | |
188 | |
189 private: | |
190 InstAssign(IceCfg *Cfg, Variable *Dest, Operand *Source); | |
191 InstAssign(const InstAssign &) LLVM_DELETED_FUNCTION; | |
192 InstAssign &operator=(const InstAssign &) LLVM_DELETED_FUNCTION; | |
193 virtual ~InstAssign() {} | |
194 }; | |
195 | |
196 // Branch instruction. This represents both conditional and | |
197 // unconditional branches. | |
198 class InstBr : public Inst { | |
199 public: | |
200 // Create a conditional branch. If TargetTrue==TargetFalse, it is | |
201 // optimized to an unconditional branch. | |
202 static InstBr *create(IceCfg *Cfg, Operand *Source, CfgNode *TargetTrue, | |
203 CfgNode *TargetFalse) { | |
204 return new (Cfg->allocateInst<InstBr>()) | |
205 InstBr(Cfg, Source, TargetTrue, TargetFalse); | |
206 } | |
207 // Create an unconditional branch. | |
208 static InstBr *create(IceCfg *Cfg, CfgNode *Target) { | |
209 return new (Cfg->allocateInst<InstBr>()) InstBr(Cfg, Target); | |
210 } | |
211 bool isUnconditional() const { return getTargetTrue() == NULL; } | |
212 Operand *getCondition() const { | |
213 assert(!isUnconditional()); | |
214 return getSrc(0); | |
215 } | |
216 CfgNode *getTargetTrue() const { return TargetTrue; } | |
217 CfgNode *getTargetFalse() const { return TargetFalse; } | |
218 CfgNode *getTargetUnconditional() const { | |
219 assert(isUnconditional()); | |
220 return getTargetFalse(); | |
221 } | |
222 virtual NodeList getTerminatorEdges() const; | |
223 virtual void dump(const IceCfg *Cfg) const; | |
224 static bool classof(const Inst *Inst) { return Inst->getKind() == Br; } | |
225 | |
226 private: | |
227 // Conditional branch | |
228 InstBr(IceCfg *Cfg, Operand *Source, CfgNode *TargetTrue, | |
229 CfgNode *TargetFalse); | |
230 // Unconditional branch | |
231 InstBr(IceCfg *Cfg, CfgNode *Target); | |
232 InstBr(const InstBr &) LLVM_DELETED_FUNCTION; | |
233 InstBr &operator=(const InstBr &) LLVM_DELETED_FUNCTION; | |
234 virtual ~InstBr() {} | |
235 | |
236 CfgNode *const TargetFalse; // Doubles as unconditional branch target | |
237 CfgNode *const TargetTrue; // NULL if unconditional branch | |
238 }; | |
239 | |
240 // Call instruction. The call target is captured as getSrc(0), and | |
241 // arg I is captured as getSrc(I+1). | |
242 class InstCall : public Inst { | |
243 public: | |
244 // The Tail argument represents the "tail" marker from the original | |
245 // bitcode instruction (which doesn't necessarily mean that this | |
246 // call must be executed as a tail call). | |
JF
2014/04/23 03:51:28
What does it mean?
Jim Stichnoth
2014/04/26 15:02:11
Per offline discussion - since the tail marker isn
| |
247 static InstCall *create(IceCfg *Cfg, IceSize_t NumArgs, Variable *Dest, | |
248 Operand *CallTarget, bool Tail) { | |
249 return new (Cfg->allocateInst<InstCall>()) | |
250 InstCall(Cfg, NumArgs, Dest, CallTarget, Tail); | |
251 } | |
252 void addArg(Operand *Arg) { addSource(Arg); } | |
253 Operand *getCallTarget() const { return getSrc(0); } | |
254 Operand *getArg(IceSize_t I) const { return getSrc(I + 1); } | |
255 IceSize_t getNumArgs() const { return getSrcSize() - 1; } | |
256 bool isTail() const { return Tail; } | |
257 virtual void dump(const IceCfg *Cfg) const; | |
258 static bool classof(const Inst *Inst) { return Inst->getKind() == Call; } | |
259 | |
260 private: | |
261 InstCall(IceCfg *Cfg, IceSize_t NumArgs, Variable *Dest, Operand *CallTarget, | |
262 bool Tail) | |
263 : Inst(Cfg, Inst::Call, NumArgs + 1, Dest), Tail(Tail) { | |
264 // Set HasSideEffects so that the call instruction can't be | |
265 // dead-code eliminated. Don't set this for a deletable intrinsic | |
266 // call. | |
267 HasSideEffects = true; | |
268 addSource(CallTarget); | |
269 } | |
270 InstCall(const InstCall &) LLVM_DELETED_FUNCTION; | |
271 InstCall &operator=(const InstCall &) LLVM_DELETED_FUNCTION; | |
272 virtual ~InstCall() {} | |
273 const bool Tail; | |
274 }; | |
275 | |
276 #define ICEINSTCAST_TABLE \ | |
277 /* enum value, printable string */ \ | |
278 X(Trunc, "trunc") X(Zext, "zext") X(Sext, "sext") X(Fptrunc, "fptrunc") \ | |
279 X(Fpext, "fpext") X(Fptoui, "fptoui") X(Fptosi, "fptosi") \ | |
280 X(Uitofp, "uitofp") X(Sitofp, "sitofp") X(Bitcast, "bitcast") | |
JF
2014/04/23 03:51:28
clang-un-format
Jim Stichnoth
2014/04/26 15:02:11
Done.
| |
281 | |
282 // Cast instruction (a.k.a. conversion operation). | |
283 class InstCast : public Inst { | |
284 public: | |
285 #define X(tag, str) tag, | |
286 | |
287 enum OpKind { | |
288 ICEINSTCAST_TABLE | |
289 }; | |
290 #undef X | |
291 static InstCast *create(IceCfg *Cfg, OpKind CastKind, Variable *Dest, | |
292 Operand *Source) { | |
293 return new (Cfg->allocateInst<InstCast>()) | |
294 InstCast(Cfg, CastKind, Dest, Source); | |
295 } | |
296 OpKind getCastKind() const { return CastKind; } | |
297 virtual void dump(const IceCfg *Cfg) const; | |
298 static bool classof(const Inst *Inst) { return Inst->getKind() == Cast; } | |
299 | |
300 private: | |
301 InstCast(IceCfg *Cfg, OpKind CastKind, Variable *Dest, Operand *Source); | |
302 InstCast(const InstCast &) LLVM_DELETED_FUNCTION; | |
303 InstCast &operator=(const InstCast &) LLVM_DELETED_FUNCTION; | |
304 virtual ~InstCast() {} | |
305 const OpKind CastKind; | |
306 }; | |
307 | |
308 #define ICEINSTFCMP_TABLE \ | |
309 /* enum value, printable string */ \ | |
310 X(False, "false") X(Oeq, "oeq") X(Ogt, "ogt") X(Oge, "oge") X(Olt, "olt") \ | |
311 X(Ole, "ole") X(One, "one") X(Ord, "ord") X(Ueq, "ueq") X(Ugt, "ugt") \ | |
312 X(Uge, "uge") X(Ult, "ult") X(Ule, "ule") X(Une, "une") X(Uno, "uno") \ | |
313 X(True, "true") | |
JF
2014/04/23 03:51:28
clang-un-format
Jim Stichnoth
2014/04/26 15:02:11
Done.
| |
314 | |
315 // Floating-point comparison instruction. The source operands are | |
316 // captured in getSrc(0) and getSrc(1). | |
317 class InstFcmp : public Inst { | |
318 public: | |
319 #define X(tag, str) tag, | |
320 | |
321 enum FCond { | |
322 ICEINSTFCMP_TABLE | |
323 }; | |
324 #undef X | |
325 static InstFcmp *create(IceCfg *Cfg, FCond Condition, Variable *Dest, | |
326 Operand *Source1, Operand *Source2) { | |
327 return new (Cfg->allocateInst<InstFcmp>()) | |
328 InstFcmp(Cfg, Condition, Dest, Source1, Source2); | |
329 } | |
330 FCond getCondition() const { return Condition; } | |
331 virtual void dump(const IceCfg *Cfg) const; | |
332 static bool classof(const Inst *Inst) { return Inst->getKind() == Fcmp; } | |
333 | |
334 private: | |
335 InstFcmp(IceCfg *Cfg, FCond Condition, Variable *Dest, Operand *Source1, | |
336 Operand *Source2); | |
337 InstFcmp(const InstFcmp &) LLVM_DELETED_FUNCTION; | |
338 InstFcmp &operator=(const InstFcmp &) LLVM_DELETED_FUNCTION; | |
339 virtual ~InstFcmp() {} | |
340 const FCond Condition; | |
341 }; | |
342 | |
343 #define ICEINSTICMP_TABLE \ | |
344 /* enum value, printable string */ \ | |
345 X(Eq, "eq") X(Ne, "ne") X(Ugt, "ugt") X(Uge, "uge") X(Ult, "ult") \ | |
346 X(Ule, "ule") X(Sgt, "sgt") X(Sge, "sge") X(Slt, "slt") X(Sle, "sle") | |
JF
2014/04/23 03:51:28
clang-un-format
Jim Stichnoth
2014/04/26 15:02:11
Done.
| |
347 | |
348 // Integer comparison instruction. The source operands are captured | |
349 // in getSrc(0) and getSrc(1). | |
350 class InstIcmp : public Inst { | |
351 public: | |
352 #define X(tag, str) tag, | |
353 | |
354 enum ICond { | |
355 ICEINSTICMP_TABLE | |
356 }; | |
357 #undef X | |
358 static InstIcmp *create(IceCfg *Cfg, ICond Condition, Variable *Dest, | |
359 Operand *Source1, Operand *Source2) { | |
360 return new (Cfg->allocateInst<InstIcmp>()) | |
361 InstIcmp(Cfg, Condition, Dest, Source1, Source2); | |
362 } | |
363 ICond getCondition() const { return Condition; } | |
364 virtual void dump(const IceCfg *Cfg) const; | |
365 static bool classof(const Inst *Inst) { return Inst->getKind() == Icmp; } | |
366 | |
367 private: | |
368 InstIcmp(IceCfg *Cfg, ICond Condition, Variable *Dest, Operand *Source1, | |
369 Operand *Source2); | |
370 InstIcmp(const InstIcmp &) LLVM_DELETED_FUNCTION; | |
371 InstIcmp &operator=(const InstIcmp &) LLVM_DELETED_FUNCTION; | |
372 virtual ~InstIcmp() {} | |
373 const ICond Condition; | |
374 }; | |
375 | |
376 // Load instruction. The source address is captured in getSrc(0). | |
377 class InstLoad : public Inst { | |
378 public: | |
379 static InstLoad *create(IceCfg *Cfg, Variable *Dest, Operand *SourceAddr) { | |
380 return new (Cfg->allocateInst<InstLoad>()) InstLoad(Cfg, Dest, SourceAddr); | |
381 } | |
382 Operand *getSourceAddress() const { return getSrc(0); } | |
383 virtual void dump(const IceCfg *Cfg) const; | |
384 static bool classof(const Inst *Inst) { return Inst->getKind() == Load; } | |
385 | |
386 private: | |
387 InstLoad(IceCfg *Cfg, Variable *Dest, Operand *SourceAddr); | |
388 InstLoad(const InstLoad &) LLVM_DELETED_FUNCTION; | |
389 InstLoad &operator=(const InstLoad &) LLVM_DELETED_FUNCTION; | |
390 virtual ~InstLoad() {} | |
391 }; | |
392 | |
393 // Phi instruction. For incoming edge I, the node is Labels[I] and | |
394 // the Phi source operand is getSrc(I). | |
395 class InstPhi : public Inst { | |
396 public: | |
397 static InstPhi *create(IceCfg *Cfg, IceSize_t MaxSrcs, Variable *Dest) { | |
398 return new (Cfg->allocateInst<InstPhi>()) InstPhi(Cfg, MaxSrcs, Dest); | |
399 } | |
400 void addArgument(Operand *Source, CfgNode *Label); | |
401 virtual void dump(const IceCfg *Cfg) const; | |
402 static bool classof(const Inst *Inst) { return Inst->getKind() == Phi; } | |
403 | |
404 private: | |
405 InstPhi(IceCfg *Cfg, IceSize_t MaxSrcs, Variable *Dest); | |
406 InstPhi(const InstPhi &) LLVM_DELETED_FUNCTION; | |
407 InstPhi &operator=(const InstPhi &) LLVM_DELETED_FUNCTION; | |
408 virtual ~InstPhi() { | |
409 #ifdef ICE_NO_ARENAS | |
410 delete[] Labels; | |
JF
2014/04/23 03:51:28
Call you call Cfg->deleteInst. That allows you to
Jim Stichnoth
2014/04/26 15:02:11
Done.
| |
411 #endif // ICE_NO_ARENAS | |
412 } | |
413 | |
414 // Labels[] duplicates the InEdges[] information in the enclosing | |
415 // CfgNode, but the Phi instruction is created before InEdges[] | |
416 // is available, so it's more complicated to share the list. | |
417 CfgNode **Labels; | |
418 }; | |
419 | |
420 // Ret instruction. The return value is captured in getSrc(0), but if | |
421 // there is no return value (void-type function), then | |
422 // getSrcSize()==0 and hasRetValue()==false. | |
423 class InstRet : public Inst { | |
424 public: | |
425 static InstRet *create(IceCfg *Cfg, Operand *RetValue = NULL) { | |
426 return new (Cfg->allocateInst<InstRet>()) InstRet(Cfg, RetValue); | |
427 } | |
428 bool hasRetValue() const { return getSrcSize(); } | |
429 Operand *getRetValue() const { | |
430 assert(hasRetValue()); | |
431 return getSrc(0); | |
432 } | |
433 virtual NodeList getTerminatorEdges() const { return NodeList(); } | |
434 virtual void dump(const IceCfg *Cfg) const; | |
435 static bool classof(const Inst *Inst) { return Inst->getKind() == Ret; } | |
436 | |
437 private: | |
438 InstRet(IceCfg *Cfg, Operand *RetValue); | |
439 InstRet(const InstRet &) LLVM_DELETED_FUNCTION; | |
440 InstRet &operator=(const InstRet &) LLVM_DELETED_FUNCTION; | |
441 virtual ~InstRet() {} | |
442 }; | |
443 | |
444 // Select instruction. The condition, true, and false operands are captured. | |
445 class InstSelect : public Inst { | |
446 public: | |
447 static InstSelect *create(IceCfg *Cfg, Variable *Dest, Operand *Condition, | |
448 Operand *SourceTrue, Operand *SourceFalse) { | |
449 return new (Cfg->allocateInst<InstSelect>()) | |
450 InstSelect(Cfg, Dest, Condition, SourceTrue, SourceFalse); | |
451 } | |
452 Operand *getCondition() const { return getSrc(0); } | |
453 Operand *getTrueOperand() const { return getSrc(1); } | |
454 Operand *getFalseOperand() const { return getSrc(2); } | |
455 virtual void dump(const IceCfg *Cfg) const; | |
456 static bool classof(const Inst *Inst) { return Inst->getKind() == Select; } | |
457 | |
458 private: | |
459 InstSelect(IceCfg *Cfg, Variable *Dest, Operand *Condition, Operand *Source1, | |
460 Operand *Source2); | |
461 InstSelect(const InstSelect &) LLVM_DELETED_FUNCTION; | |
462 InstSelect &operator=(const InstSelect &) LLVM_DELETED_FUNCTION; | |
463 virtual ~InstSelect() {} | |
464 }; | |
465 | |
466 // Store instruction. The address operand is captured, along with the | |
467 // data operand to be stored into the address. | |
468 class InstStore : public Inst { | |
469 public: | |
470 static InstStore *create(IceCfg *Cfg, Operand *Data, Operand *Addr) { | |
471 return new (Cfg->allocateInst<InstStore>()) InstStore(Cfg, Data, Addr); | |
472 } | |
473 Operand *getAddr() const { return getSrc(1); } | |
474 Operand *getData() const { return getSrc(0); } | |
475 virtual void dump(const IceCfg *Cfg) const; | |
476 static bool classof(const Inst *Inst) { return Inst->getKind() == Store; } | |
477 | |
478 private: | |
479 InstStore(IceCfg *Cfg, Operand *Data, Operand *Addr); | |
480 InstStore(const InstStore &) LLVM_DELETED_FUNCTION; | |
481 InstStore &operator=(const InstStore &) LLVM_DELETED_FUNCTION; | |
482 virtual ~InstStore() {} | |
483 }; | |
484 | |
485 // Switch instruction. The single source operand is captured as | |
486 // getSrc(0). | |
487 class InstSwitch : public Inst { | |
488 public: | |
489 static InstSwitch *create(IceCfg *Cfg, IceSize_t NumCases, Operand *Source, | |
490 CfgNode *LabelDefault) { | |
491 return new (Cfg->allocateInst<InstSwitch>()) | |
492 InstSwitch(Cfg, NumCases, Source, LabelDefault); | |
493 } | |
494 Operand *getComparison() const { return getSrc(0); } | |
495 CfgNode *getLabelDefault() const { return LabelDefault; } | |
496 IceSize_t getNumCases() const { return NumCases; } | |
497 uint64_t getValue(IceSize_t I) const { | |
498 assert(I < NumCases); | |
499 return Values[I]; | |
500 } | |
501 CfgNode *getLabel(IceSize_t I) const { | |
502 assert(I < NumCases); | |
503 return Labels[I]; | |
504 } | |
505 void addBranch(IceSize_t CaseIndex, uint64_t Value, CfgNode *Label); | |
506 virtual NodeList getTerminatorEdges() const; | |
507 virtual void dump(const IceCfg *Cfg) const; | |
508 static bool classof(const Inst *Inst) { return Inst->getKind() == Switch; } | |
509 | |
510 private: | |
511 InstSwitch(IceCfg *Cfg, IceSize_t NumCases, Operand *Source, | |
512 CfgNode *LabelDefault); | |
513 InstSwitch(const InstSwitch &) LLVM_DELETED_FUNCTION; | |
514 InstSwitch &operator=(const InstSwitch &) LLVM_DELETED_FUNCTION; | |
515 virtual ~InstSwitch() { | |
516 #ifdef ICE_NO_ARENAS | |
517 delete[] Values; | |
518 delete[] Labels; | |
JF
2014/04/23 03:51:28
Same on delete.
Jim Stichnoth
2014/04/26 15:02:11
Done.
| |
519 #endif // ICE_NO_ARENAS | |
520 } | |
521 | |
522 CfgNode *LabelDefault; | |
523 IceSize_t NumCases; // not including the default case | |
524 uint64_t *Values; // size is NumCases | |
525 CfgNode **Labels; // size is NumCases | |
526 }; | |
527 | |
528 // Unreachable instruction. This is a terminator instruction with no | |
529 // operands. | |
530 class InstUnreachable : public Inst { | |
531 public: | |
532 static InstUnreachable *create(IceCfg *Cfg) { | |
533 return new (Cfg->allocateInst<InstUnreachable>()) InstUnreachable(Cfg); | |
534 } | |
535 virtual NodeList getTerminatorEdges() const { return NodeList(); } | |
536 virtual void dump(const IceCfg *Cfg) const; | |
537 static bool classof(const Inst *Inst) { | |
538 return Inst->getKind() == Unreachable; | |
539 } | |
540 | |
541 private: | |
542 InstUnreachable(IceCfg *Cfg); | |
543 InstUnreachable(const InstUnreachable &) LLVM_DELETED_FUNCTION; | |
544 InstUnreachable &operator=(const InstUnreachable &) LLVM_DELETED_FUNCTION; | |
545 virtual ~InstUnreachable() {} | |
546 }; | |
547 | |
548 } // end of namespace Ice | |
549 | |
550 #endif // SUBZERO_SRC_ICEINST_H | |
OLD | NEW |