diff --git a/llvm/include/llvm/CodeGen/LiveRangeEdit.h b/llvm/include/llvm/CodeGen/LiveRangeEdit.h --- a/llvm/include/llvm/CodeGen/LiveRangeEdit.h +++ b/llvm/include/llvm/CodeGen/LiveRangeEdit.h @@ -134,10 +134,10 @@ : Parent(parent), NewRegs(newRegs), MRI(MF.getRegInfo()), LIS(lis), VRM(vrm), TII(*MF.getSubtarget().getInstrInfo()), TheDelegate(delegate), FirstNew(newRegs.size()), DeadRemats(deadRemats) { - MRI.setDelegate(this); + MRI.setDelegate(this, DelegateReceiver::LRE); } - ~LiveRangeEdit() override { MRI.resetDelegate(this); } + ~LiveRangeEdit() override { MRI.resetDelegate(this, DelegateReceiver::LRE); } const LiveInterval &getParent() const { assert(Parent && "No parent LiveInterval"); diff --git a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h --- a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h @@ -44,6 +44,25 @@ using RegClassOrRegBank = PointerUnion; +/// Enum values for the intended delegate receivers. +enum class DelegateReceiver : uint8_t { + LRE, // For LiveRangeEdit + RESERVED // For target specific use +}; + +template <> struct DenseMapInfo { + static inline DelegateReceiver getEmptyKey() { return DelegateReceiver(-1); } + static inline DelegateReceiver getTombstoneKey() { + return DelegateReceiver(-2); + } + static unsigned getHashValue(DelegateReceiver val) { + return std::hash{}(unsigned(val)); + } + static bool isEqual(DelegateReceiver LHS, DelegateReceiver RHS) { + return LHS == RHS; + } +}; + /// MachineRegisterInfo - Keep track of information for virtual and physical /// registers, including vreg register classes, use/def chains for registers, /// etc. @@ -56,11 +75,13 @@ virtual ~Delegate() = default; virtual void MRI_NoteNewVirtualRegister(Register Reg) = 0; + virtual void MRI_NotecloneVirtualRegister(Register ClonedReg, + Register Reg) {} }; private: MachineFunction *MF; - Delegate *TheDelegate = nullptr; + SmallDenseMap TheDelegates; /// True if subregister liveness is tracked. const bool TracksSubRegLiveness; @@ -152,21 +173,27 @@ return MF->getSubtarget().getRegisterInfo(); } - void resetDelegate(Delegate *delegate) { + Delegate *getDelegate(DelegateReceiver DR) { + if (TheDelegates.find(DR) == TheDelegates.end()) + return nullptr; + + return TheDelegates[DR]; + } + + void resetDelegate(Delegate *delegate, DelegateReceiver DR) { // Ensure another delegate does not take over unless the current - // delegate first unattaches itself. If we ever need to multicast - // notifications, we will need to change to using a list. - assert(TheDelegate == delegate && - "Only the current delegate can perform reset!"); - TheDelegate = nullptr; + // delegate first unattaches itself. + assert(getDelegate(DR) == delegate && + "Only an existing delegate ca0n perform reset!"); + TheDelegates.erase(DR); } - void setDelegate(Delegate *delegate) { - assert(delegate && !TheDelegate && - "Attempted to set delegate to null, or to change it without " + void setDelegate(Delegate *delegate, DelegateReceiver DR) { + assert(delegate && !TheDelegates.count(DR) && + "Attempted to add null delegate, or to change it without " "first resetting it!"); - TheDelegate = delegate; + TheDelegates[DR] = delegate; } //===--------------------------------------------------------------------===// diff --git a/llvm/lib/CodeGen/MachineRegisterInfo.cpp b/llvm/lib/CodeGen/MachineRegisterInfo.cpp --- a/llvm/lib/CodeGen/MachineRegisterInfo.cpp +++ b/llvm/lib/CodeGen/MachineRegisterInfo.cpp @@ -48,6 +48,7 @@ RegAllocHints.reserve(256); UsedPhysRegMask.resize(NumRegs); PhysRegUseDefLists.reset(new MachineOperand*[NumRegs]()); + TheDelegates.clear(); } /// setRegClass - Set the register class of the specified virtual register. @@ -146,6 +147,9 @@ VRegInfo.grow(Reg); RegAllocHints.grow(Reg); insertVRegByName(Name, Reg); + for (auto &TheDelegate : TheDelegates) + TheDelegate.second->MRI_NoteNewVirtualRegister(Reg); + return Reg; } @@ -162,8 +166,6 @@ // New virtual register number. Register Reg = createIncompleteVirtualRegister(Name); VRegInfo[Reg].first = RegClass; - if (TheDelegate) - TheDelegate->MRI_NoteNewVirtualRegister(Reg); return Reg; } @@ -172,8 +174,9 @@ Register Reg = createIncompleteVirtualRegister(Name); VRegInfo[Reg].first = VRegInfo[VReg].first; setType(Reg, getType(VReg)); + Delegate *TheDelegate = getDelegate(DelegateReceiver::RESERVED); if (TheDelegate) - TheDelegate->MRI_NoteNewVirtualRegister(Reg); + TheDelegate->MRI_NotecloneVirtualRegister(Reg, VReg); return Reg; } @@ -189,8 +192,6 @@ // FIXME: Should we use a dummy register class? VRegInfo[Reg].first = static_cast(nullptr); setType(Reg, Ty); - if (TheDelegate) - TheDelegate->MRI_NoteNewVirtualRegister(Reg); return Reg; }