[llvm] 491dd27 - [LazyCallGraph] Build SCCs of the reference graph in order

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 2 13:22:50 PST 2020


Author: Fangrui Song
Date: 2020-11-02T13:22:42-08:00
New Revision: 491dd2711f7234e21983da355c32107ee1f6a750

URL: https://github.com/llvm/llvm-project/commit/491dd2711f7234e21983da355c32107ee1f6a750
DIFF: https://github.com/llvm/llvm-project/commit/491dd2711f7234e21983da355c32107ee1f6a750.diff

LOG: [LazyCallGraph] Build SCCs of the reference graph in order

```
// The legacy PM CGPassManager discovers SCCs this way:
for function in the source order
  tarjanSCC(function)

// While the new PM CGSCCPassManager does:
for function in the reversed source order [1]
  discover a reference graph SCC
  build call graph SCCs inside the reference graph SCC
```

In the common cases, reference graph ~= call graph, the new PM order is
undesired because for `a | b | c` (3 independent functions), the new PM will
process them in the reversed order: c, b, a. If `a <-> b <-> c`, we can see
that `-print-after-all` will report the sole SCC as `scc: (c, b, a)`.

This patch corrects the iteration order. The discovered SCC order will match
the legacy PM in the common cases.

For some tests (`Transforms/Inline/cgscc-*.ll` and
`unittests/Analysis/CGSCCPassManagerTest.cpp`), the behaviors are dependent on
the SCC discovery order and there are too many check lines for the particular
order.  This patch simply reverses the function order to avoid changing too many
check lines.

Differential Revision: https://reviews.llvm.org/D90566

Added: 
    

Modified: 
    llvm/lib/Analysis/LazyCallGraph.cpp
    llvm/test/Analysis/LazyCallGraph/alias.ll
    llvm/test/Analysis/LazyCallGraph/basic.ll
    llvm/test/Other/scc-pass-printer.ll
    llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll
    llvm/test/Transforms/Inline/cgscc-cycle-debug.ll
    llvm/test/Transforms/Inline/cgscc-cycle.ll
    llvm/test/Transforms/Inline/cgscc-incremental-invalidate.ll
    llvm/test/Transforms/Inline/cgscc-invalidate.ll
    llvm/test/Transforms/OpenMP/globalization_remarks.ll
    llvm/test/Transforms/OpenMP/parallel_region_merging.ll
    llvm/unittests/Analysis/CGSCCPassManagerTest.cpp
    llvm/unittests/Analysis/LazyCallGraphTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/LazyCallGraph.cpp b/llvm/lib/Analysis/LazyCallGraph.cpp
index e00ceffc8f12..26529891bc03 100644
--- a/llvm/lib/Analysis/LazyCallGraph.cpp
+++ b/llvm/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/llvm/test/Analysis/LazyCallGraph/alias.ll b/llvm/test/Analysis/LazyCallGraph/alias.ll
index 7c9ca5182f91..054c4d991a2d 100644
--- a/llvm/test/Analysis/LazyCallGraph/alias.ll
+++ b/llvm/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/llvm/test/Analysis/LazyCallGraph/basic.ll b/llvm/test/Analysis/LazyCallGraph/basic.ll
index 0d05a7a6514e..eaaecc53801c 100644
--- a/llvm/test/Analysis/LazyCallGraph/basic.ll
+++ b/llvm/test/Analysis/LazyCallGraph/basic.ll
@@ -256,39 +256,20 @@ entry:
 ; Verify the SCCs formed.
 ;
 ; CHECK-LABEL: RefSCC with 1 call SCCs:
-; CHECK-NEXT:    SCC with 3 functions:
-; 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:
-; CHECK-NEXT:      test3_bb1
 ; CHECK-NEXT:    SCC with 1 functions:
-; CHECK-NEXT:      test3_ba1
-;
-; CHECK-LABEL: RefSCC with 3 call SCCs:
-; CHECK-NEXT:    SCC with 2 functions:
-; CHECK-NEXT:      test3_ac2
-; CHECK-NEXT:      test3_ac1
-; 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-NEXT:      f
 ;
 ; CHECK-LABEL: RefSCC with 1 call SCCs:
 ; CHECK-NEXT:    SCC with 1 functions:
