diff --git a/lib/Analysis/LazyCallGraph.cpp b/lib/Analysis/LazyCallGraph.cpp index e00ceffc8f1..26529891bc0 100644 --- a/lib/Analysis/LazyCallGraph.cpp +++ b/lib/Analysis/LazyCallGraph.cpp @@ -1729,10 +1729,7 @@ void LazyCallGraph::buildRefSCCs() { for (Edge &E : *this) Roots.push_back(&E.getNode()); - // The roots will be popped of a stack, so use reverse to get a less - // surprising order. This doesn't change any of the semantics anywhere. - std::reverse(Roots.begin(), Roots.end()); - + // The roots will be iterated in order. buildGenericSCCs( Roots, [](Node &N) { diff --git a/test/Analysis/LazyCallGraph/alias.ll b/test/Analysis/LazyCallGraph/alias.ll index 7c9ca5182f9..054c4d991a2 100644 --- a/test/Analysis/LazyCallGraph/alias.ll +++ b/test/Analysis/LazyCallGraph/alias.ll @@ -8,13 +8,13 @@ target triple = "x86_64-grtev4-linux-gnu" ; CHECK: Edges in function: bar ; CHECK: Edges in function: baz -; CHECK: RefSCC with 1 call SCCs: -; CHECK-NEXT: SCC with 1 functions: -; CHECK-NEXT: bar - ; CHECK: RefSCC with 1 call SCCs: ; CHECK-NEXT: SCC with 1 functions: ; CHECK-NEXT: foo +; CHECK-EMPTY: +; CHECK: RefSCC with 1 call SCCs: +; CHECK-NEXT: SCC with 1 functions: +; CHECK-NEXT: bar ; CHECK-NOT: baz diff --git a/test/Analysis/LazyCallGraph/basic.ll b/test/Analysis/LazyCallGraph/basic.ll index 0d05a7a6514..eaaecc53801 100644 --- a/test/Analysis/LazyCallGraph/basic.ll +++ b/test/Analysis/LazyCallGraph/basic.ll @@ -256,10 +256,74 @@ entry: ; Verify the SCCs formed. ; ; CHECK-LABEL: RefSCC with 1 call SCCs: +; CHECK-NEXT: SCC with 1 functions: +; CHECK-NEXT: f +; +; CHECK-LABEL: RefSCC with 1 call SCCs: +; CHECK-NEXT: SCC with 1 functions: +; CHECK-NEXT: f1 +; +; CHECK-LABEL: RefSCC with 1 call SCCs: +; CHECK-NEXT: SCC with 1 functions: +; CHECK-NEXT: f2 +; +; CHECK-LABEL: RefSCC with 1 call SCCs: +; CHECK-NEXT: SCC with 1 functions: +; CHECK-NEXT: f3 +; +; CHECK-LABEL: RefSCC with 1 call SCCs: +; CHECK-NEXT: SCC with 1 functions: +; CHECK-NEXT: f4 +; +; CHECK-LABEL: RefSCC with 1 call SCCs: +; CHECK-NEXT: SCC with 1 functions: +; CHECK-NEXT: f5 +; +; CHECK-LABEL: RefSCC with 1 call SCCs: +; CHECK-NEXT: SCC with 1 functions: +; CHECK-NEXT: f6 +; +; CHECK-LABEL: RefSCC with 1 call SCCs: +; CHECK-NEXT: SCC with 1 functions: +; CHECK-NEXT: f7 +; +; CHECK-LABEL: RefSCC with 1 call SCCs: +; CHECK-NEXT: SCC with 1 functions: +; CHECK-NEXT: f8 +; +; CHECK-LABEL: RefSCC with 1 call SCCs: +; CHECK-NEXT: SCC with 1 functions: +; CHECK-NEXT: f9 +; +; CHECK-LABEL: RefSCC with 1 call SCCs: +; CHECK-NEXT: SCC with 1 functions: +; CHECK-NEXT: f10 +; +; CHECK-LABEL: RefSCC with 1 call SCCs: +; CHECK-NEXT: SCC with 1 functions: +; CHECK-NEXT: f11 +; +; CHECK-LABEL: RefSCC with 1 call SCCs: +; CHECK-NEXT: SCC with 1 functions: +; CHECK-NEXT: f12 +; +; CHECK-LABEL: RefSCC with 1 call SCCs: +; CHECK-NEXT: SCC with 1 functions: +; CHECK-NEXT: test0 +; +; CHECK-LABEL: RefSCC with 1 call SCCs: +; CHECK-NEXT: SCC with 1 functions: +; CHECK-NEXT: test1 +; +; CHECK-LABEL: RefSCC with 1 call SCCs: +; CHECK-NEXT: SCC with 1 functions: +; CHECK-NEXT: test2 +; +; CHECK-LABEL: RefSCC with 1 call SCCs: ; CHECK-NEXT: SCC with 3 functions: +; CHECK-NEXT: test3_ca2 ; CHECK-NEXT: test3_ca3 ; CHECK-NEXT: test3_ca1 -; CHECK-NEXT: test3_ca2 ; ; CHECK-LABEL: RefSCC with 2 call SCCs: ; CHECK-NEXT: SCC with 1 functions: @@ -269,75 +333,11 @@ entry: ; ; CHECK-LABEL: RefSCC with 3 call SCCs: ; CHECK-NEXT: SCC with 2 functions: -; CHECK-NEXT: test3_ac2 ; CHECK-NEXT: test3_ac1 +; CHECK-NEXT: test3_ac2 ; CHECK-NEXT: SCC with 2 functions: ; CHECK-NEXT: test3_ab2 ; CHECK-NEXT: test3_ab1 ; CHECK-NEXT: SCC with 2 functions: -; CHECK-NEXT: test3_aa2 ; CHECK-NEXT: test3_aa1 -; -; CHECK-LABEL: RefSCC with 1 call SCCs: -; CHECK-NEXT: SCC with 1 functions: -; CHECK-NEXT: f7 -; -; CHECK-LABEL: RefSCC with 1 call SCCs: -; CHECK-NEXT: SCC with 1 functions: -; CHECK-NEXT: f6 -; -; CHECK-LABEL: RefSCC with 1 call SCCs: -; CHECK-NEXT: SCC with 1 functions: -; CHECK-NEXT: f5 -; -; CHECK-LABEL: RefSCC with 1 call SCCs: -; CHECK-NEXT: SCC with 1 functions: -; CHECK-NEXT: f4 -; -; CHECK-LABEL: RefSCC with 1 call SCCs: -; CHECK-NEXT: SCC with 1 functions: -; CHECK-NEXT: f3 -; -; CHECK-LABEL: RefSCC with 1 call SCCs: -; CHECK-NEXT: SCC with 1 functions: -; CHECK-NEXT: f2 -; -; CHECK-LABEL: RefSCC with 1 call SCCs: -; CHECK-NEXT: SCC with 1 functions: -; CHECK-NEXT: f1 -; -; CHECK-LABEL: RefSCC with 1 call SCCs: -; CHECK-NEXT: SCC with 1 functions: -; CHECK-NEXT: test2 -; -; CHECK-LABEL: RefSCC with 1 call SCCs: -; CHECK-NEXT: SCC with 1 functions: -; CHECK-NEXT: f10 -; -; CHECK-LABEL: RefSCC with 1 call SCCs: -; CHECK-NEXT: SCC with 1 functions: -; CHECK-NEXT: f12 -; -; CHECK-LABEL: RefSCC with 1 call SCCs: -; CHECK-NEXT: SCC with 1 functions: -; CHECK-NEXT: f11 -; -; CHECK-LABEL: RefSCC with 1 call SCCs: -; CHECK-NEXT: SCC with 1 functions: -; CHECK-NEXT: f9 -; -; CHECK-LABEL: RefSCC with 1 call SCCs: -; CHECK-NEXT: SCC with 1 functions: -; CHECK-NEXT: f8 -; -; CHECK-LABEL: RefSCC with 1 call SCCs: -; CHECK-NEXT: SCC with 1 functions: -; CHECK-NEXT: test1 -; -; CHECK-LABEL: RefSCC with 1 call SCCs: -; CHECK-NEXT: SCC with 1 functions: -; CHECK-NEXT: f -; -; CHECK-LABEL: RefSCC with 1 call SCCs: -; CHECK-NEXT: SCC with 1 functions: -; CHECK-NEXT: test0 +; CHECK-NEXT: test3_aa2 diff --git a/test/Other/scc-pass-printer.ll b/test/Other/scc-pass-printer.ll index 9f0625d5721..9d6016ba4e8 100644 --- a/test/Other/scc-pass-printer.ll +++ b/test/Other/scc-pass-printer.ll @@ -1,36 +1,50 @@ ; RUN: opt < %s 2>&1 -disable-output \ -; RUN: -inline -print-after-all | FileCheck %s -check-prefix=INL +; RUN: -inline -print-after-all | FileCheck %s --check-prefix=LEGACY ; RUN: opt < %s 2>&1 -disable-output \ ; RUN: -passes=inline -print-after-all | FileCheck %s -check-prefix=INL ; RUN: opt < %s 2>&1 -disable-output \ ; RUN: -passes=inliner-wrapper -print-after-all | FileCheck %s -check-prefix=INL ; RUN: opt < %s 2>&1 -disable-output \ -; RUN: -inline -print-after-all -print-module-scope | FileCheck %s -check-prefix=INL-MOD +; RUN: -inline -print-after-all -print-module-scope | FileCheck %s -check-prefix=LEGACY-MOD ; RUN: opt < %s 2>&1 -disable-output \ ; RUN: -passes=inline -print-after-all -print-module-scope | FileCheck %s -check-prefix=INL-MOD ; RUN: opt < %s 2>&1 -disable-output \ ; RUN: -passes=inliner-wrapper -print-after-all -print-module-scope | FileCheck %s -check-prefix=INL-MOD -; INL: IR Dump After {{Function Integration/Inlining|InlinerPass .*scc: .bar, foo}} -; INL: define void @bar() -; INL-NEXT: call void @foo() -; INL: define void @foo() -; INL-NEXT: call void @bar() -; INL: IR Dump After {{Function Integration/Inlining|InlinerPass .*scc: .tester}} -; INL: define void @tester() -; INL-NEXT: call void @foo() -; INL: IR Dump After +; LEGACY: IR Dump After Function Integration/Inlining +; LEGACY: define void @bar() +; LEGACY-NEXT: call void @foo() +; LEGACY: define void @foo() +; LEGACY-NEXT: call void @bar() +; LEGACY: IR Dump After Function Integration/Inlining +; LEGACY: define void @tester() +; LEGACY-NEXT: call void @foo() -; INL-MOD: IR Dump After {{Function Integration/Inlining|InlinerPass .*scc: .bar, foo}} +; INL: IR Dump After InlinerPass *** (scc: (foo, bar)) +; INL: define void @foo() +; INL-NEXT: call void @bar() +; INL: define void @bar() +; INL-NEXT: call void @foo() +; INL: IR Dump After InlinerPass *** (scc: (tester)) +; INL: define void @tester() +; INL-NEXT: call void @foo() + +; LEGACY-MOD: IR Dump After Function Integration/Inlining +; LEGACY-MOD-NEXT: ModuleID = +; LEGACY-MOD: define void @tester() +; LEGACY-MOD: define void @foo() +; LEGACY-MOD: define void @bar() + +; INL-MOD-LABEL:*** IR Dump After InlinerPass *** (scc: (foo, bar)) ; INL-MOD-NEXT: ModuleID = ; INL-MOD-NEXT: source_filename = ; INL-MOD: define void @tester() ; INL-MOD-NEXT: call void @foo() ; INL-MOD: define void @foo() -; INL-MOD-NEXT: call void @bar() +; INL-MOD-NEXT: call void @bar() ; INL-MOD: define void @bar() -; INL-MOD-NEXT: call void @foo() -; INL-MOD: IR Dump After {{Function Integration/Inlining|InlinerPass .*scc: .tester}} +; INL-MOD-NEXT: call void @foo() +; INL-MOD-LABEL:*** IR Dump After InlinerPass *** (scc: (tester)) ; INL-MOD-NEXT: ModuleID = ; INL-MOD-NEXT: source_filename = ; INL-MOD: define void @tester() diff --git a/test/Transforms/Attributor/IPConstantProp/PR26044.ll b/test/Transforms/Attributor/IPConstantProp/PR26044.ll index ed4e49958ed..f068180fb57 100644 --- a/test/Transforms/Attributor/IPConstantProp/PR26044.ll +++ b/test/Transforms/Attributor/IPConstantProp/PR26044.ll @@ -97,37 +97,21 @@ define void @fn_no_null_opt(i32* %P, i1 %C) null_pointer_is_valid { ; IS__TUNIT____: exit: ; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fn_no_null_opt -; IS__CGSCC_OPM-SAME: (i32* nocapture nofree writeonly align 4 dereferenceable_or_null(4) [[P:%.*]], i1 [[C:%.*]]) [[ATTR2:#.*]] { -; IS__CGSCC_OPM-NEXT: entry: -; IS__CGSCC_OPM-NEXT: br label [[IF_END:%.*]] -; IS__CGSCC_OPM: for.cond1: -; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]] -; IS__CGSCC_OPM: if.end: -; IS__CGSCC_OPM-NEXT: [[E_2:%.*]] = phi i32* [ undef, [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ] -; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* null, align 4 -; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32 @fn0(i32 [[TMP0]]) -; IS__CGSCC_OPM-NEXT: store i32 [[CALL]], i32* [[P]], align 4 -; IS__CGSCC_OPM-NEXT: br label [[FOR_COND1]] -; IS__CGSCC_OPM: exit: -; IS__CGSCC_OPM-NEXT: ret void -; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fn_no_null_opt -; IS__CGSCC_NPM-SAME: (i32* nocapture nofree writeonly align 4 dereferenceable_or_null(4) [[P:%.*]], i1 [[C:%.*]]) [[ATTR2:#.*]] { -; IS__CGSCC_NPM-NEXT: entry: -; IS__CGSCC_NPM-NEXT: br label [[IF_END:%.*]] -; IS__CGSCC_NPM: for.cond1: -; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]] -; IS__CGSCC_NPM: if.end: -; IS__CGSCC_NPM-NEXT: [[E_2:%.*]] = phi i32* [ undef, [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ] -; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* null, align 536870912 -; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32 @fn0(i32 [[TMP0]]) -; IS__CGSCC_NPM-NEXT: store i32 [[CALL]], i32* [[P]], align 4 -; IS__CGSCC_NPM-NEXT: br label [[FOR_COND1]] -; IS__CGSCC_NPM: exit: -; IS__CGSCC_NPM-NEXT: ret void +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid +; IS__CGSCC____-LABEL: define {{[^@]+}}@fn_no_null_opt +; IS__CGSCC____-SAME: (i32* nocapture nofree writeonly align 4 dereferenceable_or_null(4) [[P:%.*]], i1 [[C:%.*]]) [[ATTR2:#.*]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: br label [[IF_END:%.*]] +; IS__CGSCC____: for.cond1: +; IS__CGSCC____-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]] +; IS__CGSCC____: if.end: +; IS__CGSCC____-NEXT: [[E_2:%.*]] = phi i32* [ undef, [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ] +; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* null, align 4 +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @fn0(i32 [[TMP0]]) +; IS__CGSCC____-NEXT: store i32 [[CALL]], i32* [[P]], align 4 +; IS__CGSCC____-NEXT: br label [[FOR_COND1]] +; IS__CGSCC____: exit: +; IS__CGSCC____-NEXT: ret void ; entry: br label %if.end diff --git a/test/Transforms/Inline/cgscc-cycle-debug.ll b/test/Transforms/Inline/cgscc-cycle-debug.ll index 435d540208b..21a5ae52475 100644 --- a/test/Transforms/Inline/cgscc-cycle-debug.ll +++ b/test/Transforms/Inline/cgscc-cycle-debug.ll @@ -10,7 +10,7 @@ ; REQUIRES: asserts ; RUN: opt < %s -passes='cgscc(inline)' -inline-threshold=500 -debug-only=cgscc -S 2>&1 | FileCheck %s -; CHECK: Running an SCC pass across the RefSCC: [(test1_c, test1_a, test1_b)] +; CHECK: Running an SCC pass across the RefSCC: [(test1_a, test1_b, test1_c)] ; CHECK: Enqueuing the existing SCC in the worklist:(test1_b) ; CHECK: Enqueuing a newly formed SCC:(test1_c) ; CHECK: Enqueuing a new RefSCC in the update worklist: [(test1_b)] @@ -42,4 +42,4 @@ define void @test1_c(i32 %num) #0 { ret void } -attributes #0 = { noinline nounwind optnone } \ No newline at end of file +attributes #0 = { noinline nounwind optnone } diff --git a/test/Transforms/Inline/cgscc-cycle.ll b/test/Transforms/Inline/cgscc-cycle.ll index bc3bdc99fff..fafa945e9f4 100644 --- a/test/Transforms/Inline/cgscc-cycle.ll +++ b/test/Transforms/Inline/cgscc-cycle.ll @@ -153,59 +153,6 @@ bb2: @a = global i64 0 @b = global i64 0 -define void @test3_c(i32 %i) { -entry: - %cmp = icmp eq i32 %i, 5 - br i1 %cmp, label %if.end, label %if.then - -if.then: ; preds = %entry - %call = tail call i64 @random() - %t0 = load i64, i64* @a - %add = add nsw i64 %t0, %call - store i64 %add, i64* @a - br label %if.end - -if.end: ; preds = %entry, %if.then - tail call void @test3_d(i32 %i) - %t6 = load i64, i64* @a - %add85 = add nsw i64 %t6, 1 - store i64 %add85, i64* @a - ret void -} - -declare i64 @random() - -define void @test3_d(i32 %i) { -entry: - %cmp = icmp eq i32 %i, 5 - br i1 %cmp, label %if.end, label %if.then - -if.then: ; preds = %entry - %call = tail call i64 @random() - %t0 = load i64, i64* @a - %add = add nsw i64 %t0, %call - store i64 %add, i64* @a - br label %if.end - -if.end: ; preds = %entry, %if.then - tail call void @test3_c(i32 %i) - tail call void @test3_b() - %t6 = load i64, i64* @a - %add79 = add nsw i64 %t6, 3 - store i64 %add79, i64* @a - ret void -} - -; Function Attrs: noinline -define void @test3_b() #0 { -entry: - tail call void @test3_a() - %t0 = load i64, i64* @a - %add = add nsw i64 %t0, 2 - store i64 %add, i64* @a - ret void -} - ; Check test3_c is inlined into test3_a once and only once. ; CHECK-LABEL: @test3_a( ; CHECK: tail call void @test3_b() @@ -229,4 +176,57 @@ entry: ret void } +; Function Attrs: noinline +define void @test3_b() #0 { +entry: + tail call void @test3_a() + %t0 = load i64, i64* @a + %add = add nsw i64 %t0, 2 + store i64 %add, i64* @a + ret void +} + +define void @test3_d(i32 %i) { +entry: + %cmp = icmp eq i32 %i, 5 + br i1 %cmp, label %if.end, label %if.then + +if.then: ; preds = %entry + %call = tail call i64 @random() + %t0 = load i64, i64* @a + %add = add nsw i64 %t0, %call + store i64 %add, i64* @a + br label %if.end + +if.end: ; preds = %entry, %if.then + tail call void @test3_c(i32 %i) + tail call void @test3_b() + %t6 = load i64, i64* @a + %add79 = add nsw i64 %t6, 3 + store i64 %add79, i64* @a + ret void +} + +define void @test3_c(i32 %i) { +entry: + %cmp = icmp eq i32 %i, 5 + br i1 %cmp, label %if.end, label %if.then + +if.then: ; preds = %entry + %call = tail call i64 @random() + %t0 = load i64, i64* @a + %add = add nsw i64 %t0, %call + store i64 %add, i64* @a + br label %if.end + +if.end: ; preds = %entry, %if.then + tail call void @test3_d(i32 %i) + %t6 = load i64, i64* @a + %add85 = add nsw i64 %t6, 1 + store i64 %add85, i64* @a + ret void +} + +declare i64 @random() + attributes #0 = { noinline } diff --git a/test/Transforms/Inline/cgscc-incremental-invalidate.ll b/test/Transforms/Inline/cgscc-incremental-invalidate.ll index 311de67ad50..448c213ba9d 100644 --- a/test/Transforms/Inline/cgscc-incremental-invalidate.ll +++ b/test/Transforms/Inline/cgscc-incremental-invalidate.ll @@ -64,14 +64,14 @@ return: ; reducing an SCC in the inliner cannot accidentially leave stale function ; analysis results due to failing to invalidate them for all the functions. -; The inliner visits this last function. It can't actually break any cycles -; here, but because we visit this function we compute fresh analyses for it. -; These analyses are then invalidated when we inline callee disrupting the -; CFG, and it is important that they be freed. -define void @test1_h() { -; CHECK-LABEL: define void @test1_h() +; We visit this function first in the inliner, and while we inline callee +; perturbing the CFG, we don't inline anything else and the SCC structure +; remains in tact. +define void @test1_f() { +; CHECK-LABEL: define void @test1_f() entry: - call void @test1_g() + ; We force this edge to survive inlining. + call void @test1_g() noinline ; CHECK: call void @test1_g() ; Pull interesting CFG into this function. @@ -105,14 +105,14 @@ entry: ; CHECK: ret void } -; We visit this function first in the inliner, and while we inline callee -; perturbing the CFG, we don't inline anything else and the SCC structure -; remains in tact. -define void @test1_f() { -; CHECK-LABEL: define void @test1_f() +; The inliner visits this last function. It can't actually break any cycles +; here, but because we visit this function we compute fresh analyses for it. +; These analyses are then invalidated when we inline callee disrupting the +; CFG, and it is important that they be freed. +define void @test1_h() { +; CHECK-LABEL: define void @test1_h() entry: - ; We force this edge to survive inlining. - call void @test1_g() noinline + call void @test1_g() ; CHECK: call void @test1_g() ; Pull interesting CFG into this function. diff --git a/test/Transforms/Inline/cgscc-invalidate.ll b/test/Transforms/Inline/cgscc-invalidate.ll index 69d84f65e25..725a28e2b16 100644 --- a/test/Transforms/Inline/cgscc-invalidate.ll +++ b/test/Transforms/Inline/cgscc-invalidate.ll @@ -65,6 +65,25 @@ entry: ; The 'test3_' prefixed functions test the scenario of not inlining preserving ; dominators after splitting an SCC into two smaller SCCs. +; This function gets visited first and we end up inlining everything we +; can into this routine. That splits test3_g into a separate SCC that is enqued +; for later processing. +define void @test3_f() { +; CHECK-LABEL: define void @test3_f() +entry: + ; Create the first edge in the SCC cycle. + call void @test3_g() +; CHECK-NOT: @test3_g() +; CHECK: call void @test3_f() + + ; Pull interesting CFG into this function. + call void @callee() +; CHECK-NOT: call void @callee() + + ret void +; CHECK: ret void +} + ; This function ends up split into a separate SCC, which can cause its analyses ; to become stale if the splitting doesn't properly invalidate things. Also, as ; a consequence of being split out, test3_f is too large to inline by the time @@ -83,22 +102,3 @@ entry: ret void ; CHECK: ret void } - -; The second function gets visited first and we end up inlining everything we -; can into this routine. That splits test3_g into a separate SCC that is enqued -; for later processing. -define void @test3_f() { -; CHECK-LABEL: define void @test3_f() -entry: - ; Create the first edge in the SCC cycle. - call void @test3_g() -; CHECK-NOT: @test3_g() -; CHECK: call void @test3_f() - - ; Pull interesting CFG into this function. - call void @callee() -; CHECK-NOT: call void @callee() - - ret void -; CHECK: ret void -} diff --git a/test/Transforms/OpenMP/globalization_remarks.ll b/test/Transforms/OpenMP/globalization_remarks.ll index 77d37736b7f..ea0ed82e15a 100644 --- a/test/Transforms/OpenMP/globalization_remarks.ll +++ b/test/Transforms/OpenMP/globalization_remarks.ll @@ -12,8 +12,8 @@ target triple = "nvptx64-nvidia-cuda" @__omp_offloading_801_3022563__Z6maini1v_l17_exec_mode = weak constant i8 0 @llvm.compiler.used = appending global [1 x i8*] [i8* @__omp_offloading_801_3022563__Z6maini1v_l17_exec_mode], section "llvm.metadata" -; CHECK: remark: declare_target_codegen_globalization.cpp:10:1: Found thread data sharing on the GPU. Expect degraded performance due to data globalization. ; CHECK: remark: declare_target_codegen_globalization.cpp:17:1: Found thread data sharing on the GPU. Expect degraded performance due to data globalization. +; CHECK: remark: declare_target_codegen_globalization.cpp:10:1: Found thread data sharing on the GPU. Expect degraded performance due to data globalization. ; Function Attrs: norecurse nounwind define weak void @__omp_offloading_801_3022563__Z6maini1v_l17(i32* nonnull align 4 dereferenceable(4) %a) local_unnamed_addr #0 !dbg !10 { diff --git a/test/Transforms/OpenMP/parallel_region_merging.ll b/test/Transforms/OpenMP/parallel_region_merging.ll index 70862999628..188f21d44b1 100644 --- a/test/Transforms/OpenMP/parallel_region_merging.ll +++ b/test/Transforms/OpenMP/parallel_region_merging.ll @@ -141,7 +141,6 @@ define internal void @merge_some..omp_par(i32* noalias nocapture readnone %0, i3 ; #pragma omp cancel parallel ; } ; } -; ; #pragma omp parallel ; { ; if (cancel2) { @@ -206,7 +205,7 @@ declare i32 @__kmpc_cancel(%struct.ident_t*, i32, i32) local_unnamed_addr ; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* [[GLOB1]]) ; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]] ; CHECK: omp_parallel: -; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* [[GLOB1]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*)* @merge_all..omp_par.3 to void (i32*, i32*, ...)*), i32* [[TMP2]]) +; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* [[GLOB1]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*)* @merge_all..omp_par.2 to void (i32*, i32*, ...)*), i32* [[TMP2]]) ; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]] ; CHECK: omp.par.outlined.exit: ; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]] @@ -216,7 +215,7 @@ declare i32 @__kmpc_cancel(%struct.ident_t*, i32, i32) local_unnamed_addr ; CHECK-NEXT: ret void ; ; -; CHECK-LABEL: define {{[^@]+}}@merge_all..omp_par.3 +; CHECK-LABEL: define {{[^@]+}}@merge_all..omp_par.2 ; CHECK-SAME: (i32* noalias [[TID_ADDR:%.*]], i32* noalias [[ZERO_ADDR:%.*]], i32* [[TMP0:%.*]]) [[ATTR0:#.*]] { ; CHECK-NEXT: omp.par.entry: ; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4 @@ -285,7 +284,7 @@ declare i32 @__kmpc_cancel(%struct.ident_t*, i32, i32) local_unnamed_addr ; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* [[GLOB1]]) ; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]] ; CHECK: omp_parallel: -; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* [[GLOB1]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*)* @merge_some..omp_par.2 to void (i32*, i32*, ...)*), i32* [[TMP2]]) +; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* [[GLOB1]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*)* @merge_some..omp_par.5 to void (i32*, i32*, ...)*), i32* [[TMP2]]) ; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]] ; CHECK: omp.par.outlined.exit: ; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]] @@ -295,7 +294,7 @@ declare i32 @__kmpc_cancel(%struct.ident_t*, i32, i32) local_unnamed_addr ; CHECK-NEXT: ret void ; ; -; CHECK-LABEL: define {{[^@]+}}@merge_some..omp_par.2 +; CHECK-LABEL: define {{[^@]+}}@merge_some..omp_par.5 ; CHECK-SAME: (i32* noalias [[TID_ADDR:%.*]], i32* noalias [[ZERO_ADDR:%.*]], i32* [[TMP0:%.*]]) [[ATTR0]] { ; CHECK-NEXT: omp.par.entry: ; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4 @@ -349,7 +348,7 @@ declare i32 @__kmpc_cancel(%struct.ident_t*, i32, i32) local_unnamed_addr ; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* [[GLOB1]]) ; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]] ; CHECK: omp_parallel: -; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* [[GLOB1]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i32*)* @merge_cancellable_regions..omp_par.1 to void (i32*, i32*, ...)*), i32* [[TMP4]], i32* [[TMP5]]) +; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* [[GLOB1]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i32*)* @merge_cancellable_regions..omp_par.6 to void (i32*, i32*, ...)*), i32* [[TMP4]], i32* [[TMP5]]) ; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]] ; CHECK: omp.par.outlined.exit: ; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]] @@ -359,7 +358,7 @@ declare i32 @__kmpc_cancel(%struct.ident_t*, i32, i32) local_unnamed_addr ; CHECK-NEXT: ret void ; ; -; CHECK-LABEL: define {{[^@]+}}@merge_cancellable_regions..omp_par.1 +; CHECK-LABEL: define {{[^@]+}}@merge_cancellable_regions..omp_par.6 ; CHECK-SAME: (i32* noalias [[TID_ADDR:%.*]], i32* noalias [[ZERO_ADDR:%.*]], i32* [[TMP0:%.*]], i32* [[TMP1:%.*]]) [[ATTR0]] { ; CHECK-NEXT: omp.par.entry: ; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4 diff --git a/unittests/Analysis/CGSCCPassManagerTest.cpp b/unittests/Analysis/CGSCCPassManagerTest.cpp index 1b42ba270bc..9193a2d83ef 100644 --- a/unittests/Analysis/CGSCCPassManagerTest.cpp +++ b/unittests/Analysis/CGSCCPassManagerTest.cpp @@ -219,36 +219,36 @@ public: // |/ // x // - "define void @f() {\n" + "define void @x() {\n" + "entry:\n" + " ret void\n" + "}\n" + "define void @h3() {\n" "entry:\n" - " call void @g()\n" " call void @h1()\n" " ret void\n" "}\n" - "define void @g() {\n" - "entry:\n" - " call void @g()\n" - " call void @x()\n" - " ret void\n" - "}\n" - "define void @h1() {\n" - "entry:\n" - " call void @h2()\n" - " ret void\n" - "}\n" "define void @h2() {\n" "entry:\n" " call void @h3()\n" " call void @x()\n" " ret void\n" "}\n" - "define void @h3() {\n" + "define void @h1() {\n" "entry:\n" - " call void @h1()\n" + " call void @h2()\n" " ret void\n" "}\n" - "define void @x() {\n" + "define void @g() {\n" "entry:\n" + " call void @g()\n" + " call void @x()\n" + " ret void\n" + "}\n" + "define void @f() {\n" + "entry:\n" + " call void @g()\n" + " call void @h1()\n" " ret void\n" "}\n")) { FAM.registerPass([&] { return TargetLibraryAnalysis(); }); diff --git a/unittests/Analysis/LazyCallGraphTest.cpp b/unittests/Analysis/LazyCallGraphTest.cpp index 04c48c08544..c2c1cd2e28a 100644 --- a/unittests/Analysis/LazyCallGraphTest.cpp +++ b/unittests/Analysis/LazyCallGraphTest.cpp @@ -337,22 +337,6 @@ TEST(LazyCallGraphTest, BasicGraphFormation) { EXPECT_FALSE(D.isDescendantOf(D)); EXPECT_EQ(&D, &*CG.postorder_ref_scc_begin()); - LazyCallGraph::RefSCC &C = *J++; - ASSERT_EQ(1, C.size()); - for (LazyCallGraph::Node &N : *C.begin()) - Nodes.push_back(std::string(N.getFunction().getName())); - llvm::sort(Nodes); - EXPECT_EQ(3u, Nodes.size()); - EXPECT_EQ("c1", Nodes[0]); - EXPECT_EQ("c2", Nodes[1]); - EXPECT_EQ("c3", Nodes[2]); - Nodes.clear(); - EXPECT_TRUE(C.isParentOf(D)); - EXPECT_FALSE(C.isChildOf(D)); - EXPECT_TRUE(C.isAncestorOf(D)); - EXPECT_FALSE(C.isDescendantOf(D)); - EXPECT_EQ(&C, &*std::next(CG.postorder_ref_scc_begin())); - LazyCallGraph::RefSCC &B = *J++; ASSERT_EQ(1, B.size()); for (LazyCallGraph::Node &N : *B.begin()) @@ -367,9 +351,25 @@ TEST(LazyCallGraphTest, BasicGraphFormation) { EXPECT_FALSE(B.isChildOf(D)); EXPECT_TRUE(B.isAncestorOf(D)); EXPECT_FALSE(B.isDescendantOf(D)); + EXPECT_EQ(&B, &*std::next(CG.postorder_ref_scc_begin())); + + LazyCallGraph::RefSCC &C = *J++; + ASSERT_EQ(1, C.size()); + for (LazyCallGraph::Node &N : *C.begin()) + Nodes.push_back(std::string(N.getFunction().getName())); + llvm::sort(Nodes); + EXPECT_EQ(3u, Nodes.size()); + EXPECT_EQ("c1", Nodes[0]); + EXPECT_EQ("c2", Nodes[1]); + EXPECT_EQ("c3", Nodes[2]); + Nodes.clear(); EXPECT_FALSE(B.isAncestorOf(C)); EXPECT_FALSE(C.isAncestorOf(B)); - EXPECT_EQ(&B, &*std::next(CG.postorder_ref_scc_begin(), 2)); + EXPECT_TRUE(C.isParentOf(D)); + EXPECT_FALSE(C.isChildOf(D)); + EXPECT_TRUE(C.isAncestorOf(D)); + EXPECT_FALSE(C.isDescendantOf(D)); + EXPECT_EQ(&C, &*std::next(CG.postorder_ref_scc_begin(), 2)); LazyCallGraph::RefSCC &A = *J++; ASSERT_EQ(1, A.size()); @@ -1206,10 +1206,10 @@ TEST(LazyCallGraphTest, InlineAndDeleteFunction) { ASSERT_NE(I, E); EXPECT_EQ(&NewDRC, &*I) << "Actual RefSCC: " << *I; ASSERT_NE(++I, E); - EXPECT_EQ(&CRC, &*I) << "Actual RefSCC: " << *I; - ASSERT_NE(++I, E); EXPECT_EQ(&BRC, &*I) << "Actual RefSCC: " << *I; ASSERT_NE(++I, E); + EXPECT_EQ(&CRC, &*I) << "Actual RefSCC: " << *I; + ASSERT_NE(++I, E); EXPECT_EQ(&ARC, &*I) << "Actual RefSCC: " << *I; EXPECT_EQ(++I, E); } @@ -1997,8 +1997,8 @@ TEST(LazyCallGraphTest, HandleBlockAddress2) { CG.buildRefSCCs(); auto I = CG.postorder_ref_scc_begin(); - LazyCallGraph::RefSCC &GRC = *I++; LazyCallGraph::RefSCC &FRC = *I++; + LazyCallGraph::RefSCC &GRC = *I++; EXPECT_EQ(CG.postorder_ref_scc_end(), I); LazyCallGraph::Node &F = *CG.lookup(lookupFunction(*M, "f"));