mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-16 12:24:03 +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:
@ -374,22 +374,26 @@ LiveInterval::FindLiveRangeContaining(unsigned Idx) {
|
|||||||
/// is the result of a copy instruction in the source program, that occurs at
|
/// is the result of a copy instruction in the source program, that occurs at
|
||||||
/// index 'CopyIdx' that copies from 'Other' to 'this'.
|
/// index 'CopyIdx' that copies from 'Other' to 'this'.
|
||||||
void LiveInterval::join(LiveInterval &Other, unsigned CopyIdx) {
|
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
|
// 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,
|
// more liverange chunks in the other set than there are in the 'this' set,
|
||||||
// swap sets to merge the fewest chunks in possible.
|
// swap sets to merge the fewest chunks in possible.
|
||||||
if (Other.ranges.size() > ranges.size()) {
|
//
|
||||||
std::swap(MergedSrcValIdx, MergedDstValIdx);
|
// Also, if one range is a physreg and one is a vreg, we always merge from the
|
||||||
std::swap(ranges, Other.ranges);
|
// vreg into the physreg, which leaves the vreg intervals pristine.
|
||||||
std::swap(NumValues, Other.NumValues);
|
unsigned OtherOffs = 1, ThisOffs = 0;
|
||||||
std::swap(InstDefiningValue, Other.InstDefiningValue);
|
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.
|
// Join the ranges of other into the ranges of this interval.
|
||||||
std::map<unsigned, unsigned> Dst2SrcIdxMap;
|
std::map<unsigned, unsigned> Dst2SrcIdxMap;
|
||||||
iterator InsertPos = begin();
|
iterator InsertPos = begin();
|
||||||
|
@ -790,39 +790,34 @@ bool LiveIntervals::JoinCopy(MachineInstr *CopyMI,
|
|||||||
return false;
|
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,
|
// 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
|
// we have to update any aliased register's live ranges to indicate that they
|
||||||
// have clobbered values for this range.
|
// have clobbered values for this range.
|
||||||
if (MRegisterInfo::isPhysicalRegister(SrcReg) ||
|
if (MRegisterInfo::isPhysicalRegister(DstReg)) {
|
||||||
MRegisterInfo::isPhysicalRegister(DstReg)) {
|
for (const unsigned *AS = mri_->getAliasSet(DstReg); *AS; ++AS)
|
||||||
// Figure out which register is the physical reg and which one is the
|
getInterval(*AS).MergeInClobberRanges(SrcInt);
|
||||||
// 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_);
|
DEBUG(std::cerr << "\n\t\tJoined. Result = "; DestInt.print(std::cerr, mri_);
|
||||||
std::cerr << "\n");
|
std::cerr << "\n");
|
||||||
|
|
||||||
if (!MRegisterInfo::isPhysicalRegister(SrcReg)) {
|
// 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);
|
r2iMap_.erase(SrcReg);
|
||||||
r2rMap_[SrcReg] = DstReg;
|
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);
|
|
||||||
}
|
|
||||||
++numJoins;
|
++numJoins;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user