[llvm-commits] [llvm] r78465 - in /llvm/trunk: include/llvm/CodeGen/RegisterScavenging.h lib/CodeGen/RegisterScavenging.cpp test/CodeGen/Thumb2/2009-08-08-ScavengerAssert.ll

Jakob Stoklund Olesen stoklund at 2pi.dk
Sat Aug 8 06:18:48 PDT 2009


Author: stoklund
Date: Sat Aug  8 08:18:47 2009
New Revision: 78465

URL: http://llvm.org/viewvc/llvm-project?rev=78465&view=rev
Log:
Simplify RegScavenger::forward a bit more.

Verify that early clobber registers and their aliases are not used.

All changes to RegsAvailable are now done as a transaction so the order of
operands makes no difference.

The included test case is from PR4686. It has behaviour that was dependent on the order of operands.

Added:
    llvm/trunk/test/CodeGen/Thumb2/2009-08-08-ScavengerAssert.ll
Modified:
    llvm/trunk/include/llvm/CodeGen/RegisterScavenging.h
    llvm/trunk/lib/CodeGen/RegisterScavenging.cpp

Modified: llvm/trunk/include/llvm/CodeGen/RegisterScavenging.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/RegisterScavenging.h?rev=78465&r1=78464&r2=78465&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/RegisterScavenging.h (original)
+++ llvm/trunk/include/llvm/CodeGen/RegisterScavenging.h Sat Aug  8 08:18:47 2009
@@ -162,8 +162,14 @@
   MachineInstr *findFirstUse(MachineBasicBlock *MBB,
                              MachineBasicBlock::iterator I, unsigned Reg,
                              unsigned &Dist);
+
+  /// Add Reg and all its sub-registers to BV.
+  void addRegWithSubRegs(BitVector &BV, unsigned Reg);
+
+  /// Add Reg and its aliases to BV.
+  void addRegWithAliases(BitVector &BV, unsigned Reg);
 };
- 
+
 } // End llvm namespace
 
 #endif

Modified: llvm/trunk/lib/CodeGen/RegisterScavenging.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegisterScavenging.cpp?rev=78465&r1=78464&r2=78465&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/RegisterScavenging.cpp (original)
+++ llvm/trunk/lib/CodeGen/RegisterScavenging.cpp Sat Aug  8 08:18:47 2009
@@ -51,13 +51,6 @@
   return SeenSuperDef && SeenSuperUse;
 }
 
-static bool RedefinesSuperRegPart(const MachineInstr *MI,
-                                  const MachineOperand &MO,
-                                  const TargetRegisterInfo *TRI) {
-  assert(MO.isReg() && MO.isDef() && "Not a register def!");
-  return RedefinesSuperRegPart(MI, MO.getReg(), TRI);
-}
-
 bool RegScavenger::isSuperRegUsed(unsigned Reg) const {
   for (const unsigned *SuperRegs = TRI->getSuperRegisters(Reg);
        unsigned SuperReg = *SuperRegs; ++SuperRegs)
@@ -190,6 +183,18 @@
 }
 #endif
 
+void RegScavenger::addRegWithSubRegs(BitVector &BV, unsigned Reg) {
+  BV.set(Reg);
+  for (const unsigned *R = TRI->getSubRegisters(Reg); *R; R++)
+    BV.set(*R);
+}
+
+void RegScavenger::addRegWithAliases(BitVector &BV, unsigned Reg) {
+  BV.set(Reg);
+  for (const unsigned *R = TRI->getAliasSet(Reg); *R; R++)
+    BV.set(*R);
+}
+
 void RegScavenger::forward() {
   // Move ptr forward.
   if (!Tracking) {
@@ -209,76 +214,59 @@
     ScavengeRestore = NULL;
   }
 
-  // Separate register operands into 3 classes: uses, defs, earlyclobbers.
-  SmallVector<std::pair<const MachineOperand*,unsigned>, 4> UseMOs;
-  SmallVector<std::pair<const MachineOperand*,unsigned>, 4> DefMOs;
-  SmallVector<std::pair<const MachineOperand*,unsigned>, 4> EarlyClobberMOs;
+  // Find out which registers are early clobbered, killed, defined, and marked
+  // def-dead in this instruction.
+  BitVector EarlyClobberRegs(NumPhysRegs);
+  BitVector KillRegs(NumPhysRegs);
+  BitVector DefRegs(NumPhysRegs);
+  BitVector DeadRegs(NumPhysRegs);
   for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
     const MachineOperand &MO = MI->getOperand(i);
-    if (!MO.isReg() || MO.getReg() == 0 || MO.isUndef())
+    if (!MO.isReg() || MO.isUndef())
       continue;
-    if (MO.isUse())
-      UseMOs.push_back(std::make_pair(&MO,i));
-    else if (MO.isEarlyClobber())
-      EarlyClobberMOs.push_back(std::make_pair(&MO,i));
-    else {
-      assert(MO.isDef());
-      DefMOs.push_back(std::make_pair(&MO,i));
-    }
-  }
-
-  // Process uses first.
-  BitVector KillRegs(NumPhysRegs);
-  for (unsigned i = 0, e = UseMOs.size(); i != e; ++i) {
-    const MachineOperand MO = *UseMOs[i].first;
-    unsigned Idx = UseMOs[i].second;
     unsigned Reg = MO.getReg();
+    if (!Reg || isReserved(Reg))
+      continue;
 
-    assert(isUsed(Reg) && "Using an undefined register!");
-
-    // Two-address operands implicitly kill.
-    if ((MO.isKill() || MI->isRegTiedToDefOperand(Idx)) && !isReserved(Reg)) {
-      KillRegs.set(Reg);
-
-      // Mark sub-registers as used.
-      for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
-           unsigned SubReg = *SubRegs; ++SubRegs)
-        KillRegs.set(SubReg);
+    if (MO.isUse()) {
+      // Two-address operands implicitly kill.
+      if (MO.isKill() || MI->isRegTiedToDefOperand(i))
+        addRegWithSubRegs(KillRegs, Reg);
+    } else {
+      assert(MO.isDef());
+      if (MO.isDead())
+        addRegWithSubRegs(DeadRegs, Reg);
+      else
+        addRegWithSubRegs(DefRegs, Reg);
+      if (MO.isEarlyClobber())
+        addRegWithAliases(EarlyClobberRegs, Reg);
     }
   }
 
