diff --git a/include/llvm/CodeGen/LiveRangeEdit.h b/include/llvm/CodeGen/LiveRangeEdit.h index 30ec10f4b8b..43a956605ad 100644 --- a/include/llvm/CodeGen/LiveRangeEdit.h +++ b/include/llvm/CodeGen/LiveRangeEdit.h @@ -22,6 +22,7 @@ #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/CodeGen/LiveInterval.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Target/TargetMachine.h" namespace llvm { @@ -32,7 +33,7 @@ class MachineBlockFrequencyInfo; class MachineLoopInfo; class VirtRegMap; -class LiveRangeEdit { +class LiveRangeEdit : private MachineRegisterInfo::Delegate { public: /// Callback methods for LiveRangeEdit owners. class Delegate { @@ -96,6 +97,10 @@ private: /// Helper for eliminateDeadDefs. void eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink); + /// MachineRegisterInfo callback to notify when new virtual + /// registers are created. + void MRI_NoteNewVirtualRegister(unsigned VReg); + public: /// Create a LiveRangeEdit for breaking down parent into smaller pieces. /// @param parent The register being spilled or split. @@ -117,7 +122,9 @@ public: TII(*MF.getTarget().getInstrInfo()), TheDelegate(delegate), FirstNew(newRegs.size()), - ScannedRemattable(false) {} + ScannedRemattable(false) { MRI.setDelegate(this); } + + ~LiveRangeEdit() { MRI.resetDelegate(this); } LiveInterval &getParent() const { assert(Parent && "No parent LiveInterval"); diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h index 7a6dcd05897..4fb1ac90aab 100644 --- a/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/include/llvm/CodeGen/MachineRegisterInfo.h @@ -27,7 +27,17 @@ namespace llvm { /// registers, including vreg register classes, use/def chains for registers, /// etc. class MachineRegisterInfo { +public: + class Delegate { + public: + virtual void MRI_NoteNewVirtualRegister(unsigned Reg) {} + + virtual ~Delegate() {} + }; + +private: const TargetMachine &TM; + Delegate *TheDelegate; /// IsSSA - True when the machine function is in SSA form and virtual /// registers have a single def. @@ -116,6 +126,23 @@ public: return TM.getRegisterInfo(); } + void resetDelegate(Delegate *delegate) { + // 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 = 0; + } + + void setDelegate(Delegate *delegate) { + assert(delegate && !TheDelegate && + "Attempted to set delegate to null, or to change it without " + "first resetting it!"); + + TheDelegate = delegate; + } + //===--------------------------------------------------------------------===// // Function State //===--------------------------------------------------------------------===// diff --git a/lib/CodeGen/LiveRangeEdit.cpp b/lib/CodeGen/LiveRangeEdit.cpp index 4e6c4c705d4..04f92adefd1 100644 --- a/lib/CodeGen/LiveRangeEdit.cpp +++ b/lib/CodeGen/LiveRangeEdit.cpp @@ -33,11 +33,9 @@ void LiveRangeEdit::Delegate::anchor() { } LiveInterval &LiveRangeEdit::createFrom(unsigned OldReg) { unsigned VReg = MRI.createVirtualRegister(MRI.getRegClass(OldReg)); if (VRM) { - VRM->grow(); VRM->setIsSplitFromReg(VReg, VRM->getOriginal(OldReg)); } LiveInterval &LI = LIS.getOrCreateInterval(VReg); - NewRegs.push_back(VReg); return LI; } @@ -387,6 +385,17 @@ void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl &Dead, } } +// Keep track of new virtual registers created via +// MachineRegisterInfo::createVirtualRegister. +void +LiveRangeEdit::MRI_NoteNewVirtualRegister(unsigned VReg) +{ + if (VRM) + VRM->grow(); + + NewRegs.push_back(VReg); +} + void LiveRangeEdit::calculateRegClassAndHint(MachineFunction &MF, const MachineLoopInfo &Loops, diff --git a/lib/CodeGen/MachineRegisterInfo.cpp b/lib/CodeGen/MachineRegisterInfo.cpp index 7f2c0caca43..ce7d567cc29 100644 --- a/lib/CodeGen/MachineRegisterInfo.cpp +++ b/lib/CodeGen/MachineRegisterInfo.cpp @@ -20,7 +20,7 @@ using namespace llvm; MachineRegisterInfo::MachineRegisterInfo(const TargetMachine &TM) - : TM(TM), IsSSA(true), TracksLiveness(true) { + : TM(TM), TheDelegate(0), IsSSA(true), TracksLiveness(true) { VRegInfo.reserve(256); RegAllocHints.reserve(256); UsedRegUnits.resize(getTargetRegisterInfo()->getNumRegUnits()); @@ -108,6 +108,8 @@ MachineRegisterInfo::createVirtualRegister(const TargetRegisterClass *RegClass){ VRegInfo.grow(Reg); VRegInfo[Reg].first = RegClass; RegAllocHints.grow(Reg); + if (TheDelegate) + TheDelegate->MRI_NoteNewVirtualRegister(Reg); return Reg; }