[llvm-commits] [llvm] r43606 - in /llvm/trunk: include/llvm/CodeGen/SimpleRegisterCoalescing.h lib/CodeGen/SimpleRegisterCoalescing.cpp
Evan Cheng
evan.cheng at apple.com
Wed Oct 31 23:22:48 PDT 2007
Author: evancheng
Date: Thu Nov 1 01:22:48 2007
New Revision: 43606
URL: http://llvm.org/viewvc/llvm-project?rev=43606&view=rev
Log:
- Coalesce extract_subreg when both intervals are relatively small.
- Some code clean up.
Modified:
llvm/trunk/include/llvm/CodeGen/SimpleRegisterCoalescing.h
llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp
Modified: llvm/trunk/include/llvm/CodeGen/SimpleRegisterCoalescing.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SimpleRegisterCoalescing.h?rev=43606&r1=43605&r2=43606&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/SimpleRegisterCoalescing.h (original)
+++ llvm/trunk/include/llvm/CodeGen/SimpleRegisterCoalescing.h Thu Nov 1 01:22:48 2007
@@ -109,11 +109,11 @@
/// 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
Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp?rev=43606&r1=43605&r2=43606&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp (original)
+++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Thu Nov 1 01:22:48 2007
@@ -197,22 +197,24 @@
/// 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 @@
// 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 @@
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 @@
// 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 @@
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 @@
// 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 @@
// 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 @@
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;
+ }
}
}
}
More information about the llvm-commits
mailing list