1;; Note that this needs new pass manager for now. Passing `-sample-profile-inline-replay` to legacy pass manager is a no-op.
2
3;; Check baseline inline decisions
4; RUN: opt < %s -passes=sample-profile -sample-profile-file=%S/Inputs/inline-topdown.prof -sample-profile-merge-inlinee -sample-profile-top-down-load -pass-remarks=inline -S 2>&1 | FileCheck -check-prefix=DEFAULT %s
5
6;; Check replay inline decisions
7; RUN: opt < %s -passes=sample-profile -sample-profile-file=%S/Inputs/inline-topdown.prof -sample-profile-inline-replay=%S/Inputs/inline-replay.txt -sample-profile-inline-replay-scope=Module  -sample-profile-merge-inlinee -sample-profile-top-down-load -pass-remarks=inline -S 2>&1 | FileCheck -check-prefix=REPLAY %s
8
9;; Check baseline inline decisions with "inline-topdown-inline-all.prof" which inlines all sites
10; RUN: opt < %s -passes=sample-profile -sample-profile-file=%S/Inputs/inline-topdown-inline-all.prof -sample-profile-merge-inlinee -sample-profile-top-down-load -pass-remarks=inline -S 2>&1 | FileCheck -check-prefix=DEFAULT-ALL %s
11
12;; Check function scope replay inline decisions with "inline-topdown-inline-all.prof" and "inline-topdown-function-scope.txt" which only contains: '_Z3sumii' inlined into 'main'
13;; 1. _Z3sumii is inlined into main, but all other inline candidates in main (e.g. _Z3subii) are not inlined
14;; 2. Inline decisions made in other functions match default sample inlining, in this case _Z3subii is inlined into _Z3sumii
15; RUN: opt < %s -passes=sample-profile -sample-profile-file=%S/Inputs/inline-topdown-inline-all.prof -sample-profile-inline-replay=%S/Inputs/inline-replay-function-scope.txt -sample-profile-inline-replay-scope=Function -sample-profile-merge-inlinee -sample-profile-top-down-load -pass-remarks=inline -S 2>&1 | FileCheck -check-prefix=REPLAY-ALL-FUNCTION %s
16
17;; Check behavior on non-existent replay file
18; RUN: not opt < %s -passes=sample-profile -sample-profile-file=%S/Inputs/inline-topdown.prof -sample-profile-inline-replay=%S -sample-profile-merge-inlinee -sample-profile-top-down-load -pass-remarks=inline -S 2>&1 | FileCheck -check-prefix=REPLAY-ERROR %s
19
20;; Check scope inlining errors out on non <Module|Function> inputs
21; RUN: not opt < %s -passes=sample-profile -sample-profile-file=%S/Inputs/inline-topdown.prof -sample-profile-inline-replay=%S/Inputs/inline-replay.txt -sample-profile-inline-replay-scope=function -sample-profile-merge-inlinee -sample-profile-top-down-load -pass-remarks=inline -S 2>&1 | FileCheck -check-prefix=REPLAY-ERROR-SCOPE %s
22
23; DEFAULT: '_Z3sumii' inlined into 'main' to match profiling context with (cost={{[-0-9]+}}
24; DEFAULT: '_Z3subii' inlined into '_Z3sumii' to match profiling context with (cost={{[-0-9]+}}
25; DEFAULT-NOT: '_Z3subii' inlined into 'main'
26
27; REPLAY: '_Z3sumii' inlined into 'main' to match profiling context with (cost=always)
28; REPLAY: '_Z3subii' inlined into 'main' to match profiling context with (cost=always)
29; REPLAY-NOT: '_Z3subii' inlined into '_Z3sumii'
30
31; DEFAULT-ALL: '_Z3sumii' inlined into 'main' to match profiling context with (cost={{[-0-9]+}}
32; DEFAULT-ALL: '_Z3subii' inlined into 'main' to match profiling context with (cost={{[-0-9]+}}
33; DEFAULT-ALL: '_Z3subii' inlined into '_Z3sumii' to match profiling context with (cost={{[-0-9]+}}
34
35; REPLAY-ALL-FUNCTION : _Z3sumii' inlined into 'main' to match profiling context with (cost=always)
36; REPLAY-ALL-FUNCTION-NOT: '_Z3subii' inlined into 'main' to match profiling context with (cost={{[-0-9]+}}
37; REPLAY-ALL-FUNCTION: '_Z3subii' inlined into '_Z3sumii' to match profiling context with (cost={{[-0-9]+}}
38
39; REPLAY-ERROR: error: Could not open remarks file:
40; REPLAY-ERROR-SCOPE: for the --sample-profile-inline-replay-scope option: Cannot find option named 'function'!
41
42@.str = private unnamed_addr constant [11 x i8] c"sum is %d\0A\00", align 1
43
44define i32 @_Z3sumii(i32 %x, i32 %y) #0 !dbg !6 {
45entry:
46  %x.addr = alloca i32, align 4
47  %y.addr = alloca i32, align 4
48  store i32 %x, i32* %x.addr, align 4
49  store i32 %y, i32* %y.addr, align 4
50  %tmp = load i32, i32* %x.addr, align 4, !dbg !8
51  %tmp1 = load i32, i32* %y.addr, align 4, !dbg !8
52  %add = add nsw i32 %tmp, %tmp1, !dbg !8
53  %tmp2 = load i32, i32* %x.addr, align 4, !dbg !8
54  %tmp3 = load i32, i32* %y.addr, align 4, !dbg !8
55  %call = call i32 @_Z3subii(i32 %tmp2, i32 %tmp3), !dbg !8
56  ret i32 %add, !dbg !8
57}
58
59define i32 @_Z3subii(i32 %x, i32 %y) #0 !dbg !9 {
60entry:
61  %x.addr = alloca i32, align 4
62  %y.addr = alloca i32, align 4
63  store i32 %x, i32* %x.addr, align 4
64  store i32 %y, i32* %y.addr, align 4
65  %tmp = load i32, i32* %x.addr, align 4, !dbg !10
66  %tmp1 = load i32, i32* %y.addr, align 4, !dbg !10
67  %add = sub nsw i32 %tmp, %tmp1, !dbg !10
68  ret i32 %add, !dbg !11
69}
70
71define i32 @main() #0 !dbg !12 {
72entry:
73  %retval = alloca i32, align 4
74  %s = alloca i32, align 4
75  %i = alloca i32, align 4
76  store i32 0, i32* %retval
77  store i32 0, i32* %i, align 4, !dbg !13
78  br label %while.cond, !dbg !14
79
80while.cond:                                       ; preds = %if.end, %entry
81  %tmp = load i32, i32* %i, align 4, !dbg !15
82  %inc = add nsw i32 %tmp, 1, !dbg !15
83  store i32 %inc, i32* %i, align 4, !dbg !15
84  %cmp = icmp slt i32 %tmp, 400000000, !dbg !15
85  br i1 %cmp, label %while.body, label %while.end, !dbg !15
86
87while.body:                                       ; preds = %while.cond
88  %tmp1 = load i32, i32* %i, align 4, !dbg !17
89  %cmp1 = icmp ne i32 %tmp1, 100, !dbg !17
90  br i1 %cmp1, label %if.then, label %if.else, !dbg !17
91
92if.then:                                          ; preds = %while.body
93  %tmp2 = load i32, i32* %i, align 4, !dbg !19
94  %tmp3 = load i32, i32* %s, align 4, !dbg !19
95  %call = call i32 @_Z3sumii(i32 %tmp2, i32 %tmp3), !dbg !19
96  store i32 %call, i32* %s, align 4, !dbg !19
97  br label %if.end, !dbg !19
98
99if.else:                                          ; preds = %while.body
100  store i32 30, i32* %s, align 4, !dbg !21
101  br label %if.end
102
103if.end:                                           ; preds = %if.else, %if.then
104  br label %while.cond, !dbg !23
105
106while.end:                                        ; preds = %while.cond
107  %tmp4 = load i32, i32* %s, align 4, !dbg !25
108  %call2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i32 0, i32 0), i32 %tmp4), !dbg !25
109  ret i32 0, !dbg !26
110}
111
112declare i32 @printf(i8*, ...)
113
114attributes #0 = { "use-sample-profile" }
115
116!llvm.dbg.cu = !{!0}
117!llvm.module.flags = !{!3, !4}
118!llvm.ident = !{!5}
119
120!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.5 ", isOptimized: false, runtimeVersion: 0, emissionKind: NoDebug, enums: !2, retainedTypes: !2, globals: !2, imports: !2)
121!1 = !DIFile(filename: "calls.cc", directory: ".")
122!2 = !{}
123!3 = !{i32 2, !"Dwarf Version", i32 4}
124!4 = !{i32 1, !"Debug Info Version", i32 3}
125!5 = !{!"clang version 3.5 "}
126!6 = distinct !DISubprogram(name: "sum", linkageName: "_Z3sumii", scope: !1, file: !1, line: 3, type: !7, scopeLine: 3, virtualIndex: 6, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
127!7 = !DISubroutineType(types: !2)
128!8 = !DILocation(line: 4, scope: !6)
129!9 = distinct !DISubprogram(name: "sub", linkageName: "_Z3subii", scope: !1, file: !1, line: 20, type: !7, scopeLine: 20, virtualIndex: 6, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
130!10 = !DILocation(line: 20, scope: !9)
131!11 = !DILocation(line: 21, scope: !9)
132!12 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 7, type: !7, scopeLine: 7, virtualIndex: 6, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
133!13 = !DILocation(line: 8, scope: !12)
134!14 = !DILocation(line: 9, scope: !12)
135!15 = !DILocation(line: 9, scope: !16)
136!16 = !DILexicalBlockFile(scope: !12, file: !1, discriminator: 2)
137!17 = !DILocation(line: 10, scope: !18)
138!18 = distinct !DILexicalBlock(scope: !12, file: !1, line: 10)
139!19 = !DILocation(line: 10, scope: !20)
140!20 = !DILexicalBlockFile(scope: !18, file: !1, discriminator: 2)
141!21 = !DILocation(line: 10, scope: !22)
142!22 = !DILexicalBlockFile(scope: !18, file: !1, discriminator: 4)
143!23 = !DILocation(line: 10, scope: !24)
144!24 = !DILexicalBlockFile(scope: !18, file: !1, discriminator: 6)
145!25 = !DILocation(line: 11, scope: !12)
146!26 = !DILocation(line: 12, scope: !12)
147