llvm.org GIT mirror llvm / 3560346
[IPSCCP] Run Solve each time we resolved an undef in a function. Once we resolved an undef in a function we can run Solve, which could lead to finding a constant return value for the function, which in turn could turn undefs into constants in other functions that call it, before resolving undefs there. Computationally the amount of work we are doing stays the same, just the order we process things is slightly different and potentially there are a few less undefs to resolve. We are still relying on the order of functions in the IR, which means depending on the order, we are able to resolve the optimal undef first or not. For example, if @test1 comes before @testf, we find the constant return value of @testf too late and we cannot use it while solving @test1. This on its own does not lead to more constants removed in the test-suite, probably because currently we have to be very lucky to visit applicable functions in the right order. Maybe we manage to come up with a better way of resolving undefs in more 'profitable' functions first. Reviewers: efriedma, mssimpso, davide Reviewed By: efriedma, davide Differential Revision: https://reviews.llvm.org/D49385 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@337283 91177308-0d34-0410-b5e6-96231b3b80d8 Florian Hahn 1 year, 2 months ago
3 changed file(s) with 55 addition(s) and 7 deletion(s). Raw diff Collapse all Expand all
19011901
19021902 // Solve for constants.
19031903 bool ResolvedUndefs = true;
1904 Solver.Solve();
19041905 while (ResolvedUndefs) {
1905 Solver.Solve();
1906
19071906 LLVM_DEBUG(dbgs() << "RESOLVING UNDEFS\n");
19081907 ResolvedUndefs = false;
19091908 for (Function &F : M)
1910 ResolvedUndefs |= Solver.ResolvedUndefsIn(F);
1909 if (Solver.ResolvedUndefsIn(F)) {
1910 // We run Solve() after we resolved an undef in a function, because
1911 // we might deduce a fact that eliminates an undef in another function.
1912 Solver.Solve();
1913 ResolvedUndefs = true;
1914 }
19111915 }
19121916
19131917 bool MadeChanges = false;
0 ; RUN: opt < %s -ipsccp -S | FileCheck %s
1
2 ; CHECK-LABEL: @testf(
3 ; CHECK: ret i32 undef
4 ;
5 define internal i32 @testf() {
6 entry:
7 br i1 undef, label %if.then, label %if.end
8
9 if.then: ; preds = %entry, %if.then
10 br label %if.end
11
12 if.end: ; preds = %if.then1, %entry
13 ret i32 10
14 }
15
16 ; CHECK-LABEL: @test1(
17 ; CHECK: ret i32 undef
18 ;
19 define internal i32 @test1() {
20 entry:
21 br label %if.then
22
23 if.then: ; preds = %entry, %if.then
24 %call = call i32 @testf()
25 %res = icmp eq i32 %call, 10
26 br i1 %res, label %ret1, label %ret2
27
28 ret1: ; preds = %if.then, %entry
29 ret i32 99
30
31 ret2: ; preds = %if.then, %entry
32 ret i32 0
33 }
34
35 ; CHECK-LABEL: @main(
36 ; CHECK-NEXT: %res = call i32 @test1()
37 ; CHECK-NEXT: ret i32 99
38 ;
39 define i32 @main() {
40 %res = call i32 @test1()
41 ret i32 %res
42 }
246246 ; CHECK: ret i64 0
247247 }
248248
249 define void @test11b() {
249 define i64 @test11b() {
250250 %call1 = call i64 @test11a()
251251 %call2 = call i64 @llvm.ctpop.i64(i64 %call1)
252 ret void
253 ; CHECK-LABEL: define void @test11b
252 ret i64 %call2
253 ; CHECK-LABEL: define i64 @test11b
254254 ; CHECK: %[[call1:.*]] = call i64 @test11a()
255 ; CHECK: %[[call2:.*]] = call i64 @llvm.ctpop.i64(i64 0)
255 ; CHECK-NOT: call i64 @llvm.ctpop.i64
256 ; CHECK-NEXT: ret i64 0
256257 }
257258
258259 declare i64 @llvm.ctpop.i64(i64)