1
0
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:
Jakob Stoklund Olesen 2012-08-08 22:12:01 +00:00
parent 674a10c78a
commit 98908a7b0c

View File

@ -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) {