[llvm-commits] CVS: llvm/lib/CodeGen/LiveInterval.cpp LiveIntervalAnalysis.cpp

Chris Lattner lattner at cs.uiuc.edu
Fri Aug 25 16:41:38 PDT 2006



Changes in directory llvm/lib/CodeGen:

LiveInterval.cpp updated: 1.30 -> 1.31
LiveIntervalAnalysis.cpp updated: 1.167 -> 1.168
---
Log message:

Completely change the way that joining with physregs is implemented.  This
paves the way for future changes, increases coallescing opportunities (in
theory, not witnessed in practice), and eliminates the really expensive
LiveIntervals::overlapsAliases method.



---
Diffs of the changes:  (+72 -35)

 LiveInterval.cpp         |   47 +++++++++++++++++++++++++++++++-----
 LiveIntervalAnalysis.cpp |   60 +++++++++++++++++++++++++----------------------
 2 files changed, 72 insertions(+), 35 deletions(-)


Index: llvm/lib/CodeGen/LiveInterval.cpp
diff -u llvm/lib/CodeGen/LiveInterval.cpp:1.30 llvm/lib/CodeGen/LiveInterval.cpp:1.31
--- llvm/lib/CodeGen/LiveInterval.cpp:1.30	Thu Aug 24 18:22:59 2006
+++ llvm/lib/CodeGen/LiveInterval.cpp	Fri Aug 25 18:41:24 2006
@@ -261,15 +261,15 @@
   return MergeTo;
 }
 