-; CHECK-NEXT:      f7
+; CHECK-NEXT:      f1
 ;
 ; CHECK-LABEL: RefSCC with 1 call SCCs:
 ; CHECK-NEXT:    SCC with 1 functions:
-; CHECK-NEXT:      f6
+; CHECK-NEXT:      f2
 ;
 ; CHECK-LABEL: RefSCC with 1 call SCCs:
 ; CHECK-NEXT:    SCC with 1 functions:
-; CHECK-NEXT:      f5
+; CHECK-NEXT:      f3
 ;
 ; CHECK-LABEL: RefSCC with 1 call SCCs:
 ; CHECK-NEXT:    SCC with 1 functions:
@@ -296,27 +277,27 @@ entry:
 ;
 ; CHECK-LABEL: RefSCC with 1 call SCCs:
 ; CHECK-NEXT:    SCC with 1 functions:
-; CHECK-NEXT:      f3
+; CHECK-NEXT:      f5
 ;
 ; CHECK-LABEL: RefSCC with 1 call SCCs:
 ; CHECK-NEXT:    SCC with 1 functions:
-; CHECK-NEXT:      f2
+; CHECK-NEXT:      f6
 ;
 ; CHECK-LABEL: RefSCC with 1 call SCCs:
 ; CHECK-NEXT:    SCC with 1 functions:
-; CHECK-NEXT:      f1
+; CHECK-NEXT:      f7
 ;
 ; CHECK-LABEL: RefSCC with 1 call SCCs:
 ; CHECK-NEXT:    SCC with 1 functions:
-; CHECK-NEXT:      test2
+; CHECK-NEXT:      f8
 ;
 ; CHECK-LABEL: RefSCC with 1 call SCCs:
 ; CHECK-NEXT:    SCC with 1 functions:
-; CHECK-NEXT:      f10
+; CHECK-NEXT:      f9
 ;
 ; CHECK-LABEL: RefSCC with 1 call SCCs:
 ; CHECK-NEXT:    SCC with 1 functions:
-; CHECK-NEXT:      f12
+; CHECK-NEXT:      f10
 ;
 ; CHECK-LABEL: RefSCC with 1 call SCCs:
 ; CHECK-NEXT:    SCC with 1 functions:
@@ -324,11 +305,11 @@ entry:
 ;
 ; CHECK-LABEL: RefSCC with 1 call SCCs:
 ; CHECK-NEXT:    SCC with 1 functions:
-; CHECK-NEXT:      f9
+; CHECK-NEXT:      f12
 ;
 ; CHECK-LABEL: RefSCC with 1 call SCCs:
 ; CHECK-NEXT:    SCC with 1 functions:
-; CHECK-NEXT:      f8
+; CHECK-NEXT:      test0
 ;
 ; CHECK-LABEL: RefSCC with 1 call SCCs:
 ; CHECK-NEXT:    SCC with 1 functions:
@@ -336,8 +317,27 @@ entry:
 ;
 ; CHECK-LABEL: RefSCC with 1 call SCCs:
 ; CHECK-NEXT:    SCC with 1 functions:
-; CHECK-NEXT:      f
+; 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-LABEL: RefSCC with 2 call SCCs:
 ; CHECK-NEXT:    SCC with 1 functions:
-; CHECK-NEXT:      test0
+; CHECK-NEXT:      test3_bb1
+; CHECK-NEXT:    SCC with 1 functions:
+; CHECK-NEXT:      test3_ba1
+;
+; CHECK-LABEL: RefSCC with 3 call SCCs:
+; CHECK-NEXT:    SCC with 2 functions:
+; 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_aa1
+; CHECK-NEXT:      test3_aa2

