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

Side by Side Diff: src/IceOperand.h

Issue 1676123002: Subzero: Use a proper RegNumT type instead of int32_t/SizeT. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Revert some method name changes 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
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 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 } 395 }
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
406 /// value NoRegister. Its public ctor allows direct use of enum values, such as
407 /// RegNumT(Reg_eax), but not things like RegNumT(Reg_eax+1). This is to try to
408 /// prevent inappropriate assumptions about enum ordering. If needed, the
409 /// fromInt() method can be used, such as when a RegNumT is based on a bitvector
410 /// index.
411 class RegNumT {
412 public:
413 using BaseType = uint32_t;
414 RegNumT() = default;
415 RegNumT(const RegNumT &) = default;
416 template <typename AnyEnum>
417 RegNumT(AnyEnum Value,
418 typename std::enable_if<std::is_enum<AnyEnum>::value, int>::type = 0)
419 : Value(Value) {
420 validate(Value);
421 }
422 RegNumT &operator=(const RegNumT &) = default;
423 operator unsigned() const { return Value; }
424 /// Asserts that the register is valid, i.e. not NoRegister. Note that the
425 /// ctor already does the target-specific limit check.
426 void assertIsValid() const { assert(Value != NoRegister); }
427 static RegNumT fromInt(BaseType Value) { return RegNumT(Value); }
428 /// Marks cases that inappropriately add/subtract RegNumT values, and
429 /// therefore need to be fixed because they make assumptions about register
430 /// enum value ordering. TODO(stichnot): Remove fixme() as soon as all
431 /// current uses are fixed/removed.
432 static RegNumT fixme(BaseType Value) { return RegNumT(Value); }
433 /// The target's staticInit() method should call setLimit() to register the
434 /// upper bound of allowable values.
435 static void setLimit(BaseType Value) {
436 // Make sure it's only called once.
437 assert(Limit == 0);
438 assert(Value != 0);
439 Limit = Value;
440 }
441 // Define NoRegister as an enum value so that it can be used as an argument
John 2016/02/10 16:01:51 nice. :)
Jim Stichnoth 2016/02/10 17:47:20 True, though that inhibits certain uses of "auto",
Jim Stichnoth 2016/02/10 18:47:30 I am now le refreshed, and realize the horror of t
442 // for the public ctor.
443 enum { NoRegister = std::numeric_limits<BaseType>::max() };
444
445 private:
446 BaseType Value = NoRegister;
447 static BaseType Limit;
448 /// Private ctor called only by fromInt() and fixme().
449 RegNumT(BaseType Value) : Value(Value) { validate(Value); }
450 /// The ctor calls this to validate against the target-supplied limit.
451 static void validate(BaseType Value) {
452 (void)Value;
453 assert(Value == NoRegister || Value < Limit);
454 }
455 /// Disallow operators that inappropriately make assumptions about register
456 /// enum value ordering.
457 bool operator<(const RegNumT &) = delete;
458 bool operator<=(const RegNumT &) = delete;
459 bool operator>(const RegNumT &) = delete;
460 bool operator>=(const RegNumT &) = delete;
461 };
462
463 /// RegNumBitVector wraps llvm::SmallBitVector so that instead of this pattern:
464 ///
465 /// for (int i = V.find_first(); i != -1; i = V.find_next(i)) {
466 /// RegNumT RegNum = RegNumT::fromInt(i);
467 /// ...
468 /// }
469 ///
470 /// this cleaner pattern can be used:
471 ///
472 /// for (RegNumT RegNum : RegNumBitVector(V)) {
473 /// ...
474 /// }
475 class RegNumBitVector {
John 2016/02/10 16:01:51 This is an iterator, so maybe just rename it to Re
Jim Stichnoth 2016/02/10 17:47:20 I was trying to control the identifier length a bi
476 using T = llvm::SmallBitVector;
477 static constexpr int Sentinel = -1;
478 RegNumBitVector() = delete;
479 RegNumBitVector(const RegNumBitVector &) = delete;
480 RegNumBitVector &operator=(const RegNumBitVector &) = delete;
481
482 public:
483 class Iterator {
484 Iterator() = delete;
485 Iterator &operator=(const Iterator &) = delete;
486
487 public:
488 explicit Iterator(const T &V) : V(V), Current(V.find_first()) {}
489 Iterator(const T &V, int Value) : V(V), Current(Value) {}
490 Iterator(const Iterator &) = default;
491 RegNumT operator*() {
492 assert(Current != Sentinel);
493 return RegNumT::fromInt(Current);
494 }
495 Iterator &operator++() {
496 assert(Current != Sentinel);
497 Current = V.find_next(Current);
498 return *this;
499 }
500 bool operator!=(Iterator &Other) { return Current != Other.Current; }
501
502 private:
503 const T &V;
504 int Current;
505 };
506
507 explicit RegNumBitVector(const T &V) : V(V) {}
508 Iterator begin() { return Iterator(V); }
509 Iterator end() { return Iterator(V, Sentinel); }
510
511 private:
512 const T &V;
513 };
514
405 /// RegWeight is a wrapper for a uint32_t weight value, with a special value 515 /// RegWeight is a wrapper for a uint32_t weight value, with a special value
406 /// that represents infinite weight, and an addWeight() method that ensures that 516 /// that represents infinite weight, and an addWeight() method that ensures that
407 /// W+infinity=infinity. 517 /// W+infinity=infinity.
408 class RegWeight { 518 class RegWeight {
409 public: 519 public:
410 RegWeight() = default; 520 RegWeight() = default;
411 explicit RegWeight(uint32_t Weight) : Weight(Weight) {} 521 explicit RegWeight(uint32_t Weight) : Weight(Weight) {}
412 RegWeight(const RegWeight &) = default; 522 RegWeight(const RegWeight &) = default;
413 RegWeight &operator=(const RegWeight &) = default; 523 RegWeight &operator=(const RegWeight &) = default;
414 constexpr static uint32_t Inf = ~0; /// Force regalloc to give a register 524 constexpr static uint32_t Inf = ~0; /// Force regalloc to give a register
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 bool getIgnoreLiveness() const { return IgnoreLiveness; } 637 bool getIgnoreLiveness() const { return IgnoreLiveness; }
528 638
529 int32_t getStackOffset() const { return StackOffset; } 639 int32_t getStackOffset() const { return StackOffset; }
530 void setStackOffset(int32_t Offset) { StackOffset = Offset; } 640 void setStackOffset(int32_t Offset) { StackOffset = Offset; }
531 /// Returns the variable's stack offset in symbolic form, to improve 641 /// Returns the variable's stack offset in symbolic form, to improve
532 /// readability in DecorateAsm mode. 642 /// readability in DecorateAsm mode.
533 IceString getSymbolicStackOffset(const Cfg *Func) const { 643 IceString getSymbolicStackOffset(const Cfg *Func) const {
534 return "lv$" + getName(Func); 644 return "lv$" + getName(Func);
535 } 645 }
536 646
537 static constexpr int32_t NoRegister = -1; 647 bool hasReg() const { return getRegNum() != RegNumT::NoRegister; }
538 bool hasReg() const { return getRegNum() != NoRegister; } 648 RegNumT getRegNum() const { return RegNum; }
539 int32_t getRegNum() const { return RegNum; } 649 void setRegNum(RegNumT NewRegNum) {
540 void setRegNum(int32_t NewRegNum) {
541 // Regnum shouldn't be set more than once. 650 // Regnum shouldn't be set more than once.
542 assert(!hasReg() || RegNum == NewRegNum); 651 assert(!hasReg() || RegNum == NewRegNum);
543 RegNum = NewRegNum; 652 RegNum = NewRegNum;
544 } 653 }
545 bool hasRegTmp() const { return getRegNumTmp() != NoRegister; } 654 bool hasRegTmp() const { return getRegNumTmp() != RegNumT::NoRegister; }
546 int32_t getRegNumTmp() const { return RegNumTmp; } 655 RegNumT getRegNumTmp() const { return RegNumTmp; }
547 void setRegNumTmp(int32_t NewRegNum) { RegNumTmp = NewRegNum; } 656 void setRegNumTmp(RegNumT NewRegNum) { RegNumTmp = NewRegNum; }
548 657
549 RegWeight getWeight(const Cfg *Func) const; 658 RegWeight getWeight(const Cfg *Func) const;
550 659
551 void setMustHaveReg() { RegRequirement = RR_MustHaveRegister; } 660 void setMustHaveReg() { RegRequirement = RR_MustHaveRegister; }
552 bool mustHaveReg() const { return RegRequirement == RR_MustHaveRegister; } 661 bool mustHaveReg() const { return RegRequirement == RR_MustHaveRegister; }
553 void setMustNotHaveReg() { RegRequirement = RR_MustNotHaveRegister; } 662 void setMustNotHaveReg() { RegRequirement = RR_MustNotHaveRegister; }
554 bool mustNotHaveReg() const { 663 bool mustNotHaveReg() const {
555 return RegRequirement == RR_MustNotHaveRegister; 664 return RegRequirement == RR_MustNotHaveRegister;
556 } 665 }
557 void setRematerializable(int32_t NewRegNum, int32_t NewOffset) { 666 void setRematerializable(RegNumT NewRegNum, int32_t NewOffset) {
558 IsRematerializable = true; 667 IsRematerializable = true;
559 setRegNum(NewRegNum); 668 setRegNum(NewRegNum);
560 setStackOffset(NewOffset); 669 setStackOffset(NewOffset);
561 setMustHaveReg(); 670 setMustHaveReg();
562 } 671 }
563 bool isRematerializable() const { return IsRematerializable; } 672 bool isRematerializable() const { return IsRematerializable; }
564 673
565 void setRegClass(uint8_t RC) { RegisterClass = static_cast<RegClass>(RC); } 674 void setRegClass(uint8_t RC) { RegisterClass = static_cast<RegClass>(RC); }
566 RegClass getRegClass() const { return RegisterClass; } 675 RegClass getRegClass() const { return RegisterClass; }
567 676
(...skipping 18 matching lines...) Expand all
586 constexpr bool UseTrimmed = true; 695 constexpr bool UseTrimmed = true;
587 return Live.overlapsInst(Other->Live.getStart(), UseTrimmed); 696 return Live.overlapsInst(Other->Live.getStart(), UseTrimmed);
588 } 697 }
589 698
590 /// Creates a temporary copy of the variable with a different type. Used 699 /// Creates a temporary copy of the variable with a different type. Used
591 /// primarily for syntactic correctness of textual assembly emission. Note 700 /// primarily for syntactic correctness of textual assembly emission. Note
592 /// that only basic information is copied, in particular not IsArgument, 701 /// that only basic information is copied, in particular not IsArgument,
593 /// IsImplicitArgument, IgnoreLiveness, RegNumTmp, Live, LoVar, HiVar, 702 /// IsImplicitArgument, IgnoreLiveness, RegNumTmp, Live, LoVar, HiVar,
594 /// VarsReal. If NewRegNum!=NoRegister, then that register assignment is made 703 /// VarsReal. If NewRegNum!=NoRegister, then that register assignment is made
595 /// instead of copying the existing assignment. 704 /// instead of copying the existing assignment.
596 const Variable *asType(Type Ty, int32_t NewRegNum) const; 705 const Variable *asType(Type Ty, RegNumT NewRegNum) const;
597 706
598 void emit(const Cfg *Func) const override; 707 void emit(const Cfg *Func) const override;
599 using Operand::dump; 708 using Operand::dump;
600 void dump(const Cfg *Func, Ostream &Str) const override; 709 void dump(const Cfg *Func, Ostream &Str) const override;
601 710
602 /// Return reg num of base register, if different from stack/frame register. 711 /// Return reg num of base register, if different from stack/frame register.
603 virtual int32_t getBaseRegNum() const { return NoRegister; } 712 virtual RegNumT getBaseRegNum() const { return RegNumT::NoRegister; }
604 713
605 static bool classof(const Operand *Operand) { 714 static bool classof(const Operand *Operand) {
606 OperandKind Kind = Operand->getKind(); 715 OperandKind Kind = Operand->getKind();
607 return Kind >= kVariable && Kind <= kVariable_Max; 716 return Kind >= kVariable && Kind <= kVariable_Max;
608 } 717 }
609 718
610 protected: 719 protected:
611 Variable(OperandKind K, Type Ty, SizeT Index) 720 Variable(OperandKind K, Type Ty, SizeT Index)
612 : Operand(K, Ty), Number(Index), 721 : Operand(K, Ty), Number(Index),
613 RegisterClass(static_cast<RegClass>(Ty)) { 722 RegisterClass(static_cast<RegClass>(Ty)) {
(...skipping 11 matching lines...) Expand all
625 /// and validating live ranges. This is usually reserved for the stack 734 /// and validating live ranges. This is usually reserved for the stack
626 /// pointer and other physical registers specifically referenced by name. 735 /// pointer and other physical registers specifically referenced by name.
627 bool IgnoreLiveness = false; 736 bool IgnoreLiveness = false;
628 // If IsRematerializable, RegNum keeps track of which register (stack or frame 737 // If IsRematerializable, RegNum keeps track of which register (stack or frame
629 // pointer), and StackOffset is the known offset from that register. 738 // pointer), and StackOffset is the known offset from that register.
630 bool IsRematerializable = false; 739 bool IsRematerializable = false;
631 RegRequirement RegRequirement = RR_MayHaveRegister; 740 RegRequirement RegRequirement = RR_MayHaveRegister;
632 RegClass RegisterClass; 741 RegClass RegisterClass;
633 /// RegNum is the allocated register, or NoRegister if it isn't 742 /// RegNum is the allocated register, or NoRegister if it isn't
634 /// register-allocated. 743 /// register-allocated.
635 int32_t RegNum = NoRegister; 744 RegNumT RegNum = RegNumT::NoRegister;
636 /// RegNumTmp is the tentative assignment during register allocation. 745 /// RegNumTmp is the tentative assignment during register allocation.
637 int32_t RegNumTmp = NoRegister; 746 RegNumT RegNumTmp = RegNumT::NoRegister;
638 /// StackOffset is the canonical location on stack (only if 747 /// StackOffset is the canonical location on stack (only if
639 /// RegNum==NoRegister || IsArgument). 748 /// RegNum==NoRegister || IsArgument).
640 int32_t StackOffset = 0; 749 int32_t StackOffset = 0;
641 LiveRange Live; 750 LiveRange Live;
642 /// VarsReal (and Operand::Vars) are set up such that Vars[0] == this. 751 /// VarsReal (and Operand::Vars) are set up such that Vars[0] == this.
643 Variable *VarsReal[1]; 752 Variable *VarsReal[1];
644 }; 753 };
645 754
646 // Variable64On32 represents a 64-bit variable on a 32-bit architecture. In 755 // Variable64On32 represents a 64-bit variable on a 32-bit architecture. In
647 // this situation the variable must be split into a low and a high word. 756 // this situation the variable must be split into a low and a high word.
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
812 private: 921 private:
813 const Cfg *Func; 922 const Cfg *Func;
814 MetadataKind Kind; 923 MetadataKind Kind;
815 CfgVector<VariableTracking> Metadata; 924 CfgVector<VariableTracking> Metadata;
816 const static InstDefList NoDefinitions; 925 const static InstDefList NoDefinitions;
817 }; 926 };
818 927
819 } // end of namespace Ice 928 } // end of namespace Ice
820 929
821 #endif // SUBZERO_SRC_ICEOPERAND_H 930 #endif // SUBZERO_SRC_ICEOPERAND_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698