1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 11:13:28 +01:00

Simplify the coalescer (finally!) by making LiveIntervals::processImplicitDefs a little more aggressive and teaching liveintervals to make use of isUndef marker on MachineOperands.

llvm-svn: 76223
This commit is contained in:
Evan Cheng 2009-07-17 19:43:40 +00:00
parent 56e00a404f
commit ba5b67f66d
3 changed files with 46 additions and 159 deletions

View File

@ -123,7 +123,6 @@ void LiveIntervals::processImplicitDefs() {
++I;
if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) {
unsigned Reg = MI->getOperand(0).getReg();
MI->getOperand(0).setIsUndef();
ImpDefRegs.insert(Reg);
ImpDefMIs.push_back(MI);
continue;
@ -175,11 +174,13 @@ void LiveIntervals::processImplicitDefs() {
for (unsigned i = 0, e = ImpDefMIs.size(); i != e; ++i) {
MachineInstr *MI = ImpDefMIs[i];
unsigned Reg = MI->getOperand(0).getReg();
if (TargetRegisterInfo::isPhysicalRegister(Reg))
// Physical registers are not liveout (yet).
continue;
if (!ImpDefRegs.count(Reg))
if (TargetRegisterInfo::isPhysicalRegister(Reg) ||
!ImpDefRegs.count(Reg)) {
// Delete all "local" implicit_def's. That include those which define
// physical registers since they cannot be liveout.
MI->eraseFromParent();
continue;
}
// If there are multiple defs of the same register and at least one
// is not an implicit_def, do not insert implicit_def's before the
@ -195,6 +196,10 @@ void LiveIntervals::processImplicitDefs() {
if (Skip)
continue;
// The only implicit_def which we want to keep are those that are live
// out of its block.
MI->eraseFromParent();
for (MachineRegisterInfo::use_iterator UI = mri_->use_begin(Reg),
UE = mri_->use_end(); UI != UE; ) {
MachineOperand &RMO = UI.getOperand();
@ -203,12 +208,19 @@ void LiveIntervals::processImplicitDefs() {
MachineBasicBlock *RMBB = RMI->getParent();
if (RMBB == MBB)
continue;
// Turn a copy use into an implicit_def.
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
if (tii_->isMoveInstr(*RMI, SrcReg, DstReg, SrcSubReg, DstSubReg) &&
Reg == SrcReg) {
RMI->setDesc(tii_->get(TargetInstrInfo::IMPLICIT_DEF));
for (int j = RMI->getNumOperands() - 1, ee = 0; j > ee; --j)
RMI->RemoveOperand(j);
continue;
}
const TargetRegisterClass* RC = mri_->getRegClass(Reg);
unsigned NewVReg = mri_->createVirtualRegister(RC);
MachineInstrBuilder MIB =
BuildMI(*RMBB, RMI, RMI->getDebugLoc(),
tii_->get(TargetInstrInfo::IMPLICIT_DEF), NewVReg);
(*MIB).getOperand(0).setIsUndef();
RMO.setReg(NewVReg);
RMO.setIsUndef();
RMO.setIsKill();
@ -593,17 +605,12 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
unsigned MOIdx,
LiveInterval &interval) {
DOUT << "\t\tregister: "; DEBUG(printRegName(interval.reg));
LiveVariables::VarInfo& vi = lv_->getVarInfo(interval.reg);
if (mi->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) {
DOUT << "is a implicit_def\n";
return;
}
// Virtual registers may be defined multiple times (due to phi
// elimination and 2-addr elimination). Much of what we do only has to be
// done once for the vreg. We use an empty interval to detect the first
// time we see a vreg.
LiveVariables::VarInfo& vi = lv_->getVarInfo(interval.reg);
if (interval.empty()) {
// Get the Idx of the defining instructions.
unsigned defIndex = getDefIndex(MIIdx);
@ -981,7 +988,8 @@ void LiveIntervals::computeIntervals() {
DOUT << "********** COMPUTING LIVE INTERVALS **********\n"
<< "********** Function: "
<< ((Value*)mf_->getFunction())->getName() << '\n';
SmallVector<unsigned, 8> UndefUses;
for (MachineFunction::iterator MBBI = mf_->begin(), E = mf_->end();
MBBI != E; ++MBBI) {
MachineBasicBlock *MBB = MBBI;
@ -1013,10 +1021,14 @@ void LiveIntervals::computeIntervals() {
// Handle defs.
for (int i = MI->getNumOperands() - 1; i >= 0; --i) {
MachineOperand &MO = MI->getOperand(i);
if (!MO.isReg() || !MO.getReg())
continue;
// handle register defs - build intervals
if (MO.isReg() && MO.getReg() && MO.isDef()) {
if (MO.isDef())
handleRegisterDef(MBB, MI, MIIndex, MO, i);
}
else if (MO.isUndef())
UndefUses.push_back(MO.getReg());
}
// Skip over the empty slots after each instruction.
@ -1031,6 +1043,14 @@ void LiveIntervals::computeIntervals() {
MIIndex += InstrSlots::NUM;
}
}
// Create empty intervals for registers defined by implicit_def's (except
// for those implicit_def that define values which are liveout of their
// blocks.
for (unsigned i = 0, e = UndefUses.size(); i != e; ++i) {
unsigned UndefReg = UndefUses[i];
(void)getOrCreateInterval(UndefReg);
}
}
bool LiveIntervals::findLiveInMBBs(unsigned Start, unsigned End,
@ -1523,23 +1543,13 @@ rewriteInstructionForSpills(const LiveInterval &li, const VNInfo *VNI,
continue;
if (RegJ == RegI) {
Ops.push_back(j);
HasUse |= MOj.isUse();
HasDef |= MOj.isDef();
if (!MOj.isUndef()) {
HasUse |= MOj.isUse();
HasDef |= MOj.isDef();
}
}
}
if (HasUse && !li.liveAt(getUseIndex(index)))
// Must be defined by an implicit def. It should not be spilled. Note,
// this is for correctness reason. e.g.
// 8 %reg1024<def> = IMPLICIT_DEF
// 12 %reg1024<def> = INSERT_SUBREG %reg1024<kill>, %reg1025, 2
// The live range [12, 14) are not part of the r1024 live interval since
// it's defined by an implicit def. It will not conflicts with live
// interval of r1025. Now suppose both registers are spilled, you can
// easily see a situation where both registers are reloaded before
// the INSERT_SUBREG and both target registers that would overlap.
HasUse = false;
// Create a new virtual register for the spill interval.
// Create the new register now so we can map the fold instruction
// to the new register so when it is unfolded we get the correct
@ -1728,7 +1738,8 @@ rewriteInstructionsForSpills(const LiveInterval &li, bool TrySplit,
unsigned index = getInstructionIndex(MI);
if (index < start || index >= end)
continue;
if (O.isUse() && !li.liveAt(getUseIndex(index)))
if (O.isUndef())
// Must be defined by an implicit def. It should not be spilled. Note,
// this is for correctness reason. e.g.
// 8 %reg1024<def> = IMPLICIT_DEF

View File

@ -786,35 +786,6 @@ SimpleRegisterCoalescing::UpdateRegDefsUses(unsigned SrcReg, unsigned DstReg,
}
}
/// RemoveDeadImpDef - Remove implicit_def instructions which are "re-defining"
/// registers due to insert_subreg coalescing. e.g.
/// r1024 = op
/// r1025 = implicit_def
/// r1025 = insert_subreg r1025, r1024
/// = op r1025
/// =>
/// r1025 = op
/// r1025 = implicit_def
/// r1025 = insert_subreg r1025, r1025
/// = op r1025
void
SimpleRegisterCoalescing::RemoveDeadImpDef(unsigned Reg, LiveInterval &LI) {
for (MachineRegisterInfo::reg_iterator I = mri_->reg_begin(Reg),
E = mri_->reg_end(); I != E; ) {
MachineOperand &O = I.getOperand();
MachineInstr *DefMI = &*I;
++I;
if (!O.isDef())
continue;
if (DefMI->getOpcode() != TargetInstrInfo::IMPLICIT_DEF)
continue;
if (!LI.liveBeforeAndAt(li_->getInstructionIndex(DefMI)))
continue;
li_->RemoveMachineInstrFromMaps(DefMI);
DefMI->eraseFromParent();
}
}
/// RemoveUnnecessaryKills - Remove kill markers that are no longer accurate
/// due to live range lengthening as the result of coalescing.
void SimpleRegisterCoalescing::RemoveUnnecessaryKills(unsigned Reg,
@ -1002,65 +973,6 @@ bool SimpleRegisterCoalescing::CanCoalesceWithImpDef(MachineInstr *CopyMI,
}
/// TurnCopiesFromValNoToImpDefs - The specified value# is defined by an
/// implicit_def and it is being removed. Turn all copies from this value#
/// into implicit_defs.
void SimpleRegisterCoalescing::TurnCopiesFromValNoToImpDefs(LiveInterval &li,
VNInfo *VNI) {
SmallVector<MachineInstr*, 4> ImpDefs;
MachineOperand *LastUse = NULL;
unsigned LastUseIdx = li_->getUseIndex(VNI->def);
for (MachineRegisterInfo::reg_iterator RI = mri_->reg_begin(li.reg),
RE = mri_->reg_end(); RI != RE;) {
MachineOperand *MO = &RI.getOperand();
MachineInstr *MI = &*RI;
++RI;
if (MO->isDef()) {
if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF)
ImpDefs.push_back(MI);
continue;
}
if (JoinedCopies.count(MI))
continue;
unsigned UseIdx = li_->getUseIndex(li_->getInstructionIndex(MI));
LiveInterval::iterator ULR = li.FindLiveRangeContaining(UseIdx);
if (ULR == li.end() || ULR->valno != VNI)
continue;
// If the use is a copy, turn it into an identity copy.
unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
if (tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) &&
SrcReg == li.reg) {
// Change it to an implicit_def.
MI->setDesc(tii_->get(TargetInstrInfo::IMPLICIT_DEF));
for (int i = MI->getNumOperands() - 1, e = 0; i > e; --i)
MI->RemoveOperand(i);
// It's no longer a copy, update the valno it defines.
unsigned DefIdx = li_->getDefIndex(UseIdx);
LiveInterval &DstInt = li_->getInterval(DstReg);
LiveInterval::iterator DLR = DstInt.FindLiveRangeContaining(DefIdx);
assert(DLR != DstInt.end() && "Live range not found!");
assert(DLR->valno->copy == MI);
DLR->valno->copy = NULL;
ReMatCopies.insert(MI);
} else if (UseIdx > LastUseIdx) {
LastUseIdx = UseIdx;
LastUse = MO;
}
}
if (LastUse) {
LastUse->setIsKill();
li.addKill(VNI, LastUseIdx+1, false);
} else {
// Remove dead implicit_def's.
while (!ImpDefs.empty()) {
MachineInstr *ImpDef = ImpDefs.back();
ImpDefs.pop_back();
li_->RemoveMachineInstrFromMaps(ImpDef);
ImpDef->eraseFromParent();
}
}
}
/// isWinToJoinVRWithSrcPhysReg - Return true if it's worth while to join a
/// a virtual destination register with physical source register.
bool
@ -1786,13 +1698,6 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
if (TargetRegisterInfo::isVirtualRegister(DstReg))
RemoveUnnecessaryKills(DstReg, *ResDstInt);
if (isInsSubReg)
// Avoid:
// r1024 = op
// r1024 = implicit_def
// ...
// = r1024
RemoveDeadImpDef(DstReg, *ResDstInt);
UpdateRegDefsUses(SrcReg, DstReg, SubIdx);
// SrcReg is guarateed to be the register whose live interval that is
@ -1808,29 +1713,6 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
delete SavedLI;
}
if (isEmpty) {
// Now the copy is being coalesced away, the val# previously defined
// by the copy is being defined by an IMPLICIT_DEF which defines a zero
// length interval. Remove the val#.
unsigned CopyIdx = li_->getDefIndex(li_->getInstructionIndex(CopyMI));
const LiveRange *LR = ResDstInt->getLiveRangeContaining(CopyIdx);
VNInfo *ImpVal = LR->valno;
assert(ImpVal->def == CopyIdx);
unsigned NextDef = LR->end;
TurnCopiesFromValNoToImpDefs(*ResDstInt, ImpVal);
ResDstInt->removeValNo(ImpVal);
LR = ResDstInt->FindLiveRangeContaining(NextDef);
if (LR != ResDstInt->end() && LR->valno->def == NextDef) {
// Special case: vr1024 = implicit_def
// vr1024 = insert_subreg vr1024, vr1025, c
// The insert_subreg becomes a "copy" that defines a val# which can itself
// be coalesced away.
MachineInstr *DefMI = li_->getInstructionFromIndex(NextDef);
if (DefMI->getOpcode() == TargetInstrInfo::INSERT_SUBREG)
LR->valno->copy = DefMI;
}
}
// If resulting interval has a preference that no longer fits because of subreg
// coalescing, just clear the preference.
unsigned Preference = getRegAllocPreference(ResDstInt->reg, *mf_, mri_, tri_);
@ -2695,10 +2577,8 @@ SimpleRegisterCoalescing::TurnCopyIntoImpDef(MachineBasicBlock::iterator &I,
if (EndMBB != MBB)
return false;
DstInt.removeValNo(DstLR->valno);
CopyMI->setDesc(tii_->get(TargetInstrInfo::IMPLICIT_DEF));
for (int i = CopyMI->getNumOperands() - 1, e = 0; i > e; --i)
CopyMI->RemoveOperand(i);
CopyMI->getOperand(0).setIsUndef();
li_->RemoveMachineInstrFromMaps(CopyMI);
CopyMI->eraseFromParent();
bool NoUse = mri_->use_empty(SrcReg);
if (NoUse) {
for (MachineRegisterInfo::reg_iterator RI = mri_->reg_begin(SrcReg),

View File

@ -277,10 +277,6 @@ namespace llvm {
/// subregister.
void UpdateRegDefsUses(unsigned SrcReg, unsigned DstReg, unsigned SubIdx);
/// RemoveDeadImpDef - Remove implicit_def instructions which are
/// "re-defining" registers due to insert_subreg coalescing. e.g.
void RemoveDeadImpDef(unsigned Reg, LiveInterval &LI);
/// RemoveUnnecessaryKills - Remove kill markers that are no longer accurate
/// due to live range lengthening as the result of coalescing.
void RemoveUnnecessaryKills(unsigned Reg, LiveInterval &LI);