mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-10-25 10:27:04 +00:00
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:
@@ -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,
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user