[llvm-commits] [llvm] r49542 - in /llvm/trunk: include/llvm/CodeGen/LiveIntervalAnalysis.h lib/CodeGen/LiveIntervalAnalysis.cpp lib/CodeGen/VirtRegMap.cpp lib/CodeGen/VirtRegMap.h

Evan Cheng evan.cheng at apple.com
Fri Apr 11 10:53:36 PDT 2008


Author: evancheng
Date: Fri Apr 11 12:53:36 2008
New Revision: 49542

URL: http://llvm.org/viewvc/llvm-project?rev=49542&view=rev
Log:
Use of implicit_def is not part of live interval. Create empty intervals for the uses when the live interval is being spilled.

Modified:
    llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h
    llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp
    llvm/trunk/lib/CodeGen/VirtRegMap.cpp
    llvm/trunk/lib/CodeGen/VirtRegMap.h

Modified: llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h?rev=49542&r1=49541&r2=49542&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h (original)
+++ llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h Fri Apr 11 12:53:36 2008
@@ -394,9 +394,11 @@
                           BitVector &RestoreMBBs,
                           std::map<unsigned,std::vector<SRInfo> >&RestoreIdxes);
 
-    /// removeSpilledImpDefs - Remove IMPLICIT_DEF instructions which are being
-    /// spilled.
-    void removeSpilledImpDefs(const LiveInterval &li, VirtRegMap &vrm);
+    /// handleSpilledImpDefs - Remove IMPLICIT_DEF instructions which are being
+    /// spilled and create empty intervals for their uses.
+    void handleSpilledImpDefs(const LiveInterval &li, VirtRegMap &vrm,
+                              const TargetRegisterClass* rc,
+                              std::vector<LiveInterval*> &NewLIs);
 
     /// rewriteImplicitOps - Rewrite implicit use operands of MI (i.e. uses of
     /// interval on to-be re-materialized operands of MI) with new register.

Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=49542&r1=49541&r2=49542&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original)
+++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Fri Apr 11 12:53:36 2008
@@ -1319,19 +1319,37 @@
       Restores[i].index = -1;
 }
 
-/// removeSpilledImpDefs - Remove IMPLICIT_DEF instructions which are being
-/// spilled.
-void LiveIntervals::removeSpilledImpDefs(const LiveInterval &li,
-                                         VirtRegMap &vrm) {
+/// handleSpilledImpDefs - Remove IMPLICIT_DEF instructions which are being
+/// spilled and create empty intervals for their uses.
+void
+LiveIntervals::handleSpilledImpDefs(const LiveInterval &li, VirtRegMap &vrm,
+                                    const TargetRegisterClass* rc,
+                                    std::vector<LiveInterval*> &NewLIs) {
   for (MachineRegisterInfo::reg_iterator ri = mri_->reg_begin(li.reg),
          re = mri_->reg_end(); ri != re; ) {
+    MachineOperand &O = ri.getOperand();
     MachineInstr *MI = &*ri;
     ++ri;
-    if (MI->getOpcode() != TargetInstrInfo::IMPLICIT_DEF)
-      continue;
-    RemoveMachineInstrFromMaps(MI);
-    vrm.RemoveMachineInstrFromMaps(MI);
-    MI->eraseFromParent();
+    if (O.isDef()) {
+      assert(MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF &&
+             "Register def was not rewritten?");
+      RemoveMachineInstrFromMaps(MI);
+      vrm.RemoveMachineInstrFromMaps(MI);
+      MI->eraseFromParent();
+    } else {
+      // This must be an use of an implicit_def so it's not part of the live
+      // interval. Create a new empty live interval for it.
+      // FIXME: Can we simply erase some of the instructions? e.g. Stores?
+      unsigned NewVReg = mri_->createVirtualRegister(rc);
+      vrm.grow();
+      vrm.setIsImplicitlyDefined(NewVReg);
+      NewLIs.push_back(&getOrCreateInterval(NewVReg));
+      for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+        MachineOperand &MO = MI->getOperand(i);
+        if (MO.isReg() && MO.getReg() == li.reg)
+          MO.setReg(NewVReg);
+      }
+    }
   }
 }
 
@@ -1415,7 +1433,7 @@
       IsFirstRange = false;
     }
 
-    removeSpilledImpDefs(li, vrm);
+    handleSpilledImpDefs(li, vrm, rc, NewLIs);
     return NewLIs;
   }
 
@@ -1485,7 +1503,7 @@
 
   // Insert spills / restores if we are splitting.
   if (!TrySplit) {
-    removeSpilledImpDefs(li, vrm);
+    handleSpilledImpDefs(li, vrm, rc, NewLIs);
     return NewLIs;
   }
 
@@ -1640,7 +1658,7 @@
     }
   }
 
-  removeSpilledImpDefs(li, vrm);
+  handleSpilledImpDefs(li, vrm, rc, RetNewLIs);
   return RetNewLIs;
 }
 

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

==============================================================================
--- llvm/trunk/lib/CodeGen/VirtRegMap.cpp (original)
+++ llvm/trunk/lib/CodeGen/VirtRegMap.cpp Fri Apr 11 12:53:36 2008
@@ -21,6 +21,7 @@
 #include "llvm/Function.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetInstrInfo.h"
@@ -69,6 +70,8 @@
     Virt2SplitKillMap(0), ReMatMap(NULL), ReMatId(MAX_STACK_SLOT+1),
     LowSpillSlot(NO_STACK_SLOT), HighSpillSlot(NO_STACK_SLOT) {
   SpillSlotToUsesMap.resize(8);
+  ImplicitDefed.resize(MF.getRegInfo().getLastVirtReg()+1-
+                       TargetRegisterInfo::FirstVirtualRegister);
   grow();
 }
 
@@ -80,6 +83,7 @@
   Virt2SplitMap.grow(LastVirtReg);
   Virt2SplitKillMap.grow(LastVirtReg);
   ReMatMap.grow(LastVirtReg);
+  ImplicitDefed.resize(LastVirtReg-TargetRegisterInfo::FirstVirtualRegister+1);
 }
 
 int VirtRegMap::assignVirt2StackSlot(unsigned virtReg) {
@@ -1155,6 +1159,8 @@
 
       // We want to process implicit virtual register uses first.
       if (MO.isImplicit())
+        // If the virtual register is implicitly defined, emit a implicit_def
+        // before so scavenger knows it's "defined".
         VirtUseOps.insert(VirtUseOps.begin(), i);
       else
         VirtUseOps.push_back(i);
@@ -1177,6 +1183,8 @@
           ReusedOperands.markClobbered(Phys);
         unsigned RReg = SubIdx ? TRI->getSubReg(Phys, SubIdx) : Phys;
         MI.getOperand(i).setReg(RReg);
+        if (VRM.isImplicitlyDefined(VirtReg))
+          BuildMI(MBB, MI, TII->get(TargetInstrInfo::IMPLICIT_DEF), RReg);
         continue;
       }
       

Modified: llvm/trunk/lib/CodeGen/VirtRegMap.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegMap.h?rev=49542&r1=49541&r2=49542&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/VirtRegMap.h (original)
+++ llvm/trunk/lib/CodeGen/VirtRegMap.h Fri Apr 11 12:53:36 2008
@@ -18,6 +18,7 @@
 #define LLVM_CODEGEN_VIRTREGMAP_H
 
 #include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/ADT/BitVector.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/IndexedMap.h"
 #include "llvm/ADT/SmallPtrSet.h"
@@ -116,6 +117,10 @@
     /// SpillSlotToUsesMap - Records uses for each register spill slot.
     SmallVector<SmallPtrSet<MachineInstr*, 4>, 8> SpillSlotToUsesMap;
 
+    /// ImplicitDefed - One bit for each virtual register. If set it indicates
+    /// the register is implicitly defined.
+    BitVector ImplicitDefed;
+
     VirtRegMap(const VirtRegMap&);     // DO NOT IMPLEMENT
     void operator=(const VirtRegMap&); // DO NOT IMPLEMENT
 
@@ -382,6 +387,16 @@
       return !SpillSlotToUsesMap[FrameIndex-LowSpillSlot].empty();
     }
 
+    /// @brief Mark the specified register as being implicitly defined.
+    void setIsImplicitlyDefined(unsigned VirtReg) {
+      ImplicitDefed.set(VirtReg-TargetRegisterInfo::FirstVirtualRegister);
+    }
+
+    /// @brief Returns true if the virtual register is implicitly defined.
+    bool isImplicitlyDefined(unsigned VirtReg) const {
+      return ImplicitDefed[VirtReg-TargetRegisterInfo::FirstVirtualRegister];
+    }
+
     /// @brief Updates information about the specified virtual register's value
     /// folded into newMI machine instruction.
     void virtFolded(unsigned VirtReg, MachineInstr *OldMI, MachineInstr *NewMI,





More information about the llvm-commits mailing list