| 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 |
| 11 /// This file declares the Inst class and its target-independent | 11 /// This file declares the Inst class and its target-independent |
| 12 /// subclasses, which represent the high-level Vanilla ICE instructions | 12 /// subclasses, which represent the high-level Vanilla ICE instructions |
| 13 /// and map roughly 1:1 to LLVM instructions. | 13 /// and map roughly 1:1 to LLVM instructions. |
| 14 /// | 14 /// |
| 15 //===----------------------------------------------------------------------===// | 15 //===----------------------------------------------------------------------===// |
| 16 | 16 |
| 17 #ifndef SUBZERO_SRC_ICEINST_H | 17 #ifndef SUBZERO_SRC_ICEINST_H |
| 18 #define SUBZERO_SRC_ICEINST_H | 18 #define SUBZERO_SRC_ICEINST_H |
| 19 | 19 |
| 20 #include "IceCfg.h" | 20 #include "IceCfg.h" |
| 21 #include "IceDefs.h" | 21 #include "IceDefs.h" |
| 22 #include "IceInst.def" | 22 #include "IceInst.def" |
| 23 #include "IceIntrinsics.h" | 23 #include "IceIntrinsics.h" |
| 24 #include "IceTypes.h" | 24 #include "IceTypes.h" |
| 25 | 25 |
| 26 // TODO: The Cfg structure, and instructions in particular, need to be | 26 // TODO: The Cfg structure, and instructions in particular, need to be |
| 27 // validated for things like valid operand types, valid branch | 27 // validated for things like valid operand types, valid branch targets, proper |
| 28 // targets, proper ordering of Phi and non-Phi instructions, etc. | 28 // ordering of Phi and non-Phi instructions, etc. Most of the validity |
| 29 // Most of the validity checking will be done in the bitcode reader. | 29 // checking will be done in the bitcode reader. We need a list of everything |
| 30 // We need a list of everything that should be validated, and tests | 30 // that should be validated, and tests for each. |
| 31 // for each. | |
| 32 | 31 |
| 33 namespace Ice { | 32 namespace Ice { |
| 34 | 33 |
| 35 /// Base instruction class for ICE. Inst has two subclasses: | 34 /// Base instruction class for ICE. Inst has two subclasses: InstHighLevel and |
| 36 /// InstHighLevel and InstTarget. High-level ICE instructions inherit | 35 /// InstTarget. High-level ICE instructions inherit from InstHighLevel, and |
| 37 /// from InstHighLevel, and low-level (target-specific) ICE | 36 /// low-level (target-specific) ICE instructions inherit from InstTarget. |
| 38 /// instructions inherit from InstTarget. | |
| 39 class Inst : public llvm::ilist_node<Inst> { | 37 class Inst : public llvm::ilist_node<Inst> { |
| 40 Inst() = delete; | 38 Inst() = delete; |
| 41 Inst(const Inst &) = delete; | 39 Inst(const Inst &) = delete; |
| 42 Inst &operator=(const Inst &) = delete; | 40 Inst &operator=(const Inst &) = delete; |
| 43 | 41 |
| 44 public: | 42 public: |
| 45 enum InstKind { | 43 enum InstKind { |
| 46 // Arbitrary (alphabetical) order, except put Unreachable first. | 44 // Arbitrary (alphabetical) order, except put Unreachable first. |
| 47 Unreachable, | 45 Unreachable, |
| 48 Alloca, | 46 Alloca, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 61 Select, | 59 Select, |
| 62 Store, | 60 Store, |
| 63 Switch, | 61 Switch, |
| 64 Assign, // not part of LLVM/PNaCl bitcode | 62 Assign, // not part of LLVM/PNaCl bitcode |
| 65 BundleLock, // not part of LLVM/PNaCl bitcode | 63 BundleLock, // not part of LLVM/PNaCl bitcode |
| 66 BundleUnlock, // not part of LLVM/PNaCl bitcode | 64 BundleUnlock, // not part of LLVM/PNaCl bitcode |
| 67 FakeDef, // not part of LLVM/PNaCl bitcode | 65 FakeDef, // not part of LLVM/PNaCl bitcode |
| 68 FakeUse, // not part of LLVM/PNaCl bitcode | 66 FakeUse, // not part of LLVM/PNaCl bitcode |
| 69 FakeKill, // not part of LLVM/PNaCl bitcode | 67 FakeKill, // not part of LLVM/PNaCl bitcode |
| 70 JumpTable, // not part of LLVM/PNaCl bitcode | 68 JumpTable, // not part of LLVM/PNaCl bitcode |
| 71 Target // target-specific low-level ICE | 69 // Anything >= Target is an InstTarget subclass. Note that the value-spaces |
| 72 // Anything >= Target is an InstTarget subclass. | 70 // are shared across targets. To avoid confusion over the definition of |
| 73 // Note that the value-spaces are shared across targets. | 71 // shared values, an object specific to one target should never be passed |
| 74 // To avoid confusion over the definition of shared values, | 72 // to a different target. |
| 75 // an object specific to one target should never be passed | 73 Target, |
| 76 // to a different target. | 74 Target_Max = std::numeric_limits<uint8_t>::max(), |
| 77 }; | 75 }; |
| 78 InstKind getKind() const { return Kind; } | 76 InstKind getKind() const { return Kind; } |
| 79 | 77 |
| 80 InstNumberT getNumber() const { return Number; } | 78 InstNumberT getNumber() const { return Number; } |
| 81 void renumber(Cfg *Func); | 79 void renumber(Cfg *Func); |
| 82 enum { | 80 enum { |
| 83 NumberDeleted = -1, | 81 NumberDeleted = -1, |
| 84 NumberSentinel = 0, | 82 NumberSentinel = 0, |
| 85 NumberInitial = 2, | 83 NumberInitial = 2, |
| 86 NumberExtended = NumberInitial - 1 | 84 NumberExtended = NumberInitial - 1 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 100 | 98 |
| 101 SizeT getSrcSize() const { return NumSrcs; } | 99 SizeT getSrcSize() const { return NumSrcs; } |
| 102 Operand *getSrc(SizeT I) const { | 100 Operand *getSrc(SizeT I) const { |
| 103 assert(I < getSrcSize()); | 101 assert(I < getSrcSize()); |
| 104 return Srcs[I]; | 102 return Srcs[I]; |
| 105 } | 103 } |
| 106 | 104 |
| 107 bool isLastUse(const Operand *Src) const; | 105 bool isLastUse(const Operand *Src) const; |
| 108 void spliceLivenessInfo(Inst *OrigInst, Inst *SpliceAssn); | 106 void spliceLivenessInfo(Inst *OrigInst, Inst *SpliceAssn); |
| 109 | 107 |
| 110 /// Returns a list of out-edges corresponding to a terminator | 108 /// Returns a list of out-edges corresponding to a terminator instruction, |
| 111 /// instruction, which is the last instruction of the block. | 109 /// which is the last instruction of the block. The list must not contain |
| 112 /// The list must not contain duplicates. | 110 /// duplicates. |
| 113 virtual NodeList getTerminatorEdges() const { | 111 virtual NodeList getTerminatorEdges() const { |
| 114 // All valid terminator instructions override this method. For | 112 // All valid terminator instructions override this method. For the default |
| 115 // the default implementation, we assert in case some CfgNode | 113 // implementation, we assert in case some CfgNode is constructed without a |
| 116 // is constructed without a terminator instruction at the end. | 114 // terminator instruction at the end. |
| 117 llvm_unreachable( | 115 llvm_unreachable( |
| 118 "getTerminatorEdges() called on a non-terminator instruction"); | 116 "getTerminatorEdges() called on a non-terminator instruction"); |
| 119 return NodeList(); | 117 return NodeList(); |
| 120 } | 118 } |
| 121 virtual bool isUnconditionalBranch() const { return false; } | 119 virtual bool isUnconditionalBranch() const { return false; } |
| 122 /// If the instruction is a branch-type instruction with OldNode as a | 120 /// If the instruction is a branch-type instruction with OldNode as a |
| 123 /// target, repoint it to NewNode and return true, otherwise return | 121 /// target, repoint it to NewNode and return true, otherwise return |
| 124 /// false. Repoint all instances of OldNode as a target. | 122 /// false. Repoint all instances of OldNode as a target. |
| 125 virtual bool repointEdges(CfgNode *OldNode, CfgNode *NewNode) { | 123 virtual bool repointEdges(CfgNode *OldNode, CfgNode *NewNode) { |
| 126 (void)OldNode; | 124 (void)OldNode; |
| 127 (void)NewNode; | 125 (void)NewNode; |
| 128 return false; | 126 return false; |
| 129 } | 127 } |
| 130 | 128 |
| 131 virtual bool isSimpleAssign() const { return false; } | 129 virtual bool isSimpleAssign() const { return false; } |
| 132 | 130 |
| 133 void livenessLightweight(Cfg *Func, LivenessBV &Live); | 131 void livenessLightweight(Cfg *Func, LivenessBV &Live); |
| 134 /// Calculates liveness for this instruction. Returns true if this | 132 // Calculates liveness for this instruction. Returns true if this |
| 135 /// instruction is (tentatively) still live and should be retained, | 133 /// instruction is (tentatively) still live and should be retained, and false |
| 136 /// and false if this instruction is (tentatively) dead and should be | 134 /// if this instruction is (tentatively) dead and should be deleted. The |
| 137 /// deleted. The decision is tentative until the liveness dataflow | 135 /// decision is tentative until the liveness dataflow algorithm has converged, |
| 138 /// algorithm has converged, and then a separate pass permanently | 136 /// and then a separate pass permanently deletes dead instructions. |
| 139 /// deletes dead instructions. | |
| 140 bool liveness(InstNumberT InstNumber, LivenessBV &Live, Liveness *Liveness, | 137 bool liveness(InstNumberT InstNumber, LivenessBV &Live, Liveness *Liveness, |
| 141 LiveBeginEndMap *LiveBegin, LiveBeginEndMap *LiveEnd); | 138 LiveBeginEndMap *LiveBegin, LiveBeginEndMap *LiveEnd); |
| 142 | 139 |
| 143 /// Get the number of native instructions that this instruction | 140 /// Get the number of native instructions that this instruction ultimately |
| 144 /// ultimately emits. By default, high-level instructions don't | 141 /// emits. By default, high-level instructions don't result in any native |
| 145 /// result in any native instructions, and a target-specific | 142 /// instructions, and a target-specific instruction results in a single native |
| 146 /// instruction results in a single native instruction. | 143 /// instruction. |
| 147 virtual uint32_t getEmitInstCount() const { return 0; } | 144 virtual uint32_t getEmitInstCount() const { return 0; } |
| 148 // TODO(stichnot): Change Inst back to abstract once the g++ build | 145 // TODO(stichnot): Change Inst back to abstract once the g++ build |
| 149 // issue is fixed. llvm::ilist<Ice::Inst> doesn't work under g++ | 146 // issue is fixed. llvm::ilist<Ice::Inst> doesn't work under g++ |
| 150 // because the resize(size_t, Ice::Inst) method is incorrectly | 147 // because the resize(size_t, Ice::Inst) method is incorrectly |
| 151 // declared and thus doesn't allow the abstract class Ice::Inst. | 148 // declared and thus doesn't allow the abstract class Ice::Inst. |
| 152 // The method should be declared resize(size_t, const Ice::Inst &). | 149 // The method should be declared resize(size_t, const Ice::Inst &). |
| 153 // virtual void emit(const Cfg *Func) const = 0; | 150 // virtual void emit(const Cfg *Func) const = 0; |
| 154 // virtual void emitIAS(const Cfg *Func) const = 0; | 151 // virtual void emitIAS(const Cfg *Func) const = 0; |
| 155 virtual void emit(const Cfg *) const { | 152 virtual void emit(const Cfg *) const { |
| 156 llvm_unreachable("emit on abstract class"); | 153 llvm_unreachable("emit on abstract class"); |
| (...skipping 796 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 953 | 950 |
| 954 public: | 951 public: |
| 955 uint32_t getEmitInstCount() const override { return 1; } | 952 uint32_t getEmitInstCount() const override { return 1; } |
| 956 void dump(const Cfg *Func) const override; | 953 void dump(const Cfg *Func) const override; |
| 957 static bool classof(const Inst *Inst) { return Inst->getKind() >= Target; } | 954 static bool classof(const Inst *Inst) { return Inst->getKind() >= Target; } |
| 958 | 955 |
| 959 protected: | 956 protected: |
| 960 InstTarget(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest) | 957 InstTarget(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest) |
| 961 : Inst(Func, Kind, MaxSrcs, Dest) { | 958 : Inst(Func, Kind, MaxSrcs, Dest) { |
| 962 assert(Kind >= Target); | 959 assert(Kind >= Target); |
| 960 assert(Kind <= Target_Max); |
| 963 } | 961 } |
| 964 }; | 962 }; |
| 965 | 963 |
| 966 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source); | 964 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source); |
| 967 | 965 |
| 968 } // end of namespace Ice | 966 } // end of namespace Ice |
| 969 | 967 |
| 970 namespace llvm { | 968 namespace llvm { |
| 971 | 969 |
| 972 /// Override the default ilist traits so that Inst's private ctor and | 970 /// Override the default ilist traits so that Inst's private ctor and |
| 973 /// deleted dtor aren't invoked. | 971 /// deleted dtor aren't invoked. |
| 974 template <> | 972 template <> |
| 975 struct ilist_traits<Ice::Inst> : public ilist_default_traits<Ice::Inst> { | 973 struct ilist_traits<Ice::Inst> : public ilist_default_traits<Ice::Inst> { |
| 976 Ice::Inst *createSentinel() const { | 974 Ice::Inst *createSentinel() const { |
| 977 return static_cast<Ice::Inst *>(&Sentinel); | 975 return static_cast<Ice::Inst *>(&Sentinel); |
| 978 } | 976 } |
| 979 static void destroySentinel(Ice::Inst *) {} | 977 static void destroySentinel(Ice::Inst *) {} |
| 980 Ice::Inst *provideInitialHead() const { return createSentinel(); } | 978 Ice::Inst *provideInitialHead() const { return createSentinel(); } |
| 981 Ice::Inst *ensureHead(Ice::Inst *) const { return createSentinel(); } | 979 Ice::Inst *ensureHead(Ice::Inst *) const { return createSentinel(); } |
| 982 static void noteHead(Ice::Inst *, Ice::Inst *) {} | 980 static void noteHead(Ice::Inst *, Ice::Inst *) {} |
| 983 void deleteNode(Ice::Inst *) {} | 981 void deleteNode(Ice::Inst *) {} |
| 984 | 982 |
| 985 private: | 983 private: |
| 986 mutable ilist_half_node<Ice::Inst> Sentinel; | 984 mutable ilist_half_node<Ice::Inst> Sentinel; |
| 987 }; | 985 }; |
| 988 | 986 |
| 989 } // end of namespace llvm | 987 } // end of namespace llvm |
| 990 | 988 |
| 991 #endif // SUBZERO_SRC_ICEINST_H | 989 #endif // SUBZERO_SRC_ICEINST_H |
| OLD | NEW |