Notify LiveRangeEdit of new virtual registers.
authorMark Lacey <mark.lacey@apple.com>
Wed, 14 Aug 2013 23:50:09 +0000 (23:50 +0000)
committerMark Lacey <mark.lacey@apple.com>
Wed, 14 Aug 2013 23:50:09 +0000 (23:50 +0000)
Add a delegate class to MachineRegisterInfo with a single virtual
function, MRI_NoteNewVirtualRegister(). Update LiveRangeEdit to inherit
from this delegate class and override the definition of the callback
with an implementation that tracks the newly created virtual registers.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188435 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/LiveRangeEdit.h
include/llvm/CodeGen/MachineRegisterInfo.h
lib/CodeGen/LiveRangeEdit.cpp
lib/CodeGen/MachineRegisterInfo.cpp

index 30ec10f4b8b555bff3ac083e3fb88fa28eafdb77..43a956605ad80de72e19fdffc918533ea6938bfd 100644 (file)
@@ -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");
index 7a6dcd05897b57282fe914ce1bbea72b00a8e240..4fb1ac90aabb596088e20285fd62849022123a46 100644 (file)
@@ -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
   //===--------------------------------------------------------------------===//
index 4e6c4c705d44b48c2ad4ccebca6e4b3caf7b57b5..04f92adefd12783c309709b5ebc63a47db388d99 100644 (file)
@@ -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<MachineInstr*> &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,
index 7f2c0caca43c4ca2d471e916e6c99670f34987d6..ce7d567cc2927d330e1a498fe91dbbf183642a34 100644 (file)
@@ -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;
 }