[llvm-commits] [llvm] r127827 - in /llvm/trunk: include/llvm/CodeGen/LiveIntervalAnalysis.h lib/CodeGen/InlineSpiller.cpp lib/CodeGen/LiveIntervalAnalysis.cpp lib/CodeGen/LiveRangeEdit.cpp lib/CodeGen/LiveRangeEdit.h lib/CodeGen/SplitKit.cpp

Jakob Stoklund Olesen stoklund at 2pi.dk
Thu Mar 17 13:37:07 PDT 2011


Author: stoklund
Date: Thu Mar 17 15:37:07 2011
New Revision: 127827

URL: http://llvm.org/viewvc/llvm-project?rev=127827&view=rev
Log:
Dead code elimination may separate the live interval into multiple connected components.

I have convinced myself that it can only happen when a phi value dies. When it
happens, allocate new virtual registers for the components.

Modified:
    llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h
    llvm/trunk/lib/CodeGen/InlineSpiller.cpp
    llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp
    llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp
    llvm/trunk/lib/CodeGen/LiveRangeEdit.h
    llvm/trunk/lib/CodeGen/SplitKit.cpp

Modified: llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h?rev=127827&r1=127826&r2=127827&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h (original)
+++ llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h Thu Mar 17 15:37:07 2011
@@ -160,7 +160,9 @@
     /// defs for new uses, and it doesn't remove dead defs.
     /// Dead PHIDef values are marked as unused.
     /// New dead machine instructions are added to the dead vector.
-    void shrinkToUses(LiveInterval *li,
+    /// Return true if the interval may have been separated into multiple
+    /// connected components.
+    bool shrinkToUses(LiveInterval *li,
                       SmallVectorImpl<MachineInstr*> *dead = 0);
 
     // Interval removal

Modified: llvm/trunk/lib/CodeGen/InlineSpiller.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/InlineSpiller.cpp?rev=127827&r1=127826&r2=127827&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/InlineSpiller.cpp (original)
+++ llvm/trunk/lib/CodeGen/InlineSpiller.cpp Thu Mar 17 15:37:07 2011
@@ -460,7 +460,7 @@
   }
 
   // Alocate a new register for the remat.
-  LiveInterval &NewLI = Edit->create(MRI, LIS, VRM);
+  LiveInterval &NewLI = Edit->create(LIS, VRM);
   NewLI.markNotSpillable();
 
   // Rematting for a copy: Set allocation hint to be the destination register.
@@ -685,7 +685,7 @@
 
     // Allocate interval around instruction.
     // FIXME: Infer regclass from instruction alone.
-    LiveInterval &NewLI = Edit->create(MRI, LIS, VRM);
+    LiveInterval &NewLI = Edit->create(LIS, VRM);
     NewLI.markNotSpillable();
 
     if (Reads)

Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=127827&r1=127826&r2=127827&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original)
+++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Thu Mar 17 15:37:07 2011
@@ -746,7 +746,7 @@
 /// shrinkToUses - After removing some uses of a register, shrink its live
 /// range to just the remaining uses. This method does not compute reaching
 /// defs for new uses, and it doesn't remove dead defs.
