OLD | NEW |
---|---|
1 //===- subzero/src/IceInst.h - High-level instructions ----------*- C++ -*-===// | 1 //===- subzero/src/IceInst.h - High-level instructions ----------*- C++ -*-===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file declares the Inst class and its target-independent | 10 // This file declares the Inst class and its target-independent |
11 // subclasses, which represent the high-level Vanilla ICE instructions | 11 // subclasses, which represent the high-level Vanilla ICE instructions |
12 // and map roughly 1:1 to LLVM instructions. | 12 // and map roughly 1:1 to LLVM instructions. |
13 // | 13 // |
14 //===----------------------------------------------------------------------===// | 14 //===----------------------------------------------------------------------===// |
15 | 15 |
16 #ifndef SUBZERO_SRC_ICEINST_H | 16 #ifndef SUBZERO_SRC_ICEINST_H |
17 #define SUBZERO_SRC_ICEINST_H | 17 #define SUBZERO_SRC_ICEINST_H |
18 | 18 |
19 #include "IceDefs.h" | 19 #include "IceDefs.h" |
20 #include "IceInst.def" | 20 #include "IceInst.def" |
21 #include "IceIntrinsics.h" | |
21 #include "IceTypes.h" | 22 #include "IceTypes.h" |
22 | 23 |
23 // TODO: The Cfg structure, and instructions in particular, need to be | 24 // TODO: The Cfg structure, and instructions in particular, need to be |
24 // validated for things like valid operand types, valid branch | 25 // validated for things like valid operand types, valid branch |
25 // targets, proper ordering of Phi and non-Phi instructions, etc. | 26 // targets, proper ordering of Phi and non-Phi instructions, etc. |
26 // Most of the validity checking will be done in the bitcode reader. | 27 // Most of the validity checking will be done in the bitcode reader. |
27 // We need a list of everything that should be validated, and tests | 28 // We need a list of everything that should be validated, and tests |
28 // for each. | 29 // for each. |
29 | 30 |
30 namespace Ice { | 31 namespace Ice { |
31 | 32 |
32 class Inst { | 33 class Inst { |
33 public: | 34 public: |
34 enum InstKind { | 35 enum InstKind { |
35 // Arbitrary (alphabetical) order, except put Unreachable first. | 36 // Arbitrary (alphabetical) order, except put Unreachable first. |
36 Unreachable, | 37 Unreachable, |
37 Alloca, | 38 Alloca, |
38 Arithmetic, | 39 Arithmetic, |
39 Assign, // not part of LLVM/PNaCl bitcode | 40 Assign, // not part of LLVM/PNaCl bitcode |
40 Br, | 41 Br, |
41 Call, | 42 Call, |
42 Cast, | 43 Cast, |
43 Fcmp, | 44 Fcmp, |
44 Icmp, | 45 Icmp, |
46 IntrinsicCall, | |
45 Load, | 47 Load, |
46 Phi, | 48 Phi, |
47 Ret, | 49 Ret, |
48 Select, | 50 Select, |
49 Store, | 51 Store, |
50 Switch, | 52 Switch, |
51 FakeDef, // not part of LLVM/PNaCl bitcode | 53 FakeDef, // not part of LLVM/PNaCl bitcode |
52 FakeUse, // not part of LLVM/PNaCl bitcode | 54 FakeUse, // not part of LLVM/PNaCl bitcode |
53 FakeKill, // not part of LLVM/PNaCl bitcode | 55 FakeKill, // not part of LLVM/PNaCl bitcode |
54 Target // target-specific low-level ICE | 56 Target // target-specific low-level ICE |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
279 CfgNode *const TargetFalse; // Doubles as unconditional branch target | 281 CfgNode *const TargetFalse; // Doubles as unconditional branch target |
280 CfgNode *const TargetTrue; // NULL if unconditional branch | 282 CfgNode *const TargetTrue; // NULL if unconditional branch |
281 }; | 283 }; |
282 | 284 |
283 // Call instruction. The call target is captured as getSrc(0), and | 285 // Call instruction. The call target is captured as getSrc(0), and |
284 // arg I is captured as getSrc(I+1). | 286 // arg I is captured as getSrc(I+1). |
285 class InstCall : public Inst { | 287 class InstCall : public Inst { |
286 public: | 288 public: |
287 static InstCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest, | 289 static InstCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest, |
288 Operand *CallTarget) { | 290 Operand *CallTarget) { |
291 // 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. | |
289 return new (Func->allocateInst<InstCall>()) | 294 return new (Func->allocateInst<InstCall>()) |
290 InstCall(Func, NumArgs, Dest, CallTarget); | 295 InstCall(Func, NumArgs, Dest, CallTarget, true, Inst::Call); |
Jim Stichnoth
2014/06/12 20:52:07
I don't know if I've been 100% consistent with thi
jvoung (off chromium)
2014/06/16 20:51:59
Yep that's more readable -- Done.
| |
291 } | 296 } |
292 void addArg(Operand *Arg) { addSource(Arg); } | 297 void addArg(Operand *Arg) { addSource(Arg); } |
293 Operand *getCallTarget() const { return getSrc(0); } | 298 Operand *getCallTarget() const { return getSrc(0); } |
294 Operand *getArg(SizeT I) const { return getSrc(I + 1); } | 299 Operand *getArg(SizeT I) const { return getSrc(I + 1); } |
295 SizeT getNumArgs() const { return getSrcSize() - 1; } | 300 SizeT getNumArgs() const { return getSrcSize() - 1; } |
296 virtual void dump(const Cfg *Func) const; | 301 virtual void dump(const Cfg *Func) const; |
297 static bool classof(const Inst *Inst) { return Inst->getKind() == Call; } | 302 static bool classof(const Inst *Inst) { return Inst->getKind() == Call; } |
298 | 303 |
299 private: | 304 protected: |
300 InstCall(Cfg *Func, SizeT NumArgs, Variable *Dest, Operand *CallTarget) | 305 InstCall(Cfg *Func, SizeT NumArgs, Variable *Dest, Operand *CallTarget, |
301 : Inst(Func, Inst::Call, NumArgs + 1, Dest) { | 306 bool HasSideEff, InstKind Kind) |
302 // Set HasSideEffects so that the call instruction can't be | 307 : Inst(Func, Kind, NumArgs + 1, Dest) { |
303 // dead-code eliminated. Don't set this for a deletable intrinsic | 308 HasSideEffects = HasSideEff; |
304 // call. | |
305 HasSideEffects = true; | |
306 addSource(CallTarget); | 309 addSource(CallTarget); |
307 } | 310 } |
311 virtual ~InstCall() {} | |
312 | |
313 private: | |
308 InstCall(const InstCall &) LLVM_DELETED_FUNCTION; | 314 InstCall(const InstCall &) LLVM_DELETED_FUNCTION; |
309 InstCall &operator=(const InstCall &) LLVM_DELETED_FUNCTION; | 315 InstCall &operator=(const InstCall &) LLVM_DELETED_FUNCTION; |
310 virtual ~InstCall() {} | |
311 }; | 316 }; |
312 | 317 |
313 // Cast instruction (a.k.a. conversion operation). | 318 // Cast instruction (a.k.a. conversion operation). |
314 class InstCast : public Inst { | 319 class InstCast : public Inst { |
315 public: | 320 public: |
316 enum OpKind { | 321 enum OpKind { |
317 #define X(tag, str) tag, | 322 #define X(tag, str) tag, |
318 ICEINSTCAST_TABLE | 323 ICEINSTCAST_TABLE |
319 #undef X | 324 #undef X |
320 _num | 325 _num |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
388 | 393 |
389 private: | 394 private: |
390 InstIcmp(Cfg *Func, ICond Condition, Variable *Dest, Operand *Source1, | 395 InstIcmp(Cfg *Func, ICond Condition, Variable *Dest, Operand *Source1, |
391 Operand *Source2); | 396 Operand *Source2); |
392 InstIcmp(const InstIcmp &) LLVM_DELETED_FUNCTION; | 397 InstIcmp(const InstIcmp &) LLVM_DELETED_FUNCTION; |
393 InstIcmp &operator=(const InstIcmp &) LLVM_DELETED_FUNCTION; | 398 InstIcmp &operator=(const InstIcmp &) LLVM_DELETED_FUNCTION; |
394 virtual ~InstIcmp() {} | 399 virtual ~InstIcmp() {} |
395 const ICond Condition; | 400 const ICond Condition; |
396 }; | 401 }; |
397 | 402 |
403 // Call to an intrinsic function. The call target is captured as getSrc(0), | |
404 // and arg I is captured as getSrc(I+1). | |
405 class InstIntrinsicCall : public InstCall { | |
406 public: | |
407 static InstIntrinsicCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest, | |
408 Operand *CallTarget, | |
409 const IntrinsicInfo &Info) { | |
410 return new (Func->allocateInst<InstIntrinsicCall>()) | |
411 InstIntrinsicCall(Func, NumArgs, Dest, CallTarget, Info); | |
412 } | |
413 static bool classof(const Inst *Inst) { | |
414 return Inst->getKind() == IntrinsicCall; | |
415 } | |
416 | |
417 IntrinsicInfo getIntrinsicInfo() const { return Info; } | |
418 private: | |
419 InstIntrinsicCall(Cfg *Func, SizeT NumArgs, Variable *Dest, | |
420 Operand *CallTarget, const IntrinsicInfo &Info) | |
421 : InstCall(Func, NumArgs, Dest, CallTarget, | |
422 Info.HasSideEffects, Inst::IntrinsicCall), | |
423 Info(Info) {} | |
424 InstIntrinsicCall(const InstIntrinsicCall &) LLVM_DELETED_FUNCTION; | |
425 InstIntrinsicCall &operator=(const InstIntrinsicCall &) LLVM_DELETED_FUNCTION; | |
426 virtual ~InstIntrinsicCall() {} | |
427 const IntrinsicInfo Info; | |
428 }; | |
429 | |
398 // Load instruction. The source address is captured in getSrc(0). | 430 // Load instruction. The source address is captured in getSrc(0). |
399 class InstLoad : public Inst { | 431 class InstLoad : public Inst { |
400 public: | 432 public: |
401 static InstLoad *create(Cfg *Func, Variable *Dest, Operand *SourceAddr) { | 433 static InstLoad *create(Cfg *Func, Variable *Dest, Operand *SourceAddr) { |
402 return new (Func->allocateInst<InstLoad>()) | 434 return new (Func->allocateInst<InstLoad>()) |
403 InstLoad(Func, Dest, SourceAddr); | 435 InstLoad(Func, Dest, SourceAddr); |
404 } | 436 } |
405 Operand *getSourceAddress() const { return getSrc(0); } | 437 Operand *getSourceAddress() const { return getSrc(0); } |
406 virtual void dump(const Cfg *Func) const; | 438 virtual void dump(const Cfg *Func) const; |
407 static bool classof(const Inst *Inst) { return Inst->getKind() == Load; } | 439 static bool classof(const Inst *Inst) { return Inst->getKind() == Load; } |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
666 assert(Kind >= Target); | 698 assert(Kind >= Target); |
667 } | 699 } |
668 InstTarget(const InstTarget &) LLVM_DELETED_FUNCTION; | 700 InstTarget(const InstTarget &) LLVM_DELETED_FUNCTION; |
669 InstTarget &operator=(const InstTarget &) LLVM_DELETED_FUNCTION; | 701 InstTarget &operator=(const InstTarget &) LLVM_DELETED_FUNCTION; |
670 virtual ~InstTarget() {} | 702 virtual ~InstTarget() {} |
671 }; | 703 }; |
672 | 704 |
673 } // end of namespace Ice | 705 } // end of namespace Ice |
674 | 706 |
675 #endif // SUBZERO_SRC_ICEINST_H | 707 #endif // SUBZERO_SRC_ICEINST_H |
OLD | NEW |