Completely change the way that joining with physregs is implemented. This
authorChris Lattner <sabre@nondot.org>
Fri, 25 Aug 2006 23:41:24 +0000 (23:41 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 25 Aug 2006 23:41:24 +0000 (23:41 +0000)
paves the way for future changes, increases coallescing opportunities (in
theory, not witnessed in practice), and eliminates the really expensive
LiveIntervals::overlapsAliases method.

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

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

index 646d808ca21490cb83a57a42032b4bcd12a7e18c..c9fef0cd16433c69865e8516fcece833911c13b7 100644 (file)
@@ -148,6 +148,10 @@ namespace llvm {
     /// cause merging of V1/V2 values numbers and compaction of the value space.
     void MergeValueNumberInto(unsigned V1, unsigned V2);
 
+    /// 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 MergeInClobberRanges(const LiveInterval &Clobbers);
 
     bool empty() const { return ranges.empty(); }
 
index 4752b6df51389d1870414b073794b10cf4eaee94..80c050ff330494405383c97dadf83360eb458361 100644 (file)
@@ -261,15 +261,15 @@ LiveInterval::extendIntervalStartTo(Ranges::iterator I, unsigned NewStart) {
   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 @@ void LiveInterval::join(LiveInterval &Other, unsigned CopyIdx) {
   }
 
   // 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 @@ void LiveInterval::join(LiveInterval &Other, unsigned CopyIdx) {
   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 5a7587f0e5e7bbfd385f392b8365850f7f9ab43d..d094da9ed11aed9d905fab02d6cd05d407dae5e1 100644 (file)
@@ -673,7 +673,8 @@ bool LiveIntervals::AdjustCopiesBackFrom(LiveInterval &IntA, LiveInterval &IntB,
   // 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 @@ bool LiveIntervals::AdjustCopiesBackFrom(LiveInterval &IntA, LiveInterval &IntB,
   // 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 @@ bool LiveIntervals::JoinCopy(MachineInstr *CopyMI,
   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 @@ bool LiveIntervals::differingRegisterClasses(unsigned RegA,
     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;