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);
}
// 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;
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
// 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
// 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)
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");
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;