Avoid splitting critical edge twice for a set of PHI uses.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@114338 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2010-09-20 19:12:55 +00:00
parent 345adbe572
commit 7af6dc47a5

View File

@ -86,11 +86,11 @@ namespace {
MachineBasicBlock *SplitCriticalEdge(MachineInstr *MI,
MachineBasicBlock *From,
MachineBasicBlock *To,
bool AllPHIUse);
bool BreakPHIEdge);
bool SinkInstruction(MachineInstr *MI, bool &SawStore);
bool AllUsesDominatedByBlock(unsigned Reg, MachineBasicBlock *MBB,
MachineBasicBlock *DefMBB,
bool &AllPHIUse, bool &LocalUse) const;
bool &BreakPHIEdge, bool &LocalUse) const;
bool PerformTrivialForwardCoalescing(MachineInstr *MI,
MachineBasicBlock *MBB);
};
@ -138,7 +138,8 @@ bool
MachineSinking::AllUsesDominatedByBlock(unsigned Reg,
MachineBasicBlock *MBB,
MachineBasicBlock *DefMBB,
bool &AllPHIUse, bool &LocalUse) const {
bool &BreakPHIEdge,
bool &LocalUse) const {
assert(TargetRegisterInfo::isVirtualRegister(Reg) &&
"Only makes sense for vregs");
@ -150,7 +151,10 @@ MachineSinking::AllUsesDominatedByBlock(unsigned Reg,
// the definition of the vreg. Dwarf generator handles this although the
// user might not get the right info at runtime.
// PHI is in the successor BB. e.g.
// BreakPHIEdge is true if all the uses are in the successor MBB being sunken
// into and they are all PHI nodes. In this case, machine-sink must break
// the critical edge first. e.g.
//
// BB#1: derived from LLVM BB %bb4.preheader
// Predecessors according to CFG: BB#0
// ...
@ -162,9 +166,7 @@ MachineSinking::AllUsesDominatedByBlock(unsigned Reg,
// BB#2: derived from LLVM BB %bb.nph
// Predecessors according to CFG: BB#0 BB#1
// %reg16386<def> = PHI %reg16434, <BB#0>, %reg16385, <BB#1>
//
// Machine sink should break the critical edge first.
AllPHIUse = true;
BreakPHIEdge = true;
for (MachineRegisterInfo::use_nodbg_iterator
I = MRI->use_nodbg_begin(Reg), E = MRI->use_nodbg_end();
I != E; ++I) {
@ -172,11 +174,11 @@ MachineSinking::AllUsesDominatedByBlock(unsigned Reg,
MachineBasicBlock *UseBlock = UseInst->getParent();
if (!(UseBlock == MBB && UseInst->isPHI() &&
UseInst->getOperand(I.getOperandNo()+1).getMBB() == DefMBB)) {
AllPHIUse = false;
BreakPHIEdge = false;
break;
}
}
if (AllPHIUse)
if (BreakPHIEdge)
return true;
for (MachineRegisterInfo::use_nodbg_iterator
@ -304,7 +306,7 @@ bool MachineSinking::isWorthBreakingCriticalEdge(MachineInstr *MI,
MachineBasicBlock *MachineSinking::SplitCriticalEdge(MachineInstr *MI,
MachineBasicBlock *FromBB,
MachineBasicBlock *ToBB,
bool AllPHIUse) {
bool BreakPHIEdge) {
if (!isWorthBreakingCriticalEdge(MI, FromBB, ToBB))
return 0;
@ -356,7 +358,7 @@ MachineBasicBlock *MachineSinking::SplitCriticalEdge(MachineInstr *MI,
//
// There is no need to do this check if all the uses are PHI nodes. PHI
// sources are only defined on the specific predecessor edges.
if (!AllPHIUse) {
if (!BreakPHIEdge) {
for (MachineBasicBlock::pred_iterator PI = ToBB->pred_begin(),
E = ToBB->pred_end(); PI != E; ++PI) {
if (*PI == FromBB)
@ -392,7 +394,7 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {
// decide.
MachineBasicBlock *SuccToSinkTo = 0;
bool AllPHIUse = false;
bool BreakPHIEdge = false;
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
const MachineOperand &MO = MI->getOperand(i);
if (!MO.isReg()) continue; // Ignore non-register operands.
@ -452,7 +454,7 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {
// must be sinkable to the same block.
bool LocalUse = false;
if (!AllUsesDominatedByBlock(Reg, SuccToSinkTo, ParentBlock,
AllPHIUse, LocalUse))
BreakPHIEdge, LocalUse))
return false;
continue;
@ -464,7 +466,7 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {
E = ParentBlock->succ_end(); SI != E; ++SI) {
bool LocalUse = false;
if (AllUsesDominatedByBlock(Reg, *SI, ParentBlock,
AllPHIUse, LocalUse)) {
BreakPHIEdge, LocalUse)) {
SuccToSinkTo = *SI;
break;
}
@ -538,7 +540,7 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {
DEBUG(dbgs() << "Sinking along critical edge.\n");
else {
MachineBasicBlock *NewSucc =
SplitCriticalEdge(MI, ParentBlock, SuccToSinkTo, AllPHIUse);
SplitCriticalEdge(MI, ParentBlock, SuccToSinkTo, BreakPHIEdge);
if (!NewSucc) {
DEBUG(dbgs() << " *** PUNTING: Not legal or profitable to "
"break critical edge\n");
@ -550,15 +552,19 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {
<< " -- BB#" << SuccToSinkTo->getNumber() << '\n');
SuccToSinkTo = NewSucc;
++NumSplit;
BreakPHIEdge = false;
}
}
}
if (AllPHIUse) {
if (BreakPHIEdge) {
// BreakPHIEdge is true if all the uses are in the successor MBB being
// sunken into and they are all PHI nodes. In this case, machine-sink must
// break the critical edge first.
if (NumSplit == SplitLimit)
return false;
MachineBasicBlock *NewSucc = SplitCriticalEdge(MI, ParentBlock,
SuccToSinkTo, AllPHIUse);
SuccToSinkTo, BreakPHIEdge);
if (!NewSucc) {
DEBUG(dbgs() << " *** PUNTING: Not legal or profitable to "
"break critical edge\n");