diff --git a/llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp b/llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp --- a/llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp +++ b/llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp @@ -44,24 +44,20 @@ TEST(BasicBlockUtils, EliminateUnreachableBlocks) { LLVMContext C; - - std::unique_ptr M = parseIR( - C, - "define i32 @has_unreachable(i1 %cond) {\n" - "entry:\n" - " br i1 %cond, label %bb0, label %bb1\n" - "bb0:\n" - " br label %bb1\n" - "bb1:\n" - " %phi = phi i32 [ 0, %entry ], [ 1, %bb0 ]" - " ret i32 %phi\n" - "bb2:\n" - " ret i32 42\n" - "}\n" - "\n" - ); - - auto *F = M->getFunction("has_unreachable"); + std::unique_ptr M = parseIR(C, R"IR( +define i32 @has_unreachable(i1 %cond) { +entry: + br i1 %cond, label %bb0, label %bb1 +bb0: + br label %bb1 +bb1: + %phi = phi i32 [ 0, %entry ], [ 1, %bb0 ] + ret i32 %phi +bb2: + ret i32 42 +} +)IR"); + Function *F = M->getFunction("has_unreachable"); DominatorTree DT(*F); DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager); @@ -74,20 +70,19 @@ TEST(BasicBlockUtils, SplitEdge_ex1) { LLVMContext C; - std::unique_ptr M = - parseIR(C, "define void @foo(i1 %cond0) {\n" - "entry:\n" - " br i1 %cond0, label %bb0, label %bb1\n" - "bb0:\n" - " %0 = mul i32 1, 2\n" - " br label %bb1\n" - "bb1:\n" - " br label %bb2\n" - "bb2:\n" - " ret void\n" - "}\n" - "\n"); - + std::unique_ptr M = parseIR(C, R"IR( +define void @foo(i1 %cond0) { +entry: + br i1 %cond0, label %bb0, label %bb1 +bb0: + %0 = mul i32 1, 2 + br label %bb1 +bb1: + br label %bb2 +bb2: + ret void +} +)IR"); Function *F = M->getFunction("foo"); DominatorTree DT(*F); BasicBlock *SrcBlock; @@ -114,16 +109,16 @@ TEST(BasicBlockUtils, SplitEdge_ex2) { LLVMContext C; - std::unique_ptr M = parseIR(C, "define void @foo() {\n" - "bb0:\n" - " br label %bb2\n" - "bb1:\n" - " br label %bb2\n" - "bb2:\n" - " ret void\n" - "}\n" - "\n"); - + std::unique_ptr M = parseIR(C, R"IR( +define void @foo() { +bb0: + br label %bb2 +bb1: + br label %bb2 +bb2: + ret void +} +)IR"); Function *F = M->getFunction("foo"); DominatorTree DT(*F); @@ -151,34 +146,33 @@ TEST(BasicBlockUtils, SplitEdge_ex3) { LLVMContext C; - std::unique_ptr M = - parseIR(C, "define i32 @foo(i32 %n) {\n" - "entry:\n" - " br label %header\n" - "header:\n" - " %sum.02 = phi i32 [ 0, %entry ], [ %sum.1, %bb3 ]\n" - " %0 = phi i32 [ 0, %entry ], [ %4, %bb3 ] \n" - " %1 = icmp slt i32 %0, %n \n" - " br i1 %1, label %bb0, label %bb1\n" - "bb0:\n" - " %2 = add nsw i32 %sum.02, 2\n" - " br label %bb2\n" - "bb1:\n" - " %3 = add nsw i32 %sum.02, 1\n" - " br label %bb2\n" - "bb2:\n" - " %sum.1 = phi i32 [ %2, %bb0 ], [ %3, %bb1 ]\n" - " br label %bb3\n" - "bb3:\n" - " %4 = add nsw i32 %0, 1 \n" - " %5 = icmp slt i32 %4, 100\n" - " br i1 %5, label %header, label %bb4\n" - "bb4:\n" - " %sum.0.lcssa = phi i32 [ %sum.1, %bb3 ]\n" - " ret i32 %sum.0.lcssa\n" - "}\n" - "\n"); - + std::unique_ptr M = parseIR(C, R"IR( +define i32 @foo(i32 %n) { +entry: + br label %header +header: + %sum.02 = phi i32 [ 0, %entry ], [ %sum.1, %bb3 ] + %0 = phi i32 [ 0, %entry ], [ %4, %bb3 ] + %1 = icmp slt i32 %0, %n + br i1 %1, label %bb0, label %bb1 +bb0: + %2 = add nsw i32 %sum.02, 2 + br label %bb2 +bb1: + %3 = add nsw i32 %sum.02, 1 + br label %bb2 +bb2: + %sum.1 = phi i32 [ %2, %bb0 ], [ %3, %bb1 ] + br label %bb3 +bb3: + %4 = add nsw i32 %0, 1 + %5 = icmp slt i32 %4, 100 + br i1 %5, label %header, label %bb4 +bb4: + %sum.0.lcssa = phi i32 [ %sum.1, %bb3 ] + ret i32 %sum.0.lcssa +} +)IR"); Function *F = M->getFunction("foo"); DominatorTree DT(*F); @@ -224,36 +218,36 @@ TEST(BasicBlockUtils, SplitEdge_ex4) { LLVMContext C; - std::unique_ptr M = parseIR( - C, "define void @bar(i32 %cond) personality i8 0 {\n" - "entry:\n" - " switch i32 %cond, label %exit [\n" - " i32 -1, label %continue\n" - " i32 0, label %continue\n" - " i32 1, label %continue_alt\n" - " i32 2, label %continue_alt\n" - " ]\n" - "exit:\n" - " ret void\n" - "continue:\n" - " invoke void @sink() to label %normal unwind label %exception\n" - "continue_alt:\n" - " invoke void @sink_alt() to label %normal unwind label %exception\n" - "exception:\n" - " %cleanup = landingpad i8 cleanup\n" - " br label %trivial-eh-handler\n" - "trivial-eh-handler:\n" - " call void @sideeffect(i32 1)\n" - " br label %normal\n" - "normal:\n" - " call void @sideeffect(i32 0)\n" - " ret void\n" - "}\n" - "\n" - "declare void @sideeffect(i32)\n" - "declare void @sink() cold\n" - "declare void @sink_alt() cold\n"); + std::unique_ptr M = parseIR(C, R"IR( +define void @bar(i32 %cond) personality i8 0 { +entry: + switch i32 %cond, label %exit [ + i32 -1, label %continue + i32 0, label %continue + i32 1, label %continue_alt + i32 2, label %continue_alt + ] +exit: + ret void +continue: + invoke void @sink() to label %normal unwind label %exception +continue_alt: + invoke void @sink_alt() to label %normal unwind label %exception +exception: + %cleanup = landingpad i8 cleanup + br label %trivial-eh-handler +trivial-eh-handler: + call void @sideeffect(i32 1) + br label %normal +normal: + call void @sideeffect(i32 0) + ret void +} +declare void @sideeffect(i32) +declare void @sink() cold +declare void @sink_alt() cold +)IR"); Function *F = M->getFunction("bar"); DominatorTree DT(*F); @@ -310,20 +304,20 @@ TEST(BasicBlockUtils, splitBasicBlockBefore_ex1) { LLVMContext C; - std::unique_ptr M = parseIR(C, "define void @foo() {\n" - "bb0:\n" - " %0 = mul i32 1, 2\n" - " br label %bb2\n" - "bb1:\n" - " br label %bb3\n" - "bb2:\n" - " %1 = phi i32 [ %0, %bb0 ]\n" - " br label %bb3\n" - "bb3:\n" - " ret void\n" - "}\n" - "\n"); - + std::unique_ptr M = parseIR(C, R"IR( +define void @foo() { +bb0: + %0 = mul i32 1, 2 + br label %bb2 +bb1: + br label %bb3 +bb2: + %1 = phi i32 [ %0, %bb0 ] + br label %bb3 +bb3: + ret void +} +)IR"); Function *F = M->getFunction("foo"); DominatorTree DT(*F); @@ -345,27 +339,24 @@ #ifndef NDEBUG TEST(BasicBlockUtils, splitBasicBlockBefore_ex2) { LLVMContext C; - std::unique_ptr M = - parseIR(C, "define void @foo() {\n" - "bb0:\n" - " %0 = mul i32 1, 2\n" - " br label %bb2\n" - "bb1:\n" - " br label %bb2\n" - "bb2:\n" - " %1 = phi i32 [ %0, %bb0 ], [ 1, %bb1 ]\n" - " br label %bb3\n" - "bb3:\n" - " ret void\n" - "}\n" - "\n"); - + std::unique_ptr M = parseIR(C, R"IR( +define void @foo() { +bb0: + %0 = mul i32 1, 2 + br label %bb2 +bb1: + br label %bb2 +bb2: + %1 = phi i32 [ %0, %bb0 ], [ 1, %bb1 ] + br label %bb3 +bb3: + ret void +} +)IR"); Function *F = M->getFunction("foo"); DominatorTree DT(*F); - BasicBlock *DestBlock; - - DestBlock = getBasicBlockByName(*F, "bb2"); + BasicBlock *DestBlock = getBasicBlockByName(*F, "bb2"); ASSERT_DEATH( { @@ -378,22 +369,18 @@ TEST(BasicBlockUtils, NoUnreachableBlocksToEliminate) { LLVMContext C; - - std::unique_ptr M = parseIR( - C, - "define i32 @no_unreachable(i1 %cond) {\n" - "entry:\n" - " br i1 %cond, label %bb0, label %bb1\n" - "bb0:\n" - " br label %bb1\n" - "bb1:\n" - " %phi = phi i32 [ 0, %entry ], [ 1, %bb0 ]" - " ret i32 %phi\n" - "}\n" - "\n" - ); - - auto *F = M->getFunction("no_unreachable"); + std::unique_ptr M = parseIR(C, R"IR( +define i32 @no_unreachable(i1 %cond) { +entry: + br i1 %cond, label %bb0, label %bb1 +bb0: + br label %bb1 +bb1: + %phi = phi i32 [ 0, %entry ], [ 1, %bb0 ] + ret i32 %phi +} +)IR"); + Function *F = M->getFunction("no_unreachable"); DominatorTree DT(*F); DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager); @@ -406,22 +393,18 @@ TEST(BasicBlockUtils, SplitBlockPredecessors) { LLVMContext C; - - std::unique_ptr M = parseIR( - C, - "define i32 @basic_func(i1 %cond) {\n" - "entry:\n" - " br i1 %cond, label %bb0, label %bb1\n" - "bb0:\n" - " br label %bb1\n" - "bb1:\n" - " %phi = phi i32 [ 0, %entry ], [ 1, %bb0 ]" - " ret i32 %phi\n" - "}\n" - "\n" - ); - - auto *F = M->getFunction("basic_func"); + std::unique_ptr M = parseIR(C, R"IR( +define i32 @basic_func(i1 %cond) { +entry: + br i1 %cond, label %bb0, label %bb1 +bb0: + br label %bb1 +bb1: + %phi = phi i32 [ 0, %entry ], [ 1, %bb0 ] + ret i32 %phi +} +)IR"); + Function *F = M->getFunction("basic_func"); DominatorTree DT(*F); // Make sure the dominator tree is properly updated if calling this on the @@ -432,23 +415,19 @@ TEST(BasicBlockUtils, SplitCriticalEdge) { LLVMContext C; - - std::unique_ptr M = parseIR( - C, - "define void @crit_edge(i1 %cond0, i1 %cond1) {\n" - "entry:\n" - " br i1 %cond0, label %bb0, label %bb1\n" - "bb0:\n" - " br label %bb1\n" - "bb1:\n" - " br label %bb2\n" - "bb2:\n" - " ret void\n" - "}\n" - "\n" - ); - - auto *F = M->getFunction("crit_edge"); + std::unique_ptr M = parseIR(C, R"IR( +define void @crit_edge(i1 %cond0, i1 %cond1) { +entry: + br i1 %cond0, label %bb0, label %bb1 +bb0: + br label %bb1 +bb1: + br label %bb2 +bb2: + ret void +} +)IR"); + Function *F = M->getFunction("crit_edge"); DominatorTree DT(*F); PostDominatorTree PDT(*F); @@ -460,41 +439,32 @@ TEST(BasicBlockUtils, SplitIndirectBrCriticalEdge) { LLVMContext C; - - std::unique_ptr M = - parseIR(C, "define void @crit_edge(i8* %cond0, i1 %cond1) {\n" - "entry:\n" - " indirectbr i8* %cond0, [label %bb0, label %bb1]\n" - "bb0:\n" - " br label %bb1\n" - "bb1:\n" - " %p = phi i32 [0, %bb0], [0, %entry]\n" - " br i1 %cond1, label %bb2, label %bb3\n" - "bb2:\n" - " ret void\n" - "bb3:\n" - " ret void\n" - "}\n"); - - auto *F = M->getFunction("crit_edge"); + std::unique_ptr M = parseIR(C, R"IR( +define void @crit_edge(i8* %cond0, i1 %cond1) { +entry: + indirectbr i8* %cond0, [label %bb0, label %bb1] +bb0: + br label %bb1 +bb1: + %p = phi i32 [0, %bb0], [0, %entry] + br i1 %cond1, label %bb2, label %bb3 +bb2: + ret void +bb3: + ret void +} +)IR"); + Function *F = M->getFunction("crit_edge"); DominatorTree DT(*F); LoopInfo LI(DT); BranchProbabilityInfo BPI(*F, LI); BlockFrequencyInfo BFI(*F, BPI, LI); - auto Block = [&F](StringRef BBName) -> const BasicBlock & { - for (auto &BB : *F) - if (BB.getName() == BBName) - return BB; - llvm_unreachable("Block not found"); - }; - - bool Split = SplitIndirectBrCriticalEdges(*F, &BPI, &BFI); - - EXPECT_TRUE(Split); + ASSERT_TRUE(SplitIndirectBrCriticalEdges(*F, &BPI, &BFI)); // Check that successors of the split block get their probability correct. - BasicBlock *SplitBB = Block("bb1").getTerminator()->getSuccessor(0); + BasicBlock *BB1 = getBasicBlockByName(*F, "bb1"); + BasicBlock *SplitBB = BB1->getTerminator()->getSuccessor(0); EXPECT_EQ(2u, SplitBB->getTerminator()->getNumSuccessors()); EXPECT_EQ(BranchProbability(1, 2), BPI.getEdgeProbability(SplitBB, 0u)); EXPECT_EQ(BranchProbability(1, 2), BPI.getEdgeProbability(SplitBB, 1u)); @@ -502,93 +472,85 @@ TEST(BasicBlockUtils, SetEdgeProbability) { LLVMContext C; - - std::unique_ptr M = parseIR( - C, "define void @edge_probability(i32 %0) {\n" - "entry:\n" - "switch i32 %0, label %LD [\n" - " i32 700, label %L0\n" - " i32 701, label %L1\n" - " i32 702, label %L2\n" - " i32 703, label %L3\n" - " i32 704, label %L4\n" - " i32 705, label %L5\n" - " i32 706, label %L6\n" - " i32 707, label %L7\n" - " i32 708, label %L8\n" - " i32 709, label %L9\n" - " i32 710, label %L10\n" - " i32 711, label %L11\n" - " i32 712, label %L12\n" - " i32 713, label %L13\n" - " i32 714, label %L14\n" - " i32 715, label %L15\n" - " i32 716, label %L16\n" - " i32 717, label %L17\n" - " i32 718, label %L18\n" - " i32 719, label %L19\n" - "], !prof !{!\"branch_weights\", i32 1, i32 1, i32 1, i32 1, i32 1, " - "i32 451, i32 1, i32 12, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, " - "i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1}\n" - "LD:\n" - " unreachable\n" - "L0:\n" - " ret void\n" - "L1:\n" - " ret void\n" - "L2:\n" - " ret void\n" - "L3:\n" - " ret void\n" - "L4:\n" - " ret void\n" - "L5:\n" - " ret void\n" - "L6:\n" - " ret void\n" - "L7:\n" - " ret void\n" - "L8:\n" - " ret void\n" - "L9:\n" - " ret void\n" - "L10:\n" - " ret void\n" - "L11:\n" - " ret void\n" - "L12:\n" - " ret void\n" - "L13:\n" - " ret void\n" - "L14:\n" - " ret void\n" - "L15:\n" - " ret void\n" - "L16:\n" - " ret void\n" - "L17:\n" - " ret void\n" - "L18:\n" - " ret void\n" - "L19:\n" - " ret void\n" - "}\n"); - - auto *F = M->getFunction("edge_probability"); + std::unique_ptr M = parseIR(C, R"IR( +define void @edge_probability(i32 %0) { +entry: +switch i32 %0, label %LD [ + i32 700, label %L0 + i32 701, label %L1 + i32 702, label %L2 + i32 703, label %L3 + i32 704, label %L4 + i32 705, label %L5 + i32 706, label %L6 + i32 707, label %L7 + i32 708, label %L8 + i32 709, label %L9 + i32 710, label %L10 + i32 711, label %L11 + i32 712, label %L12 + i32 713, label %L13 + i32 714, label %L14 + i32 715, label %L15 + i32 716, label %L16 + i32 717, label %L17 + i32 718, label %L18 + i32 719, label %L19 +], !prof !{!"branch_weights", i32 1, i32 1, i32 1, i32 1, i32 1, i32 451, i32 1, + i32 12, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, + i32 1, i32 1, i32 1, i32 1, i32 1} +LD: + unreachable +L0: + ret void +L1: + ret void +L2: + ret void +L3: + ret void +L4: + ret void +L5: + ret void +L6: + ret void +L7: + ret void +L8: + ret void +L9: + ret void +L10: + ret void +L11: + ret void +L12: + ret void +L13: + ret void +L14: + ret void +L15: + ret void +L16: + ret void +L17: + ret void +L18: + ret void +L19: + ret void +} +)IR"); + Function *F = M->getFunction("edge_probability"); DominatorTree DT(*F); LoopInfo LI(DT); BranchProbabilityInfo BPI(*F, LI); - auto Block = [&F](StringRef BBName) -> const BasicBlock & { - for (auto &BB : *F) - if (BB.getName() == BBName) - return BB; - llvm_unreachable("Block not found"); - }; - // Check that the unreachable block has the minimal probability. - const BasicBlock &EntryBB = Block("entry"); - const BasicBlock &UnreachableBB = Block("LD"); + const BasicBlock *EntryBB = getBasicBlockByName(*F, "entry"); + const BasicBlock *UnreachableBB = getBasicBlockByName(*F, "LD"); EXPECT_EQ(BranchProbability::getRaw(1), - BPI.getEdgeProbability(&EntryBB, &UnreachableBB)); + BPI.getEdgeProbability(EntryBB, UnreachableBB)); }