From 0547bab214c65402cd80846e8bccb7535c0ddf09 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Thu, 1 Nov 2007 06:22:48 +0000 Subject: [PATCH] - Coalesce extract_subreg when both intervals are relatively small. - Some code clean up. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43606 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../llvm/CodeGen/SimpleRegisterCoalescing.h | 10 +-- lib/CodeGen/SimpleRegisterCoalescing.cpp | 69 ++++++++++++------- 2 files changed, 51 insertions(+), 28 deletions(-) diff --git a/include/llvm/CodeGen/SimpleRegisterCoalescing.h b/include/llvm/CodeGen/SimpleRegisterCoalescing.h index b62c26cf222..b84781b15cb 100644 --- a/include/llvm/CodeGen/SimpleRegisterCoalescing.h +++ b/include/llvm/CodeGen/SimpleRegisterCoalescing.h @@ -109,11 +109,11 @@ namespace llvm { /// JoinCopy - Attempt to join intervals corresponding to SrcReg/DstReg, /// which are the src/dst of the copy instruction CopyMI. This returns true - /// if the copy was successfully coalesced away, or if it is never possible - /// to coalesce these this copy, due to register constraints. It returns - /// false if it is not currently possible to coalesce this interval, but - /// it may be possible if other things get coalesced. - bool JoinCopy(MachineInstr *CopyMI, unsigned SrcReg, unsigned DstReg); + /// if the copy was successfully coalesced away. If it is not currently + /// possible to coalesce this interval, but it may be possible if other + /// things get coalesced, then it returns true by reference in 'Again'. + bool JoinCopy(MachineInstr *CopyMI, unsigned SrcReg, unsigned DstReg, + bool &Again); /// JoinIntervals - Attempt to join these two intervals. On failure, this /// returns false. Otherwise, if one of the intervals being joined is a diff --git a/lib/CodeGen/SimpleRegisterCoalescing.cpp b/lib/CodeGen/SimpleRegisterCoalescing.cpp index b2c29fcfc4b..0d90128bee9 100644 --- a/lib/CodeGen/SimpleRegisterCoalescing.cpp +++ b/lib/CodeGen/SimpleRegisterCoalescing.cpp @@ -197,22 +197,24 @@ void SimpleRegisterCoalescing::AddSubRegIdxPairs(unsigned Reg, unsigned SubIdx) /// JoinCopy - Attempt to join intervals corresponding to SrcReg/DstReg, /// which are the src/dst of the copy instruction CopyMI. This returns true -/// if the copy was successfully coalesced away, or if it is never possible -/// to coalesce this copy, due to register constraints. It returns -/// false if it is not currently possible to coalesce this interval, but -/// it may be possible if other things get coalesced. +/// if the copy was successfully coalesced away. If it is not currently +/// possible to coalesce this interval, but it may be possible if other +/// things get coalesced, then it returns true by reference in 'Again'. bool SimpleRegisterCoalescing::JoinCopy(MachineInstr *CopyMI, - unsigned SrcReg, unsigned DstReg) { + unsigned SrcReg, unsigned DstReg, + bool &Again) { DOUT << li_->getInstructionIndex(CopyMI) << '\t' << *CopyMI; // Get representative registers. unsigned repSrcReg = rep(SrcReg); unsigned repDstReg = rep(DstReg); + Again = false; + // If they are already joined we continue. if (repSrcReg == repDstReg) { DOUT << "\tCopy already coalesced.\n"; - return true; // Not coalescable. + return false; // Not coalescable. } bool SrcIsPhys = MRegisterInfo::isPhysicalRegister(repSrcReg); @@ -221,17 +223,17 @@ bool SimpleRegisterCoalescing::JoinCopy(MachineInstr *CopyMI, // If they are both physical registers, we cannot join them. if (SrcIsPhys && DstIsPhys) { DOUT << "\tCan not coalesce physregs.\n"; - return true; // Not coalescable. + return false; // Not coalescable. } // We only join virtual registers with allocatable physical registers. if (SrcIsPhys && !allocatableRegs_[repSrcReg]) { DOUT << "\tSrc reg is unallocatable physreg.\n"; - return true; // Not coalescable. + return false; // Not coalescable. } if (DstIsPhys && !allocatableRegs_[repDstReg]) { DOUT << "\tDst reg is unallocatable physreg.\n"; - return true; // Not coalescable. + return false; // Not coalescable. } bool isExtSubReg = CopyMI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG; @@ -265,19 +267,30 @@ bool SimpleRegisterCoalescing::JoinCopy(MachineInstr *CopyMI, RHS.overlaps(li_->getInterval(RealDstReg))) { DOUT << "Interfere with register "; DEBUG(li_->getInterval(RealDstReg).print(DOUT, mri_)); - return true; // Not coalescable + return false; // Not coalescable } for (const unsigned* SR = mri_->getSubRegisters(RealDstReg); *SR; ++SR) if (li_->hasInterval(*SR) && RHS.overlaps(li_->getInterval(*SR))) { DOUT << "Interfere with sub-register "; DEBUG(li_->getInterval(*SR).print(DOUT, mri_)); - return true; // Not coalescable + return false; // Not coalescable } - } else if (li_->getInterval(repDstReg).getSize() > - li_->getInterval(repSrcReg).getSize()) { + } else { + unsigned SrcSize= li_->getInterval(repSrcReg).getSize() / InstrSlots::NUM; + unsigned DstSize= li_->getInterval(repDstReg).getSize() / InstrSlots::NUM; + const TargetRegisterClass *RC=mf_->getSSARegMap()->getRegClass(repDstReg); + unsigned Threshold = allocatableRCRegs_[RC].count(); // Be conservative. If both sides are virtual registers, do not coalesce - // if the sub-register live interval is longer. - return false; + // if this will cause a high use density interval to target a smaller set + // of registers. + if (DstSize > Threshold || SrcSize > Threshold) { + LiveVariables::VarInfo &svi = lv_->getVarInfo(repSrcReg); + LiveVariables::VarInfo &dvi = lv_->getVarInfo(repDstReg); + if ((float)dvi.NumUses / DstSize < (float)svi.NumUses / SrcSize) { + Again = true; // May be possible to coalesce later. + return false; + } + } } } else if (differingRegisterClasses(repSrcReg, repDstReg)) { // If they are not of the same register class, we cannot join them. @@ -286,6 +299,7 @@ bool SimpleRegisterCoalescing::JoinCopy(MachineInstr *CopyMI, // a physical register that's compatible with the other side. e.g. // r1024 = MOV32to32_ r1025 // but later r1024 is assigned EAX then r1025 may be coalesced with EAX. + Again = true; // May be possible to coalesce later. return false; } @@ -359,6 +373,7 @@ bool SimpleRegisterCoalescing::JoinCopy(MachineInstr *CopyMI, JoinVInt.preference = JoinPReg; ++numAborts; DOUT << "\tMay tie down a physical register, abort!\n"; + Again = true; // May be possible to coalesce later. return false; } } @@ -401,6 +416,7 @@ bool SimpleRegisterCoalescing::JoinCopy(MachineInstr *CopyMI, // Otherwise, we are unable to join the intervals. DOUT << "Interference!\n"; + Again = true; // May be possible to coalesce later. return false; } @@ -971,13 +987,17 @@ void SimpleRegisterCoalescing::CopyCoalesceInMBB(MachineBasicBlock *MBB, // Try coalescing physical register + virtual register first. for (unsigned i = 0, e = PhysCopies.size(); i != e; ++i) { CopyRec &TheCopy = PhysCopies[i]; - if (!JoinCopy(TheCopy.MI, TheCopy.SrcReg, TheCopy.DstReg)) - TryAgain.push_back(TheCopy); + bool Again = false; + if (!JoinCopy(TheCopy.MI, TheCopy.SrcReg, TheCopy.DstReg, Again)) + if (Again) + TryAgain.push_back(TheCopy); } for (unsigned i = 0, e = VirtCopies.size(); i != e; ++i) { CopyRec &TheCopy = VirtCopies[i]; - if (!JoinCopy(TheCopy.MI, TheCopy.SrcReg, TheCopy.DstReg)) - TryAgain.push_back(TheCopy); + bool Again = false; + if (!JoinCopy(TheCopy.MI, TheCopy.SrcReg, TheCopy.DstReg, Again)) + if (Again) + TryAgain.push_back(TheCopy); } } @@ -1021,10 +1041,13 @@ void SimpleRegisterCoalescing::joinIntervals() { for (unsigned i = 0, e = TryAgainList.size(); i != e; ++i) { CopyRec &TheCopy = TryAgainList[i]; - if (TheCopy.MI && - JoinCopy(TheCopy.MI, TheCopy.SrcReg, TheCopy.DstReg)) { - TheCopy.MI = 0; // Mark this one as done. - ProgressMade = true; + if (TheCopy.MI) { + bool Again = false; + bool Success = JoinCopy(TheCopy.MI,TheCopy.SrcReg,TheCopy.DstReg,Again); + if (Success || !Again) { + TheCopy.MI = 0; // Mark this one as done. + ProgressMade = true; + } } } }