summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorDiego Novillo <dnovillo@google.com>2014-01-10 23:23:51 +0000
committerDiego Novillo <dnovillo@google.com>2014-01-10 23:23:51 +0000
commit4b2b2da9c76acff7f38854ad4187ce2a3d46da9d (patch)
treeec87b8eb0bfbb3844615d88334a9fe13dd436dcd /test
parent0de8cecb840e1b332a0a6f39855ddecda94202e8 (diff)
downloadllvm-4b2b2da9c76acff7f38854ad4187ce2a3d46da9d.tar.gz
llvm-4b2b2da9c76acff7f38854ad4187ce2a3d46da9d.tar.bz2
llvm-4b2b2da9c76acff7f38854ad4187ce2a3d46da9d.tar.xz
Extend and simplify the sample profile input file.
1- Use the line_iterator class to read profile files. 2- Allow comments in profile file. Lines starting with '#' are completely ignored while reading the profile. 3- Add parsing support for discriminators and indirect call samples. Our external profiler can emit more profile information that we are currently not handling. This patch does not add new functionality to support this information, but it allows profile files to provide it. I will add actual support later on (for at least one of these features, I need support for DWARF discriminators in Clang). A sample line may contain the following additional information: Discriminator. This is used if the sampled program was compiled with DWARF discriminator support (http://wiki.dwarfstd.org/index.php?title=Path_Discriminators). This is currently only emitted by GCC and we just ignore it. Potential call targets and samples. If present, this line contains a call instruction. This models both direct and indirect calls. Each called target is listed together with the number of samples. For example, 130: 7 foo:3 bar:2 baz:7 The above means that at relative line offset 130 there is a call instruction that calls one of foo(), bar() and baz(). With baz() being the relatively more frequent call target. Differential Revision: http://llvm-reviews.chandlerc.com/D2355 4- Simplify format of profile input file. This implements earlier suggestions to simplify the format of the sample profile file. The symbol table is not necessary and function profiles do not need to know the number of samples in advance. Differential Revision: http://llvm-reviews.chandlerc.com/D2419 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@198973 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r--test/Transforms/SampleProfile/Inputs/bad_fn_header.prof3
-rw-r--r--test/Transforms/SampleProfile/Inputs/bad_sample_line.prof5
-rw-r--r--test/Transforms/SampleProfile/Inputs/branch.prof5
-rw-r--r--test/Transforms/SampleProfile/Inputs/calls.prof11
-rw-r--r--test/Transforms/SampleProfile/Inputs/missing_num_syms.prof5
-rw-r--r--test/Transforms/SampleProfile/Inputs/missing_samples.prof6
-rw-r--r--test/Transforms/SampleProfile/Inputs/missing_symtab.prof5
-rw-r--r--test/Transforms/SampleProfile/Inputs/propagate.prof5
-rw-r--r--test/Transforms/SampleProfile/Inputs/syntax.prof5
-rw-r--r--test/Transforms/SampleProfile/calls.ll107
-rw-r--r--test/Transforms/SampleProfile/syntax.ll10
11 files changed, 124 insertions, 43 deletions
diff --git a/test/Transforms/SampleProfile/Inputs/bad_fn_header.prof b/test/Transforms/SampleProfile/Inputs/bad_fn_header.prof
index 90459e65d0..763956f068 100644
--- a/test/Transforms/SampleProfile/Inputs/bad_fn_header.prof
+++ b/test/Transforms/SampleProfile/Inputs/bad_fn_header.prof
@@ -1,6 +1,3 @@
-symbol table
-1
-empty
empty:100:BAD
0: 0
1: 100
diff --git a/test/Transforms/SampleProfile/Inputs/bad_sample_line.prof b/test/Transforms/SampleProfile/Inputs/bad_sample_line.prof
index 8c0d7630f9..038c45f77e 100644
--- a/test/Transforms/SampleProfile/Inputs/bad_sample_line.prof
+++ b/test/Transforms/SampleProfile/Inputs/bad_sample_line.prof
@@ -1,6 +1,3 @@
-symbol table
-1
-empty
-empty:100:0:1
+empty:100:0
0: 0
1: BAD
diff --git a/test/Transforms/SampleProfile/Inputs/branch.prof b/test/Transforms/SampleProfile/Inputs/branch.prof
index d19894d428..cd1cb5b1f1 100644
--- a/test/Transforms/SampleProfile/Inputs/branch.prof
+++ b/test/Transforms/SampleProfile/Inputs/branch.prof
@@ -1,7 +1,4 @@
-symbol table
-1
-main
-main:15680:0:7
+main:15680:0
0: 0
4: 0
7: 0
diff --git a/test/Transforms/SampleProfile/Inputs/calls.prof b/test/Transforms/SampleProfile/Inputs/calls.prof
new file mode 100644
index 0000000000..251cb538ef
--- /dev/null
+++ b/test/Transforms/SampleProfile/Inputs/calls.prof
@@ -0,0 +1,11 @@
+_Z3sumii:105580:5279
+0: 5279
+1: 5279
+2: 5279
+main:225715:0
+2: 5553
+3: 5391
+# This indicates that at line 3 of this function, the 'then' branch
+# of the conditional is taken (discriminator '1'). However, we still
+# do not handle this case, so we compute the wrong branch weights here.
+3.1: 5752 _Z3sumii:5860
diff --git a/test/Transforms/SampleProfile/Inputs/missing_num_syms.prof b/test/Transforms/SampleProfile/Inputs/missing_num_syms.prof
deleted file mode 100644
index 7cd053611c..0000000000
--- a/test/Transforms/SampleProfile/Inputs/missing_num_syms.prof
+++ /dev/null
@@ -1,5 +0,0 @@
-symbol table
-empty
-empty:100:0:1
-0: 0
-1: 100
diff --git a/test/Transforms/SampleProfile/Inputs/missing_samples.prof b/test/Transforms/SampleProfile/Inputs/missing_samples.prof
deleted file mode 100644
index edd36c2f52..0000000000
--- a/test/Transforms/SampleProfile/Inputs/missing_samples.prof
+++ /dev/null
@@ -1,6 +0,0 @@
-symbol table
-1
-empty
-empty:100:0:10
-0: 0
-1: 100
diff --git a/test/Transforms/SampleProfile/Inputs/missing_symtab.prof b/test/Transforms/SampleProfile/Inputs/missing_symtab.prof
deleted file mode 100644
index 2a826138b0..0000000000
--- a/test/Transforms/SampleProfile/Inputs/missing_symtab.prof
+++ /dev/null
@@ -1,5 +0,0 @@
-1
-empty
-empty:100:0:1
-0: 0
-1: 100
diff --git a/test/Transforms/SampleProfile/Inputs/propagate.prof b/test/Transforms/SampleProfile/Inputs/propagate.prof
index ea799e93ee..b28609be66 100644
--- a/test/Transforms/SampleProfile/Inputs/propagate.prof
+++ b/test/Transforms/SampleProfile/Inputs/propagate.prof
@@ -1,7 +1,4 @@
-symbol table
-1
-_Z3fooiil
-_Z3fooiil:58139:0:16
+_Z3fooiil:58139:0
0: 0
1: 0
2: 0
diff --git a/test/Transforms/SampleProfile/Inputs/syntax.prof b/test/Transforms/SampleProfile/Inputs/syntax.prof
index 9280751b2d..f3738912a9 100644
--- a/test/Transforms/SampleProfile/Inputs/syntax.prof
+++ b/test/Transforms/SampleProfile/Inputs/syntax.prof
@@ -1,6 +1,3 @@
-symbol table
-1
-empty
-empty:100:0:2
+empty:100:0
0: 0
1: 100
diff --git a/test/Transforms/SampleProfile/calls.ll b/test/Transforms/SampleProfile/calls.ll
new file mode 100644
index 0000000000..8f986e4e81
--- /dev/null
+++ b/test/Transforms/SampleProfile/calls.ll
@@ -0,0 +1,107 @@
+; RUN: opt < %s -sample-profile -sample-profile-file=%S/Inputs/calls.prof | opt -analyze -branch-prob | 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) {
+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* %x.addr, align 4, !dbg !11
+ %1 = load 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() {
+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* %i, align 4, !dbg !13
+ %inc = add nsw i32 %0, 1, !dbg !13
+ store i32 %inc, i32* %i, align 4, !dbg !13
+ %cmp = icmp slt i32 %0, 400000000, !dbg !13
+ br i1 %cmp, label %while.body, label %while.end, !dbg !13
+; CHECK: edge while.cond -> while.body probability is 11143 / 16696 = 66.7405%
+; CHECK: edge while.cond -> while.end probability is 5553 / 16696 = 33.2595%
+
+while.body: ; preds = %while.cond
+ %1 = load i32* %i, align 4, !dbg !14
+ %cmp1 = icmp ne i32 %1, 100, !dbg !14
+ br i1 %cmp1, label %if.then, label %if.else, !dbg !14
+; NOTE: These weights are wrong. We currently do not handle multiple
+; control flow paths in the same line. The edge while.body -> if.then
+; should be much heavier than the other one. Support for DWARF
+; discriminators will fix this.
+; CHECK: edge while.body -> if.then probability is 11143 / 22286 = 50%
+; CHECK: edge while.body -> if.else probability is 11143 / 22286 = 50%
+
+if.then: ; preds = %while.body
+ %2 = load i32* %i, align 4, !dbg !14
+ %3 = load i32* %s, align 4, !dbg !14
+ %call = call i32 @_Z3sumii(i32 %2, i32 %3), !dbg !14
+ store i32 %call, i32* %s, align 4, !dbg !14
+ br label %if.end, !dbg !14
+
+if.else: ; preds = %while.body
+ store i32 30, i32* %s, align 4, !dbg !14
+ br label %if.end
+
+if.end: ; preds = %if.else, %if.then
+ br label %while.cond, !dbg !14
+
+while.end: ; preds = %while.cond
+ %4 = load i32* %s, align 4, !dbg !16
+ %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([11 x i8]* @.str, i32 0, i32 0), i32 %4), !dbg !16
+ ret i32 0, !dbg !17
+}
+
+declare i32 @printf(i8*, ...)
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!8, !9}
+!llvm.ident = !{!10}
+
+!0 = metadata !{i32 786449, metadata !1, i32 4, metadata !"clang version 3.5 ", i1 false, metadata !"", i32 0, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2, metadata !""} ; [ DW_TAG_compile_unit ] [./calls.cc] [DW_LANG_C_plus_plus]
+!1 = metadata !{metadata !"calls.cc", metadata !"."}
+!2 = metadata !{i32 0}
+!3 = metadata !{metadata !4, metadata !7}
+!4 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"sum", metadata !"sum", metadata !"", i32 3, metadata !6, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 (i32, i32)* @_Z3sumii, null, null, metadata !2, i32 3} ; [ DW_TAG_subprogram ] [line 3] [def] [sum]
+!5 = metadata !{i32 786473, metadata !1} ; [ DW_TAG_file_type ] [./calls.cc]
+!6 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !2, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!7 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"main", metadata !"main", metadata !"", i32 7, metadata !6, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 ()* @main, null, null, metadata !2, i32 7} ; [ DW_TAG_subprogram ] [line 7] [def] [main]
+!8 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
+!9 = metadata !{i32 1, metadata !"Debug Info Version", i32 1}
+!10 = metadata !{metadata !"clang version 3.5 "}
+!11 = metadata !{i32 4, i32 0, metadata !4, null}
+!12 = metadata !{i32 8, i32 0, metadata !7, null} ; [ DW_TAG_imported_declaration ]
+!13 = metadata !{i32 9, i32 0, metadata !7, null}
+!14 = metadata !{i32 10, i32 0, metadata !15, null}
+!15 = metadata !{i32 786443, metadata !1, metadata !7, i32 10, i32 0, i32 0} ; [ DW_TAG_lexical_block ] [./calls.cc]
+!16 = metadata !{i32 11, i32 0, metadata !7, null}
+!17 = metadata !{i32 12, i32 0, metadata !7, null}
diff --git a/test/Transforms/SampleProfile/syntax.ll b/test/Transforms/SampleProfile/syntax.ll
index 41a08bc295..4fdfeae849 100644
--- a/test/Transforms/SampleProfile/syntax.ll
+++ b/test/Transforms/SampleProfile/syntax.ll
@@ -1,10 +1,7 @@
; RUN: not opt < %s -sample-profile -sample-profile-file=%S/Inputs/syntax.prof 2>&1 | FileCheck -check-prefix=NO-DEBUG %s
; RUN: not opt < %s -sample-profile -sample-profile-file=missing.prof 2>&1 | FileCheck -check-prefix=MISSING-FILE %s
-; RUN: not opt < %s -sample-profile -sample-profile-file=%S/Inputs/missing_symtab.prof 2>&1 | FileCheck -check-prefix=MISSING-SYMTAB %s
-; RUN: not opt < %s -sample-profile -sample-profile-file=%S/Inputs/missing_num_syms.prof 2>&1 | FileCheck -check-prefix=MISSING-NUM-SYMS %s
; RUN: not opt < %s -sample-profile -sample-profile-file=%S/Inputs/bad_fn_header.prof 2>&1 | FileCheck -check-prefix=BAD-FN-HEADER %s
; RUN: not opt < %s -sample-profile -sample-profile-file=%S/Inputs/bad_sample_line.prof 2>&1 | FileCheck -check-prefix=BAD-SAMPLE-LINE %s
-; RUN: not opt < %s -sample-profile -sample-profile-file=%S/Inputs/missing_samples.prof 2>&1 | FileCheck -check-prefix=MISSING-SAMPLES %s
define void @empty() {
entry:
@@ -12,8 +9,5 @@ entry:
}
; NO-DEBUG: LLVM ERROR: No debug information found in function empty
; MISSING-FILE: LLVM ERROR: Could not open file missing.prof: No such file or directory
-; MISSING-SYMTAB: LLVM ERROR: {{.*}}missing_symtab.prof:1: Expected 'symbol table', found 1
-; MISSING-NUM-SYMS: LLVM ERROR: {{.*}}missing_num_syms.prof:2: Expected a number, found empty
-; BAD-FN-HEADER: LLVM ERROR: {{.*}}bad_fn_header.prof:4: Expected 'mangled_name:NUM:NUM:NUM', found empty:100:BAD
-; BAD-SAMPLE-LINE: LLVM ERROR: {{.*}}bad_sample_line.prof:6: Expected 'mangled_name:NUM:NUM:NUM', found 1: BAD
-; MISSING-SAMPLES: LLVM ERROR: {{.*}}missing_samples.prof:6: Unexpected end of file
+; BAD-FN-HEADER: LLVM ERROR: {{.*}}bad_fn_header.prof:1: Expected 'mangled_name:NUM:NUM', found empty:100:BAD
+; BAD-SAMPLE-LINE: LLVM ERROR: {{.*}}bad_sample_line.prof:3: Expected 'NUM[.NUM]: NUM[ mangled_name:NUM]*', found 1: BAD