diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:46:15 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:46:15 +0000 |
| commit | dd58ef019b700900793a1eb48b52123db01b654e (patch) | |
| tree | fcfbb4df56a744f4ddc6122c50521dd3f1c5e196 /test/Transforms/SampleProfile | |
| parent | 2fe5752e3a7c345cdb59e869278d36af33c13fa4 (diff) | |
Notes
Diffstat (limited to 'test/Transforms/SampleProfile')
38 files changed, 1339 insertions, 203 deletions
diff --git a/test/Transforms/SampleProfile/Inputs/bad_discriminator_value.prof b/test/Transforms/SampleProfile/Inputs/bad_discriminator_value.prof index cc7f0d4f2773..30e26cc81841 100644 --- a/test/Transforms/SampleProfile/Inputs/bad_discriminator_value.prof +++ b/test/Transforms/SampleProfile/Inputs/bad_discriminator_value.prof @@ -1,2 +1,2 @@ empty:100:0 -1.-3: 10 + 1.-3: 10 diff --git a/test/Transforms/SampleProfile/Inputs/bad_fn_header.prof b/test/Transforms/SampleProfile/Inputs/bad_fn_header.prof index abcb0ba38415..62227746655e 100644 --- a/test/Transforms/SampleProfile/Inputs/bad_fn_header.prof +++ b/test/Transforms/SampleProfile/Inputs/bad_fn_header.prof @@ -1,3 +1,3 @@ 3empty:100:BAD -0: 0 -1: 100 + 0: 0 + 1: 100 diff --git a/test/Transforms/SampleProfile/Inputs/bad_mangle.prof b/test/Transforms/SampleProfile/Inputs/bad_mangle.prof index 50fe86119b71..33b4c42cab44 100644 --- a/test/Transforms/SampleProfile/Inputs/bad_mangle.prof +++ b/test/Transforms/SampleProfile/Inputs/bad_mangle.prof @@ -1,3 +1,3 @@ double convert<std::string, float>(float):2909472:181842 -0: 181842 -1: 181842 + 0: 181842 + 1: 181842 diff --git a/test/Transforms/SampleProfile/Inputs/bad_sample_line.prof b/test/Transforms/SampleProfile/Inputs/bad_sample_line.prof index 038c45f77e30..608affa3ff94 100644 --- a/test/Transforms/SampleProfile/Inputs/bad_sample_line.prof +++ b/test/Transforms/SampleProfile/Inputs/bad_sample_line.prof @@ -1,3 +1,3 @@ empty:100:0 -0: 0 -1: BAD + 0: 0 + 1: BAD diff --git a/test/Transforms/SampleProfile/Inputs/bad_samples.prof b/test/Transforms/SampleProfile/Inputs/bad_samples.prof index a121d8c1ac40..bce7db9708d2 100644 --- a/test/Transforms/SampleProfile/Inputs/bad_samples.prof +++ b/test/Transforms/SampleProfile/Inputs/bad_samples.prof @@ -1,2 +1,2 @@ empty:100:0 -1.3: -10 + 1.3: -10 diff --git a/test/Transforms/SampleProfile/Inputs/branch.prof b/test/Transforms/SampleProfile/Inputs/branch.prof index cd1cb5b1f16b..ac958e325c40 100644 --- a/test/Transforms/SampleProfile/Inputs/branch.prof +++ b/test/Transforms/SampleProfile/Inputs/branch.prof @@ -1,8 +1,10 @@ main:15680:0 -0: 0 -4: 0 -7: 0 -9: 10226 -10: 2243 -16: 0 -18: 0 + 1: 2500 + 4: 1000 + 5: 1000 + 6: 800 + 7: 500 + 9: 10226 + 10: 2243 + 16: 0 + 18: 0 diff --git a/test/Transforms/SampleProfile/Inputs/calls.prof b/test/Transforms/SampleProfile/Inputs/calls.prof index 57d3887dfb65..be64a1ead428 100644 --- a/test/Transforms/SampleProfile/Inputs/calls.prof +++ b/test/Transforms/SampleProfile/Inputs/calls.prof @@ -1,10 +1,10 @@ _Z3sumii:105580:5279 -0: 5279 -1: 5279 -2: 5279 + 0: 5279 + 1: 5279 + 2: 5279 main:225715:0 -2.1: 5553 -3: 5391 -# This indicates that at line 3 of this function, the 'then' branch -# of the conditional is taken (discriminator '1'). -3.1: 5752 _Z3sumii:5860 + 2.1: 5553 + 3: 5391 + # This indicates that at line 3 of this function, the 'then' branch + # of the conditional is taken (discriminator '1'). + 3.1: 5752 _Z3sumii:5860 diff --git a/test/Transforms/SampleProfile/Inputs/cov-zero-samples.prof b/test/Transforms/SampleProfile/Inputs/cov-zero-samples.prof new file mode 100644 index 000000000000..528e42ca3880 --- /dev/null +++ b/test/Transforms/SampleProfile/Inputs/cov-zero-samples.prof @@ -0,0 +1,10 @@ +main:20111403:0 + 2.1: 404065 + 3: 443089 + 3.1: 0 + 4: 404066 + 6: 0 + 7: 0 + 3.1: _Z12never_calledi:0 + 0: 0 + 1: 0 diff --git a/test/Transforms/SampleProfile/Inputs/coverage-warning.prof b/test/Transforms/SampleProfile/Inputs/coverage-warning.prof new file mode 100644 index 000000000000..57989b837a0f --- /dev/null +++ b/test/Transforms/SampleProfile/Inputs/coverage-warning.prof @@ -0,0 +1,5 @@ +foo:30000:100 + 2: 28000 + 3: 1000 +# This profile is stale. Function foo() does not have a line 8 anymore. + 8: 1700 diff --git a/test/Transforms/SampleProfile/Inputs/discriminator.prof b/test/Transforms/SampleProfile/Inputs/discriminator.prof index a6bcbc511a16..0c2561d725c3 100644 --- a/test/Transforms/SampleProfile/Inputs/discriminator.prof +++ b/test/Transforms/SampleProfile/Inputs/discriminator.prof @@ -1,8 +1,8 @@ foo:1000:0 -1: 1 -2: 1 -2.1: 100 -3: 100 -3.1: 5 -4: 100 -5: 1 + 1: 1 + 2: 1 + 2.1: 100 + 3: 100 + 3.1: 5 + 4: 100 + 5: 1 diff --git a/test/Transforms/SampleProfile/Inputs/entry_counts.prof b/test/Transforms/SampleProfile/Inputs/entry_counts.prof index 5c2172b5a4d3..95addc9f7a11 100644 --- a/test/Transforms/SampleProfile/Inputs/entry_counts.prof +++ b/test/Transforms/SampleProfile/Inputs/entry_counts.prof @@ -1,3 +1,3 @@ empty:100:13293 -0: 0 -1: 100 + 0: 0 + 1: 100 diff --git a/test/Transforms/SampleProfile/Inputs/fnptr.binprof b/test/Transforms/SampleProfile/Inputs/fnptr.binprof Binary files differindex 14d7fd555dae..a074f53db945 100644 --- a/test/Transforms/SampleProfile/Inputs/fnptr.binprof +++ b/test/Transforms/SampleProfile/Inputs/fnptr.binprof diff --git a/test/Transforms/SampleProfile/Inputs/fnptr.prof b/test/Transforms/SampleProfile/Inputs/fnptr.prof index 6a3b4e2315bb..2491c427393b 100644 --- a/test/Transforms/SampleProfile/Inputs/fnptr.prof +++ b/test/Transforms/SampleProfile/Inputs/fnptr.prof @@ -1,12 +1,12 @@ _Z3fooi:7711:610 -1: 610 + 1: 610 _Z3bari:20301:1437 -1: 1437 + 1: 1437 main:184019:0 -4: 534 -6: 2080 -9: 2064 _Z3bari:1471 _Z3fooi:631 -5.1: 1075 -5: 1075 -7: 534 -4.2: 534 + 4: 534 + 6: 2080 + 9: 2064 _Z3bari:1471 _Z3fooi:631 + 5.1: 1075 + 5: 1075 + 7: 534 + 4.2: 534 diff --git a/test/Transforms/SampleProfile/Inputs/gcc-simple.afdo b/test/Transforms/SampleProfile/Inputs/gcc-simple.afdo Binary files differnew file mode 100644 index 000000000000..93f22ce30533 --- /dev/null +++ b/test/Transforms/SampleProfile/Inputs/gcc-simple.afdo diff --git a/test/Transforms/SampleProfile/Inputs/inline-coverage.prof b/test/Transforms/SampleProfile/Inputs/inline-coverage.prof new file mode 100644 index 000000000000..3d792733149a --- /dev/null +++ b/test/Transforms/SampleProfile/Inputs/inline-coverage.prof @@ -0,0 +1,7 @@ +main:501438:0 + 2.1: 23478 + 3: 23478 + 4: 0 + 0: 0 + 3: _Z3fool:172746 + 1: 31878 diff --git a/test/Transforms/SampleProfile/Inputs/inline-hint.prof b/test/Transforms/SampleProfile/Inputs/inline-hint.prof new file mode 100644 index 000000000000..a6840346eb43 --- /dev/null +++ b/test/Transforms/SampleProfile/Inputs/inline-hint.prof @@ -0,0 +1,3 @@ +_Z6hot_fnRxi:700:0 +_Z7cold_fnRxi:1:0 +other:299:0 diff --git a/test/Transforms/SampleProfile/Inputs/inline.prof b/test/Transforms/SampleProfile/Inputs/inline.prof new file mode 100644 index 000000000000..386cdf8a7b5e --- /dev/null +++ b/test/Transforms/SampleProfile/Inputs/inline.prof @@ -0,0 +1,7 @@ +main:225715:0 + 2.1: 5553 + 3: 5391 + 3.1: _Z3sumii:5860 + 0: 5279 + 1: 5279 + 2: 5279 diff --git a/test/Transforms/SampleProfile/Inputs/nolocinfo.prof b/test/Transforms/SampleProfile/Inputs/nolocinfo.prof new file mode 100644 index 000000000000..fc69aa8ae783 --- /dev/null +++ b/test/Transforms/SampleProfile/Inputs/nolocinfo.prof @@ -0,0 +1,3 @@ +foo:30000:100 + 2: 28000 + 3: 1000 diff --git a/test/Transforms/SampleProfile/Inputs/offset.prof b/test/Transforms/SampleProfile/Inputs/offset.prof new file mode 100644 index 000000000000..b07ce3504fb2 --- /dev/null +++ b/test/Transforms/SampleProfile/Inputs/offset.prof @@ -0,0 +1,4 @@ +_Z3fooi:300:1 + 65532: 1000 + 65533: 10 + 65535: 990 diff --git a/test/Transforms/SampleProfile/Inputs/propagate.prof b/test/Transforms/SampleProfile/Inputs/propagate.prof index b28609be66c1..ee9c6d62dfd1 100644 --- a/test/Transforms/SampleProfile/Inputs/propagate.prof +++ b/test/Transforms/SampleProfile/Inputs/propagate.prof @@ -1,17 +1,17 @@ _Z3fooiil:58139:0 -0: 0 -1: 0 -2: 0 -4: 1 -5: 10 -6: 0 -7: 5 -8: 3 -9: 0 -10: 0 -11: 6339 -12: 16191 -13: 8141 -16: 1 -18: 0 -19: 0 + 0: 0 + 1: 0 + 2: 0 + 4: 1 + 5: 10 + 6: 2 + 7: 5 + 8: 3 + 9: 0 + 10: 0 + 11: 6339 + 12: 16191 + 13: 8141 + 16: 1 + 18: 0 + 19: 0 diff --git a/test/Transforms/SampleProfile/Inputs/remarks.prof b/test/Transforms/SampleProfile/Inputs/remarks.prof new file mode 100644 index 000000000000..1e905834cf41 --- /dev/null +++ b/test/Transforms/SampleProfile/Inputs/remarks.prof @@ -0,0 +1,7 @@ +main:623868:0 + 0: 0 + 0: _Z3foov:623868 + 3: 18346 + 4: 0 + 6: 19475 + 2: 18305 diff --git a/test/Transforms/SampleProfile/Inputs/syntax.prof b/test/Transforms/SampleProfile/Inputs/syntax.prof index f3738912a9dc..465212d86e84 100644 --- a/test/Transforms/SampleProfile/Inputs/syntax.prof +++ b/test/Transforms/SampleProfile/Inputs/syntax.prof @@ -1,3 +1,3 @@ empty:100:0 -0: 0 -1: 100 + 0: 0 + 1: 100 diff --git a/test/Transforms/SampleProfile/branch.ll b/test/Transforms/SampleProfile/branch.ll index 25bd455a044c..1700749f0be9 100644 --- a/test/Transforms/SampleProfile/branch.ll +++ b/test/Transforms/SampleProfile/branch.ll @@ -4,14 +4,14 @@ ; ; #include <stdio.h> ; #include <stdlib.h> -; + ; int main(int argc, char *argv[]) { ; if (argc < 2) ; return 1; ; double result; ; int limit = atoi(argv[1]); ; if (limit > 100) { -; double s = 23.041968; +; double s = 23.041968 * atoi(argv[2]); ; for (int u = 0; u < limit; u++) { ; double x = s; ; s = x + 3.049 + (double)u; @@ -19,7 +19,7 @@ ; } ; result = s; ; } else { -; result = 0; +; result = atoi(argv[2]); ; } ; printf("result is %lf\n", result); ; return 0; @@ -27,117 +27,213 @@ @.str = private unnamed_addr constant [15 x i8] c"result is %lf\0A\00", align 1 -; Function Attrs: nounwind uwtable -define i32 @main(i32 %argc, i8** nocapture readonly %argv) #0 { +; Function Attrs: uwtable +define i32 @main(i32 %argc, i8** %argv) #0 !dbg !6 { ; CHECK: Printing analysis 'Branch Probability Analysis' for function 'main': entry: - tail call void @llvm.dbg.value(metadata i32 %argc, i64 0, metadata !13, metadata !DIExpression()), !dbg !27 - tail call void @llvm.dbg.value(metadata i8** %argv, i64 0, metadata !14, metadata !DIExpression()), !dbg !27 - %cmp = icmp slt i32 %argc, 2, !dbg !28 - br i1 %cmp, label %return, label %if.end, !dbg !28 -; CHECK: edge entry -> return probability is 0 / 1 = 0% -; CHECK: edge entry -> if.end probability is 1 / 1 = 100% + %retval = alloca i32, align 4 + %argc.addr = alloca i32, align 4 + %argv.addr = alloca i8**, align 8 + %result = alloca double, align 8 + %limit = alloca i32, align 4 + %s = alloca double, align 8 + %u = alloca i32, align 4 + %x = alloca double, align 8 + store i32 0, i32* %retval, align 4 + store i32 %argc, i32* %argc.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %argc.addr, metadata !16, metadata !17), !dbg !18 + store i8** %argv, i8*** %argv.addr, align 8 + call void @llvm.dbg.declare(metadata i8*** %argv.addr, metadata !19, metadata !17), !dbg !20 + %0 = load i32, i32* %argc.addr, align 4, !dbg !21 + %cmp = icmp slt i32 %0, 2, !dbg !23 + br i1 %cmp, label %if.then, label %if.end, !dbg !24 +; CHECK: edge entry -> if.then probability is 0x4ccccccd / 0x80000000 = 60.00% +; CHECK: edge entry -> if.end probability is 0x33333333 / 0x80000000 = 40.00% + +if.then: ; preds = %entry + store i32 1, i32* %retval, align 4, !dbg !25 + br label %return, !dbg !25 if.end: ; preds = %entry - %arrayidx = getelementptr inbounds i8*, i8** %argv, i64 1, !dbg !30 - %0 = load i8*, i8** %arrayidx, align 8, !dbg !30, !tbaa !31 - %call = tail call i32 @atoi(i8* %0) #4, !dbg !30 - tail call void @llvm.dbg.value(metadata i32 %call, i64 0, metadata !17, metadata !DIExpression()), !dbg !30 - %cmp1 = icmp sgt i32 %call, 100, !dbg !35 - br i1 %cmp1, label %for.body, label %if.end6, !dbg !35 -; CHECK: edge if.end -> for.body probability is 0 / 1 = 0% -; CHECK: edge if.end -> if.end6 probability is 1 / 1 = 100% + call void @llvm.dbg.declare(metadata double* %result, metadata !26, metadata !17), !dbg !27 + call void @llvm.dbg.declare(metadata i32* %limit, metadata !28, metadata !17), !dbg !29 + %1 = load i8**, i8*** %argv.addr, align 8, !dbg !30 + %arrayidx = getelementptr inbounds i8*, i8** %1, i64 1, !dbg !30 + %2 = load i8*, i8** %arrayidx, align 8, !dbg !30 + %call = call i32 @atoi(i8* %2) #4, !dbg !31 + store i32 %call, i32* %limit, align 4, !dbg !29 + %3 = load i32, i32* %limit, align 4, !dbg !32 + %cmp1 = icmp sgt i32 %3, 100, !dbg !34 + br i1 %cmp1, label %if.then.2, label %if.else, !dbg !35 +; CHECK: edge if.end -> if.then.2 probability is 0x66666666 / 0x80000000 = 80.00% +; CHECK: edge if.end -> if.else probability is 0x1999999a / 0x80000000 = 20.00% -for.body: ; preds = %if.end, %for.body - %u.016 = phi i32 [ %inc, %for.body ], [ 0, %if.end ] - %s.015 = phi double [ %sub, %for.body ], [ 0x40370ABE6A337A81, %if.end ] - %add = fadd double %s.015, 3.049000e+00, !dbg !36 - %conv = sitofp i32 %u.016 to double, !dbg !36 - %add4 = fadd double %add, %conv, !dbg !36 - tail call void @llvm.dbg.value(metadata double %add4, i64 0, metadata !18, metadata !DIExpression()), !dbg !36 - %div = fdiv double 3.940000e+00, %s.015, !dbg !37 - %mul = fmul double %div, 3.200000e-01, !dbg !37 - %add5 = fadd double %add4, %mul, !dbg !37 - %sub = fsub double %add4, %add5, !dbg !37 - tail call void @llvm.dbg.value(metadata double %sub, i64 0, metadata !18, metadata !DIExpression()), !dbg !37 - %inc = add nsw i32 %u.016, 1, !dbg !38 - tail call void @llvm.dbg.value(metadata i32 %inc, i64 0, metadata !21, metadata !DIExpression()), !dbg !38 - %exitcond = icmp eq i32 %inc, %call, !dbg !38 - br i1 %exitcond, label %if.end6, label %for.body, !dbg !38 -; CHECK: edge for.body -> if.end6 probability is 0 / 10226 = 0% -; CHECK: edge for.body -> for.body probability is 10226 / 10226 = 100% [HOT edge] +if.then.2: ; preds = %if.end + call void @llvm.dbg.declare(metadata double* %s, metadata !36, metadata !17), !dbg !38 + %4 = load i8**, i8*** %argv.addr, align 8, !dbg !39 + %arrayidx3 = getelementptr inbounds i8*, i8** %4, i64 2, !dbg !39 + %5 = load i8*, i8** %arrayidx3, align 8, !dbg !39 + %call4 = call i32 @atoi(i8* %5) #4, !dbg !40 + %conv = sitofp i32 %call4 to double, !dbg !40 + %mul = fmul double 0x40370ABE6A337A81, %conv, !dbg !41 + store double %mul, double* %s, align 8, !dbg !38 + call void @llvm.dbg.declare(metadata i32* %u, metadata !42, metadata !17), !dbg !44 + store i32 0, i32* %u, align 4, !dbg !44 + br label %for.cond, !dbg !45 -if.end6: ; preds = %for.body, %if.end - %result.0 = phi double [ 0.000000e+00, %if.end ], [ %sub, %for.body ] - %call7 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str, i64 0, i64 0), double %result.0), !dbg !39 - br label %return, !dbg !40 -; CHECK: edge if.end6 -> return probability is 16 / 16 = 100% [HOT edge] +for.cond: ; preds = %for.inc, %if.then.2 + %6 = load i32, i32* %u, align 4, !dbg !46 + %7 = load i32, i32* %limit, align 4, !dbg !48 + %cmp5 = icmp slt i32 %6, %7, !dbg !49 + br i1 %cmp5, label %for.body, label %for.end, !dbg !50 -return: ; preds = %entry, %if.end6 - %retval.0 = phi i32 [ 0, %if.end6 ], [ 1, %entry ] - ret i32 %retval.0, !dbg !41 -} +for.body: ; preds = %for.cond + call void @llvm.dbg.declare(metadata double* %x, metadata !51, metadata !17), !dbg !53 + %8 = load double, double* %s, align 8, !dbg !54 + store double %8, double* %x, align 8, !dbg !53 + %9 = load double, double* %x, align 8, !dbg !55 + %add = fadd double %9, 3.049000e+00, !dbg !56 + %10 = load i32, i32* %u, align 4, !dbg !57 + %conv6 = sitofp i32 %10 to double, !dbg !57 + %add7 = fadd double %add, %conv6, !dbg !58 + store double %add7, double* %s, align 8, !dbg !59 + %11 = load double, double* %s, align 8, !dbg !60 + %12 = load double, double* %x, align 8, !dbg !61 + %div = fdiv double 3.940000e+00, %12, !dbg !62 + %mul8 = fmul double %div, 3.200000e-01, !dbg !63 + %add9 = fadd double %11, %mul8, !dbg !64 + %13 = load double, double* %s, align 8, !dbg !65 + %sub = fsub double %13, %add9, !dbg !65 + store double %sub, double* %s, align 8, !dbg !65 + br label %for.inc, !dbg !66 -; Function Attrs: nounwind readonly -declare i32 @atoi(i8* nocapture) #1 +for.inc: ; preds = %for.body + %14 = load i32, i32* %u, align 4, !dbg !67 + %inc = add nsw i32 %14, 1, !dbg !67 + store i32 %inc, i32* %u, align 4, !dbg !67 + br label %for.cond, !dbg !68 + +for.end: ; preds = %for.cond + %15 = load double, double* %s, align 8, !dbg !69 + store double %15, double* %result, align 8, !dbg !70 + br label %if.end.13, !dbg !71 -; Function Attrs: nounwind -declare i32 @printf(i8* nocapture readonly, ...) #2 +if.else: ; preds = %if.end + %16 = load i8**, i8*** %argv.addr, align 8, !dbg !72 + %arrayidx10 = getelementptr inbounds i8*, i8** %16, i64 2, !dbg !72 + %17 = load i8*, i8** %arrayidx10, align 8, !dbg !72 + %call11 = call i32 @atoi(i8* %17) #4, !dbg !74 + %conv12 = sitofp i32 %call11 to double, !dbg !74 + store double %conv12, double* %result, align 8, !dbg !75 + br label %if.end.13 + +if.end.13: ; preds = %if.else, %for.end + %18 = load double, double* %result, align 8, !dbg !76 + %call14 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str, i32 0, i32 0), double %18), !dbg !77 + store i32 0, i32* %retval, align 4, !dbg !78 + br label %return, !dbg !78 + +return: ; preds = %if.end.13, %if.then + %19 = load i32, i32* %retval, align 4, !dbg !79 + ret i32 %19, !dbg !79 +} ; Function Attrs: nounwind readnone -declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #3 +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: nounwind readonly +declare i32 @atoi(i8*) #2 + +declare i32 @printf(i8*, ...) #3 -attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -attributes #1 = { nounwind readonly "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -attributes #2 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -attributes #3 = { nounwind readnone } +attributes #0 = { uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind readonly "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #3 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" } attributes #4 = { nounwind readonly } !llvm.dbg.cu = !{!0} -!llvm.module.flags = !{!25, !42} -!llvm.ident = !{!26} +!llvm.module.flags = !{!13, !14} +!llvm.ident = !{!15} -!0 = !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.4 (trunk 192896) (llvm/trunk 192895)", isOptimized: true, emissionKind: 0, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) -!1 = !DIFile(filename: "branch.cc", directory: ".") +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.8.0 (trunk 248211) (llvm/trunk 248217)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, retainedTypes: !3, subprograms: !5) +!1 = !DIFile(filename: "test.cc", directory: "/ssd/llvm_commit") !2 = !{} !3 = !{!4} -!4 = !DISubprogram(name: "main", line: 4, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 4, file: !1, scope: !5, type: !6, function: i32 (i32, i8**)* @main, variables: !12) -!5 = !DIFile(filename: "branch.cc", directory: ".") -!6 = !DISubroutineType(types: !7) -!7 = !{!8, !8, !9} -!8 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) -!9 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, baseType: !10) -!10 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, baseType: !11) -!11 = !DIBasicType(tag: DW_TAG_base_type, name: "char", size: 8, align: 8, encoding: DW_ATE_signed_char) -!12 = !{!13, !14, !15, !17, !18, !21, !23} -!13 = !DILocalVariable(tag: DW_TAG_arg_variable, name: "argc", line: 4, arg: 1, scope: !4, file: !5, type: !8) -!14 = !DILocalVariable(tag: DW_TAG_arg_variable, name: "argv", line: 4, arg: 2, scope: !4, file: !5, type: !9) -!15 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "result", line: 7, scope: !4, file: !5, type: !16) -!16 = !DIBasicType(tag: DW_TAG_base_type, name: "double", size: 64, align: 64, encoding: DW_ATE_float) -!17 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "limit", line: 8, scope: !4, file: !5, type: !8) -!18 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "s", line: 10, scope: !19, file: !5, type: !16) -!19 = distinct !DILexicalBlock(line: 9, column: 0, file: !1, scope: !20) -!20 = distinct !DILexicalBlock(line: 9, column: 0, file: !1, scope: !4) -!21 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "u", line: 11, scope: !22, file: !5, type: !8) -!22 = distinct !DILexicalBlock(line: 11, column: 0, file: !1, scope: !19) -!23 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "x", line: 12, scope: !24, file: !5, type: !16) -!24 = distinct !DILexicalBlock(line: 11, column: 0, file: !1, scope: !22) -!25 = !{i32 2, !"Dwarf Version", i32 4} -!26 = !{!"clang version 3.4 (trunk 192896) (llvm/trunk 192895)"} -!27 = !DILocation(line: 4, scope: !4) -!28 = !DILocation(line: 5, scope: !29) -!29 = distinct !DILexicalBlock(line: 5, column: 0, file: !1, scope: !4) -!30 = !DILocation(line: 8, scope: !4) -!31 = !{!32, !32, i64 0} -!32 = !{!"any pointer", !33, i64 0} -!33 = !{!"omnipotent char", !34, i64 0} -!34 = !{!"Simple C/C++ TBAA"} -!35 = !DILocation(line: 9, scope: !20) -!36 = !DILocation(line: 13, scope: !24) -!37 = !DILocation(line: 14, scope: !24) -!38 = !DILocation(line: 11, scope: !22) -!39 = !DILocation(line: 20, scope: !4) -!40 = !DILocation(line: 21, scope: !4) -!41 = !DILocation(line: 22, scope: !4) -!42 = !{i32 1, !"Debug Info Version", i32 3} +!4 = !DIBasicType(name: "double", size: 64, align: 64, encoding: DW_ATE_float) +!5 = !{!6} +!6 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 4, type: !7, isLocal: false, isDefinition: true, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: false, variables: !2) +!7 = !DISubroutineType(types: !8) +!8 = !{!9, !9, !10} +!9 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!10 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !11, size: 64, align: 64) +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64, align: 64) +!12 = !DIBasicType(name: "char", size: 8, align: 8, encoding: DW_ATE_signed_char) +!13 = !{i32 2, !"Dwarf Version", i32 4} +!14 = !{i32 2, !"Debug Info Version", i32 3} +!15 = !{!"clang version 3.8.0 (trunk 248211) (llvm/trunk 248217)"} +!16 = !DILocalVariable(name: "argc", arg: 1, scope: !6, file: !1, line: 4, type: !9) +!17 = !DIExpression() +!18 = !DILocation(line: 4, column: 15, scope: !6) +!19 = !DILocalVariable(name: "argv", arg: 2, scope: !6, file: !1, line: 4, type: !10) +!20 = !DILocation(line: 4, column: 27, scope: !6) +!21 = !DILocation(line: 5, column: 8, scope: !22) +!22 = distinct !DILexicalBlock(scope: !6, file: !1, line: 5, column: 8) +!23 = !DILocation(line: 5, column: 13, scope: !22) +!24 = !DILocation(line: 5, column: 8, scope: !6) +!25 = !DILocation(line: 6, column: 6, scope: !22) +!26 = !DILocalVariable(name: "result", scope: !6, file: !1, line: 7, type: !4) +!27 = !DILocation(line: 7, column: 11, scope: !6) +!28 = !DILocalVariable(name: "limit", scope: !6, file: !1, line: 8, type: !9) +!29 = !DILocation(line: 8, column: 8, scope: !6) +!30 = !DILocation(line: 8, column: 21, scope: !6) +!31 = !DILocation(line: 8, column: 16, scope: !6) +!32 = !DILocation(line: 9, column: 8, scope: !33) +!33 = distinct !DILexicalBlock(scope: !6, file: !1, line: 9, column: 8) +!34 = !DILocation(line: 9, column: 14, scope: !33) +!35 = !DILocation(line: 9, column: 8, scope: !6) +!36 = !DILocalVariable(name: "s", scope: !37, file: !1, line: 10, type: !4) +!37 = distinct !DILexicalBlock(scope: !33, file: !1, line: 9, column: 21) +!38 = !DILocation(line: 10, column: 13, scope: !37) +!39 = !DILocation(line: 10, column: 34, scope: !37) +!40 = !DILocation(line: 10, column: 29, scope: !37) +!41 = !DILocation(line: 10, column: 27, scope: !37) +!42 = !DILocalVariable(name: "u", scope: !43, file: !1, line: 11, type: !9) +!43 = distinct !DILexicalBlock(scope: !37, file: !1, line: 11, column: 6) +!44 = !DILocation(line: 11, column: 15, scope: !43) +!45 = !DILocation(line: 11, column: 11, scope: !43) +!46 = !DILocation(line: 11, column: 22, scope: !47) +!47 = distinct !DILexicalBlock(scope: !43, file: !1, line: 11, column: 6) +!48 = !DILocation(line: 11, column: 26, scope: !47) +!49 = !DILocation(line: 11, column: 24, scope: !47) +!50 = !DILocation(line: 11, column: 6, scope: !43) +!51 = !DILocalVariable(name: "x", scope: !52, file: !1, line: 12, type: !4) +!52 = distinct !DILexicalBlock(scope: !47, file: !1, line: 11, column: 38) +!53 = !DILocation(line: 12, column: 15, scope: !52) +!54 = !DILocation(line: 12, column: 19, scope: !52) +!55 = !DILocation(line: 13, column: 12, scope: !52) +!56 = !DILocation(line: 13, column: 14, scope: !52) +!57 = !DILocation(line: 13, column: 32, scope: !52) +!58 = !DILocation(line: 13, column: 22, scope: !52) +!59 = !DILocation(line: 13, column: 10, scope: !52) +!60 = !DILocation(line: 14, column: 13, scope: !52) +!61 = !DILocation(line: 14, column: 24, scope: !52) +!62 = !DILocation(line: 14, column: 22, scope: !52) +!63 = !DILocation(line: 14, column: 26, scope: !52) +!64 = !DILocation(line: 14, column: 15, scope: !52) +!65 = !DILocation(line: 14, column: 10, scope: !52) +!66 = !DILocation(line: 15, column: 6, scope: !52) +!67 = !DILocation(line: 11, column: 34, scope: !47) +!68 = !DILocation(line: 11, column: 6, scope: !47) +!69 = !DILocation(line: 16, column: 15, scope: !37) +!70 = !DILocation(line: 16, column: 13, scope: !37) +!71 = !DILocation(line: 17, column: 4, scope: !37) +!72 = !DILocation(line: 18, column: 20, scope: !73) +!73 = distinct !DILexicalBlock(scope: !33, file: !1, line: 17, column: 11) +!74 = !DILocation(line: 18, column: 15, scope: !73) +!75 = !DILocation(line: 18, column: 13, scope: !73) +!76 = !DILocation(line: 20, column: 30, scope: !6) +!77 = !DILocation(line: 20, column: 4, scope: !6) +!78 = !DILocation(line: 21, column: 4, scope: !6) +!79 = !DILocation(line: 22, column: 2, scope: !6) diff --git a/test/Transforms/SampleProfile/calls.ll b/test/Transforms/SampleProfile/calls.ll index 10f43a1a6126..53ea9297d7d0 100644 --- a/test/Transforms/SampleProfile/calls.ll +++ b/test/Transforms/SampleProfile/calls.ll @@ -24,7 +24,7 @@ @.str = private unnamed_addr constant [11 x i8] c"sum is %d\0A\00", align 1 ; Function Attrs: nounwind uwtable -define i32 @_Z3sumii(i32 %x, i32 %y) { +define i32 @_Z3sumii(i32 %x, i32 %y) !dbg !4 { entry: %x.addr = alloca i32, align 4 %y.addr = alloca i32, align 4 @@ -37,7 +37,7 @@ entry: } ; Function Attrs: uwtable -define i32 @main() { +define i32 @main() !dbg !7 { entry: %retval = alloca i32, align 4 %s = alloca i32, align 4 @@ -52,8 +52,8 @@ while.cond: ; preds = %if.end, %entry store i32 %inc, i32* %i, align 4, !dbg !14 %cmp = icmp slt i32 %0, 400000000, !dbg !14 br i1 %cmp, label %while.body, label %while.end, !dbg !14 -; CHECK: edge while.cond -> while.body probability is 5391 / 5391 = 100% [HOT edge] -; CHECK: edge while.cond -> while.end probability is 0 / 5391 = 0% +; CHECK: edge while.cond -> while.body probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] +; CHECK: edge while.cond -> while.end probability is 0x00000000 / 0x80000000 = 0.00% while.body: ; preds = %while.cond %1 = load i32, i32* %i, align 4, !dbg !16 @@ -63,8 +63,8 @@ while.body: ; preds = %while.cond ; both branches out of while.body had the same weight. In reality, ; the edge while.body->if.then is taken most of the time. ; -; CHECK: edge while.body -> if.then probability is 5752 / 5752 = 100% [HOT edge] -; CHECK: edge while.body -> if.else probability is 0 / 5752 = 0% +; CHECK: edge while.body -> if.then probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] +; CHECK: edge while.body -> if.else probability is 0x00000000 / 0x80000000 = 0.00% if.then: ; preds = %while.body @@ -92,14 +92,14 @@ declare i32 @printf(i8*, ...) #2 !llvm.module.flags = !{!8, !9} !llvm.ident = !{!10} -!0 = !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5 ", isOptimized: false, emissionKind: 0, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5 ", isOptimized: false, emissionKind: 0, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) !1 = !DIFile(filename: "calls.cc", directory: ".") !2 = !{} !3 = !{!4, !7} -!4 = !DISubprogram(name: "sum", line: 3, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 3, file: !1, scope: !5, type: !6, function: i32 (i32, i32)* @_Z3sumii, variables: !2) +!4 = distinct !DISubprogram(name: "sum", line: 3, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 3, file: !1, scope: !5, type: !6, variables: !2) !5 = !DIFile(filename: "calls.cc", directory: ".") !6 = !DISubroutineType(types: !2) -!7 = !DISubprogram(name: "main", line: 7, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 7, file: !1, scope: !5, type: !6, function: i32 ()* @main, variables: !2) +!7 = distinct !DISubprogram(name: "main", line: 7, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 7, file: !1, scope: !5, type: !6, variables: !2) !8 = !{i32 2, !"Dwarf Version", i32 4} !9 = !{i32 1, !"Debug Info Version", i32 3} !10 = !{!"clang version 3.5 "} diff --git a/test/Transforms/SampleProfile/cov-zero-samples.ll b/test/Transforms/SampleProfile/cov-zero-samples.ll new file mode 100644 index 000000000000..d81e6438ee01 --- /dev/null +++ b/test/Transforms/SampleProfile/cov-zero-samples.ll @@ -0,0 +1,142 @@ +; RUN: opt < %s -sample-profile -sample-profile-file=%S/Inputs/cov-zero-samples.prof -sample-profile-check-record-coverage=100 -pass-remarks=sample-profile -o /dev/null 2>&1 | FileCheck %s +; +; CHECK: remark: cov-zero-samples.cc:9:25: Applied 404065 samples from profile (offset: 2.1) +; CHECK: remark: cov-zero-samples.cc:10:9: Applied 443089 samples from profile (offset: 3) +; CHECK: remark: cov-zero-samples.cc:10:36: Applied 0 samples from profile (offset: 3.1) +; CHECK: remark: cov-zero-samples.cc:11:12: Applied 404066 samples from profile (offset: 4) +; CHECK: remark: cov-zero-samples.cc:13:25: Applied 0 samples from profile (offset: 6) +; CHECK: remark: cov-zero-samples.cc:14:3: Applied 0 samples from profile (offset: 7) +; CHECK: remark: cov-zero-samples.cc:10:9: most popular destination for conditional branches at cov-zero-samples.cc:9:3 +; CHECK: remark: cov-zero-samples.cc:11:12: most popular destination for conditional branches at cov-zero-samples.cc:10:9 +; +; Coverage for this profile should be 100% +; CHECK-NOT: warning: cov-zero-samples.cc:1: + +@N = global i64 8000000000, align 8 +@.str = private unnamed_addr constant [11 x i8] c"sum is %d\0A\00", align 1 + +; Function Attrs: nounwind uwtable +define i32 @_Z12never_calledi(i32 %i) !dbg !4 { +entry: + ret i32 0, !dbg !32 +} + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata, metadata) + +; Function Attrs: norecurse uwtable +define i32 @main() !dbg !8 { +entry: + %retval = alloca i32, align 4 + %sum = alloca i32, align 4 + %i = alloca i64, align 8 + store i32 0, i32* %retval, align 4 + call void @llvm.dbg.declare(metadata i32* %sum, metadata !33, metadata !19), !dbg !34 + store i32 0, i32* %sum, align 4, !dbg !34 + call void @llvm.dbg.declare(metadata i64* %i, metadata !35, metadata !19), !dbg !37 + store i64 0, i64* %i, align 8, !dbg !37 + br label %for.cond, !dbg !38 + +for.cond: ; preds = %for.inc, %entry + %0 = load i64, i64* %i, align 8, !dbg !39 + %1 = load volatile i64, i64* @N, align 8, !dbg !42 + %cmp = icmp slt i64 %0, %1, !dbg !43 + br i1 %cmp, label %for.body, label %for.end, !dbg !44 + +for.body: ; preds = %for.cond + %2 = load i64, i64* %i, align 8, !dbg !45 + %3 = load volatile i64, i64* @N, align 8, !dbg !48 + %cmp1 = icmp sgt i64 %2, %3, !dbg !49 + br i1 %cmp1, label %if.then, label %if.end, !dbg !50 + +if.then: ; preds = %for.body + %4 = load i64, i64* %i, align 8, !dbg !51 + %conv = trunc i64 %4 to i32, !dbg !51 + %call = call i32 @_Z12never_calledi(i32 %conv), !dbg !53 + %5 = load i32, i32* %sum, align 4, !dbg !54 + %add = add nsw i32 %5, %call, !dbg !54 + store i32 %add, i32* %sum, align 4, !dbg !54 + br label %if.end, !dbg !55 + +if.end: ; preds = %if.then, %for.body + %6 = load i64, i64* %i, align 8, !dbg !56 + %div = sdiv i64 %6, 239, !dbg !57 + %7 = load i32, i32* %sum, align 4, !dbg !58 + %conv2 = sext i32 %7 to i64, !dbg !58 + %mul = mul nsw i64 %conv2, %div, !dbg !58 + %conv3 = trunc i64 %mul to i32, !dbg !58 + store i32 %conv3, i32* %sum, align 4, !dbg !58 + br label %for.inc, !dbg !59 + +for.inc: ; preds = %if.end + %8 = load i64, i64* %i, align 8, !dbg !60 + %inc = add nsw i64 %8, 1, !dbg !60 + store i64 %inc, i64* %i, align 8, !dbg !60 + br label %for.cond, !dbg !62 + +for.end: ; preds = %for.cond + %9 = load i32, i32* %sum, align 4, !dbg !63 + %call4 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i32 0, i32 0), i32 %9), !dbg !64 + ret i32 0, !dbg !65 +} + +declare i32 @printf(i8*, ...) + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!15, !16} +!llvm.ident = !{!17} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.8.0 (trunk 253667) (llvm/trunk 253670)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, subprograms: !3, globals: !11) +!1 = !DIFile(filename: "cov-zero-samples.cc", directory: ".") +!2 = !{} +!3 = !{!4, !8} +!4 = distinct !DISubprogram(name: "never_called", linkageName: "_Z12never_calledi", scope: !1, file: !1, line: 5, type: !5, isLocal: false, isDefinition: true, scopeLine: 5, flags: DIFlagPrototyped, isOptimized: false, variables: !2) +!5 = !DISubroutineType(types: !6) +!6 = !{!7, !7} +!7 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!8 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 7, type: !9, isLocal: false, isDefinition: true, scopeLine: 7, flags: DIFlagPrototyped, isOptimized: false, variables: !2) +!9 = !DISubroutineType(types: !10) +!10 = !{!7} +!11 = !{!12} +!12 = !DIGlobalVariable(name: "N", scope: !0, file: !1, line: 3, type: !13, isLocal: false, isDefinition: true, variable: i64* @N) +!13 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !14) +!14 = !DIBasicType(name: "long long int", size: 64, align: 64, encoding: DW_ATE_signed) +!15 = !{i32 2, !"Dwarf Version", i32 4} +!16 = !{i32 2, !"Debug Info Version", i32 3} +!17 = !{!"clang version 3.8.0 (trunk 253667) (llvm/trunk 253670)"} +!19 = !DIExpression() +!31 = !DILexicalBlockFile(scope: !4, file: !1, discriminator: 3) +!32 = !DILocation(line: 5, column: 27, scope: !31) +!33 = !DILocalVariable(name: "sum", scope: !8, file: !1, line: 8, type: !7) +!34 = !DILocation(line: 8, column: 7, scope: !8) +!35 = !DILocalVariable(name: "i", scope: !36, file: !1, line: 9, type: !14) +!36 = distinct !DILexicalBlock(scope: !8, file: !1, line: 9, column: 3) +!37 = !DILocation(line: 9, column: 18, scope: !36) +!38 = !DILocation(line: 9, column: 8, scope: !36) +!39 = !DILocation(line: 9, column: 25, scope: !40) +!40 = !DILexicalBlockFile(scope: !41, file: !1, discriminator: 1) +!41 = distinct !DILexicalBlock(scope: !36, file: !1, line: 9, column: 3) +!42 = !DILocation(line: 9, column: 29, scope: !40) +!43 = !DILocation(line: 9, column: 27, scope: !40) +!44 = !DILocation(line: 9, column: 3, scope: !40) +!45 = !DILocation(line: 10, column: 9, scope: !46) +!46 = distinct !DILexicalBlock(scope: !47, file: !1, line: 10, column: 9) +!47 = distinct !DILexicalBlock(scope: !41, file: !1, line: 9, column: 37) +!48 = !DILocation(line: 10, column: 13, scope: !46) +!49 = !DILocation(line: 10, column: 11, scope: !46) +!50 = !DILocation(line: 10, column: 9, scope: !47) +!51 = !DILocation(line: 10, column: 36, scope: !52) +!52 = !DILexicalBlockFile(scope: !46, file: !1, discriminator: 1) +!53 = !DILocation(line: 10, column: 23, scope: !52) +!54 = !DILocation(line: 10, column: 20, scope: !52) +!55 = !DILocation(line: 10, column: 16, scope: !52) +!56 = !DILocation(line: 11, column: 12, scope: !47) +!57 = !DILocation(line: 11, column: 14, scope: !47) +!58 = !DILocation(line: 11, column: 9, scope: !47) +!59 = !DILocation(line: 12, column: 3, scope: !47) +!60 = !DILocation(line: 9, column: 33, scope: !61) +!61 = !DILexicalBlockFile(scope: !41, file: !1, discriminator: 2) +!62 = !DILocation(line: 9, column: 3, scope: !61) +!63 = !DILocation(line: 13, column: 25, scope: !8) +!64 = !DILocation(line: 13, column: 3, scope: !8) +!65 = !DILocation(line: 14, column: 3, scope: !8) diff --git a/test/Transforms/SampleProfile/coverage-warning.ll b/test/Transforms/SampleProfile/coverage-warning.ll new file mode 100644 index 000000000000..14a2710b0810 --- /dev/null +++ b/test/Transforms/SampleProfile/coverage-warning.ll @@ -0,0 +1,46 @@ +; RUN: opt < %s -sample-profile -sample-profile-file=%S/Inputs/coverage-warning.prof -sample-profile-check-record-coverage=90 -sample-profile-check-sample-coverage=100 -o /dev/null 2>&1 | FileCheck %s +define i32 @foo(i32 %i) !dbg !4 { +; The profile has samples for line locations that are no longer present. +; Coverage does not reach 90%, so we should get this warning: +; +; CHECK: warning: coverage-warning.c:1: 2 of 3 available profile records (66%) were applied +; CHECK: warning: coverage-warning.c:1: 29000 of 30700 available profile samples (94%) were applied +entry: + %retval = alloca i32, align 4 + %i.addr = alloca i32, align 4 + store i32 %i, i32* %i.addr, align 4 + %0 = load i32, i32* %i.addr, align 4, !dbg !9 + %cmp = icmp sgt i32 %0, 1000, !dbg !10 + br i1 %cmp, label %if.then, label %if.end, !dbg !9 + +if.then: ; preds = %entry + store i32 30, i32* %retval, align 4, !dbg !11 + br label %return, !dbg !11 + +if.end: ; preds = %entry + store i32 3, i32* %retval, align 4, !dbg !12 + br label %return, !dbg !12 + +return: ; preds = %if.end, %if.then + %1 = load i32, i32* %retval, align 4, !dbg !13 + ret i32 %1, !dbg !13 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!6, !7} +!llvm.ident = !{!8} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.8.0 (trunk 251524) (llvm/trunk 251531)", isOptimized: false, runtimeVersion: 0, emissionKind: 2, enums: !2, subprograms: !3) +!1 = !DIFile(filename: "coverage-warning.c", directory: ".") +!2 = !{} +!3 = !{!4} +!4 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: false, variables: !2) +!5 = !DISubroutineType(types: !2) +!6 = !{i32 2, !"Dwarf Version", i32 4} +!7 = !{i32 2, !"Debug Info Version", i32 3} +!8 = !{!"clang version 3.8.0 (trunk 251524) (llvm/trunk 251531)"} +!9 = !DILocation(line: 2, column: 7, scope: !4) +!10 = !DILocation(line: 2, column: 9, scope: !4) +!11 = !DILocation(line: 3, column: 5, scope: !4) +!12 = !DILocation(line: 4, column: 3, scope: !4) +!13 = !DILocation(line: 5, column: 1, scope: !4) diff --git a/test/Transforms/SampleProfile/discriminator.ll b/test/Transforms/SampleProfile/discriminator.ll index 2445c5c5d609..0915fc884f82 100644 --- a/test/Transforms/SampleProfile/discriminator.ll +++ b/test/Transforms/SampleProfile/discriminator.ll @@ -21,7 +21,7 @@ ; This means that the predicate 'i < 5' (line 3) is executed 100 times, ; but the then branch (line 3.1) is only executed 5 times. -define i32 @foo(i32 %i) #0 { +define i32 @foo(i32 %i) #0 !dbg !4 { ; CHECK: Printing analysis 'Branch Probability Analysis' for function 'foo': entry: %i.addr = alloca i32, align 4 @@ -34,15 +34,15 @@ while.cond: ; preds = %if.end, %entry %0 = load i32, i32* %i.addr, align 4, !dbg !12 %cmp = icmp slt i32 %0, 100, !dbg !12 br i1 %cmp, label %while.body, label %while.end, !dbg !12 -; CHECK: edge while.cond -> while.body probability is 100 / 101 = 99.0099% [HOT edge] -; CHECK: edge while.cond -> while.end probability is 1 / 101 = 0.990099% +; CHECK: edge while.cond -> while.body probability is 0x7ebb907a / 0x80000000 = 99.01% [HOT edge] +; CHECK: edge while.cond -> while.end probability is 0x01446f86 / 0x80000000 = 0.99% while.body: ; preds = %while.cond %1 = load i32, i32* %i.addr, align 4, !dbg !14 %cmp1 = icmp slt i32 %1, 50, !dbg !14 br i1 %cmp1, label %if.then, label %if.end, !dbg !14 -; CHECK: edge while.body -> if.then probability is 5 / 100 = 5% -; CHECK: edge while.body -> if.end probability is 95 / 100 = 95% [HOT edge] +; CHECK: edge while.body -> if.then probability is 0x06666666 / 0x80000000 = 5.00% +; CHECK: edge while.body -> if.end probability is 0x7999999a / 0x80000000 = 95.00% [HOT edge] if.then: ; preds = %while.body %2 = load i32, i32* %x, align 4, !dbg !17 @@ -66,11 +66,11 @@ while.end: ; preds = %while.cond !llvm.module.flags = !{!7, !8} !llvm.ident = !{!9} -!0 = !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.5 ", isOptimized: false, emissionKind: 0, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) +!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.5 ", isOptimized: false, emissionKind: 0, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) !1 = !DIFile(filename: "discriminator.c", directory: ".") !2 = !{} !3 = !{!4} -!4 = !DISubprogram(name: "foo", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 1, file: !1, scope: !5, type: !6, function: i32 (i32)* @foo, variables: !2) +!4 = distinct !DISubprogram(name: "foo", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 1, file: !1, scope: !5, type: !6, variables: !2) !5 = !DIFile(filename: "discriminator.c", directory: ".") !6 = !DISubroutineType(types: !2) !7 = !{i32 2, !"Dwarf Version", i32 4} diff --git a/test/Transforms/SampleProfile/entry_counts.ll b/test/Transforms/SampleProfile/entry_counts.ll index bf66e693a9d1..50cd575295a9 100644 --- a/test/Transforms/SampleProfile/entry_counts.ll +++ b/test/Transforms/SampleProfile/entry_counts.ll @@ -3,7 +3,7 @@ ; According to the profile, function empty() was called 13,293 times. ; CHECK: {{.*}} = !{!"function_entry_count", i64 13293} -define void @empty() { +define void @empty() !dbg !4 { entry: ret void, !dbg !9 } @@ -12,11 +12,11 @@ entry: !llvm.module.flags = !{!6, !7} !llvm.ident = !{!8} -!0 = !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.7.0 (trunk 237249) (llvm/trunk 237261)", isOptimized: false, runtimeVersion: 0, emissionKind: 2, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) -!1 = !DIFile(filename: "entry_counts.c", directory: "/usr/local/google/home/dnovillo/llvm/test/pgo") +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.7.0 (trunk 237249) (llvm/trunk 237261)", isOptimized: false, runtimeVersion: 0, emissionKind: 2, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) +!1 = !DIFile(filename: "entry_counts.c", directory: ".") !2 = !{} !3 = !{!4} -!4 = !DISubprogram(name: "empty", scope: !1, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, function: void ()* @empty, variables: !2) +!4 = distinct !DISubprogram(name: "empty", scope: !1, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, variables: !2) !5 = !DISubroutineType(types: !2) !6 = !{i32 2, !"Dwarf Version", i32 4} !7 = !{i32 2, !"Debug Info Version", i32 3} diff --git a/test/Transforms/SampleProfile/fnptr.ll b/test/Transforms/SampleProfile/fnptr.ll index 368da42fc8a1..7b07ca9679bb 100644 --- a/test/Transforms/SampleProfile/fnptr.ll +++ b/test/Transforms/SampleProfile/fnptr.ll @@ -5,12 +5,12 @@ ; RUN: opt < %s -sample-profile -sample-profile-file=%S/Inputs/fnptr.prof | opt -analyze -branch-prob | FileCheck %s ; RUN: opt < %s -sample-profile -sample-profile-file=%S/Inputs/fnptr.binprof | opt -analyze -branch-prob | FileCheck %s -; CHECK: edge for.body3 -> if.then probability is 534 / 2598 = 20.5543% -; CHECK: edge for.body3 -> if.else probability is 2064 / 2598 = 79.4457% -; CHECK: edge for.inc -> for.inc12 probability is 1052 / 2598 = 40.4927% -; CHECK: edge for.inc -> for.body3 probability is 1546 / 2598 = 59.5073% -; CHECK: edge for.inc12 -> for.end14 probability is 518 / 1052 = 49.2395% -; CHECK: edge for.inc12 -> for.cond1.preheader probability is 534 / 1052 = 50.7605% +; CHECK: edge for.body3 -> if.then probability is 0x1a4f3959 / 0x80000000 = 20.55% +; CHECK: edge for.body3 -> if.else probability is 0x65b0c6a7 / 0x80000000 = 79.45% +; CHECK: edge for.inc -> for.inc12 probability is 0x33d4a4c1 / 0x80000000 = 40.49% +; CHECK: edge for.inc -> for.body3 probability is 0x4c2b5b3f / 0x80000000 = 59.51% +; CHECK: edge for.inc12 -> for.end14 probability is 0x3f06d04e / 0x80000000 = 49.24% +; CHECK: edge for.inc12 -> for.cond1.preheader probability is 0x40f92fb2 / 0x80000000 = 50.76% ; Original C++ test case. ; @@ -46,7 +46,7 @@ @.str = private unnamed_addr constant [9 x i8] c"S = %lf\0A\00", align 1 -define double @_Z3fooi(i32 %x) #0 { +define double @_Z3fooi(i32 %x) #0 !dbg !3 { entry: %conv = sitofp i32 %x to double, !dbg !2 %call = tail call double @sin(double %conv) #3, !dbg !8 @@ -56,7 +56,7 @@ entry: declare double @sin(double) #1 -define double @_Z3bari(i32 %x) #0 { +define double @_Z3bari(i32 %x) #0 !dbg !10 { entry: %conv = sitofp i32 %x to double, !dbg !9 %call = tail call double @cos(double %conv) #3, !dbg !11 @@ -66,7 +66,7 @@ entry: declare double @cos(double) #1 -define i32 @main() #2 { +define i32 @main() #2 !dbg !13 { entry: br label %for.cond1.preheader, !dbg !12 @@ -130,17 +130,17 @@ declare i32 @printf(i8* nocapture readonly, ...) #1 !0 = !{i32 2, !"Debug Info Version", i32 3} !1 = !{!"clang version 3.6.0 "} !2 = !DILocation(line: 9, column: 3, scope: !3) -!3 = !DISubprogram(name: "foo", line: 8, isLocal: false, isDefinition: true, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 8, file: !4, scope: !5, type: !6, function: double (i32)* @_Z3fooi, variables: !7) +!3 = distinct !DISubprogram(name: "foo", line: 8, isLocal: false, isDefinition: true, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 8, file: !4, scope: !5, type: !6, variables: !7) !4 = !DIFile(filename: "fnptr.cc", directory: ".") !5 = !DIFile(filename: "fnptr.cc", directory: ".") !6 = !DISubroutineType(types: !7) !7 = !{} !8 = !DILocation(line: 9, column: 14, scope: !3) !9 = !DILocation(line: 13, column: 3, scope: !10) -!10 = !DISubprogram(name: "bar", line: 12, isLocal: false, isDefinition: true, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 12, file: !4, scope: !5, type: !6, function: double (i32)* @_Z3bari, variables: !7) +!10 = distinct !DISubprogram(name: "bar", line: 12, isLocal: false, isDefinition: true, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 12, file: !4, scope: !5, type: !6, variables: !7) !11 = !DILocation(line: 13, column: 14, scope: !10) !12 = !DILocation(line: 19, column: 3, scope: !13) -!13 = !DISubprogram(name: "main", line: 16, isLocal: false, isDefinition: true, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 16, file: !4, scope: !5, type: !6, function: i32 ()* @main, variables: !7) +!13 = distinct !DISubprogram(name: "main", line: 16, isLocal: false, isDefinition: true, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 16, file: !4, scope: !5, type: !6, variables: !7) !14 = !DILocation(line: 20, column: 5, scope: !13) !15 = !DILocation(line: 21, column: 15, scope: !13) !16 = !DILocation(line: 22, column: 11, scope: !13) diff --git a/test/Transforms/SampleProfile/gcc-simple.ll b/test/Transforms/SampleProfile/gcc-simple.ll new file mode 100644 index 000000000000..1ae927158c11 --- /dev/null +++ b/test/Transforms/SampleProfile/gcc-simple.ll @@ -0,0 +1,218 @@ +; RUN: opt < %s -sample-profile -sample-profile-file=%S/Inputs/gcc-simple.afdo -S | FileCheck %s +; XFAIL: powerpc64-, s390x, mips-, mips64-, sparc +; Original code: +; +; #include <stdlib.h> +; +; long long int foo(long i) { +; if (rand() < 500) return 2; else if (rand() > 5000) return 10; else return 90; +; } +; +; int main() { +; long long int sum = 0; +; for (int k = 0; k < 3000; k++) +; for (int i = 0; i < 200000; i++) sum += foo(i); +; return sum > 0 ? 0 : 1; +; } +; +; This test was compiled down to bytecode at -O0 to avoid inlining foo() into +; main(). The profile was generated using a GCC-generated binary (also compiled +; at -O0). The conversion from the Linux Perf profile to the GCC autofdo +; profile used the converter at https://github.com/google/autofdo +; +; $ gcc -g -O0 gcc-simple.cc -o gcc-simple +; $ perf record -b ./gcc-simple +; $ create_gcov --binary=gcc-simple --gcov=gcc-simple.afdo + +define i64 @_Z3fool(i64 %i) #0 !dbg !4 { +; CHECK: !prof ![[EC1:[0-9]+]] +entry: + %retval = alloca i64, align 8 + %i.addr = alloca i64, align 8 + store i64 %i, i64* %i.addr, align 8 + call void @llvm.dbg.declare(metadata i64* %i.addr, metadata !16, metadata !17), !dbg !18 + %call = call i32 @rand() #3, !dbg !19 + %cmp = icmp slt i32 %call, 500, !dbg !21 + br i1 %cmp, label %if.then, label %if.else, !dbg !22 +; CHECK: !prof ![[PROF1:[0-9]+]] + +if.then: ; preds = %entry + store i64 2, i64* %retval, align 8, !dbg !23 + br label %return, !dbg !23 + +if.else: ; preds = %entry + %call1 = call i32 @rand() #3, !dbg !25 + %cmp2 = icmp sgt i32 %call1, 5000, !dbg !28 + br i1 %cmp2, label %if.then.3, label %if.else.4, !dbg !29 +; CHECK: !prof ![[PROF2:[0-9]+]] + +if.then.3: ; preds = %if.else + store i64 10, i64* %retval, align 8, !dbg !30 + br label %return, !dbg !30 + +if.else.4: ; preds = %if.else + store i64 90, i64* %retval, align 8, !dbg !32 + br label %return, !dbg !32 + +return: ; preds = %if.else.4, %if.then.3, %if.then + %0 = load i64, i64* %retval, align 8, !dbg !34 + ret i64 %0, !dbg !34 +} + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: nounwind +declare i32 @rand() #2 + +; Function Attrs: nounwind uwtable +define i32 @main() #0 !dbg !9 { +; CHECK: !prof ![[EC2:[0-9]+]] +entry: + %retval = alloca i32, align 4 + %sum = alloca i64, align 8 + %k = alloca i32, align 4 + %i = alloca i32, align 4 + store i32 0, i32* %retval, align 4 + call void @llvm.dbg.declare(metadata i64* %sum, metadata !35, metadata !17), !dbg !36 + store i64 0, i64* %sum, align 8, !dbg !36 + call void @llvm.dbg.declare(metadata i32* %k, metadata !37, metadata !17), !dbg !39 + store i32 0, i32* %k, align 4, !dbg !39 + br label %for.cond, !dbg !40 + +for.cond: ; preds = %for.inc.4, %entry + %0 = load i32, i32* %k, align 4, !dbg !41 + %cmp = icmp slt i32 %0, 3000, !dbg !45 + br i1 %cmp, label %for.body, label %for.end.6, !dbg !46 +; CHECK: !prof ![[PROF3:[0-9]+]] + +for.body: ; preds = %for.cond + call void @llvm.dbg.declare(metadata i32* %i, metadata !47, metadata !17), !dbg !49 + store i32 0, i32* %i, align 4, !dbg !49 + br label %for.cond.1, !dbg !50 + +for.cond.1: ; preds = %for.inc, %for.body + %1 = load i32, i32* %i, align 4, !dbg !51 + %cmp2 = icmp slt i32 %1, 200000, !dbg !55 + br i1 %cmp2, label %for.body.3, label %for.end, !dbg !56 +; CHECK: !prof ![[PROF4:[0-9]+]] + +for.body.3: ; preds = %for.cond.1 + %2 = load i32, i32* %i, align 4, !dbg !57 + %conv = sext i32 %2 to i64, !dbg !57 + %call = call i64 @_Z3fool(i64 %conv), !dbg !59 + %3 = load i64, i64* %sum, align 8, !dbg !60 + %add = add nsw i64 %3, %call, !dbg !60 + store i64 %add, i64* %sum, align 8, !dbg !60 + br label %for.inc, !dbg !61 + +for.inc: ; preds = %for.body.3 + %4 = load i32, i32* %i, align 4, !dbg !62 + %inc = add nsw i32 %4, 1, !dbg !62 + store i32 %inc, i32* %i, align 4, !dbg !62 + br label %for.cond.1, !dbg !64 + +for.end: ; preds = %for.cond.1 + br label %for.inc.4, !dbg !65 + +for.inc.4: ; preds = %for.end + %5 = load i32, i32* %k, align 4, !dbg !67 + %inc5 = add nsw i32 %5, 1, !dbg !67 + store i32 %inc5, i32* %k, align 4, !dbg !67 + br label %for.cond, !dbg !68 + +for.end.6: ; preds = %for.cond + %6 = load i64, i64* %sum, align 8, !dbg !69 + %cmp7 = icmp sgt i64 %6, 0, !dbg !70 + %cond = select i1 %cmp7, i32 0, i32 1, !dbg !69 + ret i32 %cond, !dbg !71 +} + +; CHECK ![[EC1]] = !{!"function_entry_count", i64 24108} +; CHECK ![[PROF1]] = !{!"branch_weights", i32 1, i32 30124} +; CHECK ![[PROF2]] = !{!"branch_weights", i32 30177, i32 29579} +; CHECK ![[EC2]] = !{!"function_entry_count", i64 0} +; CHECK ![[PROF3]] = !{!"branch_weights", i32 1, i32 1} +; CHECK ![[PROF4]] = !{!"branch_weights", i32 1, i32 20238} + +attributes #0 = { nounwind uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #3 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!13, !14} +!llvm.ident = !{!15} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.8.0 (trunk 247554) (llvm/trunk 247557)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, subprograms: !3) +!1 = !DIFile(filename: "discriminator.cc", directory: "/usr/local/google/home/dnovillo/llvm/test/autofdo") +!2 = !{} +!3 = !{!4, !9} +!4 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fool", scope: !1, file: !1, line: 3, type: !5, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, variables: !2) +!5 = !DISubroutineType(types: !6) +!6 = !{!7, !8} +!7 = !DIBasicType(name: "long long int", size: 64, align: 64, encoding: DW_ATE_signed) +!8 = !DIBasicType(name: "long int", size: 64, align: 64, encoding: DW_ATE_signed) +!9 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 7, type: !10, isLocal: false, isDefinition: true, scopeLine: 7, flags: DIFlagPrototyped, isOptimized: false, variables: !2) +!10 = !DISubroutineType(types: !11) +!11 = !{!12} +!12 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!13 = !{i32 2, !"Dwarf Version", i32 4} +!14 = !{i32 2, !"Debug Info Version", i32 3} +!15 = !{!"clang version 3.8.0 (trunk 247554) (llvm/trunk 247557)"} +!16 = !DILocalVariable(name: "i", arg: 1, scope: !4, file: !1, line: 3, type: !8) +!17 = !DIExpression() +!18 = !DILocation(line: 3, column: 24, scope: !4) +!19 = !DILocation(line: 4, column: 7, scope: !20) +!20 = distinct !DILexicalBlock(scope: !4, file: !1, line: 4, column: 7) +!21 = !DILocation(line: 4, column: 14, scope: !20) +!22 = !DILocation(line: 4, column: 7, scope: !4) +!23 = !DILocation(line: 4, column: 21, scope: !24) +!24 = !DILexicalBlockFile(scope: !20, file: !1, discriminator: 1) +!25 = !DILocation(line: 4, column: 40, scope: !26) +!26 = !DILexicalBlockFile(scope: !27, file: !1, discriminator: 2) +!27 = distinct !DILexicalBlock(scope: !20, file: !1, line: 4, column: 40) +!28 = !DILocation(line: 4, column: 47, scope: !27) +!29 = !DILocation(line: 4, column: 40, scope: !20) +!30 = !DILocation(line: 4, column: 55, scope: !31) +!31 = !DILexicalBlockFile(scope: !27, file: !1, discriminator: 3) +!32 = !DILocation(line: 4, column: 71, scope: !33) +!33 = !DILexicalBlockFile(scope: !27, file: !1, discriminator: 4) +!34 = !DILocation(line: 5, column: 1, scope: !4) +!35 = !DILocalVariable(name: "sum", scope: !9, file: !1, line: 8, type: !7) +!36 = !DILocation(line: 8, column: 17, scope: !9) +!37 = !DILocalVariable(name: "k", scope: !38, file: !1, line: 9, type: !12) +!38 = distinct !DILexicalBlock(scope: !9, file: !1, line: 9, column: 3) +!39 = !DILocation(line: 9, column: 12, scope: !38) +!40 = !DILocation(line: 9, column: 8, scope: !38) +!41 = !DILocation(line: 9, column: 19, scope: !42) +!42 = !DILexicalBlockFile(scope: !43, file: !1, discriminator: 2) +!43 = !DILexicalBlockFile(scope: !44, file: !1, discriminator: 1) +!44 = distinct !DILexicalBlock(scope: !38, file: !1, line: 9, column: 3) +!45 = !DILocation(line: 9, column: 21, scope: !44) +!46 = !DILocation(line: 9, column: 3, scope: !38) +!47 = !DILocalVariable(name: "i", scope: !48, file: !1, line: 10, type: !12) +!48 = distinct !DILexicalBlock(scope: !44, file: !1, line: 10, column: 5) +!49 = !DILocation(line: 10, column: 14, scope: !48) +!50 = !DILocation(line: 10, column: 10, scope: !48) +!51 = !DILocation(line: 10, column: 21, scope: !52) +!52 = !DILexicalBlockFile(scope: !53, file: !1, discriminator: 5) +!53 = !DILexicalBlockFile(scope: !54, file: !1, discriminator: 1) +!54 = distinct !DILexicalBlock(scope: !48, file: !1, line: 10, column: 5) +!55 = !DILocation(line: 10, column: 23, scope: !54) +!56 = !DILocation(line: 10, column: 5, scope: !48) +!57 = !DILocation(line: 10, column: 49, scope: !58) +!58 = !DILexicalBlockFile(scope: !54, file: !1, discriminator: 2) +!59 = !DILocation(line: 10, column: 45, scope: !54) +!60 = !DILocation(line: 10, column: 42, scope: !54) +!61 = !DILocation(line: 10, column: 38, scope: !54) +!62 = !DILocation(line: 10, column: 34, scope: !63) +!63 = !DILexicalBlockFile(scope: !54, file: !1, discriminator: 4) +!64 = !DILocation(line: 10, column: 5, scope: !54) +!65 = !DILocation(line: 10, column: 50, scope: !66) +!66 = !DILexicalBlockFile(scope: !48, file: !1, discriminator: 3) +!67 = !DILocation(line: 9, column: 30, scope: !44) +!68 = !DILocation(line: 9, column: 3, scope: !44) +!69 = !DILocation(line: 11, column: 10, scope: !9) +!70 = !DILocation(line: 11, column: 14, scope: !9) +!71 = !DILocation(line: 11, column: 3, scope: !9) diff --git a/test/Transforms/SampleProfile/inline-coverage.ll b/test/Transforms/SampleProfile/inline-coverage.ll new file mode 100644 index 000000000000..7248540b4f7c --- /dev/null +++ b/test/Transforms/SampleProfile/inline-coverage.ll @@ -0,0 +1,135 @@ +; RUN: opt < %s -sample-profile -sample-profile-file=%S/Inputs/inline-coverage.prof -sample-profile-check-record-coverage=100 -sample-profile-check-sample-coverage=110 -pass-remarks=sample-profile -o /dev/null 2>&1 | FileCheck %s +; +; Original code: +; +; 1 #include <stdlib.h> +; 2 +; 3 long long int foo(long i) { +; 4 return rand() * i; +; 5 } +; 6 +; 7 int main() { +; 8 long long int sum = 0; +; 9 for (int i = 0; i < 200000 * 3000; i++) +; 10 sum += foo(i); +; 11 return sum > 0 ? 0 : 1; +; 12 } +; +; CHECK: remark: coverage.cc:10:12: inlined hot callee '_Z3fool' with 172746 samples into 'main' +; CHECK: remark: coverage.cc:9:19: Applied 23478 samples from profile (offset: 2.1) +; CHECK: remark: coverage.cc:10:16: Applied 23478 samples from profile (offset: 3) +; CHECK: remark: coverage.cc:4:10: Applied 31878 samples from profile (offset: 1) +; CHECK: remark: coverage.cc:11:10: Applied 0 samples from profile (offset: 4) +; CHECK: remark: coverage.cc:10:16: most popular destination for conditional branches at coverage.cc:9:3 +; +; There is one sample record with 0 samples at offset 4 in main() that we never +; use: +; CHECK: warning: coverage.cc:7: 4 of 5 available profile records (80%) were applied +; +; Since the unused sample record contributes no samples, sample coverage should +; be 100%. Note that we get this warning because we are requesting an impossible +; 110% coverage check. +; CHECK: warning: coverage.cc:7: 78834 of 78834 available profile samples (100%) were applied + +define i64 @_Z3fool(i64 %i) !dbg !4 { +entry: + %i.addr = alloca i64, align 8 + store i64 %i, i64* %i.addr, align 8 + call void @llvm.dbg.declare(metadata i64* %i.addr, metadata !16, metadata !17), !dbg !18 + %call = call i32 @rand(), !dbg !19 + %conv = sext i32 %call to i64, !dbg !19 + %0 = load i64, i64* %i.addr, align 8, !dbg !20 + %mul = mul nsw i64 %conv, %0, !dbg !21 + ret i64 %mul, !dbg !22 +} + +declare void @llvm.dbg.declare(metadata, metadata, metadata) + +declare i32 @rand() + +define i32 @main() !dbg !9 { +entry: + %retval = alloca i32, align 4 + %sum = alloca i64, align 8 + %i = alloca i32, align 4 + store i32 0, i32* %retval, align 4 + call void @llvm.dbg.declare(metadata i64* %sum, metadata !23, metadata !17), !dbg !24 + store i64 0, i64* %sum, align 8, !dbg !24 + call void @llvm.dbg.declare(metadata i32* %i, metadata !25, metadata !17), !dbg !27 + store i32 0, i32* %i, align 4, !dbg !27 + br label %for.cond, !dbg !28 + +for.cond: ; preds = %for.inc, %entry + %0 = load i32, i32* %i, align 4, !dbg !29 + %cmp = icmp slt i32 %0, 600000000, !dbg !32 + br i1 %cmp, label %for.body, label %for.end, !dbg !33 + +for.body: ; preds = %for.cond + %1 = load i32, i32* %i, align 4, !dbg !34 + %conv = sext i32 %1 to i64, !dbg !34 + %call = call i64 @_Z3fool(i64 %conv), !dbg !35 + %2 = load i64, i64* %sum, align 8, !dbg !36 + %add = add nsw i64 %2, %call, !dbg !36 + store i64 %add, i64* %sum, align 8, !dbg !36 + br label %for.inc, !dbg !37 + +for.inc: ; preds = %for.body + %3 = load i32, i32* %i, align 4, !dbg !38 + %inc = add nsw i32 %3, 1, !dbg !38 + store i32 %inc, i32* %i, align 4, !dbg !38 + br label %for.cond, !dbg !39 + +for.end: ; preds = %for.cond + %4 = load i64, i64* %sum, align 8, !dbg !40 + %cmp1 = icmp sgt i64 %4, 0, !dbg !41 + %cond = select i1 %cmp1, i32 0, i32 1, !dbg !40 + ret i32 %cond, !dbg !42 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!13, !14} +!llvm.ident = !{!15} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.8.0 (trunk 251738) (llvm/trunk 251737)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, subprograms: !3) +!1 = !DIFile(filename: "coverage.cc", directory: ".") +!2 = !{} +!3 = !{!4, !9} +!4 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fool", scope: !1, file: !1, line: 3, type: !5, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, variables: !2) +!5 = !DISubroutineType(types: !6) +!6 = !{!7, !8} +!7 = !DIBasicType(name: "long long int", size: 64, align: 64, encoding: DW_ATE_signed) +!8 = !DIBasicType(name: "long int", size: 64, align: 64, encoding: DW_ATE_signed) +!9 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 7, type: !10, isLocal: false, isDefinition: true, scopeLine: 7, flags: DIFlagPrototyped, isOptimized: false, variables: !2) +!10 = !DISubroutineType(types: !11) +!11 = !{!12} +!12 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!13 = !{i32 2, !"Dwarf Version", i32 4} +!14 = !{i32 2, !"Debug Info Version", i32 3} +!15 = !{!"clang version 3.8.0 (trunk 251738) (llvm/trunk 251737)"} +!16 = !DILocalVariable(name: "i", arg: 1, scope: !4, file: !1, line: 3, type: !8) +!17 = !DIExpression() +!18 = !DILocation(line: 3, column: 24, scope: !4) +!19 = !DILocation(line: 4, column: 10, scope: !4) +!20 = !DILocation(line: 4, column: 19, scope: !4) +!21 = !DILocation(line: 4, column: 17, scope: !4) +!22 = !DILocation(line: 4, column: 3, scope: !4) +!23 = !DILocalVariable(name: "sum", scope: !9, file: !1, line: 8, type: !7) +!24 = !DILocation(line: 8, column: 17, scope: !9) +!25 = !DILocalVariable(name: "i", scope: !26, file: !1, line: 9, type: !12) +!26 = distinct !DILexicalBlock(scope: !9, file: !1, line: 9, column: 3) +!27 = !DILocation(line: 9, column: 12, scope: !26) +!28 = !DILocation(line: 9, column: 8, scope: !26) +!29 = !DILocation(line: 9, column: 19, scope: !30) +!30 = !DILexicalBlockFile(scope: !31, file: !1, discriminator: 1) +!31 = distinct !DILexicalBlock(scope: !26, file: !1, line: 9, column: 3) +!32 = !DILocation(line: 9, column: 21, scope: !30) +!33 = !DILocation(line: 9, column: 3, scope: !30) +!34 = !DILocation(line: 10, column: 16, scope: !31) +!35 = !DILocation(line: 10, column: 12, scope: !31) +!36 = !DILocation(line: 10, column: 9, scope: !31) +!37 = !DILocation(line: 10, column: 5, scope: !31) +!38 = !DILocation(line: 9, column: 39, scope: !31) +!39 = !DILocation(line: 9, column: 3, scope: !31) +!40 = !DILocation(line: 11, column: 10, scope: !9) +!41 = !DILocation(line: 11, column: 14, scope: !9) +!42 = !DILocation(line: 11, column: 3, scope: !9) diff --git a/test/Transforms/SampleProfile/inline-hint.ll b/test/Transforms/SampleProfile/inline-hint.ll new file mode 100644 index 000000000000..16c4e64ec5bb --- /dev/null +++ b/test/Transforms/SampleProfile/inline-hint.ll @@ -0,0 +1,38 @@ +; RUN: opt %s -sample-profile -sample-profile-file=%S/Inputs/inline-hint.prof -pass-remarks=sample-profile -o /dev/null 2>&1 | FileCheck %s +; +; CHECK: Applied cold hint to globally cold function '_Z7cold_fnRxi' with 0.1 +define void @_Z7cold_fnRxi() !dbg !4 { +entry: + ret void, !dbg !29 +} + +; CHECK: Applied inline hint to globally hot function '_Z6hot_fnRxi' with 70.0 +define void @_Z6hot_fnRxi() #0 !dbg !10 { +entry: + ret void, !dbg !38 +} + +!llvm.module.flags = !{!17, !18} +!llvm.ident = !{!19} + +!1 = !DIFile(filename: "inline-hint.cc", directory: ".") +!2 = !{} +!3 = !{!4, !10, !11, !14} +!4 = distinct !DISubprogram(name: "cold_fn", linkageName: "_Z7cold_fnRxi", scope: !1, file: !1, line: 3, type: !5, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, variables: !2) +!5 = !DISubroutineType(types: !6) +!6 = !{null, !7, !9} +!7 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !8, size: 64, align: 64) +!8 = !DIBasicType(name: "long long int", size: 64, align: 64, encoding: DW_ATE_signed) +!9 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!10 = distinct !DISubprogram(name: "hot_fn", linkageName: "_Z6hot_fnRxi", scope: !1, file: !1, line: 7, type: !5, isLocal: false, isDefinition: true, scopeLine: 7, flags: DIFlagPrototyped, isOptimized: false, variables: !2) +!11 = distinct !DISubprogram(name: "compute", linkageName: "_Z7computex", scope: !1, file: !1, line: 11, type: !12, isLocal: false, isDefinition: true, scopeLine: 11, flags: DIFlagPrototyped, isOptimized: false, variables: !2) +!12 = !DISubroutineType(types: !13) +!13 = !{!8, !8} +!14 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 21, type: !15, isLocal: false, isDefinition: true, scopeLine: 21, flags: DIFlagPrototyped, isOptimized: false, variables: !2) +!15 = !DISubroutineType(types: !16) +!16 = !{!9} +!17 = !{i32 2, !"Dwarf Version", i32 4} +!18 = !{i32 2, !"Debug Info Version", i32 3} +!19 = !{!"clang version 3.8.0 (trunk 254067) (llvm/trunk 254079)"} +!29 = !DILocation(line: 5, column: 1, scope: !4) +!38 = !DILocation(line: 9, column: 1, scope: !10) diff --git a/test/Transforms/SampleProfile/inline.ll b/test/Transforms/SampleProfile/inline.ll new file mode 100644 index 000000000000..590a20f9d1d1 --- /dev/null +++ b/test/Transforms/SampleProfile/inline.ll @@ -0,0 +1,108 @@ +; RUN: opt < %s -sample-profile -sample-profile-file=%S/Inputs/inline.prof -sample-profile-inline-hot-threshold=1 -S | FileCheck %s + +; Original C++ test case +; +; #include <stdio.h> +; +; int sum(int x, int y) { +; return x + y; +; } +; +; int main() { +; int s, i = 0; +; while (i++ < 20000 * 20000) +; if (i != 100) s = sum(i, s); else s = 30; +; printf("sum is %d\n", s); +; return 0; +; } +; +@.str = private unnamed_addr constant [11 x i8] c"sum is %d\0A\00", align 1 + +; Function Attrs: nounwind uwtable +define i32 @_Z3sumii(i32 %x, i32 %y) !dbg !4 { +entry: + %x.addr = alloca i32, align 4 + %y.addr = alloca i32, align 4 + store i32 %x, i32* %x.addr, align 4 + store i32 %y, i32* %y.addr, align 4 + %0 = load i32, i32* %x.addr, align 4, !dbg !11 + %1 = load i32, i32* %y.addr, align 4, !dbg !11 + %add = add nsw i32 %0, %1, !dbg !11 + ret i32 %add, !dbg !11 +} + +; Function Attrs: uwtable +define i32 @main() !dbg !7 { +entry: + %retval = alloca i32, align 4 + %s = alloca i32, align 4 + %i = alloca i32, align 4 + store i32 0, i32* %retval + store i32 0, i32* %i, align 4, !dbg !12 + br label %while.cond, !dbg !13 + +while.cond: ; preds = %if.end, %entry + %0 = load i32, i32* %i, align 4, !dbg !14 + %inc = add nsw i32 %0, 1, !dbg !14 + store i32 %inc, i32* %i, align 4, !dbg !14 + %cmp = icmp slt i32 %0, 400000000, !dbg !14 + br i1 %cmp, label %while.body, label %while.end, !dbg !14 + +while.body: ; preds = %while.cond + %1 = load i32, i32* %i, align 4, !dbg !16 + %cmp1 = icmp ne i32 %1, 100, !dbg !16 + br i1 %cmp1, label %if.then, label %if.else, !dbg !16 + + +if.then: ; preds = %while.body + %2 = load i32, i32* %i, align 4, !dbg !18 + %3 = load i32, i32* %s, align 4, !dbg !18 + %call = call i32 @_Z3sumii(i32 %2, i32 %3), !dbg !18 +; CHECK-NOT: call i32 @_Z3sumii + store i32 %call, i32* %s, align 4, !dbg !18 + br label %if.end, !dbg !18 + +if.else: ; preds = %while.body + store i32 30, i32* %s, align 4, !dbg !20 + br label %if.end + +if.end: ; preds = %if.else, %if.then + br label %while.cond, !dbg !22 + +while.end: ; preds = %while.cond + %4 = load i32, i32* %s, align 4, !dbg !24 + %call2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i32 0, i32 0), i32 %4), !dbg !24 + ret i32 0, !dbg !25 +} + +declare i32 @printf(i8*, ...) #2 + +!llvm.module.flags = !{!8, !9} +!llvm.ident = !{!10} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5 ", isOptimized: false, emissionKind: 0, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) +!1 = !DIFile(filename: "calls.cc", directory: ".") +!2 = !{} +!3 = !{!4, !7} +!4 = distinct !DISubprogram(name: "sum", line: 3, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 3, file: !1, scope: !5, type: !6, variables: !2) +!5 = !DIFile(filename: "calls.cc", directory: ".") +!6 = !DISubroutineType(types: !2) +!7 = distinct !DISubprogram(name: "main", line: 7, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 7, file: !1, scope: !5, type: !6, variables: !2) +!8 = !{i32 2, !"Dwarf Version", i32 4} +!9 = !{i32 1, !"Debug Info Version", i32 3} +!10 = !{!"clang version 3.5 "} +!11 = !DILocation(line: 4, scope: !4) +!12 = !DILocation(line: 8, scope: !7) +!13 = !DILocation(line: 9, scope: !7) +!14 = !DILocation(line: 9, scope: !15) +!15 = !DILexicalBlockFile(discriminator: 1, file: !1, scope: !7) +!16 = !DILocation(line: 10, scope: !17) +!17 = distinct !DILexicalBlock(line: 10, column: 0, file: !1, scope: !7) +!18 = !DILocation(line: 10, scope: !19) +!19 = !DILexicalBlockFile(discriminator: 1, file: !1, scope: !17) +!20 = !DILocation(line: 10, scope: !21) +!21 = !DILexicalBlockFile(discriminator: 2, file: !1, scope: !17) +!22 = !DILocation(line: 10, scope: !23) +!23 = !DILexicalBlockFile(discriminator: 3, file: !1, scope: !17) +!24 = !DILocation(line: 11, scope: !7) +!25 = !DILocation(line: 12, scope: !7) diff --git a/test/Transforms/SampleProfile/nolocinfo.ll b/test/Transforms/SampleProfile/nolocinfo.ll new file mode 100644 index 000000000000..08bca20984dd --- /dev/null +++ b/test/Transforms/SampleProfile/nolocinfo.ll @@ -0,0 +1,38 @@ +; RUN: opt < %s -sample-profile -sample-profile-file=%S/Inputs/nolocinfo.prof -S -pass-remarks=sample-profile 2>&1 | FileCheck %s + +define i32 @foo(i32 %i) !dbg !4 { +entry: + %i.addr = alloca i32, align 4 + %0 = load i32, i32* %i.addr, align 4 + %cmp = icmp sgt i32 %0, 1000 + +; Remarks for conditional branches need debug location information for the +; referring branch. When that is not present, the compiler should not abort. +; +; CHECK: remark: nolocinfo.c:3:5: most popular destination for conditional branches at <UNKNOWN LOCATION> + br i1 %cmp, label %if.then, label %if.end + +if.then: + ret i32 0, !dbg !18 + +if.end: + ret i32 1 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!8, !9} +!llvm.ident = !{!10} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.8.0 (trunk 251335) (llvm/trunk 251344)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, subprograms: !3) +!1 = !DIFile(filename: "nolocinfo.c", directory: ".") +!2 = !{} +!3 = !{!4} +!4 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: false, variables: !2) +!5 = !DISubroutineType(types: !6) +!6 = !{!7, !7} +!7 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!8 = !{i32 2, !"Dwarf Version", i32 4} +!9 = !{i32 2, !"Debug Info Version", i32 3} +!10 = !{!"clang version 3.8.0 (trunk 251335) (llvm/trunk 251344)"} +!15 = distinct !DILexicalBlock(scope: !4, file: !1, line: 2, column: 7) +!18 = !DILocation(line: 3, column: 5, scope: !15) diff --git a/test/Transforms/SampleProfile/offset.ll b/test/Transforms/SampleProfile/offset.ll new file mode 100644 index 000000000000..499b2826402d --- /dev/null +++ b/test/Transforms/SampleProfile/offset.ll @@ -0,0 +1,82 @@ +; RUN: opt < %s -sample-profile -sample-profile-file=%S/Inputs/offset.prof | opt -analyze -branch-prob | FileCheck %s + +; Original C++ code for this test case: +; +; a.cc: +; #1 +; #2 +; #3 +; #4 +; #5 int foo(int a) { +; #6 #include "a.b" +; #7} +; +; a.b: +; #1 if (a > 0) { +; #2 return 10; +; #3 } else { +; #4 return 20; +; #5 } + +; Function Attrs: nounwind uwtable +define i32 @_Z3fooi(i32 %a) #0 !dbg !4 { +entry: + %retval = alloca i32, align 4 + %a.addr = alloca i32, align 4 + store i32 %a, i32* %a.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %a.addr, metadata !11, metadata !12), !dbg !13 + %0 = load i32, i32* %a.addr, align 4, !dbg !14 + %cmp = icmp sgt i32 %0, 0, !dbg !18 + br i1 %cmp, label %if.then, label %if.else, !dbg !19 +; CHECK: edge entry -> if.then probability is 0x0147ae14 / 0x80000000 = 1.00% +; CHECK: edge entry -> if.else probability is 0x7eb851ec / 0x80000000 = 99.00% [HOT edge] + +if.then: ; preds = %entry + store i32 10, i32* %retval, align 4, !dbg !20 + br label %return, !dbg !20 + +if.else: ; preds = %entry + store i32 20, i32* %retval, align 4, !dbg !22 + br label %return, !dbg !22 + +return: ; preds = %if.else, %if.then + %1 = load i32, i32* %retval, align 4, !dbg !24 + ret i32 %1, !dbg !24 +} + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +attributes #0 = { nounwind uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!8, !9} +!llvm.ident = !{!10} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.8.0 (trunk 250750)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, subprograms: !3) +!1 = !DIFile(filename: "a.cc", directory: "/tmp") +!2 = !{} +!3 = !{!4} +!4 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !1, file: !1, line: 5, type: !5, isLocal: false, isDefinition: true, scopeLine: 5, flags: DIFlagPrototyped, isOptimized: false, variables: !2) +!5 = !DISubroutineType(types: !6) +!6 = !{!7, !7} +!7 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!8 = !{i32 2, !"Dwarf Version", i32 4} +!9 = !{i32 2, !"Debug Info Version", i32 3} +!10 = !{!"clang version 3.8.0 (trunk 250750)"} +!11 = !DILocalVariable(name: "a", arg: 1, scope: !4, file: !1, line: 5, type: !7) +!12 = !DIExpression() +!13 = !DILocation(line: 5, column: 13, scope: !4) +!14 = !DILocation(line: 1, column: 5, scope: !15) +!15 = distinct !DILexicalBlock(scope: !17, file: !16, line: 1, column: 5) +!16 = !DIFile(filename: "./a.b", directory: "/tmp") +!17 = !DILexicalBlockFile(scope: !4, file: !16, discriminator: 0) +!18 = !DILocation(line: 1, column: 7, scope: !15) +!19 = !DILocation(line: 1, column: 5, scope: !17) +!20 = !DILocation(line: 2, column: 3, scope: !21) +!21 = distinct !DILexicalBlock(scope: !15, file: !16, line: 1, column: 12) +!22 = !DILocation(line: 4, column: 3, scope: !23) +!23 = distinct !DILexicalBlock(scope: !15, file: !16, line: 3, column: 8) +!24 = !DILocation(line: 7, column: 1, scope: !25) +!25 = !DILexicalBlockFile(scope: !4, file: !1, discriminator: 0) diff --git a/test/Transforms/SampleProfile/propagate.ll b/test/Transforms/SampleProfile/propagate.ll index 620d125875f7..eef7b162eb7a 100644 --- a/test/Transforms/SampleProfile/propagate.ll +++ b/test/Transforms/SampleProfile/propagate.ll @@ -40,7 +40,7 @@ target triple = "x86_64-unknown-linux-gnu" @.str = private unnamed_addr constant [24 x i8] c"foo(%d, %d, %ld) = %ld\0A\00", align 1 ; Function Attrs: nounwind uwtable -define i64 @_Z3fooiil(i32 %x, i32 %y, i64 %N) #0 { +define i64 @_Z3fooiil(i32 %x, i32 %y, i64 %N) #0 !dbg !4 { entry: %retval = alloca i64, align 8 %x.addr = alloca i32, align 4 @@ -73,8 +73,8 @@ for.cond: ; preds = %for.inc16, %if.else %5 = load i64, i64* %N.addr, align 8, !dbg !15 %cmp1 = icmp slt i64 %4, %5, !dbg !15 br i1 %cmp1, label %for.body, label %for.end18, !dbg !15 -; CHECK: edge for.cond -> for.body probability is 10 / 10 = 100% [HOT edge] -; CHECK: edge for.cond -> for.end18 probability is 0 / 10 = 0% +; CHECK: edge for.cond -> for.body probability is 0x745d1746 / 0x80000000 = 90.91% [HOT edge] +; CHECK: edge for.cond -> for.end18 probability is 0x0ba2e8ba / 0x80000000 = 9.09% for.body: ; preds = %for.cond %6 = load i64, i64* %i, align 8, !dbg !18 @@ -82,8 +82,8 @@ for.body: ; preds = %for.cond %div = sdiv i64 %7, 3, !dbg !18 %cmp2 = icmp sgt i64 %6, %div, !dbg !18 br i1 %cmp2, label %if.then3, label %if.end, !dbg !18 -; CHECK: edge for.body -> if.then3 probability is 1 / 5 = 20% -; CHECK: edge for.body -> if.end probability is 4 / 5 = 80% +; CHECK: edge for.body -> if.then3 probability is 0x1999999a / 0x80000000 = 20.00% +; CHECK: edge for.body -> if.end probability is 0x66666666 / 0x80000000 = 80.00% if.then3: ; preds = %for.body %8 = load i32, i32* %x.addr, align 4, !dbg !21 @@ -97,8 +97,8 @@ if.end: ; preds = %if.then3, %for.body %div4 = sdiv i64 %10, 4, !dbg !22 %cmp5 = icmp sgt i64 %9, %div4, !dbg !22 br i1 %cmp5, label %if.then6, label %if.else7, !dbg !22 -; CHECK: edge if.end -> if.then6 probability is 3 / 6342 = 0.0473037% -; CHECK: edge if.end -> if.else7 probability is 6339 / 6342 = 99.9527% [HOT edge] +; CHECK: edge if.end -> if.then6 probability is 0x000f801f / 0x80000000 = 0.05% +; CHECK: edge if.end -> if.else7 probability is 0x7ff07fe1 / 0x80000000 = 99.95% [HOT edge] if.then6: ; preds = %if.end %11 = load i32, i32* %y.addr, align 4, !dbg !24 @@ -119,8 +119,8 @@ for.cond8: ; preds = %for.inc, %if.else7 %14 = load i64, i64* %i, align 8, !dbg !28 %cmp10 = icmp slt i64 %conv9, %14, !dbg !28 br i1 %cmp10, label %for.body11, label %for.end, !dbg !28 -; CHECK: edge for.cond8 -> for.body11 probability is 16191 / 16191 = 100% [HOT edge] -; CHECK: edge for.cond8 -> for.end probability is 0 / 16191 = 0% +; CHECK: edge for.cond8 -> for.body11 probability is 0x5bfc7472 / 0x80000000 = 71.86% +; CHECK: edge for.cond8 -> for.end probability is 0x24038b8e / 0x80000000 = 28.14% for.body11: ; preds = %for.cond8 %15 = load i32, i32* %j, align 4, !dbg !31 @@ -167,7 +167,7 @@ return: ; preds = %if.end19, %if.then } ; Function Attrs: uwtable -define i32 @main() #1 { +define i32 @main() #1 !dbg !7 { entry: %retval = alloca i32, align 4 %x = alloca i32, align 4 @@ -198,14 +198,14 @@ attributes #2 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "n !llvm.module.flags = !{!8, !9} !llvm.ident = !{!10} -!0 = !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5 ", isOptimized: false, emissionKind: 0, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5 ", isOptimized: false, emissionKind: 0, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) !1 = !DIFile(filename: "propagate.cc", directory: ".") !2 = !{} !3 = !{!4, !7} -!4 = !DISubprogram(name: "foo", line: 3, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 3, file: !1, scope: !5, type: !6, function: i64 (i32, i32, i64)* @_Z3fooiil, variables: !2) +!4 = distinct !DISubprogram(name: "foo", line: 3, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 3, file: !1, scope: !5, type: !6, variables: !2) !5 = !DIFile(filename: "propagate.cc", directory: ".") !6 = !DISubroutineType(types: !{null}) -!7 = !DISubprogram(name: "main", line: 24, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 24, file: !1, scope: !5, type: !6, function: i32 ()* @main, variables: !2) +!7 = distinct !DISubprogram(name: "main", line: 24, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 24, file: !1, scope: !5, type: !6, variables: !2) !8 = !{i32 2, !"Dwarf Version", i32 4} !9 = !{i32 1, !"Debug Info Version", i32 3} !10 = !{!"clang version 3.5 "} diff --git a/test/Transforms/SampleProfile/remarks.ll b/test/Transforms/SampleProfile/remarks.ll new file mode 100644 index 000000000000..a0e6a9deb8a8 --- /dev/null +++ b/test/Transforms/SampleProfile/remarks.ll @@ -0,0 +1,185 @@ +; RUN: opt < %s -sample-profile -sample-profile-file=%S/Inputs/remarks.prof -S -pass-remarks=sample-profile 2>&1 | FileCheck %s +; +; Original test case. +; +; 1 #include <stdlib.h> +; 2 +; 3 long long foo() { +; 4 long long int sum = 0; +; 5 for (int i = 0; i < 500000000; i++) +; 6 if (i < 1000) +; 7 sum -= i; +; 8 else +; 9 sum += -i * rand(); +; 10 return sum; +; 11 } +; 12 +; 13 int main() { return foo() > 0; } + +; We are expecting foo() to be inlined in main() (almost all the cycles are +; spent inside foo). +; CHECK: remark: remarks.cc:13:21: inlined hot callee '_Z3foov' with 623868 samples into 'main' + +; The back edge for the loop is the hottest edge in the loop subgraph. +; CHECK: remark: remarks.cc:6:9: most popular destination for conditional branches at remarks.cc:5:3 + +; The predicate almost always chooses the 'else' branch. +; CHECK: remark: remarks.cc:9:15: most popular destination for conditional branches at remarks.cc:6:9 + +; Function Attrs: nounwind uwtable +define i64 @_Z3foov() #0 !dbg !4 { +entry: + %sum = alloca i64, align 8 + %i = alloca i32, align 4 + %0 = bitcast i64* %sum to i8*, !dbg !19 + call void @llvm.lifetime.start(i64 8, i8* %0) #4, !dbg !19 + call void @llvm.dbg.declare(metadata i64* %sum, metadata !9, metadata !20), !dbg !21 + store i64 0, i64* %sum, align 8, !dbg !21, !tbaa !22 + %1 = bitcast i32* %i to i8*, !dbg !26 + call void @llvm.lifetime.start(i64 4, i8* %1) #4, !dbg !26 + call void @llvm.dbg.declare(metadata i32* %i, metadata !10, metadata !20), !dbg !27 + store i32 0, i32* %i, align 4, !dbg !27, !tbaa !28 + br label %for.cond, !dbg !26 + +for.cond: ; preds = %for.inc, %entry + %2 = load i32, i32* %i, align 4, !dbg !30, !tbaa !28 + %cmp = icmp slt i32 %2, 500000000, !dbg !34 + br i1 %cmp, label %for.body, label %for.cond.cleanup, !dbg !35 + +for.cond.cleanup: ; preds = %for.cond + %3 = bitcast i32* %i to i8*, !dbg !36 + call void @llvm.lifetime.end(i64 4, i8* %3) #4, !dbg !36 + br label %for.end + +for.body: ; preds = %for.cond + %4 = load i32, i32* %i, align 4, !dbg !38, !tbaa !28 + %cmp1 = icmp slt i32 %4, 1000, !dbg !40 + br i1 %cmp1, label %if.then, label %if.else, !dbg !41 + +if.then: ; preds = %for.body + %5 = load i32, i32* %i, align 4, !dbg !42, !tbaa !28 + %conv = sext i32 %5 to i64, !dbg !42 + %6 = load i64, i64* %sum, align 8, !dbg !43, !tbaa !22 + %sub = sub nsw i64 %6, %conv, !dbg !43 + store i64 %sub, i64* %sum, align 8, !dbg !43, !tbaa !22 + br label %if.end, !dbg !44 + +if.else: ; preds = %for.body + %7 = load i32, i32* %i, align 4, !dbg !45, !tbaa !28 + %sub2 = sub nsw i32 0, %7, !dbg !46 + %call = call i32 @rand() #4, !dbg !47 + %mul = mul nsw i32 %sub2, %call, !dbg !48 + %conv3 = sext i32 %mul to i64, !dbg !46 + %8 = load i64, i64* %sum, align 8, !dbg !49, !tbaa !22 + %add = add nsw i64 %8, %conv3, !dbg !49 + store i64 %add, i64* %sum, align 8, !dbg !49, !tbaa !22 + br label %if.end + +if.end: ; preds = %if.else, %if.then + br label %for.inc, !dbg !50 + +for.inc: ; preds = %if.end + %9 = load i32, i32* %i, align 4, !dbg !51, !tbaa !28 + %inc = add nsw i32 %9, 1, !dbg !51 + store i32 %inc, i32* %i, align 4, !dbg !51, !tbaa !28 + br label %for.cond, !dbg !52 + +for.end: ; preds = %for.cond.cleanup + %10 = load i64, i64* %sum, align 8, !dbg !53, !tbaa !22 + %11 = bitcast i64* %sum to i8*, !dbg !54 + call void @llvm.lifetime.end(i64 8, i8* %11) #4, !dbg !54 + ret i64 %10, !dbg !55 +} + +; Function Attrs: nounwind argmemonly +declare void @llvm.lifetime.start(i64, i8* nocapture) #1 + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata, metadata) #2 + +; Function Attrs: nounwind +declare i32 @rand() #3 + +; Function Attrs: nounwind argmemonly +declare void @llvm.lifetime.end(i64, i8* nocapture) #1 + +; Function Attrs: nounwind uwtable +define i32 @main() #0 !dbg !13 { +entry: + %retval = alloca i32, align 4 + store i32 0, i32* %retval, align 4 + %call = call i64 @_Z3foov(), !dbg !56 + %cmp = icmp sgt i64 %call, 0, !dbg !57 + %conv = zext i1 %cmp to i32, !dbg !56 + ret i32 %conv, !dbg !58 +} + +attributes #0 = { nounwind uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind argmemonly } +attributes #2 = { nounwind readnone } +attributes #3 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!16, !17} +!llvm.ident = !{!18} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.8.0 (trunk 251041) (llvm/trunk 251053)", isOptimized: true, runtimeVersion: 0, emissionKind: 1, enums: !2, subprograms: !3) +!1 = !DIFile(filename: "remarks.cc", directory: ".") +!2 = !{} +!3 = !{!4, !13} +!4 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !1, file: !1, line: 3, type: !5, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: true, variables: !8) +!5 = !DISubroutineType(types: !6) +!6 = !{!7} +!7 = !DIBasicType(name: "long long int", size: 64, align: 64, encoding: DW_ATE_signed) +!8 = !{!9, !10} +!9 = !DILocalVariable(name: "sum", scope: !4, file: !1, line: 4, type: !7) +!10 = !DILocalVariable(name: "i", scope: !11, file: !1, line: 5, type: !12) +!11 = distinct !DILexicalBlock(scope: !4, file: !1, line: 5, column: 3) +!12 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!13 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 13, type: !14, isLocal: false, isDefinition: true, scopeLine: 13, flags: DIFlagPrototyped, isOptimized: true, variables: !2) +!14 = !DISubroutineType(types: !15) +!15 = !{!12} +!16 = !{i32 2, !"Dwarf Version", i32 4} +!17 = !{i32 2, !"Debug Info Version", i32 3} +!18 = !{!"clang version 3.8.0 (trunk 251041) (llvm/trunk 251053)"} +!19 = !DILocation(line: 4, column: 3, scope: !4) +!20 = !DIExpression() +!21 = !DILocation(line: 4, column: 17, scope: !4) +!22 = !{!23, !23, i64 0} +!23 = !{!"long long", !24, i64 0} +!24 = !{!"omnipotent char", !25, i64 0} +!25 = !{!"Simple C/C++ TBAA"} +!26 = !DILocation(line: 5, column: 8, scope: !11) +!27 = !DILocation(line: 5, column: 12, scope: !11) +!28 = !{!29, !29, i64 0} +!29 = !{!"int", !24, i64 0} +!30 = !DILocation(line: 5, column: 19, scope: !31) +!31 = !DILexicalBlockFile(scope: !32, file: !1, discriminator: 3) +!32 = !DILexicalBlockFile(scope: !33, file: !1, discriminator: 1) +!33 = distinct !DILexicalBlock(scope: !11, file: !1, line: 5, column: 3) +!34 = !DILocation(line: 5, column: 21, scope: !33) +!35 = !DILocation(line: 5, column: 3, scope: !11) +!36 = !DILocation(line: 5, column: 3, scope: !37) +!37 = !DILexicalBlockFile(scope: !33, file: !1, discriminator: 2) +!38 = !DILocation(line: 6, column: 9, scope: !39) +!39 = distinct !DILexicalBlock(scope: !33, file: !1, line: 6, column: 9) +!40 = !DILocation(line: 6, column: 11, scope: !39) +!41 = !DILocation(line: 6, column: 9, scope: !33) +!42 = !DILocation(line: 7, column: 14, scope: !39) +!43 = !DILocation(line: 7, column: 11, scope: !39) +!44 = !DILocation(line: 7, column: 7, scope: !39) +!45 = !DILocation(line: 9, column: 15, scope: !39) +!46 = !DILocation(line: 9, column: 14, scope: !39) +!47 = !DILocation(line: 9, column: 19, scope: !39) +!48 = !DILocation(line: 9, column: 17, scope: !39) +!49 = !DILocation(line: 9, column: 11, scope: !39) +!50 = !DILocation(line: 6, column: 13, scope: !39) +!51 = !DILocation(line: 5, column: 35, scope: !33) +!52 = !DILocation(line: 5, column: 3, scope: !33) +!53 = !DILocation(line: 10, column: 10, scope: !4) +!54 = !DILocation(line: 11, column: 1, scope: !4) +!55 = !DILocation(line: 10, column: 3, scope: !4) +!56 = !DILocation(line: 13, column: 21, scope: !13) +!57 = !DILocation(line: 13, column: 27, scope: !13) +!58 = !DILocation(line: 13, column: 14, scope: !13) diff --git a/test/Transforms/SampleProfile/syntax.ll b/test/Transforms/SampleProfile/syntax.ll index ed38a175288a..debbc7c87ddb 100644 --- a/test/Transforms/SampleProfile/syntax.ll +++ b/test/Transforms/SampleProfile/syntax.ll @@ -13,7 +13,7 @@ entry: } ; NO-DEBUG: warning: No debug information found in function empty: Function profile not used ; MISSING-FILE: missing.prof: Could not open profile: -; BAD-FN-HEADER: error: {{.*}}bad_fn_header.prof:1: Expected 'mangled_name:NUM:NUM', found 3empty:100:BAD +; BAD-FN-HEADER: error: {{.*}}bad_fn_header.prof: Could not open profile: Unrecognized sample profile encoding format ; BAD-SAMPLE-LINE: error: {{.*}}bad_sample_line.prof:3: Expected 'NUM[.NUM]: NUM[ mangled_name:NUM]*', found 1: BAD ; BAD-LINE-VALUES: error: {{.*}}bad_line_values.prof:2: Expected 'mangled_name:NUM:NUM', found -1: 10 ; BAD-DISCRIMINATOR-VALUE: error: {{.*}}bad_discriminator_value.prof:2: Expected 'NUM[.NUM]: NUM[ mangled_name:NUM]*', found 1.-3: 10 |
