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 /// \file | 10 /// \file |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
421 /// monotonically according to live range start, we can optimize overlaps() by | 421 /// monotonically according to live range start, we can optimize overlaps() by |
422 /// ignoring all segments that end before the start of Cur's range. The | 422 /// ignoring all segments that end before the start of Cur's range. The |
423 /// linear-scan code enables this by calling trim() on the ranges of interest | 423 /// linear-scan code enables this by calling trim() on the ranges of interest |
424 /// as Cur advances. Note that linear-scan also has to initialize TrimmedBegin | 424 /// as Cur advances. Note that linear-scan also has to initialize TrimmedBegin |
425 /// at the beginning by calling untrim(). | 425 /// at the beginning by calling untrim(). |
426 RangeType::const_iterator TrimmedBegin; | 426 RangeType::const_iterator TrimmedBegin; |
427 }; | 427 }; |
428 | 428 |
429 Ostream &operator<<(Ostream &Str, const LiveRange &L); | 429 Ostream &operator<<(Ostream &Str, const LiveRange &L); |
430 | 430 |
| 431 /// RegClass indicates the physical register class that a Variable may be |
| 432 /// register-allocated from. By default, a variable's register class is |
| 433 /// directly associated with its type. However, the target lowering may define |
| 434 /// additional target-specific register classes by extending the set of enum |
| 435 /// values. |
| 436 enum RegClass : uint8_t { |
| 437 // Define RC_void, RC_i1, RC_i8, etc. |
| 438 #define X(tag, sizeLog2, align, elts, elty, str) RC_##tag = IceType_##tag, |
| 439 ICETYPE_TABLE |
| 440 #undef X |
| 441 RC_Target, |
| 442 // Leave plenty of space for target-specific values. |
| 443 RC_Max = std::numeric_limits<uint8_t>::max() |
| 444 }; |
| 445 static_assert(RC_Target == static_cast<RegClass>(IceType_NUM), |
| 446 "Expected RC_Target and IceType_NUM to be the same"); |
| 447 |
431 /// Variable represents an operand that is register-allocated or | 448 /// Variable represents an operand that is register-allocated or |
432 /// stack-allocated. If it is register-allocated, it will ultimately have a | 449 /// stack-allocated. If it is register-allocated, it will ultimately have a |
433 /// non-negative RegNum field. | 450 /// non-negative RegNum field. |
434 class Variable : public Operand { | 451 class Variable : public Operand { |
435 Variable() = delete; | 452 Variable() = delete; |
436 Variable(const Variable &) = delete; | 453 Variable(const Variable &) = delete; |
437 Variable &operator=(const Variable &) = delete; | 454 Variable &operator=(const Variable &) = delete; |
438 | 455 |
439 enum RegRequirement : uint8_t { | 456 enum RegRequirement : uint8_t { |
440 RR_MayHaveRegister, | 457 RR_MayHaveRegister, |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
486 | 503 |
487 RegWeight getWeight(const Cfg *Func) const; | 504 RegWeight getWeight(const Cfg *Func) const; |
488 | 505 |
489 void setMustHaveReg() { RegRequirement = RR_MustHaveRegister; } | 506 void setMustHaveReg() { RegRequirement = RR_MustHaveRegister; } |
490 bool mustHaveReg() const { return RegRequirement == RR_MustHaveRegister; } | 507 bool mustHaveReg() const { return RegRequirement == RR_MustHaveRegister; } |
491 void setMustNotHaveReg() { RegRequirement = RR_MustNotHaveRegister; } | 508 void setMustNotHaveReg() { RegRequirement = RR_MustNotHaveRegister; } |
492 bool mustNotHaveReg() const { | 509 bool mustNotHaveReg() const { |
493 return RegRequirement == RR_MustNotHaveRegister; | 510 return RegRequirement == RR_MustNotHaveRegister; |
494 } | 511 } |
495 | 512 |
| 513 void setRegClass(uint8_t RC) { RegisterClass = static_cast<RegClass>(RC); } |
| 514 RegClass getRegClass() const { return RegisterClass; } |
| 515 |
496 LiveRange &getLiveRange() { return Live; } | 516 LiveRange &getLiveRange() { return Live; } |
497 const LiveRange &getLiveRange() const { return Live; } | 517 const LiveRange &getLiveRange() const { return Live; } |
498 void setLiveRange(const LiveRange &Range) { Live = Range; } | 518 void setLiveRange(const LiveRange &Range) { Live = Range; } |
499 void resetLiveRange() { Live.reset(); } | 519 void resetLiveRange() { Live.reset(); } |
500 void addLiveRange(InstNumberT Start, InstNumberT End) { | 520 void addLiveRange(InstNumberT Start, InstNumberT End) { |
501 assert(!getIgnoreLiveness()); | 521 assert(!getIgnoreLiveness()); |
502 Live.addSegment(Start, End); | 522 Live.addSegment(Start, End); |
503 } | 523 } |
504 void trimLiveRange(InstNumberT Start) { Live.trim(Start); } | 524 void trimLiveRange(InstNumberT Start) { Live.trim(Start); } |
505 void untrimLiveRange() { Live.untrim(); } | 525 void untrimLiveRange() { Live.untrim(); } |
(...skipping 24 matching lines...) Expand all Loading... |
530 /// Return reg num of base register, if different from stack/frame register. | 550 /// Return reg num of base register, if different from stack/frame register. |
531 virtual int32_t getBaseRegNum() const { return NoRegister; } | 551 virtual int32_t getBaseRegNum() const { return NoRegister; } |
532 | 552 |
533 static bool classof(const Operand *Operand) { | 553 static bool classof(const Operand *Operand) { |
534 OperandKind Kind = Operand->getKind(); | 554 OperandKind Kind = Operand->getKind(); |
535 return Kind >= kVariable && Kind <= kVariable_Max; | 555 return Kind >= kVariable && Kind <= kVariable_Max; |
536 } | 556 } |
537 | 557 |
538 protected: | 558 protected: |
539 Variable(OperandKind K, Type Ty, SizeT Index) | 559 Variable(OperandKind K, Type Ty, SizeT Index) |
540 : Operand(K, Ty), Number(Index) { | 560 : Operand(K, Ty), Number(Index), |
| 561 RegisterClass(static_cast<RegClass>(Ty)) { |
541 Vars = VarsReal; | 562 Vars = VarsReal; |
542 Vars[0] = this; | 563 Vars[0] = this; |
543 NumVars = 1; | 564 NumVars = 1; |
544 } | 565 } |
545 /// Number is unique across all variables, and is used as a (bit)vector index | 566 /// Number is unique across all variables, and is used as a (bit)vector index |
546 /// for liveness analysis. | 567 /// for liveness analysis. |
547 const SizeT Number; | 568 const SizeT Number; |
548 Cfg::IdentifierIndexType NameIndex = Cfg::IdentifierIndexInvalid; | 569 Cfg::IdentifierIndexType NameIndex = Cfg::IdentifierIndexInvalid; |
549 bool IsArgument = false; | 570 bool IsArgument = false; |
550 bool IsImplicitArgument = false; | 571 bool IsImplicitArgument = false; |
551 /// IgnoreLiveness means that the variable should be ignored when constructing | 572 /// IgnoreLiveness means that the variable should be ignored when constructing |
552 /// and validating live ranges. This is usually reserved for the stack | 573 /// and validating live ranges. This is usually reserved for the stack |
553 /// pointer and other physical registers specifically referenced by name. | 574 /// pointer and other physical registers specifically referenced by name. |
554 bool IgnoreLiveness = false; | 575 bool IgnoreLiveness = false; |
555 RegRequirement RegRequirement = RR_MayHaveRegister; | 576 RegRequirement RegRequirement = RR_MayHaveRegister; |
| 577 RegClass RegisterClass; |
556 /// RegNum is the allocated register, or NoRegister if it isn't | 578 /// RegNum is the allocated register, or NoRegister if it isn't |
557 /// register-allocated. | 579 /// register-allocated. |
558 int32_t RegNum = NoRegister; | 580 int32_t RegNum = NoRegister; |
559 /// RegNumTmp is the tentative assignment during register allocation. | 581 /// RegNumTmp is the tentative assignment during register allocation. |
560 int32_t RegNumTmp = NoRegister; | 582 int32_t RegNumTmp = NoRegister; |
561 /// StackOffset is the canonical location on stack (only if | 583 /// StackOffset is the canonical location on stack (only if |
562 /// RegNum==NoRegister || IsArgument). | 584 /// RegNum==NoRegister || IsArgument). |
563 int32_t StackOffset = 0; | 585 int32_t StackOffset = 0; |
564 LiveRange Live; | 586 LiveRange Live; |
565 /// VarsReal (and Operand::Vars) are set up such that Vars[0] == this. | 587 /// VarsReal (and Operand::Vars) are set up such that Vars[0] == this. |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
735 private: | 757 private: |
736 const Cfg *Func; | 758 const Cfg *Func; |
737 MetadataKind Kind; | 759 MetadataKind Kind; |
738 CfgVector<VariableTracking> Metadata; | 760 CfgVector<VariableTracking> Metadata; |
739 const static InstDefList NoDefinitions; | 761 const static InstDefList NoDefinitions; |
740 }; | 762 }; |
741 | 763 |
742 } // end of namespace Ice | 764 } // end of namespace Ice |
743 | 765 |
744 #endif // SUBZERO_SRC_ICEOPERAND_H | 766 #endif // SUBZERO_SRC_ICEOPERAND_H |
OLD | NEW |