PR 770 - permit coallescing of registers in subset register classes.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28197 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng
2006-05-09 06:37:48 +00:00
parent 696736be8b
commit e73701df94
2 changed files with 30 additions and 16 deletions

View File

@@ -167,9 +167,11 @@ namespace llvm {
unsigned SrcReg, unsigned DestReg, unsigned SrcReg, unsigned DestReg,
bool isLiveIn = false); bool isLiveIn = false);
/// Return true if the two specified registers belong to different /// Return true if the two specified registers belong to the same or
/// register classes. The registers may be either phys or virt regs. /// compatible register classes. The registers may be either phys or
bool differingRegisterClasses(unsigned RegA, unsigned RegB) const; /// virt regs.
bool compatibleRegisterClasses(unsigned RegA, unsigned RegB,
bool &Swap) const;
bool AdjustIfAllOverlappingRangesAreCopiesFrom(LiveInterval &IntA, bool AdjustIfAllOverlappingRangesAreCopiesFrom(LiveInterval &IntA,
LiveInterval &IntB, LiveInterval &IntB,

View File

@@ -705,9 +705,12 @@ void LiveIntervals::joinIntervalsInMachineBB(MachineBasicBlock *MBB) {
MRegisterInfo::isPhysicalRegister(DestReg)) MRegisterInfo::isPhysicalRegister(DestReg))
continue; continue;
// If they are not of the same register class, we cannot join them. // If they are not of compatible register classes, we cannot join them.
if (differingRegisterClasses(SrcReg, DestReg)) bool Swap = false;
if (!compatibleRegisterClasses(SrcReg, DestReg, Swap)) {
DEBUG(std::cerr << "Register classes aren't compatible!\n");
continue; continue;
}
LiveInterval &SrcInt = getInterval(SrcReg); LiveInterval &SrcInt = getInterval(SrcReg);
LiveInterval &DestInt = getInterval(DestReg); LiveInterval &DestInt = getInterval(DestReg);
@@ -741,7 +744,7 @@ void LiveIntervals::joinIntervalsInMachineBB(MachineBasicBlock *MBB) {
DestInt.join(SrcInt, MIDefIdx); DestInt.join(SrcInt, MIDefIdx);
DEBUG(std::cerr << "Joined. Result = " << DestInt << "\n"); DEBUG(std::cerr << "Joined. Result = " << DestInt << "\n");
if (!MRegisterInfo::isPhysicalRegister(SrcReg)) { if (!Swap && !MRegisterInfo::isPhysicalRegister(SrcReg)) {
r2iMap_.erase(SrcReg); r2iMap_.erase(SrcReg);
r2rMap_[SrcReg] = DestReg; r2rMap_[SrcReg] = DestReg;
} else { } else {
@@ -803,24 +806,33 @@ void LiveIntervals::joinIntervals() {
std::cerr << " reg " << i << " -> reg " << r2rMap_[i] << "\n"); std::cerr << " reg " << i << " -> reg " << r2rMap_[i] << "\n");
} }
/// Return true if the two specified registers belong to different register /// Return true if the two specified registers belong to same or compatible
/// classes. The registers may be either phys or virt regs. /// register classes. The registers may be either phys or virt regs.
bool LiveIntervals::differingRegisterClasses(unsigned RegA, bool LiveIntervals::compatibleRegisterClasses(unsigned RegA, unsigned RegB,
unsigned RegB) const { bool &Swap) const {
// Get the register classes for the first reg. // Get the register classes for the first reg.
if (MRegisterInfo::isPhysicalRegister(RegA)) { if (MRegisterInfo::isPhysicalRegister(RegA)) {
assert(MRegisterInfo::isVirtualRegister(RegB) && assert(MRegisterInfo::isVirtualRegister(RegB) &&
"Shouldn't consider two physregs!"); "Shouldn't consider two physregs!");
return !mf_->getSSARegMap()->getRegClass(RegB)->contains(RegA); return mf_->getSSARegMap()->getRegClass(RegB)->contains(RegA);
} }
// Compare against the regclass for the second reg. // Compare against the regclass for the second reg.
const TargetRegisterClass *RegClass = mf_->getSSARegMap()->getRegClass(RegA); const TargetRegisterClass *RegClassA = mf_->getSSARegMap()->getRegClass(RegA);
if (MRegisterInfo::isVirtualRegister(RegB)) if (MRegisterInfo::isVirtualRegister(RegB)) {
return RegClass != mf_->getSSARegMap()->getRegClass(RegB); const TargetRegisterClass *RegClassB=mf_->getSSARegMap()->getRegClass(RegB);
else if (RegClassA == RegClassB)
return !RegClass->contains(RegB); return true;
else {
if (RegClassB->hasSubRegClass(RegClassA)) {
Swap = true;
return true;
}
return RegClassA->hasSubRegClass(RegClassB);
}
} else
return RegClassA->contains(RegB);
} }
bool LiveIntervals::overlapsAliases(const LiveInterval *LHS, bool LiveIntervals::overlapsAliases(const LiveInterval *LHS,