| OLD | NEW |
| 1 //===- subzero/src/IceOperand.h - High-level operands -----------*- C++ -*-===// | 1 //===- subzero/src/IceOperand.h - High-level operands -----------*- 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 Operand class and its target-independent | 10 // This file declares the Operand class and its target-independent |
| 11 // subclasses. The main classes are Variable, which represents an | 11 // subclasses. The main classes are Variable, which represents an |
| 12 // LLVM variable that is either register- or stack-allocated, and the | 12 // LLVM variable that is either register- or stack-allocated, and the |
| 13 // Constant hierarchy, which represents integer, floating-point, | 13 // Constant hierarchy, which represents integer, floating-point, |
| 14 // and/or symbolic constants. | 14 // and/or symbolic constants. |
| 15 // | 15 // |
| 16 //===----------------------------------------------------------------------===// | 16 //===----------------------------------------------------------------------===// |
| 17 | 17 |
| 18 #ifndef SUBZERO_SRC_ICEOPERAND_H | 18 #ifndef SUBZERO_SRC_ICEOPERAND_H |
| 19 #define SUBZERO_SRC_ICEOPERAND_H | 19 #define SUBZERO_SRC_ICEOPERAND_H |
| 20 | 20 |
| 21 #include "IceCfg.h" | 21 #include "IceCfg.h" |
| 22 #include "IceDefs.h" | 22 #include "IceDefs.h" |
| 23 #include "IceGlobalContext.h" | 23 #include "IceGlobalContext.h" |
| 24 #include "IceTypes.h" | 24 #include "IceTypes.h" |
| 25 | 25 |
| 26 namespace Ice { | 26 namespace Ice { |
| 27 | 27 |
| 28 class Operand { | 28 class Operand { |
| 29 Operand(const Operand &) = delete; |
| 30 Operand &operator=(const Operand &) = delete; |
| 31 |
| 29 public: | 32 public: |
| 30 static const size_t MaxTargetKinds = 10; | 33 static const size_t MaxTargetKinds = 10; |
| 31 enum OperandKind { | 34 enum OperandKind { |
| 32 kConst_Base, | 35 kConst_Base, |
| 33 kConstInteger32, | 36 kConstInteger32, |
| 34 kConstInteger64, | 37 kConstInteger64, |
| 35 kConstFloat, | 38 kConstFloat, |
| 36 kConstDouble, | 39 kConstDouble, |
| 37 kConstRelocatable, | 40 kConstRelocatable, |
| 38 kConstUndef, | 41 kConstUndef, |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 protected: | 82 protected: |
| 80 Operand(OperandKind Kind, Type Ty) | 83 Operand(OperandKind Kind, Type Ty) |
| 81 : Ty(Ty), Kind(Kind), NumVars(0), Vars(NULL) {} | 84 : Ty(Ty), Kind(Kind), NumVars(0), Vars(NULL) {} |
| 82 Operand(Operand &&O) = default; | 85 Operand(Operand &&O) = default; |
| 83 | 86 |
| 84 const Type Ty; | 87 const Type Ty; |
| 85 const OperandKind Kind; | 88 const OperandKind Kind; |
| 86 // Vars and NumVars are initialized by the derived class. | 89 // Vars and NumVars are initialized by the derived class. |
| 87 SizeT NumVars; | 90 SizeT NumVars; |
| 88 Variable **Vars; | 91 Variable **Vars; |
| 89 | |
| 90 private: | |
| 91 Operand(const Operand &) = delete; | |
| 92 Operand &operator=(const Operand &) = delete; | |
| 93 }; | 92 }; |
| 94 | 93 |
| 95 template<class StreamType> | 94 template<class StreamType> |
| 96 inline StreamType &operator<<(StreamType &Str, const Operand &Op) { | 95 inline StreamType &operator<<(StreamType &Str, const Operand &Op) { |
| 97 Op.dump(Str); | 96 Op.dump(Str); |
| 98 return Str; | 97 return Str; |
| 99 } | 98 } |
| 100 | 99 |
| 101 // Constant is the abstract base class for constants. All | 100 // Constant is the abstract base class for constants. All |
| 102 // constants are allocated from a global arena and are pooled. | 101 // constants are allocated from a global arena and are pooled. |
| 103 class Constant : public Operand { | 102 class Constant : public Operand { |
| 103 Constant(const Constant &) = delete; |
| 104 Constant &operator=(const Constant &) = delete; |
| 105 |
| 104 public: | 106 public: |
| 105 uint32_t getPoolEntryID() const { return PoolEntryID; } | 107 uint32_t getPoolEntryID() const { return PoolEntryID; } |
| 106 using Operand::dump; | 108 using Operand::dump; |
| 107 void emit(const Cfg *Func) const override { emit(Func->getContext()); } | 109 void emit(const Cfg *Func) const override { emit(Func->getContext()); } |
| 108 virtual void emit(GlobalContext *Ctx) const = 0; | 110 virtual void emit(GlobalContext *Ctx) const = 0; |
| 109 void dump(const Cfg *Func, Ostream &Str) const = 0; | 111 void dump(const Cfg *Func, Ostream &Str) const = 0; |
| 110 | 112 |
| 111 static bool classof(const Operand *Operand) { | 113 static bool classof(const Operand *Operand) { |
| 112 OperandKind Kind = Operand->getKind(); | 114 OperandKind Kind = Operand->getKind(); |
| 113 return Kind >= kConst_Base && Kind <= kConst_Num; | 115 return Kind >= kConst_Base && Kind <= kConst_Num; |
| 114 } | 116 } |
| 115 | 117 |
| 116 protected: | 118 protected: |
| 117 Constant(OperandKind Kind, Type Ty, uint32_t PoolEntryID) | 119 Constant(OperandKind Kind, Type Ty, uint32_t PoolEntryID) |
| 118 : Operand(Kind, Ty), PoolEntryID(PoolEntryID) { | 120 : Operand(Kind, Ty), PoolEntryID(PoolEntryID) { |
| 119 Vars = NULL; | 121 Vars = NULL; |
| 120 NumVars = 0; | 122 NumVars = 0; |
| 121 } | 123 } |
| 122 ~Constant() override {} | 124 ~Constant() override {} |
| 123 // PoolEntryID is an integer that uniquely identifies the constant | 125 // PoolEntryID is an integer that uniquely identifies the constant |
| 124 // within its constant pool. It is used for building the constant | 126 // within its constant pool. It is used for building the constant |
| 125 // pool in the object code and for referencing its entries. | 127 // pool in the object code and for referencing its entries. |
| 126 const uint32_t PoolEntryID; | 128 const uint32_t PoolEntryID; |
| 127 | |
| 128 private: | |
| 129 Constant(const Constant &) = delete; | |
| 130 Constant &operator=(const Constant &) = delete; | |
| 131 }; | 129 }; |
| 132 | 130 |
| 133 // ConstantPrimitive<> wraps a primitive type. | 131 // ConstantPrimitive<> wraps a primitive type. |
| 134 template <typename T, Operand::OperandKind K> | 132 template <typename T, Operand::OperandKind K> |
| 135 class ConstantPrimitive : public Constant { | 133 class ConstantPrimitive : public Constant { |
| 134 ConstantPrimitive(const ConstantPrimitive &) = delete; |
| 135 ConstantPrimitive &operator=(const ConstantPrimitive &) = delete; |
| 136 |
| 136 public: | 137 public: |
| 137 static ConstantPrimitive *create(GlobalContext *Ctx, Type Ty, T Value, | 138 static ConstantPrimitive *create(GlobalContext *Ctx, Type Ty, T Value, |
| 138 uint32_t PoolEntryID) { | 139 uint32_t PoolEntryID) { |
| 139 return new (Ctx->allocate<ConstantPrimitive>()) | 140 return new (Ctx->allocate<ConstantPrimitive>()) |
| 140 ConstantPrimitive(Ty, Value, PoolEntryID); | 141 ConstantPrimitive(Ty, Value, PoolEntryID); |
| 141 } | 142 } |
| 142 T getValue() const { return Value; } | 143 T getValue() const { return Value; } |
| 143 using Constant::emit; | 144 using Constant::emit; |
| 144 // The target needs to implement this for each ConstantPrimitive | 145 // The target needs to implement this for each ConstantPrimitive |
| 145 // specialization. | 146 // specialization. |
| 146 void emit(GlobalContext *Ctx) const override; | 147 void emit(GlobalContext *Ctx) const override; |
| 147 using Constant::dump; | 148 using Constant::dump; |
| 148 void dump(const Cfg *, Ostream &Str) const override { Str << getValue(); } | 149 void dump(const Cfg *, Ostream &Str) const override { Str << getValue(); } |
| 149 | 150 |
| 150 static bool classof(const Operand *Operand) { | 151 static bool classof(const Operand *Operand) { |
| 151 return Operand->getKind() == K; | 152 return Operand->getKind() == K; |
| 152 } | 153 } |
| 153 | 154 |
| 154 private: | 155 private: |
| 155 ConstantPrimitive(Type Ty, T Value, uint32_t PoolEntryID) | 156 ConstantPrimitive(Type Ty, T Value, uint32_t PoolEntryID) |
| 156 : Constant(K, Ty, PoolEntryID), Value(Value) {} | 157 : Constant(K, Ty, PoolEntryID), Value(Value) {} |
| 157 ConstantPrimitive(const ConstantPrimitive &) = delete; | |
| 158 ConstantPrimitive &operator=(const ConstantPrimitive &) = delete; | |
| 159 ~ConstantPrimitive() override {} | 158 ~ConstantPrimitive() override {} |
| 160 const T Value; | 159 const T Value; |
| 161 }; | 160 }; |
| 162 | 161 |
| 163 typedef ConstantPrimitive<uint32_t, Operand::kConstInteger32> ConstantInteger32; | 162 typedef ConstantPrimitive<uint32_t, Operand::kConstInteger32> ConstantInteger32; |
| 164 typedef ConstantPrimitive<uint64_t, Operand::kConstInteger64> ConstantInteger64; | 163 typedef ConstantPrimitive<uint64_t, Operand::kConstInteger64> ConstantInteger64; |
| 165 typedef ConstantPrimitive<float, Operand::kConstFloat> ConstantFloat; | 164 typedef ConstantPrimitive<float, Operand::kConstFloat> ConstantFloat; |
| 166 typedef ConstantPrimitive<double, Operand::kConstDouble> ConstantDouble; | 165 typedef ConstantPrimitive<double, Operand::kConstDouble> ConstantDouble; |
| 167 | 166 |
| 168 template <> inline void ConstantInteger32::dump(const Cfg *, Ostream &Str) const
{ | 167 template <> inline void ConstantInteger32::dump(const Cfg *, Ostream &Str) const
{ |
| 169 if (getType() == IceType_i1) | 168 if (getType() == IceType_i1) |
| 170 Str << (getValue() ? "true" : "false"); | 169 Str << (getValue() ? "true" : "false"); |
| 171 else | 170 else |
| 172 Str << static_cast<int32_t>(getValue()); | 171 Str << static_cast<int32_t>(getValue()); |
| 173 } | 172 } |
| 174 | 173 |
| 175 template <> inline void ConstantInteger64::dump(const Cfg *, Ostream &Str) const
{ | 174 template <> inline void ConstantInteger64::dump(const Cfg *, Ostream &Str) const
{ |
| 176 assert(getType() == IceType_i64); | 175 assert(getType() == IceType_i64); |
| 177 Str << static_cast<int64_t>(getValue()); | 176 Str << static_cast<int64_t>(getValue()); |
| 178 } | 177 } |
| 179 | 178 |
| 180 // RelocatableTuple bundles the parameters that are used to | 179 // RelocatableTuple bundles the parameters that are used to |
| 181 // construct an ConstantRelocatable. It is done this way so that | 180 // construct an ConstantRelocatable. It is done this way so that |
| 182 // ConstantRelocatable can fit into the global constant pool | 181 // ConstantRelocatable can fit into the global constant pool |
| 183 // template mechanism. | 182 // template mechanism. |
| 184 class RelocatableTuple { | 183 class RelocatableTuple { |
| 184 // RelocatableTuple(const RelocatableTuple &) = delete; |
| 185 RelocatableTuple &operator=(const RelocatableTuple &) = delete; | 185 RelocatableTuple &operator=(const RelocatableTuple &) = delete; |
| 186 | 186 |
| 187 public: | 187 public: |
| 188 RelocatableTuple(const RelocOffsetT Offset, const IceString &Name, | 188 RelocatableTuple(const RelocOffsetT Offset, const IceString &Name, |
| 189 bool SuppressMangling) | 189 bool SuppressMangling) |
| 190 : Offset(Offset), Name(Name), SuppressMangling(SuppressMangling) {} | 190 : Offset(Offset), Name(Name), SuppressMangling(SuppressMangling) {} |
| 191 RelocatableTuple(const RelocatableTuple &Other) | |
| 192 : Offset(Other.Offset), Name(Other.Name), | |
| 193 SuppressMangling(Other.SuppressMangling) {} | |
| 194 | 191 |
| 195 const RelocOffsetT Offset; | 192 const RelocOffsetT Offset; |
| 196 const IceString Name; | 193 const IceString Name; |
| 197 bool SuppressMangling; | 194 bool SuppressMangling; |
| 198 }; | 195 }; |
| 199 | 196 |
| 200 bool operator<(const RelocatableTuple &A, const RelocatableTuple &B); | 197 bool operator<(const RelocatableTuple &A, const RelocatableTuple &B); |
| 201 | 198 |
| 202 // ConstantRelocatable represents a symbolic constant combined with | 199 // ConstantRelocatable represents a symbolic constant combined with |
| 203 // a fixed offset. | 200 // a fixed offset. |
| 204 class ConstantRelocatable : public Constant { | 201 class ConstantRelocatable : public Constant { |
| 202 ConstantRelocatable(const ConstantRelocatable &) = delete; |
| 203 ConstantRelocatable &operator=(const ConstantRelocatable &) = delete; |
| 204 |
| 205 public: | 205 public: |
| 206 static ConstantRelocatable *create(GlobalContext *Ctx, Type Ty, | 206 static ConstantRelocatable *create(GlobalContext *Ctx, Type Ty, |
| 207 const RelocatableTuple &Tuple, | 207 const RelocatableTuple &Tuple, |
| 208 uint32_t PoolEntryID) { | 208 uint32_t PoolEntryID) { |
| 209 return new (Ctx->allocate<ConstantRelocatable>()) ConstantRelocatable( | 209 return new (Ctx->allocate<ConstantRelocatable>()) ConstantRelocatable( |
| 210 Ty, Tuple.Offset, Tuple.Name, Tuple.SuppressMangling, PoolEntryID); | 210 Ty, Tuple.Offset, Tuple.Name, Tuple.SuppressMangling, PoolEntryID); |
| 211 } | 211 } |
| 212 | 212 |
| 213 RelocOffsetT getOffset() const { return Offset; } | 213 RelocOffsetT getOffset() const { return Offset; } |
| 214 IceString getName() const { return Name; } | 214 IceString getName() const { return Name; } |
| 215 void setSuppressMangling(bool Value) { SuppressMangling = Value; } | 215 void setSuppressMangling(bool Value) { SuppressMangling = Value; } |
| 216 bool getSuppressMangling() const { return SuppressMangling; } | 216 bool getSuppressMangling() const { return SuppressMangling; } |
| 217 using Constant::emit; | 217 using Constant::emit; |
| 218 using Constant::dump; | 218 using Constant::dump; |
| 219 void emit(GlobalContext *Ctx) const override; | 219 void emit(GlobalContext *Ctx) const override; |
| 220 void dump(const Cfg *Func, Ostream &Str) const override; | 220 void dump(const Cfg *Func, Ostream &Str) const override; |
| 221 | 221 |
| 222 static bool classof(const Operand *Operand) { | 222 static bool classof(const Operand *Operand) { |
| 223 OperandKind Kind = Operand->getKind(); | 223 OperandKind Kind = Operand->getKind(); |
| 224 return Kind == kConstRelocatable; | 224 return Kind == kConstRelocatable; |
| 225 } | 225 } |
| 226 | 226 |
| 227 private: | 227 private: |
| 228 ConstantRelocatable(Type Ty, RelocOffsetT Offset, const IceString &Name, | 228 ConstantRelocatable(Type Ty, RelocOffsetT Offset, const IceString &Name, |
| 229 bool SuppressMangling, uint32_t PoolEntryID) | 229 bool SuppressMangling, uint32_t PoolEntryID) |
| 230 : Constant(kConstRelocatable, Ty, PoolEntryID), Offset(Offset), | 230 : Constant(kConstRelocatable, Ty, PoolEntryID), Offset(Offset), |
| 231 Name(Name), SuppressMangling(SuppressMangling) {} | 231 Name(Name), SuppressMangling(SuppressMangling) {} |
| 232 ConstantRelocatable(const ConstantRelocatable &) = delete; | |
| 233 ConstantRelocatable &operator=(const ConstantRelocatable &) = delete; | |
| 234 ~ConstantRelocatable() override {} | 232 ~ConstantRelocatable() override {} |
| 235 const RelocOffsetT Offset; // fixed offset to add | 233 const RelocOffsetT Offset; // fixed offset to add |
| 236 const IceString Name; // optional for debug/dump | 234 const IceString Name; // optional for debug/dump |
| 237 bool SuppressMangling; | 235 bool SuppressMangling; |
| 238 }; | 236 }; |
| 239 | 237 |
| 240 // ConstantUndef represents an unspecified bit pattern. Although it is | 238 // ConstantUndef represents an unspecified bit pattern. Although it is |
| 241 // legal to lower ConstantUndef to any value, backends should try to | 239 // legal to lower ConstantUndef to any value, backends should try to |
| 242 // make code generation deterministic by lowering ConstantUndefs to 0. | 240 // make code generation deterministic by lowering ConstantUndefs to 0. |
| 243 class ConstantUndef : public Constant { | 241 class ConstantUndef : public Constant { |
| 242 ConstantUndef(const ConstantUndef &) = delete; |
| 243 ConstantUndef &operator=(const ConstantUndef &) = delete; |
| 244 |
| 244 public: | 245 public: |
| 245 static ConstantUndef *create(GlobalContext *Ctx, Type Ty, | 246 static ConstantUndef *create(GlobalContext *Ctx, Type Ty, |
| 246 uint32_t PoolEntryID) { | 247 uint32_t PoolEntryID) { |
| 247 return new (Ctx->allocate<ConstantUndef>()) ConstantUndef(Ty, PoolEntryID); | 248 return new (Ctx->allocate<ConstantUndef>()) ConstantUndef(Ty, PoolEntryID); |
| 248 } | 249 } |
| 249 | 250 |
| 250 using Constant::emit; | 251 using Constant::emit; |
| 251 using Constant::dump; | 252 using Constant::dump; |
| 252 // The target needs to implement this. | 253 // The target needs to implement this. |
| 253 void emit(GlobalContext *Ctx) const override; | 254 void emit(GlobalContext *Ctx) const override; |
| 254 void dump(const Cfg *, Ostream &Str) const override { Str << "undef"; } | 255 void dump(const Cfg *, Ostream &Str) const override { Str << "undef"; } |
| 255 | 256 |
| 256 static bool classof(const Operand *Operand) { | 257 static bool classof(const Operand *Operand) { |
| 257 return Operand->getKind() == kConstUndef; | 258 return Operand->getKind() == kConstUndef; |
| 258 } | 259 } |
| 259 | 260 |
| 260 private: | 261 private: |
| 261 ConstantUndef(Type Ty, uint32_t PoolEntryID) | 262 ConstantUndef(Type Ty, uint32_t PoolEntryID) |
| 262 : Constant(kConstUndef, Ty, PoolEntryID) {} | 263 : Constant(kConstUndef, Ty, PoolEntryID) {} |
| 263 ConstantUndef(const ConstantUndef &) = delete; | |
| 264 ConstantUndef &operator=(const ConstantUndef &) = delete; | |
| 265 ~ConstantUndef() override {} | 264 ~ConstantUndef() override {} |
| 266 }; | 265 }; |
| 267 | 266 |
| 268 // RegWeight is a wrapper for a uint32_t weight value, with a | 267 // RegWeight is a wrapper for a uint32_t weight value, with a |
| 269 // special value that represents infinite weight, and an addWeight() | 268 // special value that represents infinite weight, and an addWeight() |
| 270 // method that ensures that W+infinity=infinity. | 269 // method that ensures that W+infinity=infinity. |
| 271 class RegWeight { | 270 class RegWeight { |
| 271 // RegWeight(const RegWeight &) = delete; |
| 272 // RegWeight &operator=(const RegWeight &) = delete; |
| 273 |
| 272 public: | 274 public: |
| 273 RegWeight() : Weight(0) {} | 275 RegWeight() : Weight(0) {} |
| 274 RegWeight(uint32_t Weight) : Weight(Weight) {} | 276 RegWeight(uint32_t Weight) : Weight(Weight) {} |
| 275 const static uint32_t Inf = ~0; // Force regalloc to give a register | 277 const static uint32_t Inf = ~0; // Force regalloc to give a register |
| 276 const static uint32_t Zero = 0; // Force regalloc NOT to give a register | 278 const static uint32_t Zero = 0; // Force regalloc NOT to give a register |
| 277 void addWeight(uint32_t Delta) { | 279 void addWeight(uint32_t Delta) { |
| 278 if (Delta == Inf) | 280 if (Delta == Inf) |
| 279 Weight = Inf; | 281 Weight = Inf; |
| 280 else if (Weight != Inf) | 282 else if (Weight != Inf) |
| 281 Weight += Delta; | 283 Weight += Delta; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 293 bool operator<=(const RegWeight &A, const RegWeight &B); | 295 bool operator<=(const RegWeight &A, const RegWeight &B); |
| 294 bool operator==(const RegWeight &A, const RegWeight &B); | 296 bool operator==(const RegWeight &A, const RegWeight &B); |
| 295 | 297 |
| 296 // LiveRange is a set of instruction number intervals representing | 298 // LiveRange is a set of instruction number intervals representing |
| 297 // a variable's live range. Generally there is one interval per basic | 299 // a variable's live range. Generally there is one interval per basic |
| 298 // block where the variable is live, but adjacent intervals get | 300 // block where the variable is live, but adjacent intervals get |
| 299 // coalesced into a single interval. LiveRange also includes a | 301 // coalesced into a single interval. LiveRange also includes a |
| 300 // weight, in case e.g. we want a live range to have higher weight | 302 // weight, in case e.g. we want a live range to have higher weight |
| 301 // inside a loop. | 303 // inside a loop. |
| 302 class LiveRange { | 304 class LiveRange { |
| 305 // LiveRange(const LiveRange &) = delete; |
| 306 // LiveRange &operator=(const LiveRange &) = delete; |
| 307 |
| 303 public: | 308 public: |
| 304 LiveRange() : Weight(0), IsNonpoints(false) {} | 309 LiveRange() : Weight(0), IsNonpoints(false) {} |
| 305 | 310 |
| 306 void reset() { | 311 void reset() { |
| 307 Range.clear(); | 312 Range.clear(); |
| 308 Weight.setWeight(0); | 313 Weight.setWeight(0); |
| 309 untrim(); | 314 untrim(); |
| 310 IsNonpoints = false; | 315 IsNonpoints = false; |
| 311 } | 316 } |
| 312 void addSegment(InstNumberT Start, InstNumberT End); | 317 void addSegment(InstNumberT Start, InstNumberT End); |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 509 // VarsReal (and Operand::Vars) are set up such that Vars[0] == | 514 // VarsReal (and Operand::Vars) are set up such that Vars[0] == |
| 510 // this. | 515 // this. |
| 511 Variable *VarsReal[1]; | 516 Variable *VarsReal[1]; |
| 512 }; | 517 }; |
| 513 | 518 |
| 514 typedef std::vector<const Inst *> InstDefList; | 519 typedef std::vector<const Inst *> InstDefList; |
| 515 | 520 |
| 516 // VariableTracking tracks the metadata for a single variable. It is | 521 // VariableTracking tracks the metadata for a single variable. It is |
| 517 // only meant to be used internally by VariablesMetadata. | 522 // only meant to be used internally by VariablesMetadata. |
| 518 class VariableTracking { | 523 class VariableTracking { |
| 524 // VariableTracking(const VariableTracking &) = delete; |
| 525 VariableTracking &operator=(const VariableTracking &) = delete; |
| 526 |
| 519 public: | 527 public: |
| 520 enum MultiDefState { | 528 enum MultiDefState { |
| 521 // TODO(stichnot): Consider using just a simple counter. | 529 // TODO(stichnot): Consider using just a simple counter. |
| 522 MDS_Unknown, | 530 MDS_Unknown, |
| 523 MDS_SingleDef, | 531 MDS_SingleDef, |
| 524 MDS_MultiDefSingleBlock, | 532 MDS_MultiDefSingleBlock, |
| 525 MDS_MultiDefMultiBlock | 533 MDS_MultiDefMultiBlock |
| 526 }; | 534 }; |
| 527 enum MultiBlockState { | 535 enum MultiBlockState { |
| 528 MBS_Unknown, | 536 MBS_Unknown, |
| 529 MBS_SingleBlock, | 537 MBS_SingleBlock, |
| 530 MBS_MultiBlock | 538 MBS_MultiBlock |
| 531 }; | 539 }; |
| 532 VariableTracking() | 540 VariableTracking() |
| 533 : MultiDef(MDS_Unknown), MultiBlock(MBS_Unknown), SingleUseNode(NULL), | 541 : MultiDef(MDS_Unknown), MultiBlock(MBS_Unknown), SingleUseNode(NULL), |
| 534 SingleDefNode(NULL) {} | 542 SingleDefNode(NULL) {} |
| 535 MultiDefState getMultiDef() const { return MultiDef; } | 543 MultiDefState getMultiDef() const { return MultiDef; } |
| 536 MultiBlockState getMultiBlock() const { return MultiBlock; } | 544 MultiBlockState getMultiBlock() const { return MultiBlock; } |
| 537 const Inst *getFirstDefinition() const; | 545 const Inst *getFirstDefinition() const; |
| 538 const Inst *getSingleDefinition() const; | 546 const Inst *getSingleDefinition() const; |
| 539 const InstDefList &getDefinitions() const { return Definitions; } | 547 const InstDefList &getDefinitions() const { return Definitions; } |
| 540 const CfgNode *getNode() const { return SingleUseNode; } | 548 const CfgNode *getNode() const { return SingleUseNode; } |
| 541 void markUse(const Inst *Instr, const CfgNode *Node, bool IsFromDef, | 549 void markUse(const Inst *Instr, const CfgNode *Node, bool IsFromDef, |
| 542 bool IsImplicit); | 550 bool IsImplicit); |
| 543 void markDef(const Inst *Instr, const CfgNode *Node); | 551 void markDef(const Inst *Instr, const CfgNode *Node); |
| 544 | 552 |
| 545 private: | 553 private: |
| 546 VariableTracking &operator=(const VariableTracking &) = delete; | |
| 547 MultiDefState MultiDef; | 554 MultiDefState MultiDef; |
| 548 MultiBlockState MultiBlock; | 555 MultiBlockState MultiBlock; |
| 549 const CfgNode *SingleUseNode; | 556 const CfgNode *SingleUseNode; |
| 550 const CfgNode *SingleDefNode; | 557 const CfgNode *SingleDefNode; |
| 551 // All definitions of the variable are collected here, in increasing | 558 // All definitions of the variable are collected here, in increasing |
| 552 // order of instruction number. | 559 // order of instruction number. |
| 553 InstDefList Definitions; | 560 InstDefList Definitions; |
| 554 }; | 561 }; |
| 555 | 562 |
| 556 // VariablesMetadata analyzes and summarizes the metadata for the | 563 // VariablesMetadata analyzes and summarizes the metadata for the |
| 557 // complete set of Variables. | 564 // complete set of Variables. |
| 558 class VariablesMetadata { | 565 class VariablesMetadata { |
| 566 VariablesMetadata(const VariablesMetadata &) = delete; |
| 567 VariablesMetadata &operator=(const VariablesMetadata &) = delete; |
| 568 |
| 559 public: | 569 public: |
| 560 VariablesMetadata(const Cfg *Func) : Func(Func) {} | 570 VariablesMetadata(const Cfg *Func) : Func(Func) {} |
| 561 // Initialize the state by traversing all instructions/variables in | 571 // Initialize the state by traversing all instructions/variables in |
| 562 // the CFG. | 572 // the CFG. |
| 563 void init(); | 573 void init(); |
| 564 // Returns whether the given Variable is tracked in this object. It | 574 // Returns whether the given Variable is tracked in this object. It |
| 565 // should only return false if changes were made to the CFG after | 575 // should only return false if changes were made to the CFG after |
| 566 // running init(), in which case the state is stale and the results | 576 // running init(), in which case the state is stale and the results |
| 567 // shouldn't be trusted (but it may be OK e.g. for dumping). | 577 // shouldn't be trusted (but it may be OK e.g. for dumping). |
| 568 bool isTracked(const Variable *Var) const { | 578 bool isTracked(const Variable *Var) const { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 595 // entry block. | 605 // entry block. |
| 596 bool isMultiBlock(const Variable *Var) const; | 606 bool isMultiBlock(const Variable *Var) const; |
| 597 // Returns the node that the given Variable is used in, assuming | 607 // Returns the node that the given Variable is used in, assuming |
| 598 // isMultiBlock() returns false. Otherwise, NULL is returned. | 608 // isMultiBlock() returns false. Otherwise, NULL is returned. |
| 599 const CfgNode *getLocalUseNode(const Variable *Var) const; | 609 const CfgNode *getLocalUseNode(const Variable *Var) const; |
| 600 | 610 |
| 601 private: | 611 private: |
| 602 const Cfg *Func; | 612 const Cfg *Func; |
| 603 std::vector<VariableTracking> Metadata; | 613 std::vector<VariableTracking> Metadata; |
| 604 const static InstDefList NoDefinitions; | 614 const static InstDefList NoDefinitions; |
| 605 VariablesMetadata(const VariablesMetadata &) = delete; | |
| 606 VariablesMetadata &operator=(const VariablesMetadata &) = delete; | |
| 607 }; | 615 }; |
| 608 | 616 |
| 609 } // end of namespace Ice | 617 } // end of namespace Ice |
| 610 | 618 |
| 611 #endif // SUBZERO_SRC_ICEOPERAND_H | 619 #endif // SUBZERO_SRC_ICEOPERAND_H |
| OLD | NEW |