From 19273aec441411b4d571fdb87c6daa0fbe7a33a0 Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Tue, 21 Feb 2012 04:51:23 +0000 Subject: [PATCH] Clear virtual registers after they are no longer referenced. Passes after RegAlloc should be able to rely on MRI->getNumVirtRegs() == 0. This makes sharing code for pre/postRA passes more robust. Now, to check if a pass is running before the RA pipeline begins, use MRI->isSSA(). To check if a pass is running after the RA pipeline ends, use !MRI->getNumVirtRegs(). PEI resets virtual regs when it's done scavenging. PTX will either have to provide its own PEI pass or assign physregs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@151032 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/MachineRegisterInfo.h | 3 +++ lib/CodeGen/MachineRegisterInfo.cpp | 14 +++++++++++--- lib/CodeGen/PrologEpilogInserter.cpp | 9 +++++++++ lib/CodeGen/RegAllocBasic.cpp | 5 ++++- lib/CodeGen/RegAllocFast.cpp | 4 ++++ lib/CodeGen/RegAllocGreedy.cpp | 5 ++++- lib/CodeGen/RegAllocPBQP.cpp | 5 +++++ lib/CodeGen/ScheduleDAGInstrs.cpp | 2 ++ lib/Target/PTX/PTXTargetMachine.cpp | 4 +++- 9 files changed, 45 insertions(+), 6 deletions(-) diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h index 51c71b724cc..36fac85b465 100644 --- a/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/include/llvm/CodeGen/MachineRegisterInfo.h @@ -273,6 +273,9 @@ public: /// unsigned getNumVirtRegs() const { return VRegInfo.size(); } + /// clearVirtRegs - Remove all virtual registers (after physreg assignment). + void clearVirtRegs(); + /// setRegAllocationHint - Specify a register allocation hint for the /// specified virtual register. void setRegAllocationHint(unsigned Reg, unsigned Type, unsigned PrefReg) { diff --git a/lib/CodeGen/MachineRegisterInfo.cpp b/lib/CodeGen/MachineRegisterInfo.cpp index 08bf1ae9106..984112ff726 100644 --- a/lib/CodeGen/MachineRegisterInfo.cpp +++ b/lib/CodeGen/MachineRegisterInfo.cpp @@ -31,9 +31,7 @@ MachineRegisterInfo::MachineRegisterInfo(const TargetRegisterInfo &TRI) MachineRegisterInfo::~MachineRegisterInfo() { #ifndef NDEBUG - for (unsigned i = 0, e = getNumVirtRegs(); i != e; ++i) - assert(VRegInfo[TargetRegisterInfo::index2VirtReg(i)].second == 0 && - "Vreg use list non-empty still?"); + clearVirtRegs(); for (unsigned i = 0, e = UsedPhysRegs.size(); i != e; ++i) assert(!PhysRegUseDefLists[i] && "PhysRegUseDefLists has entries after all instructions are deleted"); @@ -118,6 +116,16 @@ MachineRegisterInfo::createVirtualRegister(const TargetRegisterClass *RegClass){ return Reg; } +/// clearVirtRegs - Remove all virtual registers (after physreg assignment). +void MachineRegisterInfo::clearVirtRegs() { +#ifndef NDEBUG + for (unsigned i = 0, e = getNumVirtRegs(); i != e; ++i) + assert(VRegInfo[TargetRegisterInfo::index2VirtReg(i)].second == 0 && + "Vreg use list non-empty still?"); +#endif + VRegInfo.clear(); +} + /// HandleVRegListReallocation - We just added a virtual register to the /// VRegInfo info list and it reallocated. Update the use/def lists info /// pointers. diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp index 39fda501c10..9f92978f933 100644 --- a/lib/CodeGen/PrologEpilogInserter.cpp +++ b/lib/CodeGen/PrologEpilogInserter.cpp @@ -69,6 +69,8 @@ bool PEI::runOnMachineFunction(MachineFunction &Fn) { const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo(); const TargetFrameLowering *TFI = Fn.getTarget().getFrameLowering(); + assert(!Fn.getRegInfo().getNumVirtRegs() && "Regalloc must assign all vregs"); + RS = TRI->requiresRegisterScavenging(Fn) ? new RegScavenger() : NULL; FrameIndexVirtualScavenging = TRI->requiresFrameIndexScavenging(Fn); @@ -123,6 +125,9 @@ bool PEI::runOnMachineFunction(MachineFunction &Fn) { if (TRI->requiresRegisterScavenging(Fn) && FrameIndexVirtualScavenging) scavengeFrameVirtualRegs(Fn); + // Clear any vregs created by virtual scavenging. + Fn.getRegInfo().clearVirtRegs(); + delete RS; clearAllSets(); return true; @@ -803,6 +808,10 @@ void PEI::replaceFrameIndices(MachineFunction &Fn) { /// scavengeFrameVirtualRegs - Replace all frame index virtual registers /// with physical registers. Use the register scavenger to find an /// appropriate register to use. +/// +/// FIXME: Iterating over the instruction stream is unnecessary. We can simply +/// iterate over the vreg use list, which at this point only contains machine +/// operands for which eliminateFrameIndex need a new scratch reg. void PEI::scavengeFrameVirtualRegs(MachineFunction &Fn) { // Run through the instructions and find any virtual registers. for (MachineFunction::iterator BB = Fn.begin(), diff --git a/lib/CodeGen/RegAllocBasic.cpp b/lib/CodeGen/RegAllocBasic.cpp index 18d6f473299..d1b289b3634 100644 --- a/lib/CodeGen/RegAllocBasic.cpp +++ b/lib/CodeGen/RegAllocBasic.cpp @@ -342,7 +342,10 @@ bool RABasic::runOnMachineFunction(MachineFunction &mf) { // Write out new DBG_VALUE instructions. getAnalysis().emitDebugValues(VRM); - // The pass output is in VirtRegMap. Release all the transient data. + // All machine operands and other references to virtual registers have been + // replaced. Remove the virtual registers and release all the transient data. + VRM->clearAllVirt(); + MRI->clearVirtRegs(); releaseMemory(); return true; diff --git a/lib/CodeGen/RegAllocFast.cpp b/lib/CodeGen/RegAllocFast.cpp index 6d7b5f4b656..b8b05a9f60d 100644 --- a/lib/CodeGen/RegAllocFast.cpp +++ b/lib/CodeGen/RegAllocFast.cpp @@ -1104,6 +1104,10 @@ bool RAFast::runOnMachineFunction(MachineFunction &Fn) { while (*Defs) MRI->setPhysRegUsed(*Defs++); + // All machine operands and other references to virtual registers have been + // replaced. Remove the virtual registers. + MRI->clearVirtRegs(); + SkippedInstrs.clear(); StackSlotForVirtReg.clear(); LiveDbgValueMap.clear(); diff --git a/lib/CodeGen/RegAllocGreedy.cpp b/lib/CodeGen/RegAllocGreedy.cpp index 61e5e823dfd..1d089ae253f 100644 --- a/lib/CodeGen/RegAllocGreedy.cpp +++ b/lib/CodeGen/RegAllocGreedy.cpp @@ -1698,7 +1698,10 @@ bool RAGreedy::runOnMachineFunction(MachineFunction &mf) { DebugVars->emitDebugValues(VRM); } - // The pass output is in VirtRegMap. Release all the transient data. + // All machine operands and other references to virtual registers have been + // replaced. Remove the virtual registers and release all the transient data. + VRM->clearAllVirt(); + MRI->clearVirtRegs(); releaseMemory(); return true; diff --git a/lib/CodeGen/RegAllocPBQP.cpp b/lib/CodeGen/RegAllocPBQP.cpp index 73479d7bf9a..a36eeff6ea7 100644 --- a/lib/CodeGen/RegAllocPBQP.cpp +++ b/lib/CodeGen/RegAllocPBQP.cpp @@ -667,6 +667,11 @@ bool RegAllocPBQP::runOnMachineFunction(MachineFunction &MF) { // Run rewriter vrm->rewrite(lis->getSlotIndexes()); + // All machine operands and other references to virtual registers have been + // replaced. Remove the virtual registers. + vrm->clearAllVirt(); + mri->clearVirtRegs(); + return true; } diff --git a/lib/CodeGen/ScheduleDAGInstrs.cpp b/lib/CodeGen/ScheduleDAGInstrs.cpp index b3349209a5d..879b65f9d08 100644 --- a/lib/CodeGen/ScheduleDAGInstrs.cpp +++ b/lib/CodeGen/ScheduleDAGInstrs.cpp @@ -40,6 +40,8 @@ ScheduleDAGInstrs::ScheduleDAGInstrs(MachineFunction &mf, UnitLatencies(false), Defs(TRI->getNumRegs()), Uses(TRI->getNumRegs()), LoopRegs(MLI, MDT), FirstDbgValue(0) { DbgValues.clear(); + assert(!(IsPostRA && MF.getRegInfo().getNumVirtRegs()) && + "Virtual registers must be removed prior to PostRA scheduling"); } /// Run - perform scheduling. diff --git a/lib/Target/PTX/PTXTargetMachine.cpp b/lib/Target/PTX/PTXTargetMachine.cpp index 61285b15452..930537729a5 100644 --- a/lib/Target/PTX/PTXTargetMachine.cpp +++ b/lib/Target/PTX/PTXTargetMachine.cpp @@ -126,7 +126,9 @@ public: } // namespace TargetPassConfig *PTXTargetMachine::createPassConfig(PassManagerBase &PM) { - return new PTXPassConfig(this, PM); + PTXPassConfig *PassConfig = new PTXPassConfig(this, PM); + PassConfig->disablePass(PrologEpilogCodeInserterID); + return PassConfig; } bool PTXPassConfig::addInstSelector() {