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