Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(322)

Side by Side Diff: src/IceOperand.h

Issue 1691193002: Subzero: Prototype to make use of RegNumT::No Register more concise (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: changes suggested by stichnot Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceInstX86BaseImpl.h ('k') | src/IceOperand.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 385 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 396
397 static bool classof(const Operand *Operand) { 397 static bool classof(const Operand *Operand) {
398 return Operand->getKind() == kConstUndef; 398 return Operand->getKind() == kConstUndef;
399 } 399 }
400 400
401 private: 401 private:
402 ConstantUndef(Type Ty) : Constant(kConstUndef, Ty) {} 402 ConstantUndef(Type Ty) : Constant(kConstUndef, Ty) {}
403 }; 403 };
404 404
405 /// RegNumT is for holding target-specific register numbers, plus the sentinel 405 /// RegNumT is for holding target-specific register numbers, plus the sentinel
406 /// value NoRegister. Its public ctor allows direct use of enum values, such as 406 /// value if no register is assigned. Its public ctor allows direct use of enum
407 /// RegNumT(Reg_eax), but not things like RegNumT(Reg_eax+1). This is to try to 407 /// values, such as RegNumT(Reg_eax), but not things like RegNumT(Reg_eax+1).
408 /// prevent inappropriate assumptions about enum ordering. If needed, the 408 /// This is to try to prevent inappropriate assumptions about enum ordering. If
409 /// fromInt() method can be used, such as when a RegNumT is based on a bitvector 409 /// needed, the fromInt() method can be used, such as when a RegNumT is based
410 /// index. 410 /// on a bitvector index.
411 class RegNumT { 411 class RegNumT {
412 public: 412 public:
413 using BaseType = uint32_t; 413 using BaseType = uint32_t;
414 RegNumT() = default; 414 RegNumT() = default;
415 RegNumT(const RegNumT &) = default; 415 RegNumT(const RegNumT &) = default;
416 template <typename AnyEnum> 416 template <typename AnyEnum>
417 RegNumT(AnyEnum Value, 417 RegNumT(AnyEnum Value,
418 typename std::enable_if<std::is_enum<AnyEnum>::value, int>::type = 0) 418 typename std::enable_if<std::is_enum<AnyEnum>::value, int>::type = 0)
419 : Value(Value) { 419 : Value(Value) {
420 validate(Value); 420 validate(Value);
(...skipping 13 matching lines...) Expand all
434 /// upper bound of allowable values. 434 /// upper bound of allowable values.
435 static void setLimit(BaseType Value) { 435 static void setLimit(BaseType Value) {
436 // Make sure it's only called once. 436 // Make sure it's only called once.
437 assert(Limit == 0); 437 assert(Limit == 0);
438 assert(Value != 0); 438 assert(Value != 0);
439 Limit = Value; 439 Limit = Value;
440 } 440 }
441 // Define NoRegisterValue as an enum value so that it can be used as an 441 // Define NoRegisterValue as an enum value so that it can be used as an
442 // argument for the public ctor if desired. 442 // argument for the public ctor if desired.
443 enum { NoRegisterValue = std::numeric_limits<BaseType>::max() }; 443 enum { NoRegisterValue = std::numeric_limits<BaseType>::max() };
444 const static RegNumT NoRegister /* = NoRegisterValue */; 444
445 bool hasValue() const { return Value != NoRegisterValue; }
446 bool hasNoValue() const { return !hasValue(); }
445 447
446 private: 448 private:
447 BaseType Value = NoRegisterValue; 449 BaseType Value = NoRegisterValue;
448 static BaseType Limit; 450 static BaseType Limit;
449 /// Private ctor called only by fromInt() and fixme(). 451 /// Private ctor called only by fromInt() and fixme().
450 RegNumT(BaseType Value) : Value(Value) { validate(Value); } 452 RegNumT(BaseType Value) : Value(Value) { validate(Value); }
451 /// The ctor calls this to validate against the target-supplied limit. 453 /// The ctor calls this to validate against the target-supplied limit.
452 static void validate(BaseType Value) { 454 static void validate(BaseType Value) {
453 (void)Value; 455 (void)Value;
454 assert(Value == NoRegisterValue || Value < Limit); 456 assert(Value == NoRegisterValue || Value < Limit);
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
639 bool getIgnoreLiveness() const { return IgnoreLiveness; } 641 bool getIgnoreLiveness() const { return IgnoreLiveness; }
640 642
641 int32_t getStackOffset() const { return StackOffset; } 643 int32_t getStackOffset() const { return StackOffset; }
642 void setStackOffset(int32_t Offset) { StackOffset = Offset; } 644 void setStackOffset(int32_t Offset) { StackOffset = Offset; }
643 /// Returns the variable's stack offset in symbolic form, to improve 645 /// Returns the variable's stack offset in symbolic form, to improve
644 /// readability in DecorateAsm mode. 646 /// readability in DecorateAsm mode.
645 IceString getSymbolicStackOffset(const Cfg *Func) const { 647 IceString getSymbolicStackOffset(const Cfg *Func) const {
646 return "lv$" + getName(Func); 648 return "lv$" + getName(Func);
647 } 649 }
648 650
649 bool hasReg() const { return getRegNum() != RegNumT::NoRegister; } 651 bool hasReg() const { return getRegNum().hasValue(); }
650 RegNumT getRegNum() const { return RegNum; } 652 RegNumT getRegNum() const { return RegNum; }
651 void setRegNum(RegNumT NewRegNum) { 653 void setRegNum(RegNumT NewRegNum) {
652 // Regnum shouldn't be set more than once. 654 // Regnum shouldn't be set more than once.
653 assert(!hasReg() || RegNum == NewRegNum); 655 assert(!hasReg() || RegNum == NewRegNum);
654 RegNum = NewRegNum; 656 RegNum = NewRegNum;
655 } 657 }
656 bool hasRegTmp() const { return getRegNumTmp() != RegNumT::NoRegister; } 658 bool hasRegTmp() const { return getRegNumTmp().hasValue(); }
657 RegNumT getRegNumTmp() const { return RegNumTmp; } 659 RegNumT getRegNumTmp() const { return RegNumTmp; }
658 void setRegNumTmp(RegNumT NewRegNum) { RegNumTmp = NewRegNum; } 660 void setRegNumTmp(RegNumT NewRegNum) { RegNumTmp = NewRegNum; }
659 661
660 RegWeight getWeight(const Cfg *Func) const; 662 RegWeight getWeight(const Cfg *Func) const;
661 663
662 void setMustHaveReg() { RegRequirement = RR_MustHaveRegister; } 664 void setMustHaveReg() { RegRequirement = RR_MustHaveRegister; }
663 bool mustHaveReg() const { return RegRequirement == RR_MustHaveRegister; } 665 bool mustHaveReg() const { return RegRequirement == RR_MustHaveRegister; }
664 void setMustNotHaveReg() { RegRequirement = RR_MustNotHaveRegister; } 666 void setMustNotHaveReg() { RegRequirement = RR_MustNotHaveRegister; }
665 bool mustNotHaveReg() const { 667 bool mustNotHaveReg() const {
666 return RegRequirement == RR_MustNotHaveRegister; 668 return RegRequirement == RR_MustNotHaveRegister;
(...skipping 28 matching lines...) Expand all
695 } 697 }
696 bool rangeOverlapsStart(const Variable *Other) const { 698 bool rangeOverlapsStart(const Variable *Other) const {
697 constexpr bool UseTrimmed = true; 699 constexpr bool UseTrimmed = true;
698 return Live.overlapsInst(Other->Live.getStart(), UseTrimmed); 700 return Live.overlapsInst(Other->Live.getStart(), UseTrimmed);
699 } 701 }
700 702
701 /// Creates a temporary copy of the variable with a different type. Used 703 /// Creates a temporary copy of the variable with a different type. Used
702 /// primarily for syntactic correctness of textual assembly emission. Note 704 /// primarily for syntactic correctness of textual assembly emission. Note
703 /// that only basic information is copied, in particular not IsArgument, 705 /// that only basic information is copied, in particular not IsArgument,
704 /// IsImplicitArgument, IgnoreLiveness, RegNumTmp, Live, LoVar, HiVar, 706 /// IsImplicitArgument, IgnoreLiveness, RegNumTmp, Live, LoVar, HiVar,
705 /// VarsReal. If NewRegNum!=NoRegister, then that register assignment is made 707 /// VarsReal. If NewRegNum.hasValue(), then that register assignment is made
706 /// instead of copying the existing assignment. 708 /// instead of copying the existing assignment.
707 const Variable *asType(Type Ty, RegNumT NewRegNum) const; 709 const Variable *asType(Type Ty, RegNumT NewRegNum) const;
708 710
709 void emit(const Cfg *Func) const override; 711 void emit(const Cfg *Func) const override;
710 using Operand::dump; 712 using Operand::dump;
711 void dump(const Cfg *Func, Ostream &Str) const override; 713 void dump(const Cfg *Func, Ostream &Str) const override;
712 714
713 /// Return reg num of base register, if different from stack/frame register. 715 /// Return reg num of base register, if different from stack/frame register.
714 virtual RegNumT getBaseRegNum() const { return RegNumT::NoRegister; } 716 virtual RegNumT getBaseRegNum() const { return RegNumT(); }
715 717
716 static bool classof(const Operand *Operand) { 718 static bool classof(const Operand *Operand) {
717 OperandKind Kind = Operand->getKind(); 719 OperandKind Kind = Operand->getKind();
718 return Kind >= kVariable && Kind <= kVariable_Max; 720 return Kind >= kVariable && Kind <= kVariable_Max;
719 } 721 }
720 722
721 protected: 723 protected:
722 Variable(OperandKind K, Type Ty, SizeT Index) 724 Variable(OperandKind K, Type Ty, SizeT Index)
723 : Operand(K, Ty), Number(Index), 725 : Operand(K, Ty), Number(Index),
724 RegisterClass(static_cast<RegClass>(Ty)) { 726 RegisterClass(static_cast<RegClass>(Ty)) {
725 Vars = VarsReal; 727 Vars = VarsReal;
726 Vars[0] = this; 728 Vars[0] = this;
727 NumVars = 1; 729 NumVars = 1;
728 } 730 }
729 /// Number is unique across all variables, and is used as a (bit)vector index 731 /// Number is unique across all variables, and is used as a (bit)vector index
730 /// for liveness analysis. 732 /// for liveness analysis.
731 const SizeT Number; 733 const SizeT Number;
732 Cfg::IdentifierIndexType NameIndex = Cfg::IdentifierIndexInvalid; 734 Cfg::IdentifierIndexType NameIndex = Cfg::IdentifierIndexInvalid;
733 bool IsArgument = false; 735 bool IsArgument = false;
734 bool IsImplicitArgument = false; 736 bool IsImplicitArgument = false;
735 /// IgnoreLiveness means that the variable should be ignored when constructing 737 /// IgnoreLiveness means that the variable should be ignored when constructing
736 /// and validating live ranges. This is usually reserved for the stack 738 /// and validating live ranges. This is usually reserved for the stack
737 /// pointer and other physical registers specifically referenced by name. 739 /// pointer and other physical registers specifically referenced by name.
738 bool IgnoreLiveness = false; 740 bool IgnoreLiveness = false;
739 // If IsRematerializable, RegNum keeps track of which register (stack or frame 741 // If IsRematerializable, RegNum keeps track of which register (stack or frame
740 // pointer), and StackOffset is the known offset from that register. 742 // pointer), and StackOffset is the known offset from that register.
741 bool IsRematerializable = false; 743 bool IsRematerializable = false;
742 RegRequirement RegRequirement = RR_MayHaveRegister; 744 RegRequirement RegRequirement = RR_MayHaveRegister;
743 RegClass RegisterClass; 745 RegClass RegisterClass;
744 /// RegNum is the allocated register, or NoRegister if it isn't 746 /// RegNum is the allocated register, (as long as RegNum.hasValue() is true).
745 /// register-allocated. 747 RegNumT RegNum;
746 RegNumT RegNum = RegNumT::NoRegister;
747 /// RegNumTmp is the tentative assignment during register allocation. 748 /// RegNumTmp is the tentative assignment during register allocation.
748 RegNumT RegNumTmp = RegNumT::NoRegister; 749 RegNumT RegNumTmp;
749 /// StackOffset is the canonical location on stack (only if 750 /// StackOffset is the canonical location on stack (only if
750 /// RegNum==NoRegister || IsArgument). 751 /// RegNum.hasNoValue() || IsArgument).
751 int32_t StackOffset = 0; 752 int32_t StackOffset = 0;
752 LiveRange Live; 753 LiveRange Live;
753 /// VarsReal (and Operand::Vars) are set up such that Vars[0] == this. 754 /// VarsReal (and Operand::Vars) are set up such that Vars[0] == this.
754 Variable *VarsReal[1]; 755 Variable *VarsReal[1];
755 }; 756 };
756 757
757 // Variable64On32 represents a 64-bit variable on a 32-bit architecture. In 758 // Variable64On32 represents a 64-bit variable on a 32-bit architecture. In
758 // this situation the variable must be split into a low and a high word. 759 // this situation the variable must be split into a low and a high word.
759 class Variable64On32 : public Variable { 760 class Variable64On32 : public Variable {
760 Variable64On32() = delete; 761 Variable64On32() = delete;
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
923 private: 924 private:
924 const Cfg *Func; 925 const Cfg *Func;
925 MetadataKind Kind; 926 MetadataKind Kind;
926 CfgVector<VariableTracking> Metadata; 927 CfgVector<VariableTracking> Metadata;
927 const static InstDefList NoDefinitions; 928 const static InstDefList NoDefinitions;
928 }; 929 };
929 930
930 } // end of namespace Ice 931 } // end of namespace Ice
931 932
932 #endif // SUBZERO_SRC_ICEOPERAND_H 933 #endif // SUBZERO_SRC_ICEOPERAND_H
OLDNEW
« no previous file with comments | « src/IceInstX86BaseImpl.h ('k') | src/IceOperand.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698