-  // Change states of all registers after all the uses are processed to guard
-  // against multiple uses.
-  setUnused(KillRegs);
-
-  // Process early clobber defs then process defs. We can have a early clobber
-  // that is dead, it should not conflict with a def that happens one "slot"
-  // (see InstrSlots in LiveIntervalAnalysis.h) later.
-  unsigned NumECs = EarlyClobberMOs.size();
-  unsigned NumDefs = DefMOs.size();
-
-  for (unsigned i = 0, e = NumECs + NumDefs; i != e; ++i) {
-    const MachineOperand &MO = (i < NumECs)
-      ? *EarlyClobberMOs[i].first : *DefMOs[i-NumECs].first;
-    unsigned Reg = MO.getReg();
-    if (MO.isUndef())
+  // Verify uses and defs.
+  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+    const MachineOperand &MO = MI->getOperand(i);
+    if (!MO.isReg() || MO.isUndef())
       continue;
-
-    // If it's dead upon def, then it is now free.
-    if (MO.isDead()) {
-      setUnused(Reg, MI);
+    unsigned Reg = MO.getReg();
+    if (!Reg || isReserved(Reg))
       continue;
+    if (MO.isUse()) {
+      assert(isUsed(Reg) && "Using an undefined register!");
+      assert(!EarlyClobberRegs.test(Reg) &&
+             "Using an early clobbered register!");
+    } else {
+      assert(MO.isDef());
+      assert((KillRegs.test(Reg) || isUnused(Reg) || isSuperRegUsed(Reg) ||
+              isLiveInButUnusedBefore(Reg, MI, MBB, TRI, MRI)) &&
+             "Re-defining a live register!");
     }
-
-    // Skip if this is merely redefining part of a super-register.
-    if (RedefinesSuperRegPart(MI, MO, TRI))
-      continue;
-
-    assert((isReserved(Reg) || isUnused(Reg) || isSuperRegUsed(Reg) ||
-            isLiveInButUnusedBefore(Reg, MI, MBB, TRI, MRI)) &&
-           "Re-defining a live register!");
-    setUsed(Reg);
   }
+
+  // Commit the changes.
+  setUnused(KillRegs);
+  setUnused(DeadRegs);
+  setUsed(DefRegs);
 }
 
 void RegScavenger::getRegsUsed(BitVector &used, bool includeReserved) {

Added: llvm/trunk/test/CodeGen/Thumb2/2009-08-08-ScavengerAssert.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/2009-08-08-ScavengerAssert.ll?rev=78465&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/Thumb2/2009-08-08-ScavengerAssert.ll (added)
+++ llvm/trunk/test/CodeGen/Thumb2/2009-08-08-ScavengerAssert.ll Sat Aug  8 08:18:47 2009
@@ -0,0 +1,20 @@
+; RUN: llvm-as < %s | llc -mtriple=armv7-eabi -mattr=+vfp2
+; PR4686
+
+ at g_d = external global double		; <double*> [#uses=1]
+
+define arm_aapcscc void @foo(float %yIncr) {
+entry:
+	br i1 undef, label %bb, label %bb4
+
+bb:		; preds = %entry
+	%0 = call arm_aapcs_vfpcc  float @bar()		; <float> [#uses=1]
+	%1 = fpext float %0 to double		; <double> [#uses=1]
+	store double %1, double* @g_d, align 8
+	br label %bb4
+
+bb4:		; preds = %bb, %entry
+	unreachable
+}
+
+declare arm_aapcs_vfpcc float @bar()





More information about the llvm-commits mailing list