mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-08 06:32:24 +00:00
- 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
This commit is contained in:
parent
7ebba512c3
commit
0547bab214
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user