mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-17 21:29:20 +00:00
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:
parent
3193a2d6b0
commit
88d1f587d2
@ -57,6 +57,10 @@ namespace llvm {
|
||||
|
||||
BitVector allocatableRegs_;
|
||||
|
||||
/// JoinedLIs - Keep track which register intervals have been coalesced
|
||||
/// with other intervals.
|
||||
BitVector JoinedLIs;
|
||||
|
||||
public:
|
||||
struct CopyRec {
|
||||
MachineInstr *MI;
|
||||
@ -119,8 +123,7 @@ namespace llvm {
|
||||
}
|
||||
|
||||
bool hasInterval(unsigned reg) const {
|
||||
Reg2IntervalMap::const_iterator I = r2iMap_.find(reg);
|
||||
return I != r2iMap_.end();
|
||||
return r2iMap_.count(reg);
|
||||
}
|
||||
|
||||
/// 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,
|
||||
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.
|
||||
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);
|
||||
|
||||
void removeInterval(unsigned Reg) {
|
||||
|
@ -65,6 +65,7 @@ void LiveIntervals::releaseMemory() {
|
||||
i2miMap_.clear();
|
||||
r2iMap_.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";
|
||||
|
||||
// Live range has been lengthened due to colaescing, eliminate the
|
||||
// unnecessary kills at the end of the source live ranges.
|
||||
LiveVariables::VarInfo& svi = lv_->getVarInfo(repSrcReg);
|
||||
for (unsigned i = 0, e = svi.Kills.size(); i != e; ++i) {
|
||||
MachineInstr *Kill = svi.Kills[i];
|
||||
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 1
|
||||
// Remember these liveintervals have been joined.
|
||||
JoinedLIs.set(repSrcReg - MRegisterInfo::FirstVirtualRegister);
|
||||
if (MRegisterInfo::isVirtualRegister(repDstReg))
|
||||
JoinedLIs.set(repDstReg - MRegisterInfo::FirstVirtualRegister);
|
||||
|
||||
// If the intervals were swapped by Join, swap them back so that the register
|
||||
// mapping (in the r2i map) is correct.
|
||||
@ -1427,8 +1412,10 @@ void LiveIntervals::CopyCoallesceInMBB(MachineBasicBlock *MBB,
|
||||
void LiveIntervals::joinIntervals() {
|
||||
DOUT << "********** JOINING INTERVALS ***********\n";
|
||||
|
||||
JoinedLIs.resize(getNumIntervals());
|
||||
JoinedLIs.reset();
|
||||
|
||||
std::vector<CopyRec> TryAgainList;
|
||||
|
||||
const LoopInfo &LI = getAnalysis<LoopInfo>();
|
||||
if (LI.begin() == LI.end()) {
|
||||
// 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";
|
||||
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) {
|
||||
float Weight = MRegisterInfo::isPhysicalRegister(reg) ?
|
||||
HUGE_VALF : 0.0F;
|
||||
|
Loading…
Reference in New Issue
Block a user