|
16 | 16 |
|
17 | 17 | #include "llvm/ADT/BitVector.h"
|
18 | 18 | #include "llvm/ADT/IndexedMap.h"
|
| 19 | +#include "llvm/ADT/PointerUnion.h" |
19 | 20 | #include "llvm/ADT/iterator_range.h"
|
| 21 | +// PointerUnion needs to have access to the full RegisterBank type. |
| 22 | +#include "llvm/CodeGen/GlobalISel/RegisterBank.h" |
20 | 23 | #include "llvm/CodeGen/MachineFunction.h"
|
21 | 24 | #include "llvm/CodeGen/MachineInstrBundle.h"
|
22 | 25 | #include "llvm/Target/TargetRegisterInfo.h"
|
|
26 | 29 | namespace llvm {
|
27 | 30 | class PSetIterator;
|
28 | 31 |
|
| 32 | +/// Convenient type to represent either a register class or a register bank. |
| 33 | +typedef PointerUnion<const TargetRegisterClass *, const RegisterBank *> |
| 34 | + RegClassOrRegBank; |
| 35 | + |
29 | 36 | /// MachineRegisterInfo - Keep track of information for virtual and physical
|
30 | 37 | /// registers, including vreg register classes, use/def chains for registers,
|
31 | 38 | /// etc.
|
@@ -55,8 +62,9 @@ class MachineRegisterInfo {
|
55 | 62 | ///
|
56 | 63 | /// Each element in this list contains the register class of the vreg and the
|
57 | 64 | /// start of the use/def list for the register.
|
58 |
| - IndexedMap<std::pair<const TargetRegisterClass*, MachineOperand*>, |
59 |
| - VirtReg2IndexFunctor> VRegInfo; |
| 65 | + IndexedMap<std::pair<RegClassOrRegBank, MachineOperand *>, |
| 66 | + VirtReg2IndexFunctor> |
| 67 | + VRegInfo; |
60 | 68 |
|
61 | 69 | /// RegAllocHints - This vector records register allocation hints for virtual
|
62 | 70 | /// registers. For each virtual register, it keeps a register and hint type
|
@@ -564,16 +572,62 @@ class MachineRegisterInfo {
|
564 | 572 | // Virtual Register Info
|
565 | 573 | //===--------------------------------------------------------------------===//
|
566 | 574 |
|
567 |
| - /// getRegClass - Return the register class of the specified virtual register. |
| 575 | + /// Return the register class of the specified virtual register. |
| 576 | + /// This shouldn't be used directly unless \p Reg has a register class. |
| 577 | + /// \see getRegClassOrNull when this might happen. |
568 | 578 | ///
|
569 | 579 | const TargetRegisterClass *getRegClass(unsigned Reg) const {
|
| 580 | + assert(VRegInfo[Reg].first.is<const TargetRegisterClass *>() && |
| 581 | + "Register class not set, wrong accessor"); |
| 582 | + return VRegInfo[Reg].first.get<const TargetRegisterClass *>(); |
| 583 | + } |
| 584 | + |
| 585 | + /// Return the register class of \p Reg, or null if Reg has not been assigned |
| 586 | + /// a register class yet. |
| 587 | + /// |
| 588 | + /// \note A null register class can only happen when these two |
| 589 | + /// conditions are met: |
| 590 | + /// 1. Generic virtual registers are created. |
| 591 | + /// 2. The machine function has not completely been through the |
| 592 | + /// instruction selection process. |
| 593 | + /// None of this condition is possible without GlobalISel for now. |
| 594 | + /// In other words, if GlobalISel is not used or if the query happens after |
| 595 | + /// the select pass, using getRegClass is safe. |
| 596 | + const TargetRegisterClass *getRegClassOrNull(unsigned Reg) const { |
| 597 | + const RegClassOrRegBank &Val = VRegInfo[Reg].first; |
| 598 | + if (Val.is<const TargetRegisterClass *>()) |
| 599 | + return Val.get<const TargetRegisterClass *>(); |
| 600 | + return nullptr; |
| 601 | + } |
| 602 | + |
| 603 | + /// Return the register bank of \p Reg, or null if Reg has not been assigned |
| 604 | + /// a register bank or has been assigned a register class. |
| 605 | + /// \note It is possible to get the register bank from the register class via |
| 606 | + /// RegisterBankInfo::getRegBankFromRegClass. |
| 607 | + /// |
| 608 | + const RegisterBank *getRegBankOrNull(unsigned Reg) const { |
| 609 | + const RegClassOrRegBank &Val = VRegInfo[Reg].first; |
| 610 | + if (Val.is<const RegisterBank *>()) |
| 611 | + return Val.get<const RegisterBank *>(); |
| 612 | + return nullptr; |
| 613 | + } |
| 614 | + |
| 615 | + /// Return the register bank or register class of \p Reg. |
| 616 | + /// \note Before the register bank gets assigned (i.e., before the |
| 617 | + /// RegBankSelect pass) \p Reg may not have either. |
| 618 | + /// |
| 619 | + const RegClassOrRegBank &getRegClassOrRegBank(unsigned Reg) const { |
570 | 620 | return VRegInfo[Reg].first;
|
571 | 621 | }
|
572 | 622 |
|
573 | 623 | /// setRegClass - Set the register class of the specified virtual register.
|
574 | 624 | ///
|
575 | 625 | void setRegClass(unsigned Reg, const TargetRegisterClass *RC);
|
576 | 626 |
|
| 627 | + /// Set the register bank to \p RegBank for \p Reg. |
| 628 | + /// |
| 629 | + void setRegBank(unsigned Reg, const RegisterBank &RegBank); |
| 630 | + |
577 | 631 | /// constrainRegClass - Constrain the register class of the specified virtual
|
578 | 632 | /// register to be a common subclass of RC and the current register class,
|
579 | 633 | /// but only if the new class has at least MinNumRegs registers. Return the
|
|
0 commit comments