From: Christian König <christian.koe...@amd.com> The loop handling in the CFG structurizer incorrectly assumed that only BasicBlock nodes can have a back edge, but that is also possible for the exit edges of subregions.
Fixing 4 more piglit tests on radeonsi. Signed-off-by: Christian König <christian.koe...@amd.com> --- lib/Target/R600/AMDGPUStructurizeCFG.cpp | 135 ++++++++++++++++++------------ 1 file changed, 81 insertions(+), 54 deletions(-) diff --git a/lib/Target/R600/AMDGPUStructurizeCFG.cpp b/lib/Target/R600/AMDGPUStructurizeCFG.cpp index 70622e7..9528fc2 100644 --- a/lib/Target/R600/AMDGPUStructurizeCFG.cpp +++ b/lib/Target/R600/AMDGPUStructurizeCFG.cpp @@ -120,9 +120,9 @@ class AMDGPUStructurizeCFG : public RegionPass { void buildPredicate(BranchInst *Term, unsigned Idx, BBPredicates &Pred, bool Invert); - void analyzeBlock(BasicBlock *BB); + void analyzeNode(RegionNode *N); - void analyzeLoop(BasicBlock *BB, unsigned &LoopIdx); + void analyzeLoop(RegionNode *N); void collectInfos(); @@ -227,72 +227,92 @@ void AMDGPUStructurizeCFG::buildPredicate(BranchInst *Term, unsigned Idx, Pred[Parent] = Cond; } -/// \brief Analyze the successors of each block and build up predicates -void AMDGPUStructurizeCFG::analyzeBlock(BasicBlock *BB) { - pred_iterator PI = pred_begin(BB), PE = pred_end(BB); +/// \brief Analyze the predecessors of each block and build up predicates +void AMDGPUStructurizeCFG::analyzeNode(RegionNode *N) { RegionInfo *RI = ParentRegion->getRegionInfo(); + BasicBlock *BB = N->getEntry(); BBPredicates &Pred = Predicates[BB]; - for (; PI != PE; ++PI) { + for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); + PI != PE; ++PI) { + + // Handle the case where multiple regions start at the same block + Region *R = *PI != ParentRegion->getEntry() ? + RI->getRegionFor(*PI) : ParentRegion; - // Ignore self loops - if (*PI == BB) + // Edge from inside a subregion to its entry, ignore it + if (R == N) continue; - BranchInst *Term = cast<BranchInst>((*PI)->getTerminator()); + if (R == ParentRegion) { - for (unsigned i = 0, e = Term->getNumSuccessors(); i != e; ++i) { - BasicBlock *Succ = Term->getSuccessor(i); - if (Succ != BB) - continue; + // It's a top level block in our region + BranchInst *Term = cast<BranchInst>((*PI)->getTerminator()); + for (unsigned i = 0, e = Term->getNumSuccessors(); i != e; ++i) { + BasicBlock *Succ = Term->getSuccessor(i); + if (Succ != BB) + continue; + + // Ignore self loops + if (*PI != BB) + buildPredicate(Term, i, Pred, false); + + if (!Visited.count(*PI)) { + if (!LoopStart) + LoopStart = BB; - // Handle the case where multiple regions start at the same block - Region *R = *PI != ParentRegion->getEntry() ? - RI->getRegionFor(*PI) : ParentRegion; + buildPredicate(Term, i, LoopPred, true); + } + } - if (R == ParentRegion) { - // It's a top level block in our region - buildPredicate(Term, i, Pred, false); + } else if (ParentRegion->contains(R)) { - } else if (ParentRegion->contains(R)) { - // It's a block in a sub region - while(R->getParent() != ParentRegion) - R = R->getParent(); + // It's an exit from a sub region + while(R->getParent() != ParentRegion) + R = R->getParent(); - Pred[R->getEntry()] = BoolTrue; + BasicBlock *Entry = R->getEntry(); + Pred[Entry] = BoolTrue; + if (!Visited.count(Entry)) { + if (!LoopStart) + LoopStart = BB; - } else { - // It's a branch from outside into our parent region - Pred[*PI] = BoolTrue; + LoopPred[Entry] = BoolFalse; } + + } else { + // It's a branch from outside into our entry region + Pred[*PI] = BoolTrue; } } } -/// \brief Analyze the conditions leading to loop to a previous block -void AMDGPUStructurizeCFG::analyzeLoop(BasicBlock *BB, unsigned &LoopIdx) { - BranchInst *Term = cast<BranchInst>(BB->getTerminator()); +/// \brief Determine the end of the loop +void AMDGPUStructurizeCFG::analyzeLoop(RegionNode *N) { - for (unsigned i = 0, e = Term->getNumSuccessors(); i != e; ++i) { - BasicBlock *Succ = Term->getSuccessor(i); + if (N->isSubRegion()) { + // Test for exit as back edge + BasicBlock *Exit = N->getNodeAs<Region>()->getExit(); + if (Visited.count(Exit)) + LoopEnd = N->getEntry(); - // Ignore it if it's not a back edge - if (!Visited.count(Succ)) - continue; + } else { + // Test for sucessors as back edge + BasicBlock *BB = N->getNodeAs<BasicBlock>(); + BranchInst *Term = cast<BranchInst>(BB->getTerminator()); - buildPredicate(Term, i, LoopPred, true); + for (unsigned i = 0, e = Term->getNumSuccessors(); i != e; ++i) { + BasicBlock *Succ = Term->getSuccessor(i); - LoopEnd = BB; - if (Visited[Succ] < LoopIdx) { - LoopIdx = Visited[Succ]; - LoopStart = Succ; + if (Visited.count(Succ)) + LoopEnd = BB; } } } /// \brief Collect various loop and predicate infos void AMDGPUStructurizeCFG::collectInfos() { - unsigned Number = 0, LoopIdx = ~0; + unsigned Number = 0; // Reset predicate Predicates.clear(); @@ -304,17 +324,17 @@ void AMDGPUStructurizeCFG::collectInfos() { RNVector::reverse_iterator OI = Order.rbegin(), OE = Order.rend(); for (Visited.clear(); OI != OE; ++OI) { - Visited[(*OI)->getEntry()] = ++Number; - // Analyze all the conditions leading to a node - analyzeBlock((*OI)->getEntry()); + analyzeNode(*OI); - if ((*OI)->isSubRegion()) - continue; + Visited[(*OI)->getEntry()] = ++Number; - // Find the first/last loop nodes and loop predicates - analyzeLoop((*OI)->getNodeAs<BasicBlock>(), LoopIdx); + // Find the last loop node + analyzeLoop(*OI); } + + // Both or neither must be set + assert(!LoopStart == !LoopEnd); } /// \brief Does A dominate all the predicates of B ? @@ -355,6 +375,9 @@ RegionNode *AMDGPUStructurizeCFG::skipChained(RegionNode *Node) { // Skip forward as long as it is just a linear flow while (true) { BasicBlock *Entry = Node->getEntry(); + if (Entry == LoopEnd) + return Node; + BasicBlock *Exit; if (Node->isSubRegion()) { @@ -502,10 +525,8 @@ BasicBlock *AMDGPUStructurizeCFG::wireFlowBlock(BasicBlock *Prev, RegionNode *Node) { BasicBlock *Entry = Node->getEntry(); - if (LoopStart == Entry) { + if (LoopStart == Entry) LoopStart = Prev; - LoopPred[Prev] = BoolTrue; - } // Wire it up temporary, skipChained may recurse into us BranchInst::Create(Entry, Prev); @@ -545,6 +566,9 @@ BasicBlock *AMDGPUStructurizeCFG::wireFlowBlock(BasicBlock *Prev, // Update the region info SubRegion->replaceExit(Next); + if (SubRegion->getEntry() == LoopEnd) + LoopEnd = 0; + } else { BasicBlock *BB = Node->getNodeAs<BasicBlock>(); killTerminator(BB); @@ -575,7 +599,6 @@ void AMDGPUStructurizeCFG::createFlow() { ParentRegion->getRegionInfo()->setRegionFor(Split, ParentRegion); Predicates[Split] = Predicates[Prev]; Order.push_back(ParentRegion->getBBNode(Split)); - LoopPred[Prev] = BoolTrue; if (LoopEnd == Prev) LoopEnd = Split; @@ -636,10 +659,14 @@ void AMDGPUStructurizeCFG::insertConditions() { if (Term->isUnconditional()) continue; + BasicBlock *Succ = Term->getSuccessor(0); + PhiInserter.Initialize(Boolean, ""); - PhiInserter.AddAvailableValue(&Func->getEntryBlock(), BoolFalse); + if (*FI == LoopEnd) + PhiInserter.AddAvailableValue(LoopStart, BoolTrue); + else + PhiInserter.AddAvailableValue(&Func->getEntryBlock(), BoolFalse); - BasicBlock *Succ = Term->getSuccessor(0); BBPredicates &Preds = (*FI == LoopEnd) ? LoopPred : Predicates[Succ]; for (BBPredicates::iterator PI = Preds.begin(), PE = Preds.end(); PI != PE; ++PI) { -- 1.7.9.5 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev