Author: Arthur Eubanks Date: 2021-01-13T14:54:49-08:00 New Revision: 39e6d242378a0b645abbdfc6c02de5ef8dcfb9ed
URL: https://github.com/llvm/llvm-project/commit/39e6d242378a0b645abbdfc6c02de5ef8dcfb9ed DIFF: https://github.com/llvm/llvm-project/commit/39e6d242378a0b645abbdfc6c02de5ef8dcfb9ed.diff LOG: [NewPM] Only non-trivially loop unswitch at -O3 and for non-optsize functions This matches the legacy pipeline/pass. Reviewed By: asbirlea, SjoerdMeijer Differential Revision: https://reviews.llvm.org/D94559 Added: Modified: llvm/lib/Passes/PassBuilder.cpp llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp llvm/test/Transforms/SimpleLoopUnswitch/ARM/nontrivial-unswitch-cost.ll llvm/test/Transforms/SimpleLoopUnswitch/pipeline.ll Removed: ################################################################################ diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index 0d7f442f9ff4..7b2100aef081 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -724,7 +724,8 @@ PassBuilder::buildFunctionSimplificationPipeline(OptimizationLevel Level, LPM1.addPass(LoopRotatePass(Level != OptimizationLevel::Oz)); // TODO: Investigate promotion cap for O1. LPM1.addPass(LICMPass(PTO.LicmMssaOptCap, PTO.LicmMssaNoAccForPromotionCap)); - LPM1.addPass(SimpleLoopUnswitchPass(/* NonTrivial */ true)); + LPM1.addPass( + SimpleLoopUnswitchPass(/* NonTrivial */ Level == OptimizationLevel::O3)); LPM2.addPass(LoopIdiomRecognizePass()); LPM2.addPass(IndVarSimplifyPass()); diff --git a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp index 945476a2bdaf..3125f6274848 100644 --- a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp +++ b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp @@ -2906,6 +2906,10 @@ static bool unswitchLoop(Loop &L, DominatorTree &DT, LoopInfo &LI, if (!NonTrivial && !EnableNonTrivialUnswitch) return false; + // Skip non-trivial unswitching for optsize functions. + if (L.getHeader()->getParent()->hasOptSize()) + return false; + // For non-trivial unswitching, because it often creates new loops, we rely on // the pass manager to iterate on the loops rather than trying to immediately // reach a fixed point. There is no substantial advantage to iterating diff --git a/llvm/test/Transforms/SimpleLoopUnswitch/ARM/nontrivial-unswitch-cost.ll b/llvm/test/Transforms/SimpleLoopUnswitch/ARM/nontrivial-unswitch-cost.ll index 87f52c01e955..8482adec807c 100644 --- a/llvm/test/Transforms/SimpleLoopUnswitch/ARM/nontrivial-unswitch-cost.ll +++ b/llvm/test/Transforms/SimpleLoopUnswitch/ARM/nontrivial-unswitch-cost.ll @@ -111,33 +111,19 @@ loop_exit: define void @test_unswitch_minsize(i1* %ptr, i1 %cond) #0 { ; CHECK-LABEL: @test_unswitch_minsize( ; CHECK-NEXT: entry: -; CHECK-NEXT: br i1 [[COND:%.*]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] -; CHECK: entry.split.us: -; CHECK-NEXT: br label [[LOOP_BEGIN_US:%.*]] -; CHECK: loop_begin.us: -; CHECK-NEXT: call void @x() -; CHECK-NEXT: br label [[LOOP_A_US:%.*]] -; CHECK: loop_a.us: -; CHECK-NEXT: call void @a() -; CHECK-NEXT: br label [[LOOP_LATCH_US:%.*]] -; CHECK: loop_latch.us: -; CHECK-NEXT: [[V_US:%.*]] = load i1, i1* [[PTR:%.*]], align 1 -; CHECK-NEXT: br i1 [[V_US]], label [[LOOP_BEGIN_US]], label [[LOOP_EXIT_SPLIT_US:%.*]] -; CHECK: loop_exit.split.us: -; CHECK-NEXT: br label [[LOOP_EXIT:%.*]] -; CHECK: entry.split: ; CHECK-NEXT: br label [[LOOP_BEGIN:%.*]] ; CHECK: loop_begin: ; CHECK-NEXT: call void @x() -; CHECK-NEXT: br label [[LOOP_B:%.*]] +; CHECK-NEXT: br i1 [[COND:%.*]], label [[LOOP_A:%.*]], label [[LOOP_B:%.*]] +; CHECK: loop_a: +; CHECK-NEXT: call void @a() +; CHECK-NEXT: br label [[LOOP_LATCH:%.*]] ; CHECK: loop_b: ; CHECK-NEXT: call void @b() -; CHECK-NEXT: br label [[LOOP_LATCH:%.*]] +; CHECK-NEXT: br label [[LOOP_LATCH]] ; CHECK: loop_latch: -; CHECK-NEXT: [[V:%.*]] = load i1, i1* [[PTR]], align 1 -; CHECK-NEXT: br i1 [[V]], label [[LOOP_BEGIN]], label [[LOOP_EXIT_SPLIT:%.*]] -; CHECK: loop_exit.split: -; CHECK-NEXT: br label [[LOOP_EXIT]] +; CHECK-NEXT: [[V:%.*]] = load i1, i1* [[PTR:%.*]], align 1 +; CHECK-NEXT: br i1 [[V]], label [[LOOP_BEGIN]], label [[LOOP_EXIT:%.*]] ; CHECK: loop_exit: ; CHECK-NEXT: ret void ; @@ -235,39 +221,25 @@ loop_exit: define void @test_unswitch_non_dup_code_minsize(i1* %ptr, i1 %cond) #0 { ; CHECK-LABEL: @test_unswitch_non_dup_code_minsize( ; CHECK-NEXT: entry: -; CHECK-NEXT: br i1 [[COND:%.*]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] -; CHECK: entry.split.us: -; CHECK-NEXT: br label [[LOOP_BEGIN_US:%.*]] -; CHECK: loop_begin.us: +; CHECK-NEXT: br label [[LOOP_BEGIN:%.*]] +; CHECK: loop_begin: ; CHECK-NEXT: call void @x() -; CHECK-NEXT: br label [[LOOP_A_US:%.*]] -; CHECK: loop_a.us: +; CHECK-NEXT: br i1 [[COND:%.*]], label [[LOOP_A:%.*]], label [[LOOP_B:%.*]] +; CHECK: loop_a: ; CHECK-NEXT: call void @a() ; CHECK-NEXT: call void @a() ; CHECK-NEXT: call void @a() ; CHECK-NEXT: call void @a() -; CHECK-NEXT: br label [[LOOP_LATCH_US:%.*]] -; CHECK: loop_latch.us: -; CHECK-NEXT: [[V_US:%.*]] = load i1, i1* [[PTR:%.*]], align 1 -; CHECK-NEXT: br i1 [[V_US]], label [[LOOP_BEGIN_US]], label [[LOOP_EXIT_SPLIT_US:%.*]] -; CHECK: loop_exit.split.us: -; CHECK-NEXT: br label [[LOOP_EXIT:%.*]] -; CHECK: entry.split: -; CHECK-NEXT: br label [[LOOP_BEGIN:%.*]] -; CHECK: loop_begin: -; CHECK-NEXT: call void @x() -; CHECK-NEXT: br label [[LOOP_B:%.*]] +; CHECK-NEXT: br label [[LOOP_LATCH:%.*]] ; CHECK: loop_b: ; CHECK-NEXT: call void @b() ; CHECK-NEXT: call void @b() ; CHECK-NEXT: call void @b() ; CHECK-NEXT: call void @b() -; CHECK-NEXT: br label [[LOOP_LATCH:%.*]] +; CHECK-NEXT: br label [[LOOP_LATCH]] ; CHECK: loop_latch: -; CHECK-NEXT: [[V:%.*]] = load i1, i1* [[PTR]], align 1 -; CHECK-NEXT: br i1 [[V]], label [[LOOP_BEGIN]], label [[LOOP_EXIT_SPLIT:%.*]] -; CHECK: loop_exit.split: -; CHECK-NEXT: br label [[LOOP_EXIT]] +; CHECK-NEXT: [[V:%.*]] = load i1, i1* [[PTR:%.*]], align 1 +; CHECK-NEXT: br i1 [[V]], label [[LOOP_BEGIN]], label [[LOOP_EXIT:%.*]] ; CHECK: loop_exit: ; CHECK-NEXT: ret void ; @@ -387,45 +359,31 @@ loop_exit: define void @test_unswitch_non_dup_code_in_cfg_minsize(i1* %ptr, i1 %cond) #0 { ; CHECK-LABEL: @test_unswitch_non_dup_code_in_cfg_minsize( ; CHECK-NEXT: entry: -; CHECK-NEXT: br i1 [[COND:%.*]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] -; CHECK: entry.split.us: -; CHECK-NEXT: br label [[LOOP_BEGIN_US:%.*]] -; CHECK: loop_begin.us: -; CHECK-NEXT: call void @x() -; CHECK-NEXT: br label [[LOOP_A_US:%.*]] -; CHECK: loop_a.us: -; CHECK-NEXT: [[V1_US:%.*]] = load i1, i1* [[PTR:%.*]], align 1 -; CHECK-NEXT: br i1 [[V1_US]], label [[LOOP_A_A_US:%.*]], label [[LOOP_A_B_US:%.*]] -; CHECK: loop_a_b.us: -; CHECK-NEXT: call void @a() -; CHECK-NEXT: br label [[LOOP_LATCH_US:%.*]] -; CHECK: loop_a_a.us: -; CHECK-NEXT: call void @a() -; CHECK-NEXT: br label [[LOOP_LATCH_US]] -; CHECK: loop_latch.us: -; CHECK-NEXT: [[V3_US:%.*]] = load i1, i1* [[PTR]], align 1 -; CHECK-NEXT: br i1 [[V3_US]], label [[LOOP_BEGIN_US]], label [[LOOP_EXIT_SPLIT_US:%.*]] -; CHECK: loop_exit.split.us: -; CHECK-NEXT: br label [[LOOP_EXIT:%.*]] -; CHECK: entry.split: ; CHECK-NEXT: br label [[LOOP_BEGIN:%.*]] ; CHECK: loop_begin: ; CHECK-NEXT: call void @x() -; CHECK-NEXT: br label [[LOOP_B:%.*]] +; CHECK-NEXT: br i1 [[COND:%.*]], label [[LOOP_A:%.*]], label [[LOOP_B:%.*]] +; CHECK: loop_a: +; CHECK-NEXT: [[V1:%.*]] = load i1, i1* [[PTR:%.*]], align 1 +; CHECK-NEXT: br i1 [[V1]], label [[LOOP_A_A:%.*]], label [[LOOP_A_B:%.*]] +; CHECK: loop_a_a: +; CHECK-NEXT: call void @a() +; CHECK-NEXT: br label [[LOOP_LATCH:%.*]] +; CHECK: loop_a_b: +; CHECK-NEXT: call void @a() +; CHECK-NEXT: br label [[LOOP_LATCH]] ; CHECK: loop_b: ; CHECK-NEXT: [[V2:%.*]] = load i1, i1* [[PTR]], align 1 ; CHECK-NEXT: br i1 [[V2]], label [[LOOP_B_A:%.*]], label [[LOOP_B_B:%.*]] ; CHECK: loop_b_a: ; CHECK-NEXT: call void @b() -; CHECK-NEXT: br label [[LOOP_LATCH:%.*]] +; CHECK-NEXT: br label [[LOOP_LATCH]] ; CHECK: loop_b_b: ; CHECK-NEXT: call void @b() ; CHECK-NEXT: br label [[LOOP_LATCH]] ; CHECK: loop_latch: ; CHECK-NEXT: [[V3:%.*]] = load i1, i1* [[PTR]], align 1 -; CHECK-NEXT: br i1 [[V3]], label [[LOOP_BEGIN]], label [[LOOP_EXIT_SPLIT:%.*]] -; CHECK: loop_exit.split: -; CHECK-NEXT: br label [[LOOP_EXIT]] +; CHECK-NEXT: br i1 [[V3]], label [[LOOP_BEGIN]], label [[LOOP_EXIT:%.*]] ; CHECK: loop_exit: ; CHECK-NEXT: ret void ; @@ -666,31 +624,22 @@ loop_exit: define void @test_unswitch_dedicated_exiting_minsize(i1* %ptr, i1 %cond) #0 { ; CHECK-LABEL: @test_unswitch_dedicated_exiting_minsize( ; CHECK-NEXT: entry: -; CHECK-NEXT: br i1 [[COND:%.*]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] -; CHECK: entry.split.us: -; CHECK-NEXT: br label [[LOOP_BEGIN_US:%.*]] -; CHECK: loop_begin.us: -; CHECK-NEXT: call void @x() -; CHECK-NEXT: br label [[LOOP_A_US:%.*]] -; CHECK: loop_a.us: -; CHECK-NEXT: call void @a() -; CHECK-NEXT: br label [[LOOP_LATCH_US:%.*]] -; CHECK: loop_latch.us: -; CHECK-NEXT: [[V_US:%.*]] = load i1, i1* [[PTR:%.*]], align 1 -; CHECK-NEXT: br i1 [[V_US]], label [[LOOP_BEGIN_US]], label [[LOOP_EXIT_SPLIT_US:%.*]] -; CHECK: loop_exit.split.us: -; CHECK-NEXT: br label [[LOOP_EXIT:%.*]] -; CHECK: entry.split: ; CHECK-NEXT: br label [[LOOP_BEGIN:%.*]] ; CHECK: loop_begin: ; CHECK-NEXT: call void @x() -; CHECK-NEXT: br label [[LOOP_B_EXIT:%.*]] +; CHECK-NEXT: br i1 [[COND:%.*]], label [[LOOP_A:%.*]], label [[LOOP_B_EXIT:%.*]] +; CHECK: loop_a: +; CHECK-NEXT: call void @a() +; CHECK-NEXT: br label [[LOOP_LATCH:%.*]] ; CHECK: loop_b_exit: ; CHECK-NEXT: call void @b() ; CHECK-NEXT: call void @b() ; CHECK-NEXT: call void @b() ; CHECK-NEXT: call void @b() ; CHECK-NEXT: ret void +; CHECK: loop_latch: +; CHECK-NEXT: [[V:%.*]] = load i1, i1* [[PTR:%.*]], align 1 +; CHECK-NEXT: br i1 [[V]], label [[LOOP_BEGIN]], label [[LOOP_EXIT:%.*]] ; CHECK: loop_exit: ; CHECK-NEXT: ret void ; diff --git a/llvm/test/Transforms/SimpleLoopUnswitch/pipeline.ll b/llvm/test/Transforms/SimpleLoopUnswitch/pipeline.ll index 953b407cccd9..186a65876911 100644 --- a/llvm/test/Transforms/SimpleLoopUnswitch/pipeline.ll +++ b/llvm/test/Transforms/SimpleLoopUnswitch/pipeline.ll @@ -1,12 +1,15 @@ -; RUN: opt < %s -S -passes="default<O1>" | FileCheck %s -check-prefix=O1 -; RUN: opt < %s -S -passes="default<O2>" | FileCheck %s -check-prefix=O2 +; RUN: opt < %s -S -passes="default<O1>" | FileCheck %s -check-prefixes=TRIVIAL,CHECK +; RUN: opt < %s -S -passes="default<O2>" | FileCheck %s -check-prefixes=TRIVIAL,CHECK +; RUN: opt < %s -S -passes="default<O3>" | FileCheck %s -check-prefixes=NONTRIVIAL,CHECK +; RUN: opt < %s -S -passes="default<Os>" | FileCheck %s -check-prefixes=TRIVIAL,CHECK +; RUN: opt < %s -S -passes="default<Oz>" | FileCheck %s -check-prefixes=TRIVIAL,CHECK declare i32 @a() declare i32 @b() declare i32 @c() -; O1-NOT: loop_begin.us: -; O2: loop_begin.us: +; TRIVIAL-NOT: loop_begin.us: +; NONTRIVIAL: loop_begin.us: define i32 @test1(i1* %ptr, i1 %cond1, i1 %cond2) { entry: @@ -37,3 +40,34 @@ latch: loop_exit: ret i32 0 } + +; CHECK-NOT: loop2_begin.us: +define i32 @test2(i1* %ptr, i1 %cond1, i1 %cond2) optsize { +entry: + br label %loop2_begin + +loop2_begin: + br i1 %cond1, label %loop2_a, label %loop2_b + +loop2_a: + call i32 @a() + br label %latch2 + +loop2_b: + br i1 %cond2, label %loop2_b_a, label %loop2_b_b + +loop2_b_a: + call i32 @b() + br label %latch2 + +loop2_b_b: + call i32 @c() + br label %latch2 + +latch2: + %v = load i1, i1* %ptr + br i1 %v, label %loop2_begin, label %loop2_exit + +loop2_exit: + ret i32 0 +} _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits