[llvm-commits] [llvm] r51306 - in /llvm/trunk: lib/CodeGen/VirtRegMap.cpp test/CodeGen/ARM/2008-05-19-ScavengerAssert.ll

Evan Cheng evan.cheng at apple.com
Tue May 20 01:13:21 PDT 2008


Author: evancheng
Date: Tue May 20 03:13:21 2008
New Revision: 51306

URL: http://llvm.org/viewvc/llvm-project?rev=51306&view=rev
Log:
More local spiller complexity!
If local spiller optimization turns some instruction into an identity copy, it will be removed. If the output register happens to be dead (and source is obviously killed), transfer the kill / dead information to last use / def in the same MBB.

Added:
    llvm/trunk/test/CodeGen/ARM/2008-05-19-ScavengerAssert.ll
Modified:
    llvm/trunk/lib/CodeGen/VirtRegMap.cpp

Modified: llvm/trunk/lib/CodeGen/VirtRegMap.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegMap.cpp?rev=51306&r1=51305&r2=51306&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/VirtRegMap.cpp (original)
+++ llvm/trunk/lib/CodeGen/VirtRegMap.cpp Tue May 20 03:13:21 2008
@@ -302,6 +302,7 @@
     MachineRegisterInfo *RegInfo;
     const TargetRegisterInfo *TRI;
     const TargetInstrInfo *TII;
+    DenseMap<MachineInstr*, unsigned> DistanceMap;
   public:
     bool runOnMachineFunction(MachineFunction &MF, VirtRegMap &VRM) {
       RegInfo = &MF.getRegInfo(); 
@@ -333,6 +334,9 @@
       return true;
     }
   private:
+    void TransferDeadness(MachineBasicBlock *MBB, unsigned CurDist,
+                          unsigned Reg, BitVector &RegKills,
+                          std::vector<MachineOperand*> &KillOps);
     bool PrepForUnfoldOpti(MachineBasicBlock &MBB,
                            MachineBasicBlock::iterator &MII,
                            std::vector<MachineInstr*> &MaybeDeadStores,
@@ -943,6 +947,7 @@
           VRM.assignVirt2Phys(UnfoldVR, UnfoldPR);
         VRM.virtFolded(VirtReg, FoldedMI, VirtRegMap::isRef);
         MII = MBB.insert(MII, FoldedMI);
+        InvalidateKills(MI, RegKills, KillOps);
         VRM.RemoveMachineInstrFromMaps(&MI);
         MBB.erase(&MI);
         return true;
@@ -1026,6 +1031,49 @@
   ++NumStores;
 }
 
+/// TransferDeadness - A identity copy definition is dead and it's being
+/// removed. Find the last def or use and mark it as dead / kill.
+void LocalSpiller::TransferDeadness(MachineBasicBlock *MBB, unsigned CurDist,
+                                    unsigned Reg, BitVector &RegKills,
+                                    std::vector<MachineOperand*> &KillOps) {
+  int LastUDDist = -1;
+  MachineInstr *LastUDMI = NULL;
+  for (MachineRegisterInfo::reg_iterator RI = RegInfo->reg_begin(Reg),
+         RE = RegInfo->reg_end(); RI != RE; ++RI) {
+    MachineInstr *UDMI = &*RI;
+    if (UDMI->getParent() != MBB)
+      continue;
+    DenseMap<MachineInstr*, unsigned>::iterator DI = DistanceMap.find(UDMI);
+    if (DI == DistanceMap.end() || DI->second > CurDist)
+      continue;
+    if ((int)DI->second < LastUDDist)
+      continue;
+    LastUDDist = DI->second;
+    LastUDMI = UDMI;
+  }
+
+  if (LastUDMI) {
+    const TargetInstrDesc &TID = LastUDMI->getDesc();
+    MachineOperand *LastUD = NULL;
+    for (unsigned i = 0, e = LastUDMI->getNumOperands(); i != e; ++i) {
+      MachineOperand &MO = LastUDMI->getOperand(i);
+      if (!MO.isRegister() || MO.getReg() != Reg)
+        continue;
+      if (!LastUD || (LastUD->isUse() && MO.isDef()))
+        LastUD = &MO;
+      if (TID.getOperandConstraint(i, TOI::TIED_TO) != -1)
+        return;
+    }
+    if (LastUD->isDef())
+      LastUD->setIsDead();
+    else {
+      LastUD->setIsKill();
+      RegKills.set(Reg);
+      KillOps[Reg] = LastUD;
+    }
+  }
+}
+
 /// rewriteMBB - Keep track of which spills are available even after the
 /// register allocator is done with them.  If possible, avid reloading vregs.
 void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
@@ -1054,6 +1102,8 @@
   std::vector<MachineOperand*>  KillOps;
   KillOps.resize(TRI->getNumRegs(), NULL);
 
+  unsigned Dist = 0;
+  DistanceMap.clear();
   for (MachineBasicBlock::iterator MII = MBB.begin(), E = MBB.end();
        MII != E; ) {
     MachineBasicBlock::iterator NextMII = MII; ++NextMII;
@@ -1431,6 +1481,7 @@
               InvalidateKill(InReg, RegKills, KillOps);
             }
 
+            InvalidateKills(MI, RegKills, KillOps);
             VRM.RemoveMachineInstrFromMaps(&MI);
             MBB.erase(&MI);
             Erased = true;
@@ -1442,6 +1493,7 @@
           if (PhysReg &&
               TII->unfoldMemoryOperand(MF, &MI, PhysReg, false, false, NewMIs)) {
             MBB.insert(MII, NewMIs[0]);
+            InvalidateKills(MI, RegKills, KillOps);
             VRM.RemoveMachineInstrFromMaps(&MI);
             MBB.erase(&MI);
             Erased = true;
@@ -1476,6 +1528,7 @@
               NewStore = NewMIs[1];
               MBB.insert(MII, NewStore);
               VRM.addSpillSlotUse(SS, NewStore);
+              InvalidateKills(MI, RegKills, KillOps);
               VRM.RemoveMachineInstrFromMaps(&MI);
               MBB.erase(&MI);
               Erased = true;
@@ -1549,6 +1602,13 @@
         if (TII->isMoveInstr(MI, Src, Dst) && Src == Dst) {
           ++NumDCE;
           DOUT << "Removing now-noop copy: " << MI;
+          SmallVector<unsigned, 2> KillRegs;
+          InvalidateKills(MI, RegKills, KillOps, &KillRegs);
+          if (MO.isDead() && !KillRegs.empty()) {
+            assert(KillRegs[0] == Dst);
+            // Last def is now dead.
+            TransferDeadness(&MBB, Dist, Src, RegKills, KillOps);
+          }
           VRM.RemoveMachineInstrFromMaps(&MI);
           MBB.erase(&MI);
           Erased = true;
@@ -1626,6 +1686,7 @@
           if (TII->isMoveInstr(MI, Src, Dst) && Src == Dst) {
             ++NumDCE;
             DOUT << "Removing now-noop copy: " << MI;
+            InvalidateKills(MI, RegKills, KillOps);
             VRM.RemoveMachineInstrFromMaps(&MI);
             MBB.erase(&MI);
             Erased = true;
@@ -1636,6 +1697,7 @@
       }    
     }
   ProcessNextInst:
+    DistanceMap.insert(std::make_pair(&MI, Dist++));
     if (!Erased && !BackTracked) {
       for (MachineBasicBlock::iterator II = MI; II != NextMII; ++II)
         UpdateKills(*II, RegKills, KillOps);

Added: llvm/trunk/test/CodeGen/ARM/2008-05-19-ScavengerAssert.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2008-05-19-ScavengerAssert.ll?rev=51306&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/ARM/2008-05-19-ScavengerAssert.ll (added)
+++ llvm/trunk/test/CodeGen/ARM/2008-05-19-ScavengerAssert.ll Tue May 20 03:13:21 2008
@@ -0,0 +1,22 @@
+; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin
+
+	%struct.Decoders = type { i32**, i16***, i16****, i16***, i16**, i8**, i8** }
+ at decoders = external global %struct.Decoders		; <%struct.Decoders*> [#uses=1]
+
+declare i8* @calloc(i32, i32)
+
+declare fastcc i32 @get_mem2Dint(i32***, i32, i32)
+
+define fastcc void @init_global_buffers() nounwind {
+entry:
+	%tmp151 = tail call fastcc i32 @get_mem2Dint( i32*** getelementptr (%struct.Decoders* @decoders, i32 0, i32 0), i32 16, i32 16 )		; <i32> [#uses=1]
+	%tmp158 = tail call i8* @calloc( i32 0, i32 4 )		; <i8*> [#uses=0]
+	br i1 false, label %cond_true166, label %bb190.preheader
+
+bb190.preheader:		; preds = %entry
+	%memory_size.3555 = add i32 0, %tmp151		; <i32> [#uses=0]
+	unreachable
+
+cond_true166:		; preds = %entry
+	unreachable
+}





More information about the llvm-commits mailing list