diff options
author | Evan Cheng <evan.cheng@apple.com> | 2006-05-09 06:37:48 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2006-05-09 06:37:48 +0000 |
commit | e73701df947d23c65e96abc71a3be40ad77058ee (patch) | |
tree | 7f97d9d13b42eb69a08179599e4b823ef5ad9e2c | |
parent | 696736be8b80fe3946f73605b46359345afdf57a (diff) |
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
-rw-r--r-- | include/llvm/CodeGen/LiveIntervalAnalysis.h | 8 | ||||
-rw-r--r-- | lib/CodeGen/LiveIntervalAnalysis.cpp | 38 |
2 files changed, 30 insertions, 16 deletions
diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h index 0ae4b5ad0f..f01608c176 100644 --- a/include/llvm/CodeGen/LiveIntervalAnalysis.h +++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -167,9 +167,11 @@ namespace llvm { unsigned SrcReg, unsigned DestReg, bool isLiveIn = false); - /// Return true if the two specified registers belong to different - /// register classes. The registers may be either phys or virt regs. - bool differingRegisterClasses(unsigned RegA, unsigned RegB) const; + /// Return true if the two specified registers belong to the same or + /// compatible register classes. The registers may be either phys or + /// virt regs. + bool compatibleRegisterClasses(unsigned RegA, unsigned RegB, + bool &Swap) const; bool AdjustIfAllOverlappingRangesAreCopiesFrom(LiveInterval &IntA, LiveInterval &IntB, diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index 17144f5582..946d80de6b 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -705,9 +705,12 @@ void LiveIntervals::joinIntervalsInMachineBB(MachineBasicBlock *MBB) { MRegisterInfo::isPhysicalRegister(DestReg)) continue; - // If they are not of the same register class, we cannot join them. - if (differingRegisterClasses(SrcReg, DestReg)) + // If they are not of compatible register classes, we cannot join them. + bool Swap = false; + if (!compatibleRegisterClasses(SrcReg, DestReg, Swap)) { + DEBUG(std::cerr << "Register classes aren't compatible!\n"); continue; + } LiveInterval &SrcInt = getInterval(SrcReg); LiveInterval &DestInt = getInterval(DestReg); @@ -741,7 +744,7 @@ void LiveIntervals::joinIntervalsInMachineBB(MachineBasicBlock *MBB) { DestInt.join(SrcInt, MIDefIdx); DEBUG(std::cerr << "Joined. Result = " << DestInt << "\n"); - if (!MRegisterInfo::isPhysicalRegister(SrcReg)) { + if (!Swap && !MRegisterInfo::isPhysicalRegister(SrcReg)) { r2iMap_.erase(SrcReg); r2rMap_[SrcReg] = DestReg; } else { @@ -803,24 +806,33 @@ void LiveIntervals::joinIntervals() { std::cerr << " reg " << i << " -> reg " << r2rMap_[i] << "\n"); } -/// Return true if the two specified registers belong to different register -/// classes. The registers may be either phys or virt regs. -bool LiveIntervals::differingRegisterClasses(unsigned RegA, - unsigned RegB) const { +/// Return true if the two specified registers belong to same or compatible +/// register classes. The registers may be either phys or virt regs. +bool LiveIntervals::compatibleRegisterClasses(unsigned RegA, unsigned RegB, + bool &Swap) const { // Get the register classes for the first reg. if (MRegisterInfo::isPhysicalRegister(RegA)) { assert(MRegisterInfo::isVirtualRegister(RegB) && "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. - const TargetRegisterClass *RegClass = mf_->getSSARegMap()->getRegClass(RegA); - if (MRegisterInfo::isVirtualRegister(RegB)) - return RegClass != mf_->getSSARegMap()->getRegClass(RegB); - else - return !RegClass->contains(RegB); + const TargetRegisterClass *RegClassA = mf_->getSSARegMap()->getRegClass(RegA); + if (MRegisterInfo::isVirtualRegister(RegB)) { + const TargetRegisterClass *RegClassB=mf_->getSSARegMap()->getRegClass(RegB); + if (RegClassA == RegClassB) + 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, |