mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-21 18:29:46 +00:00
Use an actual reverse-CFG reverse-postorder for the bottom-up traversal,
rather than plain postorder, so that CFG constructs like single-exit loops are reliably visited in a sensible order. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137398 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
9b7ff12dd1
commit
d8e48c4821
@ -2544,28 +2544,42 @@ ObjCARCOpt::Visit(Function &F,
|
||||
DenseMap<const BasicBlock *, BBState> &BBStates,
|
||||
MapVector<Value *, RRInfo> &Retains,
|
||||
DenseMap<Value *, RRInfo> &Releases) {
|
||||
// Use postorder for bottom-up, and reverse-postorder for top-down, because we
|
||||
// Use reverse-postorder on the reverse CFG for bottom-up, because we
|
||||
// magically know that loops will be well behaved, i.e. they won't repeatedly
|
||||
// call retain on a single pointer without doing a release.
|
||||
// call retain on a single pointer without doing a release. We can't use
|
||||
// ReversePostOrderTraversal here because we want to walk up from each
|
||||
// function exit point.
|
||||
SmallPtrSet<BasicBlock *, 16> Visited;
|
||||
SmallVector<std::pair<BasicBlock *, pred_iterator>, 16> Stack;
|
||||
SmallVector<BasicBlock *, 16> Order;
|
||||
for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) {
|
||||
BasicBlock *BB = I;
|
||||
if (BB->getTerminator()->getNumSuccessors() == 0)
|
||||
Stack.push_back(std::make_pair(BB, pred_begin(BB)));
|
||||
}
|
||||
while (!Stack.empty()) {
|
||||
pred_iterator End = pred_end(Stack.back().first);
|
||||
while (Stack.back().second != End) {
|
||||
BasicBlock *BB = *Stack.back().second++;
|
||||
if (Visited.insert(BB))
|
||||
Stack.push_back(std::make_pair(BB, pred_begin(BB)));
|
||||
}
|
||||
Order.push_back(Stack.pop_back_val().first);
|
||||
}
|
||||
bool BottomUpNestingDetected = false;
|
||||
SmallVector<BasicBlock *, 8> PostOrder;
|
||||
for (po_iterator<Function *> I = po_begin(&F), E = po_end(&F); I != E; ++I) {
|
||||
BasicBlock *BB = *I;
|
||||
PostOrder.push_back(BB);
|
||||
|
||||
while (!Order.empty()) {
|
||||
BasicBlock *BB = Order.pop_back_val();
|
||||
BottomUpNestingDetected |= VisitBottomUp(BB, BBStates, Retains);
|
||||
}
|
||||
|
||||
// Iterate through the post-order in reverse order, achieving a
|
||||
// reverse-postorder traversal. We don't use the ReversePostOrderTraversal
|
||||
// class here because it works by computing its own full postorder iteration,
|
||||
// recording the sequence, and playing it back in reverse. Since we're already
|
||||
// doing a full iteration above, we can just record the sequence manually and
|
||||
// avoid the cost of having ReversePostOrderTraversal compute it.
|
||||
// Use regular reverse-postorder for top-down.
|
||||
bool TopDownNestingDetected = false;
|
||||
for (SmallVectorImpl<BasicBlock *>::const_reverse_iterator
|
||||
RI = PostOrder.rbegin(), RE = PostOrder.rend(); RI != RE; ++RI)
|
||||
TopDownNestingDetected |= VisitTopDown(*RI, BBStates, Releases);
|
||||
typedef ReversePostOrderTraversal<Function *> RPOTType;
|
||||
RPOTType RPOT(&F);
|
||||
for (RPOTType::rpo_iterator I = RPOT.begin(), E = RPOT.end(); I != E; ++I) {
|
||||
BasicBlock *BB = *I;
|
||||
TopDownNestingDetected |= VisitTopDown(BB, BBStates, Releases);
|
||||
}
|
||||
|
||||
return TopDownNestingDetected && BottomUpNestingDetected;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user