1
+ ; REQUIRES: have_tflite
2
+ ; RUN: rm -rf %t.runfiles %t.tflite %t.model_out
3
+ ; RUN: mkdir %t.runfiles
4
+ ; RUN: cp %S/../../../../lib/Analysis/models/gen-inline-oz-test-model.py %t.runfiles
5
+ ; RUN: cp %S/../../../../lib/Analysis/models/saved-model-to-tflite.py %t.runfiles
6
+ ; RUN: %python %t.runfiles/gen-inline-oz-test-model.py %t.model_out never
7
+ ; RUN: %python %t.runfiles/saved-model-to-tflite.py %t.model_out %t.tflite
8
+
9
+ ; When running O2, we expect both callers to inline callee.
10
+ ; RUN: opt < %s -passes='default<O2>' -inline-threshold=0 -hot-callsite-threshold=100 -S | FileCheck %s --check-prefixes=O2-HOT,O2-COLD
11
+
12
+ ; The ML model we use always blocks inlining (by construction)
13
+ ; RUN: opt < %s -passes='default<O2>' -inline-threshold=0 -hot-callsite-threshold=100 \
14
+ ; RUN: -enable-ml-inliner=development -ml-inliner-model-under-training=%t.tflite \
15
+ ; RUN: -S | FileCheck %s --check-prefixes=ML-HOT,ML-COLD
16
+
17
+ ; When bypassing ML for non-cold callers, the hot caller will have its callee inlined, but the cold one won't
18
+ ; RUN: opt < %s -passes='default<O2>' -inline-threshold=0 -hot-callsite-threshold=100 \
19
+ ; RUN: -enable-ml-inliner=development -ml-inliner-model-under-training=%t.tflite \
20
+ ; RUN: -ml-inliner-skip-policy=if-caller-not-cold -S | FileCheck %s --check-prefixes=O2-HOT,ML-COLD
21
+
22
+ declare void @extern ()
23
+
24
+ define i32 @callee (i32 %x ) {
25
+ %x1 = add i32 %x , 1
26
+ %x2 = add i32 %x1 , 1
27
+ %x3 = add i32 %x2 , 1
28
+ call void @extern ()
29
+ call void @extern ()
30
+ ret i32 %x3
31
+ }
32
+
33
+ define i32 @hot_caller (i32 %y1 ) !prof !15 {
34
+ %y = call i32 @callee (i32 %y1 ), !prof !16
35
+ ret i32 %y
36
+ }
37
+
38
+ define i32 @cold_caller (i32 %y1 ) !prof !17 {
39
+ %y = call i32 @callee (i32 %y1 ), !prof !16
40
+ ret i32 %y
41
+ }
42
+
43
+
44
+ !llvm.module.flags = !{!1 }
45
+ !15 = !{!"function_entry_count" , i64 300 }
46
+ !16 = !{!"branch_weights" , i64 300 }
47
+ !17 = !{!"function_entry_count" , i64 1 }
48
+
49
+ !1 = !{i32 1 , !"ProfileSummary" , !2 }
50
+ !2 = !{!3 , !4 , !5 , !6 , !7 , !8 , !9 , !10 }
51
+ !3 = !{!"ProfileFormat" , !"SampleProfile" }
52
+ !4 = !{!"TotalCount" , i64 10000 }
53
+ !5 = !{!"MaxCount" , i64 1000 }
54
+ !6 = !{!"MaxInternalCount" , i64 1 }
55
+ !7 = !{!"MaxFunctionCount" , i64 1000 }
56
+ !8 = !{!"NumCounts" , i64 3 }
57
+ !9 = !{!"NumFunctions" , i64 3 }
58
+ !10 = !{!"DetailedSummary" , !11 }
59
+ !11 = !{!12 , !13 , !14 }
60
+ !12 = !{i32 10000 , i64 100 , i32 1 }
61
+ !13 = !{i32 999000 , i64 100 , i32 1 }
62
+ !14 = !{i32 999999 , i64 1 , i32 2 }
63
+
64
+ ; O2-HOT-LABEL: @hot_caller
65
+ ; O2-HOT-NOT: call i32 @callee
66
+ ; O2-HOT: call void @extern
67
+ ; O2-HOT-NEXT: call void @extern
68
+ ; O2-HOT-NEXT: ret
69
+ ; O2-COLD-LABEL: @cold_caller
70
+ ; O2-COLD-NOT: call i32 @callee
71
+ ; O2-COLD: call void @extern
72
+ ; O2-COLD-NEXT: call void @extern
73
+ ; O2-COLD-NEXT: ret
74
+
75
+ ; ML-HOT-LABEL: @hot_caller
76
+ ; ML-HOT-NEXT: call i32 @callee
77
+ ; ML-COLD-LABEL: @cold_caller
78
+ ; ML-COLD-NEXT: call i32 @callee
0 commit comments