xref: /llvm-project/mlir/test/IR/visitors.mlir (revision c4457e10fe7946dcedbdd7a07c320ed8b764dc7c)
1// RUN: mlir-opt -test-ir-visitors -allow-unregistered-dialect -split-input-file %s | FileCheck %s
2
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.
7
8func.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)
14    scf.if %cond {
15      "use1"(%i) : (index) -> ()
16    } else {
17      "use2"(%i) : (index) -> ()
18    }
19    "use3"(%i) : (index) -> ()
20  } {walk_blocks, walk_regions}
21  return
22}
23
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'
34
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'
41
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'
48
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'
59
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'
66
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'
73
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'
90
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'
95
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'
100
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'
105
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'
110
111// CHECK-LABEL: Op pre-order erasures
112// CHECK:       Erasing op 'scf.for'
113// CHECK:       Erasing op 'func.return'
114
115// CHECK-LABEL: Block pre-order erasures
116// CHECK:       Erasing block ^bb0 from region 0 from operation 'scf.for'
117
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'
126
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'
131
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'
142
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'
149
150// -----
151
152func.func @unstructured_cfg() {
153  "regionOp0"() ({
154    ^bb0:
155      "op0"() : () -> ()
156      cf.br ^bb2
157    ^bb1:
158      "op1"() : () -> ()
159      cf.br ^bb2
160    ^bb2:
161      "op2"() : () -> ()
162  }) : () -> ()
163  return
164}
165
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'
176
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'
183
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'
188
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'
199
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'
206
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'
211
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'
222
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'
229
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'
234
235// CHECK-LABEL: Op pre-order erasures (skip)
236// CHECK:       Erasing op 'regionOp0'
237// CHECK:       Erasing op 'func.return'
238
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'
243
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'
252
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'
257
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'
266
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'
273
274// -----
275
276func.func @unordered_cfg_with_loop() {
277  "regionOp0"() ({
278    ^bb0:
279      %c = "op0"() : () -> (i1)
280      cf.cond_br %c, ^bb2, ^bb3
281    ^bb1:
282      "op1"(%val) : (i32) -> ()
283      cf.br ^bb5
284    ^bb2:
285      %val = "op2"() : () -> (i32)
286      cf.br ^bb1
287    ^bb3:
288      "op3"() : () -> ()
289      cf.br ^bb2
290    ^bb4:
291      "op4"() : () -> ()
292      cf.br ^bb2
293    ^bb5:
294      "op5"() : () -> ()
295      cf.br ^bb7
296    ^bb6:
297      "op6"() : () -> ()
298      cf.br ^bb6
299    ^bb7:
300      "op7"() : () -> ()
301  }) : () -> ()
302  return
303}
304
305//      4
306//      |
307//      v
308// 0 -> 2 --> 1 --> 5 --> 7
309// |    ^
310// |    |      6 --
311// |   /       ^   \
312// |  /         \  /
313// v /           --
314//  3
315
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'
332
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'
341
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'
345
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'
362
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'
371
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'
375
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
385