1; RUN: opt < %s -analyze -block-freq | FileCheck %s
2; RUN: opt < %s -passes='print<block-freq>' -disable-output 2>&1 | FileCheck %s
3
4; CHECK-LABEL: Printing analysis {{.*}} for function 'double_exit':
5; CHECK-NEXT: block-frequency-info: double_exit
6define i32 @double_exit(i32 %N) {
7; Mass = 1
8; Frequency = 1
9; CHECK-NEXT: entry: float = 1.0, int = [[ENTRY:[0-9]+]]
10entry:
11  br label %outer
12
13; Mass = 1
14; Backedge mass = 1/3, exit mass = 2/3
15; Loop scale = 3/2
16; Pseudo-edges = exit
17; Pseudo-mass = 1
18; Frequency = 1*3/2*1 = 3/2
19; CHECK-NEXT: outer: float = 1.5,
20outer:
21  %I.0 = phi i32 [ 0, %entry ], [ %inc6, %outer.inc ]
22  %Return.0 = phi i32 [ 0, %entry ], [ %Return.1, %outer.inc ]
23  %cmp = icmp slt i32 %I.0, %N
24  br i1 %cmp, label %inner, label %exit, !prof !2 ; 2:1
25
26; Mass = 1
27; Backedge mass = 3/5, exit mass = 2/5
28; Loop scale = 5/2
29; Pseudo-edges = outer.inc @ 1/5, exit @ 1/5
30; Pseudo-mass = 2/3
31; Frequency = 3/2*1*5/2*2/3 = 5/2
32; CHECK-NEXT: inner: float = 2.5,
33inner:
34  %Return.1 = phi i32 [ %Return.0, %outer ], [ %call4, %inner.inc ]
35  %J.0 = phi i32 [ %I.0, %outer ], [ %inc, %inner.inc ]
36  %cmp2 = icmp slt i32 %J.0, %N
37  br i1 %cmp2, label %inner.body, label %outer.inc, !prof !1 ; 4:1
38
39; Mass = 4/5
40; Frequency = 5/2*4/5 = 2
41; CHECK-NEXT: inner.body: float = 2.0,
42inner.body:
43  %call = call i32 @c2(i32 %I.0, i32 %J.0)
44  %tobool = icmp ne i32 %call, 0
45  br i1 %tobool, label %exit, label %inner.inc, !prof !0 ; 3:1
46
47; Mass = 3/5
48; Frequency = 5/2*3/5 = 3/2
49; CHECK-NEXT: inner.inc: float = 1.5,
50inner.inc:
51  %call4 = call i32 @logic2(i32 %Return.1, i32 %I.0, i32 %J.0)
52  %inc = add nsw i32 %J.0, 1
53  br label %inner
54
55; Mass = 1/3
56; Frequency = 3/2*1/3 = 1/2
57; CHECK-NEXT: outer.inc: float = 0.5,
58outer.inc:
59  %inc6 = add nsw i32 %I.0, 1
60  br label %outer
61
62; Mass = 1
63; Frequency = 1
64; CHECK-NEXT: exit: float = 1.0, int = [[ENTRY]]
65exit:
66  %Return.2 = phi i32 [ %Return.1, %inner.body ], [ %Return.0, %outer ]
67  ret i32 %Return.2
68}
69
70!0 = !{!"branch_weights", i32 1, i32 3}
71!1 = !{!"branch_weights", i32 4, i32 1}
72!2 = !{!"branch_weights", i32 2, i32 1}
73
74declare i32 @c2(i32, i32)
75declare i32 @logic2(i32, i32, i32)
76
77; CHECK-LABEL: Printing analysis {{.*}} for function 'double_exit_in_loop':
78; CHECK-NEXT: block-frequency-info: double_exit_in_loop
79define i32 @double_exit_in_loop(i32 %N) {
80; Mass = 1
81; Frequency = 1
82; CHECK-NEXT: entry: float = 1.0, int = [[ENTRY:[0-9]+]]
83entry:
84  br label %outer
85
86; Mass = 1
87; Backedge mass = 1/2, exit mass = 1/2
88; Loop scale = 2
89; Pseudo-edges = exit
90; Pseudo-mass = 1
91; Frequency = 1*2*1 = 2
92; CHECK-NEXT: outer: float = 2.0,
93outer:
94  %I.0 = phi i32 [ 0, %entry ], [ %inc12, %outer.inc ]
95  %Return.0 = phi i32 [ 0, %entry ], [ %Return.3, %outer.inc ]
96  %cmp = icmp slt i32 %I.0, %N
97  br i1 %cmp, label %middle, label %exit, !prof !3 ; 1:1
98
99; Mass = 1
100; Backedge mass = 1/3, exit mass = 2/3
101; Loop scale = 3/2
102; Pseudo-edges = outer.inc
103; Pseudo-mass = 1/2
104; Frequency = 2*1*3/2*1/2 = 3/2
105; CHECK-NEXT: middle: float = 1.5,
106middle:
107  %J.0 = phi i32 [ %I.0, %outer ], [ %inc9, %middle.inc ]
108  %Return.1 = phi i32 [ %Return.0, %outer ], [ %Return.2, %middle.inc ]
109  %cmp2 = icmp slt i32 %J.0, %N
110  br i1 %cmp2, label %inner, label %outer.inc, !prof !2 ; 2:1
111
112; Mass = 1
113; Backedge mass = 3/5, exit mass = 2/5
114; Loop scale = 5/2
115; Pseudo-edges = middle.inc @ 1/5, outer.inc @ 1/5
116; Pseudo-mass = 2/3
117; Frequency = 3/2*1*5/2*2/3 = 5/2
118; CHECK-NEXT: inner: float = 2.5,
119inner:
120  %Return.2 = phi i32 [ %Return.1, %middle ], [ %call7, %inner.inc ]
121  %K.0 = phi i32 [ %J.0, %middle ], [ %inc, %inner.inc ]
122  %cmp5 = icmp slt i32 %K.0, %N
123  br i1 %cmp5, label %inner.body, label %middle.inc, !prof !1 ; 4:1
124
125; Mass = 4/5
126; Frequency = 5/2*4/5 = 2
127; CHECK-NEXT: inner.body: float = 2.0,
128inner.body:
129  %call = call i32 @c3(i32 %I.0, i32 %J.0, i32 %K.0)
130  %tobool = icmp ne i32 %call, 0
131  br i1 %tobool, label %outer.inc, label %inner.inc, !prof !0 ; 3:1
132
133; Mass = 3/5
134; Frequency = 5/2*3/5 = 3/2
135; CHECK-NEXT: inner.inc: float = 1.5,
136inner.inc:
137  %call7 = call i32 @logic3(i32 %Return.2, i32 %I.0, i32 %J.0, i32 %K.0)
138  %inc = add nsw i32 %K.0, 1
139  br label %inner
140
141; Mass = 1/3
142; Frequency = 3/2*1/3 = 1/2
143; CHECK-NEXT: middle.inc: float = 0.5,
144middle.inc:
145  %inc9 = add nsw i32 %J.0, 1
146  br label %middle
147
148; Mass = 1/2
149; Frequency = 2*1/2 = 1
150; CHECK-NEXT: outer.inc: float = 1.0,
151outer.inc:
152  %Return.3 = phi i32 [ %Return.2, %inner.body ], [ %Return.1, %middle ]
153  %inc12 = add nsw i32 %I.0, 1
154  br label %outer
155
156; Mass = 1
157; Frequency = 1
158; CHECK-NEXT: exit: float = 1.0, int = [[ENTRY]]
159exit:
160  ret i32 %Return.0
161}
162
163!3 = !{!"branch_weights", i32 1, i32 1}
164
165declare i32 @c3(i32, i32, i32)
166declare i32 @logic3(i32, i32, i32, i32)
167