Track all joined registers and eliminate unneeded kills after all joining are done.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34767 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2007-03-01 02:03:03 +00:00
parent 3193a2d6b0
commit 88d1f587d2
2 changed files with 52 additions and 25 deletions

View File

@ -57,6 +57,10 @@ namespace llvm {
BitVector allocatableRegs_; BitVector allocatableRegs_;
/// JoinedLIs - Keep track which register intervals have been coalesced
/// with other intervals.
BitVector JoinedLIs;
public: public:
struct CopyRec { struct CopyRec {
MachineInstr *MI; MachineInstr *MI;
@ -119,8 +123,7 @@ namespace llvm {
} }
bool hasInterval(unsigned reg) const { bool hasInterval(unsigned reg) const {
Reg2IntervalMap::const_iterator I = r2iMap_.find(reg); return r2iMap_.count(reg);
return I != r2iMap_.end();
} }
/// getMBBStartIdx - Return the base index of the first instruction in the /// getMBBStartIdx - Return the base index of the first instruction in the
@ -264,10 +267,14 @@ namespace llvm {
MachineInstr *lastRegisterUse(unsigned Reg, unsigned Start, unsigned End, MachineInstr *lastRegisterUse(unsigned Reg, unsigned Start, unsigned End,
MachineOperand *&MOU); MachineOperand *&MOU);
/// unsetRegisterKill - Unset IsKill property of all uses of specific /// unsetRegisterKill - Unset IsKill property of all uses of the specific
/// register of the specific instruction. /// register of the specific instruction.
void unsetRegisterKill(MachineInstr *MI, unsigned Reg); void unsetRegisterKill(MachineInstr *MI, unsigned Reg);
/// hasRegisterDef - True if the instruction defines the specific register.
///
bool hasRegisterDef(MachineInstr *MI, unsigned Reg);
static LiveInterval createInterval(unsigned Reg); static LiveInterval createInterval(unsigned Reg);
void removeInterval(unsigned Reg) { void removeInterval(unsigned Reg) {

View File

@ -65,6 +65,7 @@ void LiveIntervals::releaseMemory() {
i2miMap_.clear(); i2miMap_.clear();
r2iMap_.clear(); r2iMap_.clear();
r2rMap_.clear(); r2rMap_.clear();
JoinedLIs.clear();
} }
@ -987,27 +988,11 @@ bool LiveIntervals::JoinCopy(MachineInstr *CopyMI,
DOUT << "\n\t\tJoined. Result = "; DestInt.print(DOUT, mri_); DOUT << "\n\t\tJoined. Result = "; DestInt.print(DOUT, mri_);
DOUT << "\n"; DOUT << "\n";
// Live range has been lengthened due to colaescing, eliminate the #if 1
// unnecessary kills at the end of the source live ranges. // Remember these liveintervals have been joined.
LiveVariables::VarInfo& svi = lv_->getVarInfo(repSrcReg); JoinedLIs.set(repSrcReg - MRegisterInfo::FirstVirtualRegister);
for (unsigned i = 0, e = svi.Kills.size(); i != e; ++i) { if (MRegisterInfo::isVirtualRegister(repDstReg))
MachineInstr *Kill = svi.Kills[i]; JoinedLIs.set(repDstReg - MRegisterInfo::FirstVirtualRegister);
if (Kill == CopyMI || isRemoved(Kill))
continue;
if (DestInt.liveAt(getInstructionIndex(Kill) + InstrSlots::NUM))
unsetRegisterKill(Kill, repSrcReg);
}
if (MRegisterInfo::isVirtualRegister(repDstReg)) {
// If both are virtual registers...
LiveVariables::VarInfo& dvi = lv_->getVarInfo(repDstReg);
for (unsigned i = 0, e = dvi.Kills.size(); i != e; ++i) {
MachineInstr *Kill = dvi.Kills[i];
if (Kill == CopyMI || isRemoved(Kill))
continue;
if (DestInt.liveAt(getInstructionIndex(Kill) + InstrSlots::NUM))
unsetRegisterKill(Kill, repDstReg);
}
}
// If the intervals were swapped by Join, swap them back so that the register // If the intervals were swapped by Join, swap them back so that the register
// mapping (in the r2i map) is correct. // mapping (in the r2i map) is correct.
@ -1427,8 +1412,10 @@ void LiveIntervals::CopyCoallesceInMBB(MachineBasicBlock *MBB,
void LiveIntervals::joinIntervals() { void LiveIntervals::joinIntervals() {
DOUT << "********** JOINING INTERVALS ***********\n"; DOUT << "********** JOINING INTERVALS ***********\n";
JoinedLIs.resize(getNumIntervals());
JoinedLIs.reset();
std::vector<CopyRec> TryAgainList; std::vector<CopyRec> TryAgainList;
const LoopInfo &LI = getAnalysis<LoopInfo>(); const LoopInfo &LI = getAnalysis<LoopInfo>();
if (LI.begin() == LI.end()) { if (LI.begin() == LI.end()) {
// If there are no loops in the function, join intervals in function order. // If there are no loops in the function, join intervals in function order.
@ -1467,6 +1454,27 @@ void LiveIntervals::joinIntervals() {
} }
} }
} }
// Some live range has been lengthened due to colaescing, eliminate the
// unnecessary kills.
int RegNum = JoinedLIs.find_first();
while (RegNum != -1) {
unsigned Reg = RegNum + MRegisterInfo::FirstVirtualRegister;
unsigned repReg = rep(Reg);
LiveInterval &LI = getInterval(repReg);
LiveVariables::VarInfo& svi = lv_->getVarInfo(Reg);
for (unsigned i = 0, e = svi.Kills.size(); i != e; ++i) {
MachineInstr *Kill = svi.Kills[i];
// Suppose vr1 = op vr2, x
// and vr1 and vr2 are coalesced. vr2 should still be marked kill
// unless it is a two-address operand.
if (isRemoved(Kill) || hasRegisterDef(Kill, repReg))
continue;
if (LI.liveAt(getInstructionIndex(Kill) + InstrSlots::NUM))
unsetRegisterKill(Kill, repReg);
}
RegNum = JoinedLIs.find_next(RegNum);
}
DOUT << "*** Register mapping ***\n"; DOUT << "*** Register mapping ***\n";
for (int i = 0, e = r2rMap_.size(); i != e; ++i) for (int i = 0, e = r2rMap_.size(); i != e; ++i)
@ -1541,6 +1549,18 @@ void LiveIntervals::unsetRegisterKill(MachineInstr *MI, unsigned Reg) {
} }
} }
/// hasRegisterDef - True if the instruction defines the specific register.
///
bool LiveIntervals::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() &&
mri_->regsOverlap(rep(MO.getReg()), Reg))
return true;
}
return false;
}
LiveInterval LiveIntervals::createInterval(unsigned reg) { LiveInterval LiveIntervals::createInterval(unsigned reg) {
float Weight = MRegisterInfo::isPhysicalRegister(reg) ? float Weight = MRegisterInfo::isPhysicalRegister(reg) ?
HUGE_VALF : 0.0F; HUGE_VALF : 0.0F;