| 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 /// \file | 10 /// \file |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 Ret, | 60 Ret, |
| 61 Select, | 61 Select, |
| 62 Store, | 62 Store, |
| 63 Switch, | 63 Switch, |
| 64 Assign, // not part of LLVM/PNaCl bitcode | 64 Assign, // not part of LLVM/PNaCl bitcode |
| 65 BundleLock, // not part of LLVM/PNaCl bitcode | 65 BundleLock, // not part of LLVM/PNaCl bitcode |
| 66 BundleUnlock, // not part of LLVM/PNaCl bitcode | 66 BundleUnlock, // not part of LLVM/PNaCl bitcode |
| 67 FakeDef, // not part of LLVM/PNaCl bitcode | 67 FakeDef, // not part of LLVM/PNaCl bitcode |
| 68 FakeUse, // not part of LLVM/PNaCl bitcode | 68 FakeUse, // not part of LLVM/PNaCl bitcode |
| 69 FakeKill, // not part of LLVM/PNaCl bitcode | 69 FakeKill, // not part of LLVM/PNaCl bitcode |
| 70 JumpTable, // not part of LLVM/PNaCl bitcode |
| 70 Target // target-specific low-level ICE | 71 Target // target-specific low-level ICE |
| 71 // Anything >= Target is an InstTarget subclass. | 72 // Anything >= Target is an InstTarget subclass. |
| 72 // Note that the value-spaces are shared across targets. | 73 // Note that the value-spaces are shared across targets. |
| 73 // To avoid confusion over the definition of shared values, | 74 // To avoid confusion over the definition of shared values, |
| 74 // an object specific to one target should never be passed | 75 // an object specific to one target should never be passed |
| 75 // to a different target. | 76 // to a different target. |
| 76 }; | 77 }; |
| 77 InstKind getKind() const { return Kind; } | 78 InstKind getKind() const { return Kind; } |
| 78 | 79 |
| 79 InstNumberT getNumber() const { return Number; } | 80 InstNumberT getNumber() const { return Number; } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 101 Operand *getSrc(SizeT I) const { | 102 Operand *getSrc(SizeT I) const { |
| 102 assert(I < getSrcSize()); | 103 assert(I < getSrcSize()); |
| 103 return Srcs[I]; | 104 return Srcs[I]; |
| 104 } | 105 } |
| 105 | 106 |
| 106 bool isLastUse(const Operand *Src) const; | 107 bool isLastUse(const Operand *Src) const; |
| 107 void spliceLivenessInfo(Inst *OrigInst, Inst *SpliceAssn); | 108 void spliceLivenessInfo(Inst *OrigInst, Inst *SpliceAssn); |
| 108 | 109 |
| 109 /// Returns a list of out-edges corresponding to a terminator | 110 /// Returns a list of out-edges corresponding to a terminator |
| 110 /// instruction, which is the last instruction of the block. | 111 /// instruction, which is the last instruction of the block. |
| 112 /// The list must not contain duplicates. |
| 111 virtual NodeList getTerminatorEdges() const { | 113 virtual NodeList getTerminatorEdges() const { |
| 112 // All valid terminator instructions override this method. For | 114 // All valid terminator instructions override this method. For |
| 113 // the default implementation, we assert in case some CfgNode | 115 // the default implementation, we assert in case some CfgNode |
| 114 // is constructed without a terminator instruction at the end. | 116 // is constructed without a terminator instruction at the end. |
| 115 llvm_unreachable( | 117 llvm_unreachable( |
| 116 "getTerminatorEdges() called on a non-terminator instruction"); | 118 "getTerminatorEdges() called on a non-terminator instruction"); |
| 117 return NodeList(); | 119 return NodeList(); |
| 118 } | 120 } |
| 119 virtual bool isUnconditionalBranch() const { return false; } | 121 virtual bool isUnconditionalBranch() const { return false; } |
| 120 /// If the instruction is a branch-type instruction with OldNode as a | 122 /// If the instruction is a branch-type instruction with OldNode as a |
| 121 /// target, repoint it to NewNode and return true, otherwise return | 123 /// target, repoint it to NewNode and return true, otherwise return |
| 122 /// false. Only repoint one instance, even if the instruction has | 124 /// false. Repoint all instances of OldNode as a target. |
| 123 /// multiple instances of OldNode as a target. | 125 virtual bool repointEdges(CfgNode *OldNode, CfgNode *NewNode) { |
| 124 virtual bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) { | |
| 125 (void)OldNode; | 126 (void)OldNode; |
| 126 (void)NewNode; | 127 (void)NewNode; |
| 127 return false; | 128 return false; |
| 128 } | 129 } |
| 129 | 130 |
| 130 virtual bool isSimpleAssign() const { return false; } | 131 virtual bool isSimpleAssign() const { return false; } |
| 131 | 132 |
| 132 void livenessLightweight(Cfg *Func, LivenessBV &Live); | 133 void livenessLightweight(Cfg *Func, LivenessBV &Live); |
| 133 /// Calculates liveness for this instruction. Returns true if this | 134 /// Calculates liveness for this instruction. Returns true if this |
| 134 /// instruction is (tentatively) still live and should be retained, | 135 /// instruction is (tentatively) still live and should be retained, |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 345 return getSrc(0); | 346 return getSrc(0); |
| 346 } | 347 } |
| 347 CfgNode *getTargetTrue() const { return TargetTrue; } | 348 CfgNode *getTargetTrue() const { return TargetTrue; } |
| 348 CfgNode *getTargetFalse() const { return TargetFalse; } | 349 CfgNode *getTargetFalse() const { return TargetFalse; } |
| 349 CfgNode *getTargetUnconditional() const { | 350 CfgNode *getTargetUnconditional() const { |
| 350 assert(isUnconditional()); | 351 assert(isUnconditional()); |
| 351 return getTargetFalse(); | 352 return getTargetFalse(); |
| 352 } | 353 } |
| 353 NodeList getTerminatorEdges() const override; | 354 NodeList getTerminatorEdges() const override; |
| 354 bool isUnconditionalBranch() const override { return isUnconditional(); } | 355 bool isUnconditionalBranch() const override { return isUnconditional(); } |
| 355 bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) override; | 356 bool repointEdges(CfgNode *OldNode, CfgNode *NewNode) override; |
| 356 void dump(const Cfg *Func) const override; | 357 void dump(const Cfg *Func) const override; |
| 357 static bool classof(const Inst *Inst) { return Inst->getKind() == Br; } | 358 static bool classof(const Inst *Inst) { return Inst->getKind() == Br; } |
| 358 | 359 |
| 359 private: | 360 private: |
| 360 /// Conditional branch | 361 /// Conditional branch |
| 361 InstBr(Cfg *Func, Operand *Source, CfgNode *TargetTrue, CfgNode *TargetFalse); | 362 InstBr(Cfg *Func, Operand *Source, CfgNode *TargetTrue, CfgNode *TargetFalse); |
| 362 /// Unconditional branch | 363 /// Unconditional branch |
| 363 InstBr(Cfg *Func, CfgNode *Target); | 364 InstBr(Cfg *Func, CfgNode *Target); |
| 364 | 365 |
| 365 CfgNode *TargetFalse; /// Doubles as unconditional branch target | 366 CfgNode *TargetFalse; /// Doubles as unconditional branch target |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 720 uint64_t getValue(SizeT I) const { | 721 uint64_t getValue(SizeT I) const { |
| 721 assert(I < NumCases); | 722 assert(I < NumCases); |
| 722 return Values[I]; | 723 return Values[I]; |
| 723 } | 724 } |
| 724 CfgNode *getLabel(SizeT I) const { | 725 CfgNode *getLabel(SizeT I) const { |
| 725 assert(I < NumCases); | 726 assert(I < NumCases); |
| 726 return Labels[I]; | 727 return Labels[I]; |
| 727 } | 728 } |
| 728 void addBranch(SizeT CaseIndex, uint64_t Value, CfgNode *Label); | 729 void addBranch(SizeT CaseIndex, uint64_t Value, CfgNode *Label); |
| 729 NodeList getTerminatorEdges() const override; | 730 NodeList getTerminatorEdges() const override; |
| 730 bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) override; | 731 bool repointEdges(CfgNode *OldNode, CfgNode *NewNode) override; |
| 731 void dump(const Cfg *Func) const override; | 732 void dump(const Cfg *Func) const override; |
| 732 static bool classof(const Inst *Inst) { return Inst->getKind() == Switch; } | 733 static bool classof(const Inst *Inst) { return Inst->getKind() == Switch; } |
| 733 | 734 |
| 734 private: | 735 private: |
| 735 InstSwitch(Cfg *Func, SizeT NumCases, Operand *Source, CfgNode *LabelDefault); | 736 InstSwitch(Cfg *Func, SizeT NumCases, Operand *Source, CfgNode *LabelDefault); |
| 736 void destroy(Cfg *Func) override { | 737 void destroy(Cfg *Func) override { |
| 737 Func->deallocateArrayOf<uint64_t>(Values); | 738 Func->deallocateArrayOf<uint64_t>(Values); |
| 738 Func->deallocateArrayOf<CfgNode *>(Labels); | 739 Func->deallocateArrayOf<CfgNode *>(Labels); |
| 739 Inst::destroy(Func); | 740 Inst::destroy(Func); |
| 740 } | 741 } |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 892 void dump(const Cfg *Func) const override; | 893 void dump(const Cfg *Func) const override; |
| 893 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeKill; } | 894 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeKill; } |
| 894 | 895 |
| 895 private: | 896 private: |
| 896 InstFakeKill(Cfg *Func, const Inst *Linked); | 897 InstFakeKill(Cfg *Func, const Inst *Linked); |
| 897 | 898 |
| 898 /// This instruction is ignored if Linked->isDeleted() is true. | 899 /// This instruction is ignored if Linked->isDeleted() is true. |
| 899 const Inst *Linked; | 900 const Inst *Linked; |
| 900 }; | 901 }; |
| 901 | 902 |
| 903 /// JumpTable instruction. This represents a jump table that will be |
| 904 /// stored in the .rodata section. This is used to track and repoint |
| 905 /// the target CfgNodes which may change, for example due to |
| 906 /// splitting for phi lowering. |
| 907 class InstJumpTable : public InstHighLevel { |
| 908 InstJumpTable() = delete; |
| 909 InstJumpTable(const InstJumpTable &) = delete; |
| 910 InstJumpTable &operator=(const InstJumpTable &) = delete; |
| 911 |
| 912 public: |
| 913 static InstJumpTable *create(Cfg *Func, SizeT NumTargets, CfgNode *Default) { |
| 914 return new (Func->allocate<InstJumpTable>()) |
| 915 InstJumpTable(Func, NumTargets, Default); |
| 916 } |
| 917 void emit(const Cfg *Func) const override; |
| 918 void emitIAS(const Cfg *Func) const override; |
| 919 void addTarget(SizeT TargetIndex, CfgNode *Target) { |
| 920 assert(TargetIndex < NumTargets); |
| 921 Targets[TargetIndex] = Target; |
| 922 } |
| 923 bool repointEdges(CfgNode *OldNode, CfgNode *NewNode) override; |
| 924 IceString getName(const Cfg *Func) const; |
| 925 void dump(const Cfg *Func) const override; |
| 926 static bool classof(const Inst *Inst) { return Inst->getKind() == JumpTable; } |
| 927 |
| 928 private: |
| 929 InstJumpTable(Cfg *Func, SizeT NumTargets, CfgNode *Default); |
| 930 void destroy(Cfg *Func) override { |
| 931 Func->deallocateArrayOf<CfgNode *>(Targets); |
| 932 Inst::destroy(Func); |
| 933 } |
| 934 |
| 935 const SizeT LabelNumber; |
| 936 const SizeT NumTargets; |
| 937 CfgNode **Targets; |
| 938 }; |
| 939 |
| 902 /// The Target instruction is the base class for all target-specific | 940 /// The Target instruction is the base class for all target-specific |
| 903 /// instructions. | 941 /// instructions. |
| 904 class InstTarget : public Inst { | 942 class InstTarget : public Inst { |
| 905 InstTarget() = delete; | 943 InstTarget() = delete; |
| 906 InstTarget(const InstTarget &) = delete; | 944 InstTarget(const InstTarget &) = delete; |
| 907 InstTarget &operator=(const InstTarget &) = delete; | 945 InstTarget &operator=(const InstTarget &) = delete; |
| 908 | 946 |
| 909 public: | 947 public: |
| 910 uint32_t getEmitInstCount() const override { return 1; } | 948 uint32_t getEmitInstCount() const override { return 1; } |
| 911 void dump(const Cfg *Func) const override; | 949 void dump(const Cfg *Func) const override; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 937 static void noteHead(Ice::Inst *, Ice::Inst *) {} | 975 static void noteHead(Ice::Inst *, Ice::Inst *) {} |
| 938 void deleteNode(Ice::Inst *) {} | 976 void deleteNode(Ice::Inst *) {} |
| 939 | 977 |
| 940 private: | 978 private: |
| 941 mutable ilist_half_node<Ice::Inst> Sentinel; | 979 mutable ilist_half_node<Ice::Inst> Sentinel; |
| 942 }; | 980 }; |
| 943 | 981 |
| 944 } // end of namespace llvm | 982 } // end of namespace llvm |
| 945 | 983 |
| 946 #endif // SUBZERO_SRC_ICEINST_H | 984 #endif // SUBZERO_SRC_ICEINST_H |
| OLD | NEW |