Index: lib/Transforms/Scalar/LoopUnswitch.cpp =================================================================== --- lib/Transforms/Scalar/LoopUnswitch.cpp +++ lib/Transforms/Scalar/LoopUnswitch.cpp @@ -255,6 +255,9 @@ TerminatorInst *TI); void SimplifyCode(std::vector &Worklist, Loop *L); + // Remove all the unreachable blocks in the loop, such that they do not + // get duplicated the next time the loop is unswitched. + void RemoveUnreachableBlocksInLoop(Loop *L); }; } @@ -1242,6 +1245,7 @@ UI->replaceUsesOfWith(LIC, Replacement); SimplifyCode(Worklist, L); + RemoveUnreachableBlocksInLoop(L); return; } @@ -1316,6 +1320,7 @@ } SimplifyCode(Worklist, L); + RemoveUnreachableBlocksInLoop(L); } /// Now that we have simplified some instructions in the loop, walk over it and @@ -1358,6 +1363,16 @@ // Special case hacks that appear commonly in unswitched code. if (BranchInst *BI = dyn_cast(I)) { + // Try to simplify conditional branches to unconditional branches. + if (BI->isConditional() && isa(BI->getCondition())) { + BranchInst *NBI = BranchInst::Create(BI->getCondition() == + ConstantInt::getTrue(BI->getContext()) ? + BI->getSuccessor(0) : + BI->getSuccessor(1), BI); + RemoveFromWorklist(BI, Worklist); + BI->eraseFromParent(); + Worklist.push_back(NBI); + } if (BI->isUnconditional()) { // If BI's parent is the only pred of the successor, fold the two blocks // together. @@ -1397,3 +1412,35 @@ } } } + +void LoopUnswitch::RemoveUnreachableBlocksInLoop(Loop *L) { + // Run a simple dead block elimination algorithm which assumes every + // block except the header is initially dead. + SmallVector Worklist; + SmallPtrSet DeadBlocks(L->block_begin(), L->block_end()); + + // No blocks (other than the header) in this loop shall have predecessors + // that are not in the loop, as this is not valid for natural loops. This can + // can occur if the blocks are unreachable. Hopefully LoopSimplify has + // deleted them. Its still OK if they exist. + DeadBlocks.erase(L->getHeader()); + Worklist.push_back(L->getHeader()); + while (!Worklist.empty()) { + BasicBlock *BB = Worklist.back(); + Worklist.pop_back(); + for (succ_iterator I = succ_begin(BB), E = succ_end(BB); I != E; ++I) { + if (!DeadBlocks.count(*I)) + continue; + // This block becomes alive. + DeadBlocks.erase(*I); + Worklist.push_back(*I); + } + } + + // Remove the blocks that are unreachable in the loop. + for (BasicBlock *BB : DeadBlocks) { + LI->removeBlock(BB); + LPM->deleteSimpleAnalysisValue(BB, L); + BB->eraseFromParent(); + } +} Index: test/Transforms/LoopUnswitch/trivial-unswitch.ll =================================================================== --- test/Transforms/LoopUnswitch/trivial-unswitch.ll +++ test/Transforms/LoopUnswitch/trivial-unswitch.ll @@ -19,12 +19,10 @@ ; CHECK: .split.split: ; preds = %.split..split.split_crit_edge ; CHECK: br label %loop_begin -; CHECK: loop_begin: ; preds = %do_something, %.split.split -; CHECK: br i1 true, label %continue, label %loop_exit - -; CHECK: continue: ; preds = %loop_begin +; CHECK: loop_begin: ; preds = %loop_begin, %.split.split ; CHECK: %var_val = load i32, i32* %var -; CHECK: br i1 true, label %do_something, label %loop_exit +; CHECK: call void @some_func() #1 +; CHECK: br label %loop_begin define i32 @test(i32* %var, i1 %cond1, i1 %cond2) { br label %loop_begin @@ -44,4 +42,4 @@ ret i32 0 } -declare void @some_func() noreturn \ No newline at end of file +declare void @some_func() noreturn