mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-04-12 23:37:33 +00:00
Simplifications to liveinterval analysis, no functionality change.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29896 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
6da2f3268d
commit
e7f729b42b
@ -374,21 +374,25 @@ LiveInterval::FindLiveRangeContaining(unsigned Idx) {
|
||||
/// is the result of a copy instruction in the source program, that occurs at
|
||||
/// index 'CopyIdx' that copies from 'Other' to 'this'.
|
||||
void LiveInterval::join(LiveInterval &Other, unsigned CopyIdx) {
|
||||
const LiveRange *SourceLR = Other.getLiveRangeContaining(CopyIdx-1);
|
||||
const LiveRange *DestLR = getLiveRangeContaining(CopyIdx);
|
||||
assert(SourceLR && DestLR && "Not joining due to a copy?");
|
||||
unsigned MergedSrcValIdx = SourceLR->ValId;
|
||||
unsigned MergedDstValIdx = DestLR->ValId;
|
||||
|
||||
// Try to do the least amount of work possible. In particular, if there are
|
||||
// more liverange chunks in the other set than there are in the 'this' set,
|
||||
// swap sets to merge the fewest chunks in possible.
|
||||
if (Other.ranges.size() > ranges.size()) {
|
||||
std::swap(MergedSrcValIdx, MergedDstValIdx);
|
||||
std::swap(ranges, Other.ranges);
|
||||
std::swap(NumValues, Other.NumValues);
|
||||
std::swap(InstDefiningValue, Other.InstDefiningValue);
|
||||
//
|
||||
// Also, if one range is a physreg and one is a vreg, we always merge from the
|
||||
// vreg into the physreg, which leaves the vreg intervals pristine.
|
||||
unsigned OtherOffs = 1, ThisOffs = 0;
|
||||
if ((Other.ranges.size() > ranges.size() &&
|
||||
MRegisterInfo::isVirtualRegister(reg)) ||
|
||||
MRegisterInfo::isPhysicalRegister(Other.reg)) {
|
||||
swap(Other);
|
||||
std::swap(ThisOffs, OtherOffs);
|
||||
}
|
||||
|
||||
const LiveRange *SourceLR = Other.getLiveRangeContaining(CopyIdx-OtherOffs);
|
||||
const LiveRange *DestLR = getLiveRangeContaining(CopyIdx-ThisOffs);
|
||||
assert(SourceLR && DestLR && "Not joining due to a copy?");
|
||||
unsigned MergedSrcValIdx = SourceLR->ValId;
|
||||
unsigned MergedDstValIdx = DestLR->ValId;
|
||||
|
||||
// Join the ranges of other into the ranges of this interval.
|
||||
std::map<unsigned, unsigned> Dst2SrcIdxMap;
|
||||
|
@ -790,39 +790,34 @@ bool LiveIntervals::JoinCopy(MachineInstr *CopyMI,
|
||||
return false;
|
||||
}
|
||||
|
||||
// Okay, we can join these two intervals. If one of the intervals being
|
||||
// joined is a physreg, this method always canonicalizes DestInt to be it.
|
||||
// The output "SrcInt" will not have been modified.
|
||||
DestInt.join(SrcInt, MIDefIdx);
|
||||
|
||||
bool Swapped = SrcReg == DestInt.reg;
|
||||
if (Swapped)
|
||||
std::swap(SrcReg, DstReg);
|
||||
assert(MRegisterInfo::isVirtualRegister(SrcReg) &&
|
||||
"LiveInterval::join didn't work right!");
|
||||
|
||||
// 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);
|
||||
if (MRegisterInfo::isPhysicalRegister(DstReg)) {
|
||||
for (const unsigned *AS = mri_->getAliasSet(DstReg); *AS; ++AS)
|
||||
getInterval(*AS).MergeInClobberRanges(SrcInt);
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
if (!MRegisterInfo::isPhysicalRegister(SrcReg)) {
|
||||
r2iMap_.erase(SrcReg);
|
||||
r2rMap_[SrcReg] = DstReg;
|
||||
} else {
|
||||
// Otherwise merge the data structures the other way so we don't lose
|
||||
// the physreg information.
|
||||
r2rMap_[DstReg] = SrcReg;
|
||||
DestInt.reg = SrcReg;
|
||||
SrcInt.swap(DestInt);
|
||||
r2iMap_.erase(DstReg);
|
||||
}
|
||||
|
||||
// If the intervals were swapped by Join, swap them back so that the register
|
||||
// mapping (in the r2i map) is correct.
|
||||
if (Swapped) SrcInt.swap(DestInt);
|
||||
r2iMap_.erase(SrcReg);
|
||||
r2rMap_[SrcReg] = DstReg;
|
||||
|
||||
++numJoins;
|
||||
return true;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user