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. |
| 294 const bool HasSideEffects = true; |
| 295 const InstKind Kind = Inst::Call; |
289 return new (Func->allocateInst<InstCall>()) | 296 return new (Func->allocateInst<InstCall>()) |
290 InstCall(Func, NumArgs, Dest, CallTarget); | 297 InstCall(Func, NumArgs, Dest, CallTarget, HasSideEffects, Kind); |
291 } | 298 } |
292 void addArg(Operand *Arg) { addSource(Arg); } | 299 void addArg(Operand *Arg) { addSource(Arg); } |
293 Operand *getCallTarget() const { return getSrc(0); } | 300 Operand *getCallTarget() const { return getSrc(0); } |
294 Operand *getArg(SizeT I) const { return getSrc(I + 1); } | 301 Operand *getArg(SizeT I) const { return getSrc(I + 1); } |
295 SizeT getNumArgs() const { return getSrcSize() - 1; } | 302 SizeT getNumArgs() const { return getSrcSize() - 1; } |
296 virtual void dump(const Cfg *Func) const; | 303 virtual void dump(const Cfg *Func) const; |
297 static bool classof(const Inst *Inst) { return Inst->getKind() == Call; } | 304 static bool classof(const Inst *Inst) { return Inst->getKind() == Call; } |
298 | 305 |
299 private: | 306 protected: |
300 InstCall(Cfg *Func, SizeT NumArgs, Variable *Dest, Operand *CallTarget) | 307 InstCall(Cfg *Func, SizeT NumArgs, Variable *Dest, Operand *CallTarget, |
301 : Inst(Func, Inst::Call, NumArgs + 1, Dest) { | 308 bool HasSideEff, InstKind Kind) |
302 // Set HasSideEffects so that the call instruction can't be | 309 : Inst(Func, Kind, NumArgs + 1, Dest) { |
303 // dead-code eliminated. Don't set this for a deletable intrinsic | 310 HasSideEffects = HasSideEff; |
304 // call. | |
305 HasSideEffects = true; | |
306 addSource(CallTarget); | 311 addSource(CallTarget); |
307 } | 312 } |
| 313 virtual ~InstCall() {} |
| 314 |
| 315 private: |
308 InstCall(const InstCall &) LLVM_DELETED_FUNCTION; | 316 InstCall(const InstCall &) LLVM_DELETED_FUNCTION; |
309 InstCall &operator=(const InstCall &) LLVM_DELETED_FUNCTION; | 317 InstCall &operator=(const InstCall &) LLVM_DELETED_FUNCTION; |
310 virtual ~InstCall() {} | |
311 }; | 318 }; |
312 | 319 |
313 // Cast instruction (a.k.a. conversion operation). | 320 // Cast instruction (a.k.a. conversion operation). |
314 class InstCast : public Inst { | 321 class InstCast : public Inst { |
315 public: | 322 public: |
316 enum OpKind { | 323 enum OpKind { |
317 #define X(tag, str) tag, | 324 #define X(tag, str) tag, |
318 ICEINSTCAST_TABLE | 325 ICEINSTCAST_TABLE |
319 #undef X | 326 #undef X |
320 _num | 327 _num |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 | 395 |
389 private: | 396 private: |
390 InstIcmp(Cfg *Func, ICond Condition, Variable *Dest, Operand *Source1, | 397 InstIcmp(Cfg *Func, ICond Condition, Variable *Dest, Operand *Source1, |
391 Operand *Source2); | 398 Operand *Source2); |
392 InstIcmp(const InstIcmp &) LLVM_DELETED_FUNCTION; | 399 InstIcmp(const InstIcmp &) LLVM_DELETED_FUNCTION; |
393 InstIcmp &operator=(const InstIcmp &) LLVM_DELETED_FUNCTION; | 400 InstIcmp &operator=(const InstIcmp &) LLVM_DELETED_FUNCTION; |
394 virtual ~InstIcmp() {} | 401 virtual ~InstIcmp() {} |
395 const ICond Condition; | 402 const ICond Condition; |
396 }; | 403 }; |
397 | 404 |
| 405 // Call to an intrinsic function. The call target is captured as getSrc(0), |
| 406 // and arg I is captured as getSrc(I+1). |
| 407 class InstIntrinsicCall : public InstCall { |
| 408 public: |
| 409 static InstIntrinsicCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest, |
| 410 Operand *CallTarget, |
| 411 const IntrinsicInfo &Info) { |
| 412 return new (Func->allocateInst<InstIntrinsicCall>()) |
| 413 InstIntrinsicCall(Func, NumArgs, Dest, CallTarget, Info); |
| 414 } |
| 415 static bool classof(const Inst *Inst) { |
| 416 return Inst->getKind() == IntrinsicCall; |
| 417 } |
| 418 |
| 419 IntrinsicInfo getIntrinsicInfo() const { return Info; } |
| 420 private: |
| 421 InstIntrinsicCall(Cfg *Func, SizeT NumArgs, Variable *Dest, |
| 422 Operand *CallTarget, const IntrinsicInfo &Info) |
| 423 : InstCall(Func, NumArgs, Dest, CallTarget, |
| 424 Info.HasSideEffects, Inst::IntrinsicCall), |
| 425 Info(Info) {} |
| 426 InstIntrinsicCall(const InstIntrinsicCall &) LLVM_DELETED_FUNCTION; |
| 427 InstIntrinsicCall &operator=(const InstIntrinsicCall &) LLVM_DELETED_FUNCTION; |
| 428 virtual ~InstIntrinsicCall() {} |
| 429 const IntrinsicInfo Info; |
| 430 }; |
| 431 |
398 // Load instruction. The source address is captured in getSrc(0). | 432 // Load instruction. The source address is captured in getSrc(0). |
399 class InstLoad : public Inst { | 433 class InstLoad : public Inst { |
400 public: | 434 public: |
401 static InstLoad *create(Cfg *Func, Variable *Dest, Operand *SourceAddr) { | 435 static InstLoad *create(Cfg *Func, Variable *Dest, Operand *SourceAddr) { |
402 return new (Func->allocateInst<InstLoad>()) | 436 return new (Func->allocateInst<InstLoad>()) |
403 InstLoad(Func, Dest, SourceAddr); | 437 InstLoad(Func, Dest, SourceAddr); |
404 } | 438 } |
405 Operand *getSourceAddress() const { return getSrc(0); } | 439 Operand *getSourceAddress() const { return getSrc(0); } |
406 virtual void dump(const Cfg *Func) const; | 440 virtual void dump(const Cfg *Func) const; |
407 static bool classof(const Inst *Inst) { return Inst->getKind() == Load; } | 441 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); | 700 assert(Kind >= Target); |
667 } | 701 } |
668 InstTarget(const InstTarget &) LLVM_DELETED_FUNCTION; | 702 InstTarget(const InstTarget &) LLVM_DELETED_FUNCTION; |
669 InstTarget &operator=(const InstTarget &) LLVM_DELETED_FUNCTION; | 703 InstTarget &operator=(const InstTarget &) LLVM_DELETED_FUNCTION; |
670 virtual ~InstTarget() {} | 704 virtual ~InstTarget() {} |
671 }; | 705 }; |
672 | 706 |
673 } // end of namespace Ice | 707 } // end of namespace Ice |
674 | 708 |
675 #endif // SUBZERO_SRC_ICEINST_H | 709 #endif // SUBZERO_SRC_ICEINST_H |
OLD | NEW |