diff options
Diffstat (limited to 'include/llvm/CodeGen/MachineRegisterInfo.h')
| -rw-r--r-- | include/llvm/CodeGen/MachineRegisterInfo.h | 149 |
1 files changed, 109 insertions, 40 deletions
diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h index 04191bc1b74f..07d2d016f274 100644 --- a/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/include/llvm/CodeGen/MachineRegisterInfo.h @@ -16,7 +16,10 @@ #include "llvm/ADT/BitVector.h" #include "llvm/ADT/IndexedMap.h" +#include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/iterator_range.h" +// PointerUnion needs to have access to the full RegisterBank type. +#include "llvm/CodeGen/GlobalISel/RegisterBank.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBundle.h" #include "llvm/Target/TargetRegisterInfo.h" @@ -26,6 +29,10 @@ namespace llvm { class PSetIterator; +/// Convenient type to represent either a register class or a register bank. +typedef PointerUnion<const TargetRegisterClass *, const RegisterBank *> + RegClassOrRegBank; + /// MachineRegisterInfo - Keep track of information for virtual and physical /// registers, including vreg register classes, use/def chains for registers, /// etc. @@ -40,18 +47,9 @@ public: }; private: - const MachineFunction *MF; + MachineFunction *MF; Delegate *TheDelegate; - /// IsSSA - True when the machine function is in SSA form and virtual - /// registers have a single def. - bool IsSSA; - - /// TracksLiveness - True while register liveness is being tracked accurately. - /// Basic block live-in lists, kill flags, and implicit defs may not be - /// accurate when after this flag is cleared. - bool TracksLiveness; - /// True if subregister liveness is tracked. bool TracksSubRegLiveness; @@ -59,8 +57,9 @@ private: /// /// Each element in this list contains the register class of the vreg and the /// start of the use/def list for the register. - IndexedMap<std::pair<const TargetRegisterClass*, MachineOperand*>, - VirtReg2IndexFunctor> VRegInfo; + IndexedMap<std::pair<RegClassOrRegBank, MachineOperand *>, + VirtReg2IndexFunctor> + VRegInfo; /// RegAllocHints - This vector records register allocation hints for virtual /// registers. For each virtual register, it keeps a register and hint type @@ -105,6 +104,18 @@ private: /// started. BitVector ReservedRegs; + typedef DenseMap<unsigned, unsigned> VRegToSizeMap; + /// Map generic virtual registers to their actual size. + mutable std::unique_ptr<VRegToSizeMap> VRegToSize; + + /// Accessor for VRegToSize. This accessor should only be used + /// by global-isel related work. + VRegToSizeMap &getVRegToSize() const { + if (!VRegToSize) + VRegToSize.reset(new VRegToSizeMap); + return *VRegToSize.get(); + } + /// Keep track of the physical registers that are live in to the function. /// Live in values are typically arguments in registers. LiveIn values are /// allowed to have virtual registers associated with them, stored in the @@ -114,7 +125,7 @@ private: MachineRegisterInfo(const MachineRegisterInfo&) = delete; void operator=(const MachineRegisterInfo&) = delete; public: - explicit MachineRegisterInfo(const MachineFunction *MF); + explicit MachineRegisterInfo(MachineFunction *MF); const TargetRegisterInfo *getTargetRegisterInfo() const { return MF->getSubtarget().getRegisterInfo(); @@ -148,27 +159,32 @@ public: // The TwoAddressInstructionPass and PHIElimination passes take the machine // function out of SSA form when they introduce multiple defs per virtual // register. - bool isSSA() const { return IsSSA; } + bool isSSA() const { + return MF->getProperties().hasProperty( + MachineFunctionProperties::Property::IsSSA); + } // leaveSSA - Indicates that the machine function is no longer in SSA form. - void leaveSSA() { IsSSA = false; } + void leaveSSA() { + MF->getProperties().clear(MachineFunctionProperties::Property::IsSSA); + } /// tracksLiveness - Returns true when tracking register liveness accurately. - /// - /// While this flag is true, register liveness information in basic block - /// live-in lists and machine instruction operands is accurate. This means it - /// can be used to change the code in ways that affect the values in - /// registers, for example by the register scavenger. - /// - /// When this flag is false, liveness is no longer reliable. - bool tracksLiveness() const { return TracksLiveness; } + /// (see MachineFUnctionProperties::Property description for details) + bool tracksLiveness() const { + return MF->getProperties().hasProperty( + MachineFunctionProperties::Property::TracksLiveness); + } /// invalidateLiveness - Indicates that register liveness is no longer being /// tracked accurately. /// /// This should be called by late passes that invalidate the liveness /// information. - void invalidateLiveness() { TracksLiveness = false; } + void invalidateLiveness() { + MF->getProperties().clear( + MachineFunctionProperties::Property::TracksLiveness); + } /// Returns true if liveness for register class @p RC should be tracked at /// the subregister level. @@ -375,8 +391,8 @@ public: /// specified register (it may be live-in). bool def_empty(unsigned RegNo) const { return def_begin(RegNo) == def_end(); } - /// hasOneDef - Return true if there is exactly one instruction defining the - /// specified register. + /// Return true if there is exactly one operand defining the specified + /// register. bool hasOneDef(unsigned RegNo) const { def_iterator DI = def_begin(RegNo); if (DI == def_end()) @@ -551,9 +567,47 @@ public: // Virtual Register Info //===--------------------------------------------------------------------===// - /// getRegClass - Return the register class of the specified virtual register. + /// Return the register class of the specified virtual register. + /// This shouldn't be used directly unless \p Reg has a register class. + /// \see getRegClassOrNull when this might happen. /// const TargetRegisterClass *getRegClass(unsigned Reg) const { + assert(VRegInfo[Reg].first.is<const TargetRegisterClass *>() && + "Register class not set, wrong accessor"); + return VRegInfo[Reg].first.get<const TargetRegisterClass *>(); + } + + /// Return the register class of \p Reg, or null if Reg has not been assigned + /// a register class yet. + /// + /// \note A null register class can only happen when these two + /// conditions are met: + /// 1. Generic virtual registers are created. + /// 2. The machine function has not completely been through the + /// instruction selection process. + /// None of this condition is possible without GlobalISel for now. + /// In other words, if GlobalISel is not used or if the query happens after + /// the select pass, using getRegClass is safe. + const TargetRegisterClass *getRegClassOrNull(unsigned Reg) const { + const RegClassOrRegBank &Val = VRegInfo[Reg].first; + return Val.dyn_cast<const TargetRegisterClass *>(); + } + + /// Return the register bank of \p Reg, or null if Reg has not been assigned + /// a register bank or has been assigned a register class. + /// \note It is possible to get the register bank from the register class via + /// RegisterBankInfo::getRegBankFromRegClass. + /// + const RegisterBank *getRegBankOrNull(unsigned Reg) const { + const RegClassOrRegBank &Val = VRegInfo[Reg].first; + return Val.dyn_cast<const RegisterBank *>(); + } + + /// Return the register bank or register class of \p Reg. + /// \note Before the register bank gets assigned (i.e., before the + /// RegBankSelect pass) \p Reg may not have either. + /// + const RegClassOrRegBank &getRegClassOrRegBank(unsigned Reg) const { return VRegInfo[Reg].first; } @@ -561,6 +615,10 @@ public: /// void setRegClass(unsigned Reg, const TargetRegisterClass *RC); + /// Set the register bank to \p RegBank for \p Reg. + /// + void setRegBank(unsigned Reg, const RegisterBank &RegBank); + /// constrainRegClass - Constrain the register class of the specified virtual /// register to be a common subclass of RC and the current register class, /// but only if the new class has at least MinNumRegs registers. Return the @@ -587,6 +645,19 @@ public: /// unsigned createVirtualRegister(const TargetRegisterClass *RegClass); + /// Get the size in bits of \p VReg or 0 if VReg is not a generic + /// (target independent) virtual register. + unsigned getSize(unsigned VReg) const; + + /// Set the size in bits of \p VReg to \p Size. + /// Although the size should be set at build time, mir infrastructure + /// is not yet able to do it. + void setSize(unsigned VReg, unsigned Size); + + /// Create and return a new generic virtual register with a size of \p Size. + /// \pre Size > 0. + unsigned createGenericVirtualRegister(unsigned Size); + /// getNumVirtRegs - Return the number of virtual registers created. /// unsigned getNumVirtRegs() const { return VRegInfo.size(); } @@ -632,9 +703,10 @@ public: /// Return true if the specified register is modified in this function. /// This checks that no defining machine operands exist for the register or /// any of its aliases. Definitions found on functions marked noreturn are - /// ignored. The register is also considered modified when it is set in the - /// UsedPhysRegMask. - bool isPhysRegModified(unsigned PhysReg) const; + /// ignored, to consider them pass 'true' for optional parameter + /// SkipNoReturnDef. The register is also considered modified when it is set + /// in the UsedPhysRegMask. + bool isPhysRegModified(unsigned PhysReg, bool SkipNoReturnDef = false) const; /// Return true if the specified register is modified or read in this /// function. This checks that no machine operands exist for the register or @@ -820,10 +892,10 @@ public: advance(); } while (Op && Op->getParent() == P); } else if (ByBundle) { - MachineInstr *P = getBundleStart(Op->getParent()); + MachineInstr &P = getBundleStart(*Op->getParent()); do { advance(); - } while (Op && getBundleStart(Op->getParent()) == P); + } while (Op && &getBundleStart(*Op->getParent()) == &P); } return *this; @@ -922,10 +994,10 @@ public: advance(); } while (Op && Op->getParent() == P); } else if (ByBundle) { - MachineInstr *P = getBundleStart(Op->getParent()); + MachineInstr &P = getBundleStart(*Op->getParent()); do { advance(); - } while (Op && getBundleStart(Op->getParent()) == P); + } while (Op && &getBundleStart(*Op->getParent()) == &P); } return *this; @@ -937,15 +1009,12 @@ public: // Retrieve a reference to the current operand. MachineInstr &operator*() const { assert(Op && "Cannot dereference end iterator!"); - if (ByBundle) return *(getBundleStart(Op->getParent())); + if (ByBundle) + return getBundleStart(*Op->getParent()); return *Op->getParent(); } - MachineInstr *operator->() const { - assert(Op && "Cannot dereference end iterator!"); - if (ByBundle) return getBundleStart(Op->getParent()); - return Op->getParent(); - } + MachineInstr *operator->() const { return &operator*(); } }; }; |
