Use of implicit_def is not part of live interval. Create empty intervals for the...
authorEvan Cheng <evan.cheng@apple.com>
Fri, 11 Apr 2008 17:53:36 +0000 (17:53 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Fri, 11 Apr 2008 17:53:36 +0000 (17:53 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@49542 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/LiveIntervalAnalysis.h
lib/CodeGen/LiveIntervalAnalysis.cpp
lib/CodeGen/VirtRegMap.cpp
lib/CodeGen/VirtRegMap.h

index 2938fcaa3630180dc4ef4cae42b787b3a056d618..7bd4ea4a19b04aaba1f2870539e347e09c5d6801 100644 (file)
@@ -394,9 +394,11 @@ namespace llvm {
                           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.
index 0556f79e48a87d0ae7d346dcb3be566f5363a442..9f72035bc90572ffdd598af2df1eff934bae8c80 100644 (file)
@@ -1319,19 +1319,37 @@ void LiveIntervals::eraseRestoreInfo(int Id, int index, unsigned vr,
       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 @@ addIntervalsForSpills(const LiveInterval &li,
       IsFirstRange = false;
     }
 
-    removeSpilledImpDefs(li, vrm);
+    handleSpilledImpDefs(li, vrm, rc, NewLIs);
     return NewLIs;
   }
 
@@ -1485,7 +1503,7 @@ addIntervalsForSpills(const LiveInterval &li,
 
   // Insert spills / restores if we are splitting.
   if (!TrySplit) {
-    removeSpilledImpDefs(li, vrm);
+    handleSpilledImpDefs(li, vrm, rc, NewLIs);
     return NewLIs;
   }
 
@@ -1640,7 +1658,7 @@ addIntervalsForSpills(const LiveInterval &li,
     }
   }
 
-  removeSpilledImpDefs(li, vrm);
+  handleSpilledImpDefs(li, vrm, rc, RetNewLIs);
   return RetNewLIs;
 }
 
index 91b108f72f056625033c40dff4cbbb3029c22399..6a34269ceab4306b9bf909d38a241353bb3b2f0b 100644 (file)
@@ -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 @@ VirtRegMap::VirtRegMap(MachineFunction &mf)
     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 @@ void VirtRegMap::grow() {
   Virt2SplitMap.grow(LastVirtReg);
   Virt2SplitKillMap.grow(LastVirtReg);
   ReMatMap.grow(LastVirtReg);
+  ImplicitDefed.resize(LastVirtReg-TargetRegisterInfo::FirstVirtualRegister+1);
 }
 
 int VirtRegMap::assignVirt2StackSlot(unsigned virtReg) {
@@ -1155,6 +1159,8 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
 
       // 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 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
           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;
       }
       
index 6f82cfb62c7f6a9ba15bab3a5c6135d58dbe1292..46f177d4f5c67f36c396dd3d3e0d6946f7cd5c59 100644 (file)
@@ -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 @@ namespace llvm {
     /// 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 @@ namespace llvm {
       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,