1 // RUN: mlir-opt -test-ir-visitors -allow-unregistered-dialect -split-input-file %s | FileCheck %s
3 // Verify the different configurations of IR visitors.
4 // Constant, yield and other terminator ops are not matched for simplicity.
5 // Module and function op and their immediately nested blocks are not erased in
6 // callbacks with return so that the output includes more cases in pre-order.
8 func.func @structured_cfg() {
9 %c0 = arith.constant 0 : index
10 %c1 = arith.constant 1 : index
11 %c10 = arith.constant 10 : index
12 scf.for %i = %c1 to %c10 step %c1 {
13 %cond = "use0"(%i) : (index) -> (i1)
15 "use1"(%i) : (index) -> ()
17 "use2"(%i) : (index) -> ()
19 "use3"(%i) : (index) -> ()
20 } {walk_blocks, walk_regions}
24 // CHECK-LABEL: Op pre-order visit
25 // CHECK: Visiting op 'builtin.module'
26 // CHECK: Visiting op 'func.func'
27 // CHECK: Visiting op 'scf.for'
28 // CHECK: Visiting op 'use0'
29 // CHECK: Visiting op 'scf.if'
30 // CHECK: Visiting op 'use1'
31 // CHECK: Visiting op 'use2'
32 // CHECK: Visiting op 'use3'
33 // CHECK: Visiting op 'func.return'
35 // CHECK-LABEL: Block pre-order visits
36 // CHECK: Visiting block ^bb0 from region 0 from operation 'builtin.module'
37 // CHECK: Visiting block ^bb0 from region 0 from operation 'func.func'
38 // CHECK: Visiting block ^bb0 from region 0 from operation 'scf.for'
39 // CHECK: Visiting block ^bb0 from region 0 from operation 'scf.if'
40 // CHECK: Visiting block ^bb0 from region 1 from operation 'scf.if'
42 // CHECK-LABEL: Region pre-order visits
43 // CHECK: Visiting region 0 from operation 'builtin.module'
44 // CHECK: Visiting region 0 from operation 'func.func'
45 // CHECK: Visiting region 0 from operation 'scf.for'
46 // CHECK: Visiting region 0 from operation 'scf.if'
47 // CHECK: Visiting region 1 from operation 'scf.if'
49 // CHECK-LABEL: Op post-order visits
50 // CHECK: Visiting op 'use0'
51 // CHECK: Visiting op 'use1'
52 // CHECK: Visiting op 'use2'
53 // CHECK: Visiting op 'scf.if'
54 // CHECK: Visiting op 'use3'
55 // CHECK: Visiting op 'scf.for'
56 // CHECK: Visiting op 'func.return'
57 // CHECK: Visiting op 'func.func'
58 // CHECK: Visiting op 'builtin.module'
60 // CHECK-LABEL: Block post-order visits
61 // CHECK: Visiting block ^bb0 from region 0 from operation 'scf.if'
62 // CHECK: Visiting block ^bb0 from region 1 from operation 'scf.if'
63 // CHECK: Visiting block ^bb0 from region 0 from operation 'scf.for'
64 // CHECK: Visiting block ^bb0 from region 0 from operation 'func.func'
65 // CHECK: Visiting block ^bb0 from region 0 from operation 'builtin.module'
67 // CHECK-LABEL: Region post-order visits
68 // CHECK: Visiting region 0 from operation 'scf.if'
69 // CHECK: Visiting region 1 from operation 'scf.if'
70 // CHECK: Visiting region 0 from operation 'scf.for'
71 // CHECK: Visiting region 0 from operation 'func.func'
72 // CHECK: Visiting region 0 from operation 'builtin.module'
74 // CHECK-LABEL: Op reverse post-order visits
75 // CHECK: Visiting op 'func.return'
76 // CHECK: Visiting op 'scf.yield'
77 // CHECK: Visiting op 'use3'
78 // CHECK: Visiting op 'scf.yield'
79 // CHECK: Visiting op 'use2'
80 // CHECK: Visiting op 'scf.yield'
81 // CHECK: Visiting op 'use1'
82 // CHECK: Visiting op 'scf.if'
83 // CHECK: Visiting op 'use0'
84 // CHECK: Visiting op 'scf.for'
85 // CHECK: Visiting op 'arith.constant'
86 // CHECK: Visiting op 'arith.constant'
87 // CHECK: Visiting op 'arith.constant'
88 // CHECK: Visiting op 'func.func'
89 // CHECK: Visiting op 'builtin.module'
91 // CHECK-LABEL: Invoke block pre-order visits on blocks
92 // CHECK: Visiting block ^bb0 from region 0 from operation 'scf.for'
93 // CHECK: Visiting block ^bb0 from region 0 from operation 'scf.if'
94 // CHECK: Visiting block ^bb0 from region 1 from operation 'scf.if'
96 // CHECK-LABEL: Invoke block post-order visits on blocks
97 // CHECK: Visiting block ^bb0 from region 0 from operation 'scf.if'
98 // CHECK: Visiting block ^bb0 from region 1 from operation 'scf.if'
99 // CHECK: Visiting block ^bb0 from region 0 from operation 'scf.for'
101 // CHECK-LABEL: Invoke region pre-order visits on region
102 // CHECK: Visiting region 0 from operation 'scf.for'
103 // CHECK: Visiting region 0 from operation 'scf.if'
104 // CHECK: Visiting region 1 from operation 'scf.if'
106 // CHECK-LABEL: Invoke region post-order visits on region
107 // CHECK: Visiting region 0 from operation 'scf.if'
108 // CHECK: Visiting region 1 from operation 'scf.if'
109 // CHECK: Visiting region 0 from operation 'scf.for'
111 // CHECK-LABEL: Op pre-order erasures
112 // CHECK: Erasing op 'scf.for'
113 // CHECK: Erasing op 'func.return'
115 // CHECK-LABEL: Block pre-order erasures
116 // CHECK: Erasing block ^bb0 from region 0 from operation 'scf.for'
118 // CHECK-LABEL: Op post-order erasures (skip)
119 // CHECK: Erasing op 'use0'
120 // CHECK: Erasing op 'use1'
121 // CHECK: Erasing op 'use2'
122 // CHECK: Erasing op 'scf.if'
123 // CHECK: Erasing op 'use3'
124 // CHECK: Erasing op 'scf.for'
125 // CHECK: Erasing op 'func.return'
127 // CHECK-LABEL: Block post-order erasures (skip)
128 // CHECK: Erasing block ^bb0 from region 0 from operation 'scf.if'
129 // CHECK: Erasing block ^bb0 from region 1 from operation 'scf.if'
130 // CHECK: Erasing block ^bb0 from region 0 from operation 'scf.for'
132 // CHECK-LABEL: Op post-order erasures (no skip)
133 // CHECK: Erasing op 'use0'
134 // CHECK: Erasing op 'use1'
135 // CHECK: Erasing op 'use2'
136 // CHECK: Erasing op 'scf.if'
137 // CHECK: Erasing op 'use3'
138 // CHECK: Erasing op 'scf.for'
139 // CHECK: Erasing op 'func.return'
140 // CHECK: Erasing op 'func.func'
141 // CHECK: Erasing op 'builtin.module'
143 // CHECK-LABEL: Block post-order erasures (no skip)
144 // CHECK: Erasing block ^bb0 from region 0 from operation 'scf.if'
145 // CHECK: Erasing block ^bb0 from region 1 from operation 'scf.if'
146 // CHECK: Erasing block ^bb0 from region 0 from operation 'scf.for'
147 // CHECK: Erasing block ^bb0 from region 0 from operation 'func.func'
148 // CHECK: Erasing block ^bb0 from region 0 from operation 'builtin.module'
152 func.func @unstructured_cfg() {
166 // CHECK-LABEL: Op pre-order visits
167 // CHECK: Visiting op 'builtin.module'
168 // CHECK: Visiting op 'func.func'
169 // CHECK: Visiting op 'regionOp0'
170 // CHECK: Visiting op 'op0'
171 // CHECK: Visiting op 'cf.br'
172 // CHECK: Visiting op 'op1'
173 // CHECK: Visiting op 'cf.br'
174 // CHECK: Visiting op 'op2'
175 // CHECK: Visiting op 'func.return'
177 // CHECK-LABEL: Block pre-order visits
178 // CHECK: Visiting block ^bb0 from region 0 from operation 'builtin.module'
179 // CHECK: Visiting block ^bb0 from region 0 from operation 'func.func'
180 // CHECK: Visiting block ^bb0 from region 0 from operation 'regionOp0'
181 // CHECK: Visiting block ^bb1 from region 0 from operation 'regionOp0'
182 // CHECK: Visiting block ^bb2 from region 0 from operation 'regionOp0'
184 // CHECK-LABEL: Region pre-order visits
185 // CHECK: Visiting region 0 from operation 'builtin.module'
186 // CHECK: Visiting region 0 from operation 'func.func'
187 // CHECK: Visiting region 0 from operation 'regionOp0'
189 // CHECK-LABEL: Op post-order visits
190 // CHECK: Visiting op 'op0'
191 // CHECK: Visiting op 'cf.br'
192 // CHECK: Visiting op 'op1'
193 // CHECK: Visiting op 'cf.br'
194 // CHECK: Visiting op 'op2'
195 // CHECK: Visiting op 'regionOp0'
196 // CHECK: Visiting op 'func.return'
197 // CHECK: Visiting op 'func.func'
198 // CHECK: Visiting op 'builtin.module'
200 // CHECK-LABEL: Block post-order visits
201 // CHECK: Visiting block ^bb0 from region 0 from operation 'regionOp0'
202 // CHECK: Visiting block ^bb1 from region 0 from operation 'regionOp0'
203 // CHECK: Visiting block ^bb2 from region 0 from operation 'regionOp0'
204 // CHECK: Visiting block ^bb0 from region 0 from operation 'func.func'
205 // CHECK: Visiting block ^bb0 from region 0 from operation 'builtin.module'
207 // CHECK-LABEL: Region post-order visits
208 // CHECK: Visiting region 0 from operation 'regionOp0'
209 // CHECK: Visiting region 0 from operation 'func.func'
210 // CHECK: Visiting region 0 from operation 'builtin.module'
212 // CHECK-LABEL: Op reverse post-order visits
213 // CHECK: Visiting op 'func.return'
214 // CHECK: Visiting op 'op2'
215 // CHECK: Visiting op 'cf.br'
216 // CHECK: Visiting op 'op1'
217 // CHECK: Visiting op 'cf.br'
218 // CHECK: Visiting op 'op0'
219 // CHECK: Visiting op 'regionOp0'
220 // CHECK: Visiting op 'func.func'
221 // CHECK: Visiting op 'builtin.module'
223 // CHECK-LABEL: Block reverse post-order visits
224 // CHECK: Visiting block ^bb2 from region 0 from operation 'regionOp0'
225 // CHECK: Visiting block ^bb1 from region 0 from operation 'regionOp0'
226 // CHECK: Visiting block ^bb0 from region 0 from operation 'regionOp0'
227 // CHECK: Visiting block ^bb0 from region 0 from operation 'func.func'
228 // CHECK: Visiting block ^bb0 from region 0 from operation 'builtin.module'
230 // CHECK-LABEL: Region reverse post-order visits
231 // CHECK: Visiting region 0 from operation 'regionOp0'
232 // CHECK: Visiting region 0 from operation 'func.func'
233 // CHECK: Visiting region 0 from operation 'builtin.module'
235 // CHECK-LABEL: Op pre-order erasures (skip)
236 // CHECK: Erasing op 'regionOp0'
237 // CHECK: Erasing op 'func.return'
239 // CHECK-LABEL: Block pre-order erasures (skip)
240 // CHECK: Erasing block ^bb0 from region 0 from operation 'regionOp0'
241 // CHECK: Erasing block ^bb0 from region 0 from operation 'regionOp0'
242 // CHECK: Erasing block ^bb0 from region 0 from operation 'regionOp0'
244 // CHECK-LABEL: Op post-order erasures (skip)
245 // CHECK: Erasing op 'op0'
246 // CHECK: Erasing op 'cf.br'
247 // CHECK: Erasing op 'op1'
248 // CHECK: Erasing op 'cf.br'
249 // CHECK: Erasing op 'op2'
250 // CHECK: Erasing op 'regionOp0'
251 // CHECK: Erasing op 'func.return'
253 // CHECK-LABEL: Block post-order erasures (skip)
254 // CHECK: Erasing block ^bb0 from region 0 from operation 'regionOp0'
255 // CHECK: Erasing block ^bb0 from region 0 from operation 'regionOp0'
256 // CHECK: Erasing block ^bb0 from region 0 from operation 'regionOp0'
258 // CHECK-LABEL: Op post-order erasures (no skip)
259 // CHECK: Erasing op 'op0'
260 // CHECK: Erasing op 'cf.br'
261 // CHECK: Erasing op 'op1'
262 // CHECK: Erasing op 'cf.br'
263 // CHECK: Erasing op 'op2'
264 // CHECK: Erasing op 'regionOp0'
265 // CHECK: Erasing op 'func.return'
267 // CHECK-LABEL: Block post-order erasures (no skip)
268 // CHECK: Erasing block ^bb0 from region 0 from operation 'regionOp0'
269 // CHECK: Erasing block ^bb0 from region 0 from operation 'regionOp0'
270 // CHECK: Erasing block ^bb0 from region 0 from operation 'regionOp0'
271 // CHECK: Erasing block ^bb0 from region 0 from operation 'func.func'
272 // CHECK: Erasing block ^bb0 from region 0 from operation 'builtin.module'
276 func.func @unordered_cfg_with_loop() {
279 %c = "op0"() : () -> (i1)
280 cf.cond_br %c, ^bb2, ^bb3
282 "op1"(%val) : (i32) -> ()
285 %val = "op2"() : () -> (i32)
308 // 0 -> 2 --> 1 --> 5 --> 7
316 // CHECK-LABEL: Op forward dominance post-order visits
317 // CHECK: Visiting op 'op0'
318 // CHECK: Visiting op 'cf.cond_br'
319 // CHECK: Visiting op 'op2'
320 // CHECK: Visiting op 'cf.br'
321 // CHECK: Visiting op 'op1'
322 // CHECK: Visiting op 'cf.br'
323 // CHECK: Visiting op 'op5'
324 // CHECK: Visiting op 'cf.br'
325 // CHECK: Visiting op 'op7'
326 // CHECK: Visiting op 'op3'
327 // CHECK: Visiting op 'cf.br'
328 // CHECK-NOT: Visiting op 'op6'
329 // CHECK: Visiting op 'regionOp0'
330 // CHECK: Visiting op 'func.return'
331 // CHECK: Visiting op 'func.func'
333 // CHECK-LABEL: Block forward dominance post-order visits
334 // CHECK: Visiting block ^bb0 from region 0 from operation 'regionOp0'
335 // CHECK: Visiting block ^bb2 from region 0 from operation 'regionOp0'
336 // CHECK: Visiting block ^bb1 from region 0 from operation 'regionOp0'
337 // CHECK: Visiting block ^bb5 from region 0 from operation 'regionOp0'
338 // CHECK: Visiting block ^bb7 from region 0 from operation 'regionOp0'
339 // CHECK: Visiting block ^bb3 from region 0 from operation 'regionOp0'
340 // CHECK: Visiting block ^bb0 from region 0 from operation 'func.func'
342 // CHECK-LABEL: Region forward dominance post-order visits
343 // CHECK: Visiting region 0 from operation 'regionOp0'
344 // CHECK: Visiting region 0 from operation 'func.func'
346 // CHECK-LABEL: Op reverse dominance post-order visits
347 // CHECK: Visiting op 'func.return'
348 // CHECK-NOT: Visiting op 'op6'
349 // CHECK: Visiting op 'op7'
350 // CHECK: Visiting op 'cf.br'
351 // CHECK: Visiting op 'op5'
352 // CHECK: Visiting op 'cf.br'
353 // CHECK: Visiting op 'op1'
354 // CHECK: Visiting op 'cf.br'
355 // CHECK: Visiting op 'op2'
356 // CHECK: Visiting op 'cf.br'
357 // CHECK: Visiting op 'op3'
358 // CHECK: Visiting op 'cf.cond_br'
359 // CHECK: Visiting op 'op0'
360 // CHECK: Visiting op 'regionOp0'
361 // CHECK: Visiting op 'func.func'
363 // CHECK-LABEL: Block reverse dominance post-order visits
364 // CHECK: Visiting block ^bb7 from region 0 from operation 'regionOp0'
365 // CHECK: Visiting block ^bb5 from region 0 from operation 'regionOp0'
366 // CHECK: Visiting block ^bb1 from region 0 from operation 'regionOp0'
367 // CHECK: Visiting block ^bb2 from region 0 from operation 'regionOp0'
368 // CHECK: Visiting block ^bb3 from region 0 from operation 'regionOp0'
369 // CHECK: Visiting block ^bb0 from region 0 from operation 'regionOp0'
370 // CHECK: Visiting block ^bb0 from region 0 from operation 'func.func'
372 // CHECK-LABEL: Region reverse dominance post-order visits
373 // CHECK: Visiting region 0 from operation 'regionOp0'
374 // CHECK: Visiting region 0 from operation 'func.func'
376 // CHECK-LABEL: Block pre-order erasures (skip)
377 // CHECK: Erasing block ^bb0 from region 0 from operation 'regionOp0'
378 // CHECK: Cannot erase block ^bb0 from region 0 from operation 'regionOp0', still has uses
379 // CHECK: Cannot erase block ^bb1 from region 0 from operation 'regionOp0', still has uses
380 // CHECK: Erasing block ^bb2 from region 0 from operation 'regionOp0'
381 // CHECK: Erasing block ^bb2 from region 0 from operation 'regionOp0'
382 // CHECK: Cannot erase block ^bb2 from region 0 from operation 'regionOp0', still has uses
383 // CHECK: Cannot erase block ^bb3 from region 0 from operation 'regionOp0', still has uses
384 // CHECK: Cannot erase block ^bb4 from region 0 from operation 'regionOp0', still has uses