//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "regcoalescing"
-#include "llvm/CodeGen/SimpleRegisterCoalescing.h"
-#include "llvm/CodeGen/LiveIntervalAnalysis.h"
+#include "SimpleRegisterCoalescing.h"
#include "VirtRegMap.h"
+#include "llvm/CodeGen/LiveIntervalAnalysis.h"
#include "llvm/Value.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/CodeGen/LiveVariables.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/SSARegMap.h"
+#include "llvm/CodeGen/RegisterCoalescer.h"
#include "llvm/Target/MRegisterInfo.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
RegisterPass<SimpleRegisterCoalescing>
X("simple-register-coalescing", "Simple Register Coalescing");
+
+ // Declare that we implement the RegisterCoalescer interface
+ RegisterAnalysisGroup<RegisterCoalescer, true/*The Default*/> V(X);
}
const PassInfo *llvm::SimpleRegisterCoalescingID = X.getPassInfo();
void SimpleRegisterCoalescing::getAnalysisUsage(AnalysisUsage &AU) const {
- //AU.addPreserved<LiveVariables>();
AU.addPreserved<LiveIntervals>();
AU.addPreservedID(PHIEliminationID);
AU.addPreservedID(TwoAddressInstructionPassID);
for (const unsigned *AS = mri_->getSubRegisters(IntB.reg); *AS; ++AS) {
LiveInterval &AliasLI = li_->getInterval(*AS);
AliasLI.addRange(LiveRange(FillerStart, FillerEnd,
- AliasLI.getNextValue(FillerStart, 0)));
+ AliasLI.getNextValue(FillerStart, 0, li_->getVNInfoAllocator())));
}
}
return true;
}
+/// AddSubRegIdxPairs - Recursively mark all the registers represented by the
+/// specified register as sub-registers. The recursion level is expected to be
+/// shallow.
+void SimpleRegisterCoalescing::AddSubRegIdxPairs(unsigned Reg, unsigned SubIdx) {
+ std::vector<unsigned> &JoinedRegs = r2rRevMap_[Reg];
+ for (unsigned i = 0, e = JoinedRegs.size(); i != e; ++i) {
+ SubRegIdxes.push_back(std::make_pair(JoinedRegs[i], SubIdx));
+ AddSubRegIdxPairs(JoinedRegs[i], 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, bool PhysOnly) {
+ 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);
bool DstIsPhys = MRegisterInfo::isPhysicalRegister(repDstReg);
- if (PhysOnly && !SrcIsPhys && !DstIsPhys)
- // Only joining physical registers with virtual registers in this round.
- return true;
// 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.
}
-
- // If they are not of the same register class, we cannot join them.
- if (differingRegisterClasses(repSrcReg, repDstReg)) {
+
+ bool isExtSubReg = CopyMI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG;
+ unsigned RealDstReg = 0;
+ if (isExtSubReg) {
+ unsigned SubIdx = CopyMI->getOperand(2).getImm();
+ if (SrcIsPhys)
+ // r1024 = EXTRACT_SUBREG EAX, 0 then r1024 is really going to be
+ // coalesced with AX.
+ repSrcReg = mri_->getSubReg(repSrcReg, SubIdx);
+ else if (DstIsPhys) {
+ // If this is a extract_subreg where dst is a physical register, e.g.
+ // cl = EXTRACT_SUBREG reg1024, 1
+ // then create and update the actual physical register allocated to RHS.
+ const TargetRegisterClass *RC=mf_->getSSARegMap()->getRegClass(repSrcReg);
+ for (const unsigned *SRs = mri_->getSuperRegisters(repDstReg);
+ unsigned SR = *SRs; ++SRs) {
+ if (repDstReg == mri_->getSubReg(SR, SubIdx) &&
+ RC->contains(SR)) {
+ RealDstReg = SR;
+ break;
+ }
+ }
+ assert(RealDstReg && "Invalid extra_subreg instruction!");
+
+ // For this type of EXTRACT_SUBREG, conservatively
+ // check if the live interval of the source register interfere with the
+ // actual super physical register we are trying to coalesce with.
+ LiveInterval &RHS = li_->getInterval(repSrcReg);
+ if (li_->hasInterval(RealDstReg) &&
+ RHS.overlaps(li_->getInterval(RealDstReg))) {
+ DOUT << "Interfere with register ";
+ DEBUG(li_->getInterval(RealDstReg).print(DOUT, mri_));
+ 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 false; // Not coalescable
+ }
+ } 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 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.
DOUT << "\tSrc/Dest are different register classes.\n";
- return true; // Not coalescable.
+ // Allow the coalescer to try again in case either side gets coalesced to
+ // 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;
}
LiveInterval &SrcInt = li_->getInterval(repSrcReg);
// virtual register. Once the coalescing is done, it cannot be broken and
// these are not spillable! If the destination interval uses are far away,
// think twice about coalescing them!
- if (!mopd->isDead() && (SrcIsPhys || DstIsPhys)) {
+ if (!mopd->isDead() && (SrcIsPhys || DstIsPhys) && !isExtSubReg) {
LiveInterval &JoinVInt = SrcIsPhys ? DstInt : SrcInt;
unsigned JoinVReg = SrcIsPhys ? repDstReg : repSrcReg;
unsigned JoinPReg = SrcIsPhys ? repSrcReg : repDstReg;
const TargetRegisterClass *RC = mf_->getSSARegMap()->getRegClass(JoinVReg);
unsigned Threshold = allocatableRCRegs_[RC].count();
- // If the virtual register live interval is long has it has low use desity,
+ // If the virtual register live interval is long but it has low use desity,
// do not join them, instead mark the physical register as its allocation
// preference.
unsigned Length = JoinVInt.getSize() / InstrSlots::NUM;
JoinVInt.preference = JoinPReg;
++numAborts;
DOUT << "\tMay tie down a physical register, abort!\n";
+ Again = true; // May be possible to coalesce later.
return false;
}
}
// Coalescing failed.
// If we can eliminate the copy without merging the live ranges, do so now.
- if (AdjustCopiesBackFrom(SrcInt, DstInt, CopyMI))
+ if (!isExtSubReg && AdjustCopiesBackFrom(SrcInt, DstInt, CopyMI))
return true;
// Otherwise, we are unable to join the intervals.
DOUT << "Interference!\n";
+ Again = true; // May be possible to coalesce later.
return false;
}
unsetRegisterKills(I->start, I->end, repDstReg);
}
+ // If this is a extract_subreg where dst is a physical register, e.g.
+ // cl = EXTRACT_SUBREG reg1024, 1
+ // then create and update the actual physical register allocated to RHS.
+ if (RealDstReg) {
+ LiveInterval &RealDstInt = li_->getOrCreateInterval(RealDstReg);
+ SmallSet<const VNInfo*, 4> CopiedValNos;
+ for (LiveInterval::Ranges::const_iterator I = ResSrcInt->ranges.begin(),
+ E = ResSrcInt->ranges.end(); I != E; ++I) {
+ LiveInterval::const_iterator DstLR =
+ ResDstInt->FindLiveRangeContaining(I->start);
+ assert(DstLR != ResDstInt->end() && "Invalid joined interval!");
+ const VNInfo *DstValNo = DstLR->valno;
+ if (CopiedValNos.insert(DstValNo)) {
+ VNInfo *ValNo = RealDstInt.getNextValue(DstValNo->def, DstValNo->reg,
+ li_->getVNInfoAllocator());
+ RealDstInt.addKills(ValNo, DstValNo->kills);
+ RealDstInt.MergeValueInAsValue(*ResDstInt, DstValNo, ValNo);
+ }
+ }
+ repDstReg = RealDstReg;
+ }
+
// Update the liveintervals of sub-registers.
for (const unsigned *AS = mri_->getSubRegisters(repDstReg); *AS; ++AS)
- li_->getInterval(*AS).MergeInClobberRanges(*ResSrcInt);
+ li_->getOrCreateInterval(*AS).MergeInClobberRanges(*ResSrcInt,
+ li_->getVNInfoAllocator());
} else {
// Merge use info if the destination is a virtual register.
LiveVariables::VarInfo& dVI = lv_->getVarInfo(repDstReg);
dVI.NumUses += sVI.NumUses;
}
- DOUT << "\n\t\tJoined. Result = "; ResDstInt->print(DOUT, mri_);
- DOUT << "\n";
-
// Remember these liveintervals have been joined.
JoinedLIs.set(repSrcReg - MRegisterInfo::FirstVirtualRegister);
if (MRegisterInfo::isVirtualRegister(repDstReg))
JoinedLIs.set(repDstReg - MRegisterInfo::FirstVirtualRegister);
+ if (isExtSubReg && !SrcIsPhys && !DstIsPhys) {
+ if (!Swapped) {
+ // Make sure we allocate the larger super-register.
+ ResSrcInt->Copy(*ResDstInt, li_->getVNInfoAllocator());
+ std::swap(repSrcReg, repDstReg);
+ std::swap(ResSrcInt, ResDstInt);
+ }
+ unsigned SubIdx = CopyMI->getOperand(2).getImm();
+ SubRegIdxes.push_back(std::make_pair(repSrcReg, SubIdx));
+ AddSubRegIdxPairs(repSrcReg, SubIdx);
+ }
+
+ DOUT << "\n\t\tJoined. Result = "; ResDstInt->print(DOUT, mri_);
+ DOUT << "\n";
+
// repSrcReg is guarateed to be the register whose live interval that is
// being merged.
li_->removeInterval(repSrcReg);
r2rMap_[repSrcReg] = repDstReg;
+ r2rRevMap_[repDstReg].push_back(repSrcReg);
// Finally, delete the copy instruction.
li_->RemoveMachineInstrFromMaps(CopyMI);
///
static unsigned ComputeUltimateVN(VNInfo *VNI,
SmallVector<VNInfo*, 16> &NewVNInfo,
- std::map<VNInfo*, VNInfo*> &ThisFromOther,
- std::map<VNInfo*, VNInfo*> &OtherFromThis,
+ DenseMap<VNInfo*, VNInfo*> &ThisFromOther,
+ DenseMap<VNInfo*, VNInfo*> &OtherFromThis,
SmallVector<int, 16> &ThisValNoAssignments,
SmallVector<int, 16> &OtherValNoAssignments) {
unsigned VN = VNI->id;
// If this val is not a copy from the other val, then it must be a new value
// number in the destination.
- std::map<VNInfo*, VNInfo*>::iterator I = ThisFromOther.find(VNI);
+ DenseMap<VNInfo*, VNInfo*>::iterator I = ThisFromOther.find(VNI);
if (I == ThisFromOther.end()) {
NewVNInfo.push_back(VNI);
return ThisValNoAssignments[VN] = NewVNInfo.size()-1;
// Okay, now that there is a single LHS value number that we're merging the
// RHS into, update the value number info for the LHS to indicate that the
// value number is defined where the RHS value number was.
- const VNInfo *VNI = RHS.getFirstValNumInfo();
+ const VNInfo *VNI = RHS.getValNumInfo(0);
LHSValNo->def = VNI->def;
LHSValNo->reg = VNI->reg;
// Okay, the final step is to loop over the RHS live intervals, adding them to
// the LHS.
- LHS.addKills(*LHSValNo, VNI->kills);
+ LHS.addKills(LHSValNo, VNI->kills);
LHS.MergeRangesInAsValue(RHS, LHSValNo);
LHS.weight += RHS.weight;
if (RHS.preference && !LHS.preference)
// coalesced.
SmallVector<int, 16> LHSValNoAssignments;
SmallVector<int, 16> RHSValNoAssignments;
- std::map<VNInfo*, VNInfo*> LHSValsDefinedFromRHS;
- std::map<VNInfo*, VNInfo*> RHSValsDefinedFromLHS;
+ DenseMap<VNInfo*, VNInfo*> LHSValsDefinedFromRHS;
+ DenseMap<VNInfo*, VNInfo*> RHSValsDefinedFromLHS;
SmallVector<VNInfo*, 16> NewVNInfo;
// If a live interval is a physical register, conservatively check if any
int RHSVal0DefinedFromLHS = -1;
int RHSValID = -1;
VNInfo *RHSValNoInfo = NULL;
- VNInfo *RHSValNoInfo0 = RHS.getFirstValNumInfo();
+ VNInfo *RHSValNoInfo0 = RHS.getValNumInfo(0);
unsigned RHSSrcReg = RHSValNoInfo0->reg;
if ((RHSSrcReg == 0 || rep(RHSSrcReg) != LHS.reg)) {
// If RHS is not defined as a copy from the LHS, we can use simpler and
assert(RHSValID != -1 && "Didn't find value #?");
RHSValNoAssignments[0] = RHSValID;
if (RHSVal0DefinedFromLHS != -1) {
- RHSValsDefinedFromLHS[RHSValNoInfo0] =
- LHS.getLiveRangeContaining(RHSValNoInfo0->def-1)->valno;
+ // This path doesn't go through ComputeUltimateVN so just set
+ // it to anything.
+ RHSValsDefinedFromLHS[RHSValNoInfo0] = (VNInfo*)1;
}
} else {
// Loop over the value numbers of the LHS, seeing if any are defined from
i != e; ++i) {
VNInfo *VNI = *i;
unsigned ValSrcReg = VNI->reg;
- if (ValSrcReg == 0) // Src not defined by a copy?
+ if (VNI->def == ~1U ||ValSrcReg == 0) // Src not defined by a copy?
continue;
// DstReg is known to be a register in the LHS interval. If the src is
i != e; ++i) {
VNInfo *VNI = *i;
unsigned ValSrcReg = VNI->reg;
- if (ValSrcReg == 0) // Src not defined by a copy?
+ if (VNI->def == ~1U || ValSrcReg == 0) // Src not defined by a copy?
continue;
// DstReg is known to be a register in the RHS interval. If the src is
}
// Update kill info. Some live ranges are extended due to copy coalescing.
- for (std::map<VNInfo*, VNInfo*>::iterator I = RHSValsDefinedFromLHS.begin(),
- E = RHSValsDefinedFromLHS.end(); I != E; ++I) {
+ for (DenseMap<VNInfo*, VNInfo*>::iterator I = LHSValsDefinedFromRHS.begin(),
+ E = LHSValsDefinedFromRHS.end(); I != E; ++I) {
VNInfo *VNI = I->first;
- unsigned RHSValID = RHSValNoAssignments[VNI->id];
- LiveInterval::removeKill(*NewVNInfo[RHSValID], VNI->def);
- LHS.addKills(*NewVNInfo[RHSValID], VNI->kills);
+ unsigned LHSValID = LHSValNoAssignments[VNI->id];
+ LiveInterval::removeKill(NewVNInfo[LHSValID], VNI->def);
+ RHS.addKills(NewVNInfo[LHSValID], VNI->kills);
}
- for (std::map<VNInfo*, VNInfo*>::iterator I = LHSValsDefinedFromRHS.begin(),
- E = LHSValsDefinedFromRHS.end(); I != E; ++I) {
+ // Update kill info. Some live ranges are extended due to copy coalescing.
+ for (DenseMap<VNInfo*, VNInfo*>::iterator I = RHSValsDefinedFromLHS.begin(),
+ E = RHSValsDefinedFromLHS.end(); I != E; ++I) {
VNInfo *VNI = I->first;
- unsigned LHSValID = LHSValNoAssignments[VNI->id];
- LiveInterval::removeKill(*NewVNInfo[LHSValID], VNI->def);
- RHS.addKills(*NewVNInfo[LHSValID], VNI->kills);
+ unsigned RHSValID = RHSValNoAssignments[VNI->id];
+ LiveInterval::removeKill(NewVNInfo[RHSValID], VNI->def);
+ LHS.addKills(NewVNInfo[RHSValID], VNI->kills);
}
// If we get here, we know that we can coalesce the live ranges. Ask the
}
void SimpleRegisterCoalescing::CopyCoalesceInMBB(MachineBasicBlock *MBB,
- std::vector<CopyRec> *TryAgain, bool PhysOnly) {
+ std::vector<CopyRec> &TryAgain) {
DOUT << ((Value*)MBB->getBasicBlock())->getName() << ":\n";
+ std::vector<CopyRec> VirtCopies;
+ std::vector<CopyRec> PhysCopies;
for (MachineBasicBlock::iterator MII = MBB->begin(), E = MBB->end();
MII != E;) {
MachineInstr *Inst = MII++;
- // If this isn't a copy, we can't join intervals.
+ // If this isn't a copy nor a extract_subreg, we can't join intervals.
unsigned SrcReg, DstReg;
- if (!tii_->isMoveInstr(*Inst, SrcReg, DstReg)) continue;
-
- if (TryAgain && !JoinCopy(Inst, SrcReg, DstReg, PhysOnly))
- TryAgain->push_back(getCopyRec(Inst, SrcReg, DstReg));
+ if (Inst->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) {
+ DstReg = Inst->getOperand(0).getReg();
+ SrcReg = Inst->getOperand(1).getReg();
+ } else if (!tii_->isMoveInstr(*Inst, SrcReg, DstReg))
+ continue;
+
+ unsigned repSrcReg = rep(SrcReg);
+ unsigned repDstReg = rep(DstReg);
+ bool SrcIsPhys = MRegisterInfo::isPhysicalRegister(repSrcReg);
+ bool DstIsPhys = MRegisterInfo::isPhysicalRegister(repDstReg);
+ if (SrcIsPhys || DstIsPhys)
+ PhysCopies.push_back(getCopyRec(Inst, SrcReg, DstReg));
+ else
+ VirtCopies.push_back(getCopyRec(Inst, SrcReg, DstReg));
+ }
+
+ // Try coalescing physical register + virtual register first.
+ for (unsigned i = 0, e = PhysCopies.size(); i != e; ++i) {
+ CopyRec &TheCopy = PhysCopies[i];
+ 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];
+ bool Again = false;
+ if (!JoinCopy(TheCopy.MI, TheCopy.SrcReg, TheCopy.DstReg, Again))
+ if (Again)
+ TryAgain.push_back(TheCopy);
}
}
// If there are no loops in the function, join intervals in function order.
for (MachineFunction::iterator I = mf_->begin(), E = mf_->end();
I != E; ++I)
- CopyCoalesceInMBB(I, &TryAgainList);
+ CopyCoalesceInMBB(I, TryAgainList);
} else {
// Otherwise, join intervals in inner loops before other intervals.
// Unfortunately we can't just iterate over loop hierarchy here because
// Finally, join intervals in loop nest order.
for (unsigned i = 0, e = MBBs.size(); i != e; ++i)
- CopyCoalesceInMBB(MBBs[i].second, NULL, true);
- for (unsigned i = 0, e = MBBs.size(); i != e; ++i)
- CopyCoalesceInMBB(MBBs[i].second, &TryAgainList, false);
+ CopyCoalesceInMBB(MBBs[i].second, TryAgainList);
}
// Joining intervals can allow other intervals to be joined. Iteratively join
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;
+ }
}
}
}
}
DOUT << "*** Register mapping ***\n";
- for (int i = 0, e = r2rMap_.size(); i != e; ++i)
+ for (unsigned i = 0, e = r2rMap_.size(); i != e; ++i)
if (r2rMap_[i]) {
DOUT << " reg " << i << " -> ";
DEBUG(printRegName(r2rMap_[i]));
/// Return true if the two specified registers belong to different register
/// classes. The registers may be either phys or virt regs.
bool SimpleRegisterCoalescing::differingRegisterClasses(unsigned RegA,
- unsigned RegB) const {
+ unsigned RegB) const {
// Get the register classes for the first reg.
if (MRegisterInfo::isPhysicalRegister(RegA)) {
for (unsigned i = 0, NumOps = MI->getNumOperands(); i != NumOps; ++i) {
MachineOperand &MO = MI->getOperand(i);
- if (MO.isReg() && MO.isUse() && MO.getReg() &&
+ if (MO.isRegister() && MO.isUse() && MO.getReg() &&
mri_->regsOverlap(rep(MO.getReg()), Reg)) {
MOU = &MO;
return MI;
MachineOperand *SimpleRegisterCoalescing::findDefOperand(MachineInstr *MI, unsigned Reg) {
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i);
- if (MO.isReg() && MO.isDef() &&
+ if (MO.isRegister() && MO.isDef() &&
mri_->regsOverlap(rep(MO.getReg()), Reg))
return &MO;
}
void SimpleRegisterCoalescing::unsetRegisterKill(MachineInstr *MI, unsigned Reg) {
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i);
- if (MO.isReg() && MO.isKill() && MO.getReg() &&
+ if (MO.isRegister() && MO.isKill() && MO.getReg() &&
mri_->regsOverlap(rep(MO.getReg()), Reg))
MO.unsetIsKill();
}
for (unsigned i = 0, NumOps = MI->getNumOperands(); i != NumOps; ++i) {
MachineOperand &MO = MI->getOperand(i);
- if (MO.isReg() && MO.isKill() && MO.getReg() &&
+ if (MO.isRegister() && MO.isKill() && MO.getReg() &&
mri_->regsOverlap(rep(MO.getReg()), Reg)) {
MO.unsetIsKill();
}
bool SimpleRegisterCoalescing::hasRegisterDef(MachineInstr *MI, unsigned Reg) {
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i);
- if (MO.isReg() && MO.isDef() &&
+ if (MO.isRegister() && MO.isDef() &&
mri_->regsOverlap(rep(MO.getReg()), Reg))
return true;
}
}
void SimpleRegisterCoalescing::releaseMemory() {
- r2rMap_.clear();
- JoinedLIs.clear();
+ for (unsigned i = 0, e = r2rMap_.size(); i != e; ++i)
+ r2rRevMap_[i].clear();
+ r2rRevMap_.clear();
+ r2rMap_.clear();
+ JoinedLIs.clear();
+ SubRegIdxes.clear();
}
static bool isZeroLengthInterval(LiveInterval *li) {
E = mri_->regclass_end(); I != E; ++I)
allocatableRCRegs_.insert(std::make_pair(*I,mri_->getAllocatableSet(fn, *I)));
- r2rMap_.grow(mf_->getSSARegMap()->getLastVirtReg());
+ SSARegMap *RegMap = mf_->getSSARegMap();
+ r2rMap_.grow(RegMap->getLastVirtReg());
+ r2rRevMap_.grow(RegMap->getLastVirtReg());
// Join (coalesce) intervals if requested.
if (EnableJoining) {
I->second.print(DOUT, mri_);
DOUT << "\n";
}
+
+ // Transfer sub-registers info to SSARegMap now that coalescing information
+ // is complete.
+ while (!SubRegIdxes.empty()) {
+ std::pair<unsigned, unsigned> RI = SubRegIdxes.back();
+ SubRegIdxes.pop_back();
+ mf_->getSSARegMap()->setIsSubRegister(RI.first, rep(RI.first), RI.second);
+ }
}
// perform a final pass over the instructions and compute spill
if (mop.isRegister() && mop.getReg() &&
MRegisterInfo::isVirtualRegister(mop.getReg())) {
// replace register with representative register
- unsigned reg = rep(mop.getReg());
- mii->getOperand(i).setReg(reg);
+ unsigned OrigReg = mop.getReg();
+ unsigned reg = rep(OrigReg);
+ // Don't rewrite if it is a sub-register of a virtual register.
+ if (!RegMap->isSubRegister(OrigReg))
+ mii->getOperand(i).setReg(reg);
+ else if (MRegisterInfo::isPhysicalRegister(reg))
+ mii->getOperand(i).setReg(mri_->getSubReg(reg,
+ RegMap->getSubRegisterIndex(OrigReg)));
// Multiple uses of reg by the same instruction. It should not
// contribute to spill weight again.
void SimpleRegisterCoalescing::print(std::ostream &O, const Module* m) const {
li_->print(O, m);
}
+
+RegisterCoalescer* llvm::createSimpleRegisterCoalescer() {
+ return new SimpleRegisterCoalescing();
+}
+
+// Make sure that anything that uses RegisterCoalescer pulls in this file...
+DEFINING_FILE_FOR(SimpleRegisterCoalescing)