Dead code elimination may separate the live interval into multiple connected components.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Thu, 17 Mar 2011 20:37:07 +0000 (20:37 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Thu, 17 Mar 2011 20:37:07 +0000 (20:37 +0000)
I have convinced myself that it can only happen when a phi value dies. When it
happens, allocate new virtual registers for the components.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127827 91177308-0d34-0410-b5e6-96231b3b80d8

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

index b541a3a649f2b5c012b1b5221eb347a401d6ee60..8ca58b82c8bba785dd60c9c1cf969353e31d7c82 100644 (file)
@@ -160,7 +160,9 @@ namespace llvm {
     /// 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
index ff0a1051e7ad64cc2d814440d4b861c41d2978f8..ecb00881837fb407de1749a285984c6e07761969 100644 (file)
@@ -460,7 +460,7 @@ bool InlineSpiller::reMaterializeFor(MachineBasicBlock::iterator MI) {
   }
 
   // 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 @@ void InlineSpiller::spillAroundUses(unsigned Reg) {
 
     // 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)
index f2bf9172012407216eb3d1f218d2d3c44b794d14..c47c8397488e66dcf927be19d23c0eaf231e0689 100644 (file)
@@ -746,7 +746,7 @@ LiveInterval* LiveIntervals::dupInterval(LiveInterval *li) {
 /// 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 @@ void LiveIntervals::shrinkToUses(LiveInterval *li,
   }
 
   // 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 @@ void LiveIntervals::shrinkToUses(LiveInterval *li,
       // 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 @@ void LiveIntervals::shrinkToUses(LiveInterval *li,
   // Move the trimmed ranges back.
   li->ranges.swap(NewLI.ranges);
   DEBUG(dbgs() << "Shrunk: " << *li << '\n');
+  return CanSeparate;
 }
 
 
index 489d88c1dfbd251c71110e8060a93ef35176a092..f5c67b9c748372b98a1cf317fd9864dd95bcfe9f 100644 (file)
 
 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::eraseVirtReg(unsigned Reg, LiveIntervals &LIS) {
 }
 
 void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
-                                      LiveIntervals &LIS,
+                                      LiveIntervals &LIS, VirtRegMap &VRM,
                                       const TargetInstrInfo &TII) {
   SetVector<LiveInterval*,
             SmallVector<LiveInterval*, 8>,
@@ -205,7 +205,20 @@ void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
     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());
   }
 }
 
index 2bd34611c24e36fbb30a5b1d15a7e25c8c0958fe..0846961f5b9ceffef0b115902a8f067bf489df95 100644 (file)
@@ -65,6 +65,9 @@ private:
   /// 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 @@ public:
     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 @@ public:
   /// (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&);
 
 };
index 6f7b972c43a9fd5c9751f08f47e663241b345e14..ff00bd8f38c8777ef086db23dee21d856e94346a 100644 (file)
@@ -538,11 +538,11 @@ void SplitEditor::openIntv() {
 
   // 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 @@ void SplitEditor::deleteRematVictims() {
   if (Dead.empty())
     return;
 
-  Edit->eliminateDeadDefs(Dead, LIS, TII);
+  Edit->eliminateDeadDefs(Dead, LIS, VRM, TII);
 }
 
 void SplitEditor::finish() {
@@ -866,7 +866,7 @@ void SplitEditor::finish() {
     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);
   }