| 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() = delete; |
| 29 Operand(const Operand &) = delete; | 30 Operand(const Operand &) = delete; |
| 30 Operand &operator=(const Operand &) = delete; | 31 Operand &operator=(const Operand &) = delete; |
| 31 | 32 |
| 32 public: | 33 public: |
| 33 static const size_t MaxTargetKinds = 10; | 34 static const size_t MaxTargetKinds = 10; |
| 34 enum OperandKind { | 35 enum OperandKind { |
| 35 kConst_Base, | 36 kConst_Base, |
| 36 kConstInteger32, | 37 kConstInteger32, |
| 37 kConstInteger64, | 38 kConstInteger64, |
| 38 kConstFloat, | 39 kConstFloat, |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 | 91 |
| 91 template <class StreamType> | 92 template <class StreamType> |
| 92 inline StreamType &operator<<(StreamType &Str, const Operand &Op) { | 93 inline StreamType &operator<<(StreamType &Str, const Operand &Op) { |
| 93 Op.dump(Str); | 94 Op.dump(Str); |
| 94 return Str; | 95 return Str; |
| 95 } | 96 } |
| 96 | 97 |
| 97 // Constant is the abstract base class for constants. All | 98 // Constant is the abstract base class for constants. All |
| 98 // constants are allocated from a global arena and are pooled. | 99 // constants are allocated from a global arena and are pooled. |
| 99 class Constant : public Operand { | 100 class Constant : public Operand { |
| 101 Constant() = delete; |
| 100 Constant(const Constant &) = delete; | 102 Constant(const Constant &) = delete; |
| 101 Constant &operator=(const Constant &) = delete; | 103 Constant &operator=(const Constant &) = delete; |
| 102 | 104 |
| 103 public: | 105 public: |
| 104 void emitPoolLabel(Ostream &Str) const { | 106 void emitPoolLabel(Ostream &Str) const { |
| 105 Str << ".L$" << getType() << "$" << PoolEntryID; | 107 Str << ".L$" << getType() << "$" << PoolEntryID; |
| 106 } | 108 } |
| 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 | 111 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 121 ~Constant() override {} | 123 ~Constant() override {} |
| 122 // PoolEntryID is an integer that uniquely identifies the constant | 124 // PoolEntryID is an integer that uniquely identifies the constant |
| 123 // within its constant pool. It is used for building the constant | 125 // within its constant pool. It is used for building the constant |
| 124 // pool in the object code and for referencing its entries. | 126 // pool in the object code and for referencing its entries. |
| 125 const uint32_t PoolEntryID; | 127 const uint32_t PoolEntryID; |
| 126 }; | 128 }; |
| 127 | 129 |
| 128 // ConstantPrimitive<> wraps a primitive type. | 130 // ConstantPrimitive<> wraps a primitive type. |
| 129 template <typename T, Operand::OperandKind K> | 131 template <typename T, Operand::OperandKind K> |
| 130 class ConstantPrimitive : public Constant { | 132 class ConstantPrimitive : public Constant { |
| 133 ConstantPrimitive() = delete; |
| 131 ConstantPrimitive(const ConstantPrimitive &) = delete; | 134 ConstantPrimitive(const ConstantPrimitive &) = delete; |
| 132 ConstantPrimitive &operator=(const ConstantPrimitive &) = delete; | 135 ConstantPrimitive &operator=(const ConstantPrimitive &) = delete; |
| 133 | 136 |
| 134 public: | 137 public: |
| 135 typedef T PrimType; | 138 typedef T PrimType; |
| 136 | 139 |
| 137 static ConstantPrimitive *create(GlobalContext *Ctx, Type Ty, PrimType Value, | 140 static ConstantPrimitive *create(GlobalContext *Ctx, Type Ty, PrimType Value, |
| 138 uint32_t PoolEntryID) { | 141 uint32_t PoolEntryID) { |
| 139 assert(!Ctx->isIRGenerationDisabled() && | 142 assert(!Ctx->isIRGenerationDisabled() && |
| 140 "Attempt to build primitive constant when IR generation disabled"); | 143 "Attempt to build primitive constant when IR generation disabled"); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 return; | 187 return; |
| 185 assert(getType() == IceType_i64); | 188 assert(getType() == IceType_i64); |
| 186 Str << static_cast<int64_t>(getValue()); | 189 Str << static_cast<int64_t>(getValue()); |
| 187 } | 190 } |
| 188 | 191 |
| 189 // RelocatableTuple bundles the parameters that are used to | 192 // RelocatableTuple bundles the parameters that are used to |
| 190 // construct an ConstantRelocatable. It is done this way so that | 193 // construct an ConstantRelocatable. It is done this way so that |
| 191 // ConstantRelocatable can fit into the global constant pool | 194 // ConstantRelocatable can fit into the global constant pool |
| 192 // template mechanism. | 195 // template mechanism. |
| 193 class RelocatableTuple { | 196 class RelocatableTuple { |
| 197 RelocatableTuple() = delete; |
| 194 RelocatableTuple &operator=(const RelocatableTuple &) = delete; | 198 RelocatableTuple &operator=(const RelocatableTuple &) = delete; |
| 195 | 199 |
| 196 public: | 200 public: |
| 197 RelocatableTuple(const RelocOffsetT Offset, const IceString &Name, | 201 RelocatableTuple(const RelocOffsetT Offset, const IceString &Name, |
| 198 bool SuppressMangling) | 202 bool SuppressMangling) |
| 199 : Offset(Offset), Name(Name), SuppressMangling(SuppressMangling) {} | 203 : Offset(Offset), Name(Name), SuppressMangling(SuppressMangling) {} |
| 200 RelocatableTuple(const RelocatableTuple &) = default; | 204 RelocatableTuple(const RelocatableTuple &) = default; |
| 201 | 205 |
| 202 const RelocOffsetT Offset; | 206 const RelocOffsetT Offset; |
| 203 const IceString Name; | 207 const IceString Name; |
| 204 bool SuppressMangling; | 208 bool SuppressMangling; |
| 205 }; | 209 }; |
| 206 | 210 |
| 207 bool operator==(const RelocatableTuple &A, const RelocatableTuple &B); | 211 bool operator==(const RelocatableTuple &A, const RelocatableTuple &B); |
| 208 | 212 |
| 209 // ConstantRelocatable represents a symbolic constant combined with | 213 // ConstantRelocatable represents a symbolic constant combined with |
| 210 // a fixed offset. | 214 // a fixed offset. |
| 211 class ConstantRelocatable : public Constant { | 215 class ConstantRelocatable : public Constant { |
| 216 ConstantRelocatable() = delete; |
| 212 ConstantRelocatable(const ConstantRelocatable &) = delete; | 217 ConstantRelocatable(const ConstantRelocatable &) = delete; |
| 213 ConstantRelocatable &operator=(const ConstantRelocatable &) = delete; | 218 ConstantRelocatable &operator=(const ConstantRelocatable &) = delete; |
| 214 | 219 |
| 215 public: | 220 public: |
| 216 static ConstantRelocatable *create(GlobalContext *Ctx, Type Ty, | 221 static ConstantRelocatable *create(GlobalContext *Ctx, Type Ty, |
| 217 const RelocatableTuple &Tuple, | 222 const RelocatableTuple &Tuple, |
| 218 uint32_t PoolEntryID) { | 223 uint32_t PoolEntryID) { |
| 219 assert(!Ctx->isIRGenerationDisabled() && | 224 assert(!Ctx->isIRGenerationDisabled() && |
| 220 "Attempt to build relocatable constant when IR generation disabled"); | 225 "Attempt to build relocatable constant when IR generation disabled"); |
| 221 return new (Ctx->allocate<ConstantRelocatable>()) ConstantRelocatable( | 226 return new (Ctx->allocate<ConstantRelocatable>()) ConstantRelocatable( |
| (...skipping 23 matching lines...) Expand all Loading... |
| 245 ~ConstantRelocatable() override {} | 250 ~ConstantRelocatable() override {} |
| 246 const RelocOffsetT Offset; // fixed offset to add | 251 const RelocOffsetT Offset; // fixed offset to add |
| 247 const IceString Name; // optional for debug/dump | 252 const IceString Name; // optional for debug/dump |
| 248 bool SuppressMangling; | 253 bool SuppressMangling; |
| 249 }; | 254 }; |
| 250 | 255 |
| 251 // ConstantUndef represents an unspecified bit pattern. Although it is | 256 // ConstantUndef represents an unspecified bit pattern. Although it is |
| 252 // legal to lower ConstantUndef to any value, backends should try to | 257 // legal to lower ConstantUndef to any value, backends should try to |
| 253 // make code generation deterministic by lowering ConstantUndefs to 0. | 258 // make code generation deterministic by lowering ConstantUndefs to 0. |
| 254 class ConstantUndef : public Constant { | 259 class ConstantUndef : public Constant { |
| 260 ConstantUndef() = delete; |
| 255 ConstantUndef(const ConstantUndef &) = delete; | 261 ConstantUndef(const ConstantUndef &) = delete; |
| 256 ConstantUndef &operator=(const ConstantUndef &) = delete; | 262 ConstantUndef &operator=(const ConstantUndef &) = delete; |
| 257 | 263 |
| 258 public: | 264 public: |
| 259 static ConstantUndef *create(GlobalContext *Ctx, Type Ty, | 265 static ConstantUndef *create(GlobalContext *Ctx, Type Ty, |
| 260 uint32_t PoolEntryID) { | 266 uint32_t PoolEntryID) { |
| 261 assert(!Ctx->isIRGenerationDisabled() && | 267 assert(!Ctx->isIRGenerationDisabled() && |
| 262 "Attempt to build undefined constant when IR generation disabled"); | 268 "Attempt to build undefined constant when IR generation disabled"); |
| 263 return new (Ctx->allocate<ConstantUndef>()) ConstantUndef(Ty, PoolEntryID); | 269 return new (Ctx->allocate<ConstantUndef>()) ConstantUndef(Ty, PoolEntryID); |
| 264 } | 270 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 279 private: | 285 private: |
| 280 ConstantUndef(Type Ty, uint32_t PoolEntryID) | 286 ConstantUndef(Type Ty, uint32_t PoolEntryID) |
| 281 : Constant(kConstUndef, Ty, PoolEntryID) {} | 287 : Constant(kConstUndef, Ty, PoolEntryID) {} |
| 282 ~ConstantUndef() override {} | 288 ~ConstantUndef() override {} |
| 283 }; | 289 }; |
| 284 | 290 |
| 285 // RegWeight is a wrapper for a uint32_t weight value, with a | 291 // RegWeight is a wrapper for a uint32_t weight value, with a |
| 286 // special value that represents infinite weight, and an addWeight() | 292 // special value that represents infinite weight, and an addWeight() |
| 287 // method that ensures that W+infinity=infinity. | 293 // method that ensures that W+infinity=infinity. |
| 288 class RegWeight { | 294 class RegWeight { |
| 289 | |
| 290 public: | 295 public: |
| 291 RegWeight() : Weight(0) {} | 296 RegWeight() : Weight(0) {} |
| 292 RegWeight(uint32_t Weight) : Weight(Weight) {} | 297 explicit RegWeight(uint32_t Weight) : Weight(Weight) {} |
| 293 RegWeight(const RegWeight &) = default; | 298 RegWeight(const RegWeight &) = default; |
| 294 RegWeight &operator=(const RegWeight &) = default; | 299 RegWeight &operator=(const RegWeight &) = default; |
| 295 const static uint32_t Inf = ~0; // Force regalloc to give a register | 300 const static uint32_t Inf = ~0; // Force regalloc to give a register |
| 296 const static uint32_t Zero = 0; // Force regalloc NOT to give a register | 301 const static uint32_t Zero = 0; // Force regalloc NOT to give a register |
| 297 void addWeight(uint32_t Delta) { | 302 void addWeight(uint32_t Delta) { |
| 298 if (Delta == Inf) | 303 if (Delta == Inf) |
| 299 Weight = Inf; | 304 Weight = Inf; |
| 300 else if (Weight != Inf) | 305 else if (Weight != Inf) |
| 301 Weight += Delta; | 306 Weight += Delta; |
| 302 } | 307 } |
| 303 void addWeight(const RegWeight &Other) { addWeight(Other.Weight); } | 308 void addWeight(const RegWeight &Other) { addWeight(Other.Weight); } |
| 304 void setWeight(uint32_t Val) { Weight = Val; } | 309 void setWeight(uint32_t Val) { Weight = Val; } |
| 305 uint32_t getWeight() const { return Weight; } | 310 uint32_t getWeight() const { return Weight; } |
| 306 bool isInf() const { return Weight == Inf; } | 311 bool isInf() const { return Weight == Inf; } |
| 312 bool isZero() const { return Weight == Zero; } |
| 307 | 313 |
| 308 private: | 314 private: |
| 309 uint32_t Weight; | 315 uint32_t Weight; |
| 310 }; | 316 }; |
| 311 Ostream &operator<<(Ostream &Str, const RegWeight &W); | 317 Ostream &operator<<(Ostream &Str, const RegWeight &W); |
| 312 bool operator<(const RegWeight &A, const RegWeight &B); | 318 bool operator<(const RegWeight &A, const RegWeight &B); |
| 313 bool operator<=(const RegWeight &A, const RegWeight &B); | 319 bool operator<=(const RegWeight &A, const RegWeight &B); |
| 314 bool operator==(const RegWeight &A, const RegWeight &B); | 320 bool operator==(const RegWeight &A, const RegWeight &B); |
| 315 | 321 |
| 316 // LiveRange is a set of instruction number intervals representing | 322 // LiveRange is a set of instruction number intervals representing |
| 317 // a variable's live range. Generally there is one interval per basic | 323 // a variable's live range. Generally there is one interval per basic |
| 318 // block where the variable is live, but adjacent intervals get | 324 // block where the variable is live, but adjacent intervals get |
| 319 // coalesced into a single interval. LiveRange also includes a | 325 // coalesced into a single interval. LiveRange also includes a |
| 320 // weight, in case e.g. we want a live range to have higher weight | 326 // weight, in case e.g. we want a live range to have higher weight |
| 321 // inside a loop. | 327 // inside a loop. |
| 322 class LiveRange { | 328 class LiveRange { |
| 323 public: | 329 public: |
| 324 LiveRange() : Weight(0) {} | 330 LiveRange() : Weight(0) {} |
| 325 // Special constructor for building a kill set. The advantage is | 331 // Special constructor for building a kill set. The advantage is |
| 326 // that we can reserve the right amount of space in advance. | 332 // that we can reserve the right amount of space in advance. |
| 327 LiveRange(const std::vector<InstNumberT> &Kills) : Weight(0) { | 333 explicit LiveRange(const std::vector<InstNumberT> &Kills) : Weight(0) { |
| 328 Range.reserve(Kills.size()); | 334 Range.reserve(Kills.size()); |
| 329 for (InstNumberT I : Kills) | 335 for (InstNumberT I : Kills) |
| 330 addSegment(I, I); | 336 addSegment(I, I); |
| 331 } | 337 } |
| 332 LiveRange(const LiveRange &) = default; | 338 LiveRange(const LiveRange &) = default; |
| 333 LiveRange &operator=(const LiveRange &) = default; | 339 LiveRange &operator=(const LiveRange &) = default; |
| 334 | 340 |
| 335 void reset() { | 341 void reset() { |
| 336 Range.clear(); | 342 Range.clear(); |
| 337 Weight.setWeight(0); | 343 Weight.setWeight(0); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 373 // beginning by calling untrim(). | 379 // beginning by calling untrim(). |
| 374 RangeType::const_iterator TrimmedBegin; | 380 RangeType::const_iterator TrimmedBegin; |
| 375 }; | 381 }; |
| 376 | 382 |
| 377 Ostream &operator<<(Ostream &Str, const LiveRange &L); | 383 Ostream &operator<<(Ostream &Str, const LiveRange &L); |
| 378 | 384 |
| 379 // Variable represents an operand that is register-allocated or | 385 // Variable represents an operand that is register-allocated or |
| 380 // stack-allocated. If it is register-allocated, it will ultimately | 386 // stack-allocated. If it is register-allocated, it will ultimately |
| 381 // have a non-negative RegNum field. | 387 // have a non-negative RegNum field. |
| 382 class Variable : public Operand { | 388 class Variable : public Operand { |
| 389 Variable() = delete; |
| 383 Variable(const Variable &) = delete; | 390 Variable(const Variable &) = delete; |
| 384 Variable &operator=(const Variable &) = delete; | 391 Variable &operator=(const Variable &) = delete; |
| 385 | 392 |
| 386 public: | 393 public: |
| 387 static Variable *create(Cfg *Func, Type Ty, SizeT Index) { | 394 static Variable *create(Cfg *Func, Type Ty, SizeT Index) { |
| 388 return new (Func->allocate<Variable>()) Variable(kVariable, Ty, Index); | 395 return new (Func->allocate<Variable>()) Variable(kVariable, Ty, Index); |
| 389 } | 396 } |
| 390 | 397 |
| 391 SizeT getIndex() const { return Number; } | 398 SizeT getIndex() const { return Number; } |
| 392 IceString getName(const Cfg *Func) const; | 399 IceString getName(const Cfg *Func) const; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 414 void setRegNum(int32_t NewRegNum) { | 421 void setRegNum(int32_t NewRegNum) { |
| 415 // Regnum shouldn't be set more than once. | 422 // Regnum shouldn't be set more than once. |
| 416 assert(!hasReg() || RegNum == NewRegNum); | 423 assert(!hasReg() || RegNum == NewRegNum); |
| 417 RegNum = NewRegNum; | 424 RegNum = NewRegNum; |
| 418 } | 425 } |
| 419 bool hasRegTmp() const { return getRegNumTmp() != NoRegister; } | 426 bool hasRegTmp() const { return getRegNumTmp() != NoRegister; } |
| 420 int32_t getRegNumTmp() const { return RegNumTmp; } | 427 int32_t getRegNumTmp() const { return RegNumTmp; } |
| 421 void setRegNumTmp(int32_t NewRegNum) { RegNumTmp = NewRegNum; } | 428 void setRegNumTmp(int32_t NewRegNum) { RegNumTmp = NewRegNum; } |
| 422 | 429 |
| 423 RegWeight getWeight() const { return Weight; } | 430 RegWeight getWeight() const { return Weight; } |
| 424 void setWeight(uint32_t NewWeight) { Weight = NewWeight; } | 431 void setWeight(uint32_t NewWeight) { Weight = RegWeight(NewWeight); } |
| 425 void setWeightInfinite() { Weight = RegWeight::Inf; } | 432 void setWeightInfinite() { setWeight(RegWeight::Inf); } |
| 426 | 433 |
| 427 LiveRange &getLiveRange() { return Live; } | 434 LiveRange &getLiveRange() { return Live; } |
| 428 const LiveRange &getLiveRange() const { return Live; } | 435 const LiveRange &getLiveRange() const { return Live; } |
| 429 void setLiveRange(const LiveRange &Range) { Live = Range; } | 436 void setLiveRange(const LiveRange &Range) { Live = Range; } |
| 430 void resetLiveRange() { Live.reset(); } | 437 void resetLiveRange() { Live.reset(); } |
| 431 void addLiveRange(InstNumberT Start, InstNumberT End, uint32_t WeightDelta) { | 438 void addLiveRange(InstNumberT Start, InstNumberT End, uint32_t WeightDelta) { |
| 432 assert(WeightDelta != RegWeight::Inf); | 439 assert(WeightDelta != RegWeight::Inf); |
| 433 Live.addSegment(Start, End); | 440 Live.addSegment(Start, End); |
| 434 if (Weight.isInf()) | 441 if (Weight.isInf()) |
| 435 Live.setWeight(RegWeight::Inf); | 442 Live.setWeight(RegWeight(RegWeight::Inf)); |
| 436 else | 443 else |
| 437 Live.addWeight(WeightDelta * Weight.getWeight()); | 444 Live.addWeight(WeightDelta * Weight.getWeight()); |
| 438 } | 445 } |
| 439 void setLiveRangeInfiniteWeight() { Live.setWeight(RegWeight::Inf); } | 446 void setLiveRangeInfiniteWeight() { |
| 447 Live.setWeight(RegWeight(RegWeight::Inf)); |
| 448 } |
| 440 void trimLiveRange(InstNumberT Start) { Live.trim(Start); } | 449 void trimLiveRange(InstNumberT Start) { Live.trim(Start); } |
| 441 void untrimLiveRange() { Live.untrim(); } | 450 void untrimLiveRange() { Live.untrim(); } |
| 442 bool rangeEndsBefore(const Variable *Other) const { | 451 bool rangeEndsBefore(const Variable *Other) const { |
| 443 return Live.endsBefore(Other->Live); | 452 return Live.endsBefore(Other->Live); |
| 444 } | 453 } |
| 445 bool rangeOverlaps(const Variable *Other) const { | 454 bool rangeOverlaps(const Variable *Other) const { |
| 446 const bool UseTrimmed = true; | 455 const bool UseTrimmed = true; |
| 447 return Live.overlaps(Other->Live, UseTrimmed); | 456 return Live.overlaps(Other->Live, UseTrimmed); |
| 448 } | 457 } |
| 449 bool rangeOverlapsStart(const Variable *Other) const { | 458 bool rangeOverlapsStart(const Variable *Other) const { |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 563 const CfgNode *SingleDefNode; | 572 const CfgNode *SingleDefNode; |
| 564 // All definitions of the variable are collected here, in increasing | 573 // All definitions of the variable are collected here, in increasing |
| 565 // order of instruction number. | 574 // order of instruction number. |
| 566 InstDefList Definitions; // Only used if Kind==VMK_All | 575 InstDefList Definitions; // Only used if Kind==VMK_All |
| 567 const Inst *FirstOrSingleDefinition; // == Definitions[0] if Kind==VMK_All | 576 const Inst *FirstOrSingleDefinition; // == Definitions[0] if Kind==VMK_All |
| 568 }; | 577 }; |
| 569 | 578 |
| 570 // VariablesMetadata analyzes and summarizes the metadata for the | 579 // VariablesMetadata analyzes and summarizes the metadata for the |
| 571 // complete set of Variables. | 580 // complete set of Variables. |
| 572 class VariablesMetadata { | 581 class VariablesMetadata { |
| 582 VariablesMetadata() = delete; |
| 573 VariablesMetadata(const VariablesMetadata &) = delete; | 583 VariablesMetadata(const VariablesMetadata &) = delete; |
| 574 VariablesMetadata &operator=(const VariablesMetadata &) = delete; | 584 VariablesMetadata &operator=(const VariablesMetadata &) = delete; |
| 575 | 585 |
| 576 public: | 586 public: |
| 577 VariablesMetadata(const Cfg *Func) : Func(Func) {} | 587 explicit VariablesMetadata(const Cfg *Func) : Func(Func) {} |
| 578 // Initialize the state by traversing all instructions/variables in | 588 // Initialize the state by traversing all instructions/variables in |
| 579 // the CFG. | 589 // the CFG. |
| 580 void init(MetadataKind TrackingKind); | 590 void init(MetadataKind TrackingKind); |
| 581 // Add a single node. This is called by init(), and can be called | 591 // Add a single node. This is called by init(), and can be called |
| 582 // incrementally from elsewhere, e.g. after edge-splitting. | 592 // incrementally from elsewhere, e.g. after edge-splitting. |
| 583 void addNode(CfgNode *Node); | 593 void addNode(CfgNode *Node); |
| 584 // Returns whether the given Variable is tracked in this object. It | 594 // Returns whether the given Variable is tracked in this object. It |
| 585 // should only return false if changes were made to the CFG after | 595 // should only return false if changes were made to the CFG after |
| 586 // running init(), in which case the state is stale and the results | 596 // running init(), in which case the state is stale and the results |
| 587 // shouldn't be trusted (but it may be OK e.g. for dumping). | 597 // shouldn't be trusted (but it may be OK e.g. for dumping). |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 621 private: | 631 private: |
| 622 const Cfg *Func; | 632 const Cfg *Func; |
| 623 MetadataKind Kind; | 633 MetadataKind Kind; |
| 624 std::vector<VariableTracking> Metadata; | 634 std::vector<VariableTracking> Metadata; |
| 625 const static InstDefList NoDefinitions; | 635 const static InstDefList NoDefinitions; |
| 626 }; | 636 }; |
| 627 | 637 |
| 628 } // end of namespace Ice | 638 } // end of namespace Ice |
| 629 | 639 |
| 630 #endif // SUBZERO_SRC_ICEOPERAND_H | 640 #endif // SUBZERO_SRC_ICEOPERAND_H |
| OLD | NEW |