Clear virtual registers after they are no longer referenced.
authorAndrew Trick <atrick@apple.com>
Tue, 21 Feb 2012 04:51:23 +0000 (04:51 +0000)
committerAndrew Trick <atrick@apple.com>
Tue, 21 Feb 2012 04:51:23 +0000 (04:51 +0000)
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
lib/CodeGen/MachineRegisterInfo.cpp
lib/CodeGen/PrologEpilogInserter.cpp
lib/CodeGen/RegAllocBasic.cpp
lib/CodeGen/RegAllocFast.cpp
lib/CodeGen/RegAllocGreedy.cpp
lib/CodeGen/RegAllocPBQP.cpp
lib/CodeGen/ScheduleDAGInstrs.cpp
lib/Target/PTX/PTXTargetMachine.cpp

index 51c71b724ccc67c3c8254c92d242f35564ee0074..36fac85b46536e398634977096242f97a74214b2 100644 (file)
@@ -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) {
index 08bf1ae91066eb997c37b780b5a4752ef2632122..984112ff726bdd4d3c82439d401c2ea5806ee414 100644 (file)
@@ -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.
index 39fda501c10ef09a7504ea978544ad5ebc43d7dd..9f92978f93365b255a697cb1c5e7ec626818f373 100644 (file)
@@ -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(),
index 18d6f473299fa972a9eefa17f0f51dc000d9c4a1..d1b289b3634ccdb7b5f9bc53e4f6c3bc0812ea59 100644 (file)
@@ -342,7 +342,10 @@ bool RABasic::runOnMachineFunction(MachineFunction &mf) {
   // Write out new DBG_VALUE instructions.
   getAnalysis<LiveDebugVariables>().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;
index 6d7b5f4b6567e1e8c74da3fd20042b66315b7cb5..b8b05a9f60d8082bbb01c5717c4f3fa1454b569c 100644 (file)
@@ -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();
index 61e5e823dfd9ab1f97fda0a49bc19c038953f921..1d089ae253f8ead7b1f9051916fa54dbcfa757d0 100644 (file)
@@ -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;
index 73479d7bf9a757cc94ede8e34f2202d00a17268e..a36eeff6ea7db74328e95b657601d0f26db7861a 100644 (file)
@@ -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;
 }
 
index b3349209a5d21e589d543f725c69f8e1d7469796..879b65f9d089c1044c7c365a0910226b7b17f1bf 100644 (file)
@@ -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.
index 61285b154521efa9342f5647d771a28d2e0cceb4..930537729a52684759b528170bc7f7b0e2a3c0a8 100644 (file)
@@ -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() {