diff  --git a/llvm/test/Other/scc-pass-printer.ll b/llvm/test/Other/scc-pass-printer.ll
index 9f0625d57218..9d6016ba4e8f 100644
--- a/llvm/test/Other/scc-pass-printer.ll
+++ b/llvm/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()
+; 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:      IR Dump After InlinerPass *** (scc: (foo, bar))
+; 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
+; 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: IR Dump After {{Function Integration/Inlining|InlinerPass .*scc: .bar, foo}}
+; 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/llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll b/llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll
index ed4e49958ed5..f068180fb575 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll
+++ b/llvm/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/llvm/test/Transforms/Inline/cgscc-cycle-debug.ll b/llvm/test/Transforms/Inline/cgscc-cycle-debug.ll
index 435d540208bc..21a5ae524754 100644
--- a/llvm/test/Transforms/Inline/cgscc-cycle-debug.ll
+++ b/llvm/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/llvm/test/Transforms/Inline/cgscc-cycle.ll b/llvm/test/Transforms/Inline/cgscc-cycle.ll
index bc3bdc99fff2..fafa945e9f49 100644
--- a/llvm/test/Transforms/Inline/cgscc-cycle.ll
+++ b/llvm/test/Transforms/Inline/cgscc-cycle.ll
@@ -153,28 +153,39 @@ bb2:
 @a = global i64 0
 @b = global i64 0
 
-define void @test3_c(i32 %i) {
+; Check test3_c is inlined into test3_a once and only once.
+; CHECK-LABEL: @test3_a(
+; CHECK: tail call void @test3_b()
+; CHECK-NEXT: tail call void @test3_d(i32 5)
+; CHECK-NEXT: %[[LD1:.*]] = load i64, i64* @a
+; CHECK-NEXT: %[[ADD1:.*]] = add nsw i64 %[[LD1]], 1
+; CHECK-NEXT: store i64 %[[ADD1]], i64* @a
+; CHECK-NEXT: %[[LD2:.*]] = load i64, i64* @b
+; CHECK-NEXT: %[[ADD2:.*]] = add nsw i64 %[[LD2]], 5
+; CHECK-NEXT: store i64 %[[ADD2]], i64* @b
+; CHECK-NEXT: ret void
+
+; Function Attrs: noinline
+define void @test3_a() #0 {
 entry:
-  %cmp = icmp eq i32 %i, 5
-  br i1 %cmp, label %if.end, label %if.then
+  tail call void @test3_b()
+  tail call void @test3_c(i32 5)
+  %t0 = load i64, i64* @b
+  %add = add nsw i64 %t0, 5
+  store i64 %add, i64* @b
+  ret void
+}
 
-if.then:                                          ; preds = %entry
-  %call = tail call i64 @random()
+; Function Attrs: noinline
+define void @test3_b() #0 {
+entry:
+  tail call void @test3_a()
   %t0 = load i64, i64* @a
-  %add = add nsw i64 %t0, %call
+  %add = add nsw i64 %t0, 2
   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
@@ -196,37 +207,26 @@ if.end:                                           ; preds = %entry, %if.then
   ret void
 }
 