-void LiveIntervals::shrinkToUses(LiveInterval *li,
+bool LiveIntervals::shrinkToUses(LiveInterval *li,
                                  SmallVectorImpl<MachineInstr*> *dead) {
   DEBUG(dbgs() << "Shrink: " << *li << '\n');
   assert(TargetRegisterInfo::isVirtualRegister(li->reg)
@@ -835,6 +835,7 @@
   }
 
   // Handle dead values.
+  bool CanSeparate = false;
   for (LiveInterval::vni_iterator I = li->vni_begin(), E = li->vni_end();
        I != E; ++I) {
     VNInfo *VNI = *I;
@@ -848,6 +849,8 @@
       // This is a dead PHI. Remove it.
       VNI->setIsUnused(true);
       NewLI.removeRange(*LII);
+      DEBUG(dbgs() << "Dead PHI at " << VNI->def << " may separate interval\n");
+      CanSeparate = true;
     } else {
       // This is a dead def. Make sure the instruction knows.
       MachineInstr *MI = getInstructionFromIndex(VNI->def);
@@ -863,6 +866,7 @@
   // Move the trimmed ranges back.
   li->ranges.swap(NewLI.ranges);
   DEBUG(dbgs() << "Shrunk: " << *li << '\n');
+  return CanSeparate;
 }
 
 

Modified: llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp?rev=127827&r1=127826&r2=127827&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp (original)
+++ llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp Thu Mar 17 15:37:07 2011
@@ -22,16 +22,16 @@
 
 using namespace llvm;
 
-LiveInterval &LiveRangeEdit::create(MachineRegisterInfo &mri,
-                                    LiveIntervals &lis,
-                                    VirtRegMap &vrm) {
-  const TargetRegisterClass *RC = mri.getRegClass(getReg());
-  unsigned VReg = mri.createVirtualRegister(RC);
-  vrm.grow();
-  vrm.setIsSplitFromReg(VReg, vrm.getOriginal(getReg()));
-  LiveInterval &li = lis.getOrCreateInterval(VReg);
-  newRegs_.push_back(&li);
-  return li;
+LiveInterval &LiveRangeEdit::createFrom(unsigned OldReg,
+                                        LiveIntervals &LIS,
+                                        VirtRegMap &VRM) {
+  MachineRegisterInfo &MRI = VRM.getRegInfo();
+  unsigned VReg = MRI.createVirtualRegister(MRI.getRegClass(OldReg));
+  VRM.grow();
+  VRM.setIsSplitFromReg(VReg, VRM.getOriginal(OldReg));
+  LiveInterval &LI = LIS.getOrCreateInterval(VReg);
+  newRegs_.push_back(&LI);
+  return LI;
 }
 
 void LiveRangeEdit::scanRemattable(LiveIntervals &lis,
@@ -137,7 +137,7 @@
 }
 
 void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
-                                      LiveIntervals &LIS,
+                                      LiveIntervals &LIS, VirtRegMap &VRM,
                                       const TargetInstrInfo &TII) {
   SetVector<LiveInterval*,
             SmallVector<LiveInterval*, 8>,
@@ -205,7 +205,20 @@
     ToShrink.pop_back();
     if (delegate_)
       delegate_->LRE_WillShrinkVirtReg(LI->reg);
-    LIS.shrinkToUses(LI, &Dead);
+    if (!LIS.shrinkToUses(LI, &Dead))
+      continue;
+
+    // LI may have been separated, create new intervals.
+    LI->RenumberValues(LIS);
+    ConnectedVNInfoEqClasses ConEQ(LIS);
+    unsigned NumComp = ConEQ.Classify(LI);
+    if (NumComp <= 1)
+      continue;
+    DEBUG(dbgs() << NumComp << " components: " << *LI << '\n');
+    SmallVector<LiveInterval*, 8> Dups(1, LI);
+    for (unsigned i = 1; i != NumComp; ++i)
+      Dups.push_back(&createFrom(LI->reg, LIS, VRM));
+    ConEQ.Distribute(&Dups[0], VRM.getRegInfo());
   }
 }
 

Modified: llvm/trunk/lib/CodeGen/LiveRangeEdit.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveRangeEdit.h?rev=127827&r1=127826&r2=127827&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LiveRangeEdit.h (original)
+++ llvm/trunk/lib/CodeGen/LiveRangeEdit.h Thu Mar 17 15:37:07 2011
@@ -65,6 +65,9 @@
   /// live range trimmed or entirely removed.
   SmallPtrSet<const VNInfo*,4> rematted_;
 
+  /// createFrom - Create a new virtual register based on OldReg.
+  LiveInterval &createFrom(unsigned, LiveIntervals&, VirtRegMap &);
+
   /// scanRemattable - Identify the parent_ values that may rematerialize.
   void scanRemattable(LiveIntervals &lis,
                       const TargetInstrInfo &tii,
@@ -110,9 +113,11 @@
     return uselessRegs_;
   }
 
-  /// create - Create a new register with the same class and stack slot as
+  /// create - Create a new register with the same class and original slot as
   /// parent.
-  LiveInterval &create(MachineRegisterInfo&, LiveIntervals&, VirtRegMap&);
+  LiveInterval &create(LiveIntervals &LIS, VirtRegMap &VRM) {
+    return createFrom(getReg(), LIS, VRM);
+  }
 
   /// anyRematerializable - Return true if any parent values may be
   /// rematerializable.
@@ -166,7 +171,7 @@
   /// (allDefsAreDead returns true). This may cause live intervals to be trimmed
   /// and further dead efs to be eliminated.
   void eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
-                         LiveIntervals&,
+                         LiveIntervals&, VirtRegMap&,
                          const TargetInstrInfo&);
 
 };

Modified: llvm/trunk/lib/CodeGen/SplitKit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SplitKit.cpp?rev=127827&r1=127826&r2=127827&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SplitKit.cpp (original)
+++ llvm/trunk/lib/CodeGen/SplitKit.cpp Thu Mar 17 15:37:07 2011
@@ -538,11 +538,11 @@
 
   // Create the complement as index 0.
   if (Edit->empty())
-    Edit->create(MRI, LIS, VRM);
+    Edit->create(LIS, VRM);
 
   // Create the open interval.
   OpenIdx = Edit->size();
-  Edit->create(MRI, LIS, VRM);
+  Edit->create(LIS, VRM);
 }
 
 SlotIndex SplitEditor::enterIntvBefore(SlotIndex Idx) {
@@ -802,7 +802,7 @@
   if (Dead.empty())
     return;
 
-  Edit->eliminateDeadDefs(Dead, LIS, TII);
+  Edit->eliminateDeadDefs(Dead, LIS, VRM, TII);
 }
 
 void SplitEditor::finish() {
@@ -866,7 +866,7 @@
     SmallVector<LiveInterval*, 8> dups;
     dups.push_back(li);
     for (unsigned i = 1; i != NumComp; ++i)
-      dups.push_back(&Edit->create(MRI, LIS, VRM));
+      dups.push_back(&Edit->create(LIS, VRM));
     ConEQ.Distribute(&dups[0], MRI);
   }
 





More information about the llvm-commits mailing list