llvm.org GIT mirror llvm / 7f4699f
[SimplifyCFG] Avoid quadratic on a predecessors number behavior in instruction sinking. If a block has N predecessors, then the current algorithm will try to sink common code to this block N times (whenever we visit a predecessor). Every attempt to sink the common code includes going through all predecessors, so the complexity of the algorithm becomes O(N^2). With this patch we try to sink common code only when we visit the block itself. With this, the complexity goes down to O(N). As a side effect, the moment the code is sunk is slightly different than before (the order of simplifications has been changed), that's why I had to adjust two tests (note that neither of the tests is supposed to test SimplifyCFG): * test/CodeGen/AArch64/arm64-jumptable.ll - changes in this test mimic the changes that previous implementation of SimplifyCFG would do. * test/CodeGen/ARM/avoid-cpsr-rmw.ll - in this test I disabled common code sinking by a command line flag. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@321236 91177308-0d34-0410-b5e6-96231b3b80d8 Michael Zolotukhin 2 years ago
3 changed file(s) with 19 addition(s) and 25 deletion(s). Raw diff Collapse all Expand all
16531653
16541654 } // end anonymous namespace
16551655
1656 /// Given an unconditional branch that goes to BBEnd,
1657 /// check whether BBEnd has only two predecessors and the other predecessor
1658 /// ends with an unconditional branch. If it is true, sink any common code
1659 /// in the two predecessors to BBEnd.
1660 static bool SinkThenElseCodeToEnd(BranchInst *BI1) {
1661 assert(BI1->isUnconditional());
1662 BasicBlock *BBEnd = BI1->getSuccessor(0);
1663
1656 /// Check whether BB's predecessors end with unconditional branches. If it is
1657 /// true, sink any common code from the predecessors to BB.
1658 /// We also allow one predecessor to end with conditional branch (but no more
1659 /// than one).
1660 static bool SinkCommonCodeFromPredecessors(BasicBlock *BB) {
16641661 // We support two situations:
16651662 // (1) all incoming arcs are unconditional
16661663 // (2) one incoming arc is conditional
17041701 //
17051702 SmallVector UnconditionalPreds;
17061703 Instruction *Cond = nullptr;
1707 for (auto *B : predecessors(BBEnd)) {
1704 for (auto *B : predecessors(BB)) {
17081705 auto *T = B->getTerminator();
17091706 if (isa(T) && cast(T)->isUnconditional())
17101707 UnconditionalPreds.push_back(B);
17721769 DEBUG(dbgs() << "SINK: Splitting edge\n");
17731770 // We have a conditional edge and we're going to sink some instructions.
17741771 // Insert a new block postdominating all blocks we're going to sink from.
1775 if (!SplitBlockPredecessors(BI1->getSuccessor(0), UnconditionalPreds,
1776 ".sink.split"))
1772 if (!SplitBlockPredecessors(BB, UnconditionalPreds, ".sink.split"))
17771773 // Edges couldn't be split.
17781774 return false;
17791775 Changed = true;
57275723 BasicBlock *BB = BI->getParent();
57285724 BasicBlock *Succ = BI->getSuccessor(0);
57295725
5730 if (SinkCommon && Options.SinkCommonInsts && SinkThenElseCodeToEnd(BI))
5731 return true;
5732
57335726 // If the Terminator is the only non-phi instruction, simplify the block.
57345727 // If LoopHeader is provided, check if the block or its successor is a loop
57355728 // header. (This is for early invocations before loop simplify and
60076000 if (MergeBlockIntoPredecessor(BB))
60086001 return true;
60096002
6003 if (SinkCommon && Options.SinkCommonInsts)
6004 Changed |= SinkCommonCodeFromPredecessors(BB);
6005
60106006 IRBuilder<> Builder(BB);
60116007
60126008 // If there is a trivial two-entry PHI node in this basic block, and we can
55 entry:
66 switch i32 %a, label %exit [
77 i32 1, label %bb1
8 i32 2, label %bb2
8 i32 2, label %exit.sink.split
99 i32 3, label %bb3
1010 i32 4, label %bb4
1111 ]
1212 bb1:
1313 %b = add i32 %c, 1
14 store i32 %b, i32* %to
15 br label %exit
16 bb2:
17 store i32 2, i32* %to
18 br label %exit
14 br label %exit.sink.split
1915 bb3:
20 store i32 3, i32* %to
21 br label %exit
16 br label %exit.sink.split
2217 bb4:
23 store i32 5, i32* %to
18 br label %exit.sink.split
19 exit.sink.split:
20 %.sink = phi i32 [ 5, %bb4 ], [ %b, %bb1 ], [ 3, %bb3 ], [ %a, %entry ]
21 store i32 %.sink, i32* %to
2422 br label %exit
2523 exit:
2624 ret void
None ; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mcpu=cortex-a9 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-CORTEX
1 ; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mcpu=swift | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-SWIFT
0 ; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mcpu=cortex-a9 -simplifycfg-sink-common=false | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-CORTEX
1 ; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mcpu=swift -simplifycfg-sink-common=false | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-SWIFT
22 ; Avoid some 's' 16-bit instruction which partially update CPSR (and add false
33 ; dependency) when it isn't dependent on last CPSR defining instruction.
44 ; rdar://8928208