mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-18 12:29:21 +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_;
|
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) {
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user