llvm.org GIT mirror llvm / e43c10d
[IfConversion] Keep the CFG updated incrementally in IfConvertTriangle Summary: Instead of using RemoveExtraEdges (which uses analyzeBranch, which cannot always be trusted) at the end to fixup the CFG we keep the CFG updated as we go along and remove or add branches and merge blocks. This way we won't have any problems if the involved MBBs contain unanalyzable instructions. This fixes PR32721. In that case we had a triangle EBB | \ | | | TBB | / FBB where FBB didn't have any successors at all since it ended with an unconditional return. Then TBB and FBB were be merged into EBB, but EBB would still keep its successors, and the use of analyzeBranch and CorrectExtraCFGEdges wouldn't help to remove them since the return instruction is not analyzable (at least not on ARM). Reviewers: kparzysz, iteratee, MatzeB Reviewed By: iteratee Subscribers: aemerson, rengolin, javed.absar, llvm-commits Differential Revision: https://reviews.llvm.org/D33037 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302876 91177308-0d34-0410-b5e6-96231b3b80d8 Mikael Holmen 3 years ago
2 changed file(s) with 45 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
15871587 BBCvt = MBPI->getEdgeProbability(BBI.BB, &CvtMBB);
15881588 }
15891589
1590 // To be able to insert code freely at the end of BBI we sometimes remove
1591 // the branch from BBI to NextMBB temporarily. Remember if this happened.
1592 bool RemovedBranchToNextMBB = false;
15901593 if (CvtMBB.pred_size() > 1) {
15911594 BBI.NonPredSize -= TII->removeBranch(*BBI.BB);
15921595 // Copy instructions in the true block, predicate them, and add them to
15931596 // the entry block.
15941597 CopyAndPredicateBlock(BBI, *CvtBBI, Cond, true);
15951598
1596 // RemoveExtraEdges won't work if the block has an unanalyzable branch, so
1597 // explicitly remove CvtBBI as a successor.
1599 // Keep the CFG updated.
15981600 BBI.BB->removeSuccessor(&CvtMBB, true);
15991601 } else {
16001602 // Predicate the 'true' block after removing its branch.
16011603 CvtBBI->NonPredSize -= TII->removeBranch(CvtMBB);
16021604 PredicateBlock(*CvtBBI, CvtMBB.end(), Cond);
16031605
1606 // Remove the branch from the entry of the triangle to NextBB to be able to
1607 // do the merge below. Keep the CFG updated, but remember we removed the
1608 // branch since we do want to execute NextMBB, either by introducing a
1609 // branch to it again, or merging it into the entry block.
1610 // How it's handled is decided further down.
1611 BBI.NonPredSize -= TII->removeBranch(*BBI.BB);
1612 BBI.BB->removeSuccessor(&NextMBB, true);
1613 RemovedBranchToNextMBB = true;
1614
16041615 // Now merge the entry of the triangle with the true block.
1605 BBI.NonPredSize -= TII->removeBranch(*BBI.BB);
16061616 MergeBlocks(BBI, *CvtBBI, false);
16071617 }
16081618
16401650 // block. By not merging them, we make it possible to iteratively
16411651 // ifcvt the blocks.
16421652 if (!HasEarlyExit &&
1643 NextMBB.pred_size() == 1 && !NextBBI->HasFallThrough &&
1653 // We might have removed BBI from NextMBB's predecessor list above but
1654 // we want it to be there, so consider that too.
1655 (NextMBB.pred_size() == (RemovedBranchToNextMBB ? 0 : 1)) &&
1656 !NextBBI->HasFallThrough &&
16441657 !NextMBB.hasAddressTaken()) {
1658 // We will merge NextBBI into BBI, and thus remove the current
1659 // fallthrough from BBI into CvtBBI.
1660 BBI.BB->removeSuccessor(&CvtMBB, true);
16451661 MergeBlocks(BBI, *NextBBI);
16461662 FalseBBDead = true;
16471663 } else {
16481664 InsertUncondBranch(*BBI.BB, NextMBB, TII);
1665 BBI.BB->addSuccessor(&NextMBB);
16491666 BBI.HasFallThrough = false;
16501667 }
16511668 // Mixed predicated and unpredicated code. This cannot be iteratively
16521669 // predicated.
16531670 IterIfcvt = false;
16541671 }
1655
1656 RemoveExtraEdges(BBI);
16571672
16581673 // Update block info. BB can be iteratively if-converted.
16591674 if (!IterIfcvt)
0 # RUN: llc -mtriple=arm-apple-ios -run-pass=if-converter %s -o - | FileCheck %s
1 ---
2 name: foo
3 body: |
4 bb.0:
5 B %bb.2
6
7 bb.1:
8 BX_RET 14, 0
9
10 bb.2:
11 Bcc %bb.1, 1, %cpsr
12
13 bb.3:
14 B %bb.1
15
16 ...
17
18 # We should get a single block containing the BX_RET, with no successors at all
19
20 # CHECK: body:
21 # CHECK-NEXT: bb.0:
22 # CHECK-NEXT: BX_RET
23