-; Function Attrs: noinline
-define void @test3_b() #0 {
+define void @test3_c(i32 %i) {
 entry:
-  tail call void @test3_a()
+  %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, 2
+  %add = add nsw i64 %t0, %call
   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()
-; CHECK-NEXT: tail call void @test3_d(i32 5)
-; CHECK-NEXT: %[[LD1:.*]] = load i64, i64* @a
-; CHECK-NEXT: %[[ADD1:.*]] = add nsw i64 %[[LD1]], 1
-; CHECK-NEXT: store i64 %[[ADD1]], i64* @a
-; CHECK-NEXT: %[[LD2:.*]] = load i64, i64* @b
-; CHECK-NEXT: %[[ADD2:.*]] = add nsw i64 %[[LD2]], 5
-; CHECK-NEXT: store i64 %[[ADD2]], i64* @b
-; CHECK-NEXT: ret void
+  br label %if.end
 
-; Function Attrs: noinline
-define void @test3_a() #0 {
-entry:
-  tail call void @test3_b()
-  tail call void @test3_c(i32 5)
-  %t0 = load i64, i64* @b
-  %add = add nsw i64 %t0, 5
-  store i64 %add, i64* @b
+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/llvm/test/Transforms/Inline/cgscc-incremental-invalidate.ll b/llvm/test/Transforms/Inline/cgscc-incremental-invalidate.ll
index 311de67ad507..448c213ba9d2 100644
--- a/llvm/test/Transforms/Inline/cgscc-incremental-invalidate.ll
+++ b/llvm/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/llvm/test/Transforms/Inline/cgscc-invalidate.ll b/llvm/test/Transforms/Inline/cgscc-invalidate.ll
index 69d84f65e251..725a28e2b163 100644
--- a/llvm/test/Transforms/Inline/cgscc-invalidate.ll
+++ b/llvm/test/Transforms/Inline/cgscc-invalidate.ll
@@ -65,15 +65,15 @@ entry:
 ; The 'test3_' prefixed functions test the scenario of not inlining preserving
 ; dominators after splitting an SCC into two smaller SCCs.
 
-; 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
-; we get here.
-define void @test3_g() {
-; CHECK-LABEL: define void @test3_g()
+; 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 second edge in the SCC cycle.
-  call void @test3_f()
+  ; 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.
@@ -84,15 +84,15 @@ entry:
 ; 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()
+; 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
+; we get here.
+define void @test3_g() {
+; CHECK-LABEL: define void @test3_g()
 entry:
-  ; Create the first edge in the SCC cycle.
-  call void @test3_g()
-; CHECK-NOT: @test3_g()
+  ; Create the second edge in the SCC cycle.
+  call void @test3_f()
 ; CHECK: call void @test3_f()
 
   ; Pull interesting CFG into this function.

diff  --git a/llvm/test/Transforms/OpenMP/globalization_remarks.ll b/llvm/test/Transforms/OpenMP/globalization_remarks.ll
index 77d37736b7f1..ea0ed82e15ae 100644
--- a/llvm/test/Transforms/OpenMP/globalization_remarks.ll
+++ b/llvm/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/llvm/test/Transforms/OpenMP/parallel_region_merging.ll b/llvm/test/Transforms/OpenMP/parallel_region_merging.ll
index 708629996285..188f21d44b1d 100644
--- a/llvm/test/Transforms/OpenMP/parallel_region_merging.ll
+++ b/llvm/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/llvm/unittests/Analysis/CGSCCPassManagerTest.cpp b/llvm/unittests/Analysis/CGSCCPassManagerTest.cpp
index 1b42ba270bc0..9193a2d83ef6 100644
--- a/llvm/unittests/Analysis/CGSCCPassManagerTest.cpp
+++ b/llvm/unittests/Analysis/CGSCCPassManagerTest.cpp
@@ -219,15 +219,18 @@ class CGSCCPassManagerTest : public ::testing::Test {
             // |/
             // 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"
+            "define void @h2() {\n"
             "entry:\n"
-            "  call void @g()\n"
+            "  call void @h3()\n"
             "  call void @x()\n"
             "  ret void\n"
             "}\n"
@@ -236,20 +239,17 @@ class CGSCCPassManagerTest : public ::testing::Test {
             "  call void @h2()\n"
             "  ret void\n"
             "}\n"
-            "define void @h2() {\n"
+            "define void @g() {\n"
             "entry:\n"
-            "  call void @h3()\n"
+            "  call void @g()\n"
             "  call void @x()\n"
             "  ret void\n"
             "}\n"
-            "define void @h3() {\n"
+            "define void @f() {\n"
             "entry:\n"
+            "  call void @g()\n"
             "  call void @h1()\n"
             "  ret void\n"
-            "}\n"
-            "define void @x() {\n"
-            "entry:\n"
-            "  ret void\n"
             "}\n")) {
     FAM.registerPass([&] { return TargetLibraryAnalysis(); });
     MAM.registerPass([&] { return LazyCallGraphAnalysis(); });

diff  --git a/llvm/unittests/Analysis/LazyCallGraphTest.cpp b/llvm/unittests/Analysis/LazyCallGraphTest.cpp
index 04c48c085443..c2c1cd2e28aa 100644
--- a/llvm/unittests/Analysis/LazyCallGraphTest.cpp
+++ b/llvm/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"));


        


More information about the llvm-commits mailing list