mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 04:30:12 +00:00
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:
parent
345adbe572
commit
7af6dc47a5
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user