mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-20 19:42:54 +02:00
Deal with irreducible control flow when building traces.
We filter out MachineLoop back-edges during the trace-building PO traversals, but it is possible to have CFG cycles that aren't natural loops, and MachineLoopInfo doesn't include such cycles. Use a standard visited set to detect such CFG cycles, and completely ignore them when picking traces. llvm-svn: 161532
This commit is contained in:
parent
674a10c78a
commit
98908a7b0c
@ -233,7 +233,9 @@ MinInstrCountEnsemble::pickTracePred(const MachineBasicBlock *MBB) {
|
|||||||
const MachineBasicBlock *Pred = *I;
|
const MachineBasicBlock *Pred = *I;
|
||||||
const MachineTraceMetrics::TraceBlockInfo *PredTBI =
|
const MachineTraceMetrics::TraceBlockInfo *PredTBI =
|
||||||
getDepthResources(Pred);
|
getDepthResources(Pred);
|
||||||
assert(PredTBI && "Predecessor must be visited first");
|
// Ignore cycles that aren't natural loops.
|
||||||
|
if (!PredTBI)
|
||||||
|
continue;
|
||||||
// Pick the predecessor that would give this block the smallest InstrDepth.
|
// Pick the predecessor that would give this block the smallest InstrDepth.
|
||||||
unsigned Depth = PredTBI->InstrDepth + CurCount;
|
unsigned Depth = PredTBI->InstrDepth + CurCount;
|
||||||
if (!Best || Depth < BestDepth)
|
if (!Best || Depth < BestDepth)
|
||||||
@ -261,7 +263,9 @@ MinInstrCountEnsemble::pickTraceSucc(const MachineBasicBlock *MBB) {
|
|||||||
continue;
|
continue;
|
||||||
const MachineTraceMetrics::TraceBlockInfo *SuccTBI =
|
const MachineTraceMetrics::TraceBlockInfo *SuccTBI =
|
||||||
getHeightResources(Succ);
|
getHeightResources(Succ);
|
||||||
assert(SuccTBI && "Successor must be visited first");
|
// Ignore cycles that aren't natural loops.
|
||||||
|
if (!SuccTBI)
|
||||||
|
continue;
|
||||||
// Pick the successor that would give this block the smallest InstrHeight.
|
// Pick the successor that would give this block the smallest InstrHeight.
|
||||||
unsigned Height = SuccTBI->InstrHeight;
|
unsigned Height = SuccTBI->InstrHeight;
|
||||||
if (!Best || Height < BestHeight)
|
if (!Best || Height < BestHeight)
|
||||||
@ -315,6 +319,7 @@ void MachineTraceMetrics::verifyAnalysis() const {
|
|||||||
namespace {
|
namespace {
|
||||||
struct LoopBounds {
|
struct LoopBounds {
|
||||||
MutableArrayRef<MachineTraceMetrics::TraceBlockInfo> Blocks;
|
MutableArrayRef<MachineTraceMetrics::TraceBlockInfo> Blocks;
|
||||||
|
SmallPtrSet<const MachineBasicBlock*, 8> Visited;
|
||||||
const MachineLoopInfo *Loops;
|
const MachineLoopInfo *Loops;
|
||||||
bool Downward;
|
bool Downward;
|
||||||
LoopBounds(MutableArrayRef<MachineTraceMetrics::TraceBlockInfo> blocks,
|
LoopBounds(MutableArrayRef<MachineTraceMetrics::TraceBlockInfo> blocks,
|
||||||
@ -339,21 +344,19 @@ public:
|
|||||||
if (LB.Downward ? TBI.hasValidHeight() : TBI.hasValidDepth())
|
if (LB.Downward ? TBI.hasValidHeight() : TBI.hasValidDepth())
|
||||||
return false;
|
return false;
|
||||||
// From is null once when To is the trace center block.
|
// From is null once when To is the trace center block.
|
||||||
if (!From)
|
if (From) {
|
||||||
return true;
|
if (const MachineLoop *FromLoop = LB.Loops->getLoopFor(From)) {
|
||||||
const MachineLoop *FromLoop = LB.Loops->getLoopFor(From);
|
// Don't follow backedges, don't leave FromLoop when going upwards.
|
||||||
if (!FromLoop)
|
if ((LB.Downward ? To : From) == FromLoop->getHeader())
|
||||||
return true;
|
return false;
|
||||||
// Don't follow backedges, don't leave FromLoop when going upwards.
|
// Don't leave FromLoop.
|
||||||
if ((LB.Downward ? To : From) == FromLoop->getHeader())
|
if (isExitingLoop(FromLoop, LB.Loops->getLoopFor(To)))
|
||||||
return false;
|
return false;
|
||||||
// Don't leave FromLoop.
|
}
|
||||||
if (isExitingLoop(FromLoop, LB.Loops->getLoopFor(To)))
|
}
|
||||||
return false;
|
// To is a new block. Mark the block as visited in case the CFG has cycles
|
||||||
// This is a new block. The PO traversal will compute height/depth
|
// that MachineLoopInfo didn't recognize as a natural loop.
|
||||||
// resources, causing us to reject new edges to To. This only works because
|
return LB.Visited.insert(To);
|
||||||
// we reject back-edges, so the CFG is cycle-free.
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -367,6 +370,7 @@ void MachineTraceMetrics::Ensemble::computeTrace(const MachineBasicBlock *MBB) {
|
|||||||
|
|
||||||
// Run an upwards post-order search for the trace start.
|
// Run an upwards post-order search for the trace start.
|
||||||
Bounds.Downward = false;
|
Bounds.Downward = false;
|
||||||
|
Bounds.Visited.clear();
|
||||||
typedef ipo_ext_iterator<const MachineBasicBlock*, LoopBounds> UpwardPO;
|
typedef ipo_ext_iterator<const MachineBasicBlock*, LoopBounds> UpwardPO;
|
||||||
for (UpwardPO I = ipo_ext_begin(MBB, Bounds), E = ipo_ext_end(MBB, Bounds);
|
for (UpwardPO I = ipo_ext_begin(MBB, Bounds), E = ipo_ext_end(MBB, Bounds);
|
||||||
I != E; ++I) {
|
I != E; ++I) {
|
||||||
@ -386,6 +390,7 @@ void MachineTraceMetrics::Ensemble::computeTrace(const MachineBasicBlock *MBB) {
|
|||||||
|
|
||||||
// Run a downwards post-order search for the trace end.
|
// Run a downwards post-order search for the trace end.
|
||||||
Bounds.Downward = true;
|
Bounds.Downward = true;
|
||||||
|
Bounds.Visited.clear();
|
||||||
typedef po_ext_iterator<const MachineBasicBlock*, LoopBounds> DownwardPO;
|
typedef po_ext_iterator<const MachineBasicBlock*, LoopBounds> DownwardPO;
|
||||||
for (DownwardPO I = po_ext_begin(MBB, Bounds), E = po_ext_end(MBB, Bounds);
|
for (DownwardPO I = po_ext_begin(MBB, Bounds), E = po_ext_end(MBB, Bounds);
|
||||||
I != E; ++I) {
|
I != E; ++I) {
|
||||||
|
Loading…
Reference in New Issue
Block a user