Allow registers defined by implicit_def to be clobbered.
authorEvan Cheng <evan.cheng@apple.com>
Thu, 10 Apr 2008 23:47:53 +0000 (23:47 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Thu, 10 Apr 2008 23:47:53 +0000 (23:47 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@49512 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/RegisterScavenging.h
lib/CodeGen/RegisterScavenging.cpp

index 2ce0ca7bc1577d78f1e83ea357953f7cf660aa11..4b1a6a94096c86766fc83abe44110edb86ddaec0 100644 (file)
@@ -53,6 +53,10 @@ class RegScavenger {
   /// available, unset means the register is currently being used.
   BitVector RegsAvailable;
 
+  /// ImplicitDefed - If bit is set that means the register is defined by an
+  /// implicit_def instructions. That means it can be clobbered at will.
+  BitVector ImplicitDefed;
+
 public:
   RegScavenger()
     : MBB(NULL), NumPhysRegs(0), Tracking(false),
@@ -92,15 +96,26 @@ public:
   bool isUsed(unsigned Reg) const   { return !RegsAvailable[Reg]; }
   bool isUnused(unsigned Reg) const { return RegsAvailable[Reg]; }
 
+  bool isImplicitlyDefined(unsigned Reg) const { return ImplicitDefed[Reg]; }
+
   /// getRegsUsed - return all registers currently in use in used.
   void getRegsUsed(BitVector &used, bool includeReserved);
 
   /// setUsed / setUnused - Mark the state of one or a number of registers.
   ///
-  void setUsed(unsigned Reg);
-  void setUsed(BitVector Regs)   { RegsAvailable &= ~Regs; }
+  void setUsed(unsigned Reg, bool ImpDef = false);
+  void setUsed(BitVector Regs, bool ImpDef = false) {
+    RegsAvailable &= ~Regs;
+    if (ImpDef)
+      ImplicitDefed |= Regs;
+    else
+      ImplicitDefed &= ~Regs;
+  }
   void setUnused(unsigned Reg, const MachineInstr *MI);
-  void setUnused(BitVector Regs) { RegsAvailable |= Regs; }
+  void setUnused(BitVector Regs) {
+    RegsAvailable |= Regs;
+    ImplicitDefed &= ~Regs;
+  }
 
   /// FindUnusedReg - Find a unused register of the specified register class
   /// from the specified set of registers. It return 0 is none is found.
index c71d3be08b4123b73fa7236dcbf141bea02f8989..1d9effb11085a76c1a9dc0de72d6dbec3b15b404 100644 (file)
@@ -55,22 +55,28 @@ static bool RedefinesSuperRegPart(const MachineInstr *MI,
 }
 
 /// setUsed - Set the register and its sub-registers as being used.
-void RegScavenger::setUsed(unsigned Reg) {
+void RegScavenger::setUsed(unsigned Reg, bool ImpDef) {
   RegsAvailable.reset(Reg);
+  ImplicitDefed[Reg] = ImpDef;
 
   for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
-       unsigned SubReg = *SubRegs; ++SubRegs)
+       unsigned SubReg = *SubRegs; ++SubRegs) {
     RegsAvailable.reset(SubReg);
+    ImplicitDefed[SubReg] = ImpDef;
+  }
 }
 
 /// setUnused - Set the register and its sub-registers as being unused.
 void RegScavenger::setUnused(unsigned Reg, const MachineInstr *MI) {
   RegsAvailable.set(Reg);
+  ImplicitDefed.reset(Reg);
 
   for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
        unsigned SubReg = *SubRegs; ++SubRegs)
-    if (!RedefinesSuperRegPart(MI, Reg, TRI))
+    if (!RedefinesSuperRegPart(MI, Reg, TRI)) {
       RegsAvailable.set(SubReg);
+      ImplicitDefed.reset(SubReg);
+    }
 }
 
 void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) {
@@ -86,6 +92,7 @@ void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) {
   if (!MBB) {
     NumPhysRegs = TRI->getNumRegs();
     RegsAvailable.resize(NumPhysRegs);
+    ImplicitDefed.resize(NumPhysRegs);
 
     // Create reserved registers bitvector.
     ReservedRegs = TRI->getReservedRegs(MF);
@@ -216,6 +223,7 @@ void RegScavenger::forward() {
   setUnused(ChangedRegs);
 
   // Process defs.
+  bool IsImpDef = MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF;
   for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
     const MachineOperand &MO = MI->getOperand(i);
 
@@ -240,12 +248,13 @@ void RegScavenger::forward() {
     if (RedefinesSuperRegPart(MI, MO, TRI))
       continue;
 
-    // Implicit def is allowed to "re-define" any register.
+    // Implicit def is allowed to "re-define" any register. Similarly,
+    // implicitly defined registers can be clobbered.
     assert((isReserved(Reg) || isUnused(Reg) ||
-            MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF ||
+            IsImpDef || isImplicitlyDefined(Reg) ||
             isLiveInButUnusedBefore(Reg, MI, MBB, TRI, MRI)) &&
            "Re-defining a live register!");
-    setUsed(Reg);
+    setUsed(Reg, IsImpDef);
   }
 }