-LiveInterval::Ranges::iterator
-LiveInterval::addRangeFrom(LiveRange LR, Ranges::iterator From) {
+LiveInterval::iterator
+LiveInterval::addRangeFrom(LiveRange LR, iterator From) {
   unsigned Start = LR.start, End = LR.end;
-  Ranges::iterator it = std::upper_bound(From, ranges.end(), Start);
+  iterator it = std::upper_bound(From, ranges.end(), Start);
 
   // If the inserted interval starts in the middle or right at the end of
   // another interval, just extend that interval to contain the range of LR.
   if (it != ranges.begin()) {
-    Ranges::iterator B = prior(it);
+    iterator B = prior(it);
     if (LR.ValId == B->ValId) {
       if (B->start <= Start && B->end >= Start) {
         extendIntervalEndTo(B, End);
@@ -391,10 +391,9 @@
   }
 
   // Join the ranges of other into the ranges of this interval.
-  Ranges::iterator InsertPos = ranges.begin();
   std::map<unsigned, unsigned> Dst2SrcIdxMap;
-  for (Ranges::iterator I = Other.ranges.begin(),
-         E = Other.ranges.end(); I != E; ++I) {
+  iterator InsertPos = begin();
+  for (iterator I = Other.begin(), E = Other.end(); I != E; ++I) {
     // Map the ValId in the other live range to the current live range.
     if (I->ValId == MergedSrcValIdx)
       I->ValId = MergedDstValIdx;
@@ -418,6 +417,40 @@
   weight += Other.weight;
 }
 
+/// MergeInClobberRanges - For any live ranges that are not defined in the
+/// current interval, but are defined in the Clobbers interval, mark them
+/// used with an unknown definition value.
+void LiveInterval::MergeInClobberRanges(const LiveInterval &Clobbers) {
+  if (Clobbers.begin() == Clobbers.end()) return;
+  
+  // Find a value # to use for the clobber ranges.  If there is already a value#
+  // for unknown values, use it.
+  // FIXME: Use a single sentinal number for these!
+  unsigned ClobberValNo = getNextValue(~0U);
+  
+  iterator IP = begin();
+  for (const_iterator I = Clobbers.begin(), E = Clobbers.end(); I != E; ++I) {
+    unsigned Start = I->start, End = I->end;
+    IP = std::upper_bound(IP, end(), Start);
+    
+    // If the start of this range overlaps with an existing liverange, trim it.
+    if (IP != begin() && IP[-1].end > Start) {
+      Start = IP[-1].end;
+      // Trimmed away the whole range?
+      if (Start >= End) continue;
+    }
+    // If the end of this range overlaps with an existing liverange, trim it.
+    if (IP != end() && End > IP->start) {
+      End = IP->start;
+      // If this trimmed away the whole range, ignore it.
+      if (Start == End) continue;
+    }
+    
+    // Insert the clobber interval.
+    IP = addRangeFrom(LiveRange(Start, End, ClobberValNo), IP);
+  }
+}
+
 /// MergeValueNumberInto - This method is called when two value nubmers
 /// are found to be equivalent.  This eliminates V1, replacing all
 /// LiveRanges with the V1 value number with the V2 value number.  This can


Index: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp
diff -u llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.167 llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.168
--- llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.167	Thu Aug 24 17:43:55 2006
+++ llvm/lib/CodeGen/LiveIntervalAnalysis.cpp	Fri Aug 25 18:41:24 2006
@@ -673,7 +673,8 @@
   // Make sure that the end of the live range is inside the same block as
   // CopyMI.
   MachineInstr *ValLREndInst = getInstructionFromIndex(ValLR->end-1);
-  if (ValLREndInst->getParent() != CopyMI->getParent()) return false;
+  if (!ValLREndInst || 
+      ValLREndInst->getParent() != CopyMI->getParent()) return false;
 
   // Okay, we now know that ValLR ends in the same block that the CopyMI
   // live-range starts.  If there are no intervening live ranges between them in
@@ -685,7 +686,18 @@
   // Okay, we can merge them.  We need to insert a new liverange:
   // [ValLR.end, BLR.begin) of either value number, then we merge the
   // two value numbers.
-  IntB.addRange(LiveRange(ValLR->end, BLR->start, BValNo));
+  unsigned FillerStart = ValLR->end, FillerEnd = BLR->start;
+  IntB.addRange(LiveRange(FillerStart, FillerEnd, BValNo));
+
+  // If the IntB live range is assigned to a physical register, and if that
+  // physreg has aliases, 
+  if (MRegisterInfo::isPhysicalRegister(IntB.reg)) {
+    for (const unsigned *AS = mri_->getAliasSet(IntB.reg); *AS; ++AS) {
+      LiveInterval &AliasLI = getInterval(*AS);
+      AliasLI.addRange(LiveRange(FillerStart, FillerEnd,
+                                 AliasLI.getNextValue(~0U)));
+    }
+  }
 
   // Okay, merge "B1" into the same value number as "B0".
   if (BValNo != ValLR->ValId)
@@ -773,19 +785,30 @@
   if (!Joinable && AdjustCopiesBackFrom(SrcInt, DestInt, CopyMI, MIDefIdx))
     return true;
   
-  // If this looks joinable, do the final, expensive last check, checking to see
-  // if aliases overlap.  If they do, we can never join these.
-  if (Joinable && overlapsAliases(&SrcInt, &DestInt)) {
-    DEBUG(std::cerr << "Alias Overlap Interference!\n");
-    return true;   // Can never join these.
-  }
-  
   if (!Joinable) {
     DEBUG(std::cerr << "Interference!\n");
     return false;
   }
 
+  // If we're about to merge live ranges into a physical register live range,
+  // we have to update any aliased register's live ranges to indicate that they
+  // have clobbered values for this range.
+  if (MRegisterInfo::isPhysicalRegister(SrcReg) ||
+      MRegisterInfo::isPhysicalRegister(DstReg)) {
+    // Figure out which register is the physical reg and which one is the
+    // virtreg.
+    LiveInterval *PhysRegLI = &SrcInt, *VirtRegLI = &DestInt;
+    if (MRegisterInfo::isPhysicalRegister(DstReg))
+      std::swap(PhysRegLI, VirtRegLI);
+    
+    for (const unsigned *AS = mri_->getAliasSet(PhysRegLI->reg); *AS; ++AS)
+      getInterval(*AS).MergeInClobberRanges(*VirtRegLI);
+  }
+
   DestInt.join(SrcInt, MIDefIdx);
+  // FIXME: If SrcInt/DestInt are physregs, we must insert the new liveranges
+  // into all aliasing registers as clobbers.
+                               
   DEBUG(std::cerr << "\n\t\tJoined.  Result = "; DestInt.print(std::cerr, mri_);
         std::cerr << "\n");
     
@@ -911,25 +934,6 @@
     return !RegClass->contains(RegB);
 }
 
-bool LiveIntervals::overlapsAliases(const LiveInterval *LHS,
-                                    const LiveInterval *RHS) const {
-  if (!MRegisterInfo::isPhysicalRegister(LHS->reg)) {
-    if (!MRegisterInfo::isPhysicalRegister(RHS->reg))
-      return false;   // vreg-vreg merge has no aliases!
-    std::swap(LHS, RHS);
-  }
-
-  assert(MRegisterInfo::isPhysicalRegister(LHS->reg) &&
-         MRegisterInfo::isVirtualRegister(RHS->reg) &&
-         "first interval must describe a physical register");
-
-  for (const unsigned *AS = mri_->getAliasSet(LHS->reg); *AS; ++AS)
-    if (RHS->overlaps(getInterval(*AS)))
-      return true;
-
-  return false;
-}
-
 LiveInterval LiveIntervals::createInterval(unsigned reg) {
   float Weight = MRegisterInfo::isPhysicalRegister(reg) ?
                        (float)HUGE_VAL :0.0F;






More information about the llvm-commits mailing list