@@ -276,22 +276,41 @@ void parseVisibilityAttr(OpAsmParser &parser, cir::VisibilityAttr &visibility) {
276276// CIR Custom Parsers/Printers
277277// ===----------------------------------------------------------------------===//
278278
279- static mlir::ParseResult parseOmittedTerminatorRegion (mlir::OpAsmParser &parser,
280- mlir::Region ®ion) {
279+ static mlir::ParseResult
280+ parseOmittedTerminatorRegion (mlir::OpAsmParser &parser,
281+ mlir::Region &scopeRegion,
282+ mlir::Region &cleanupRegion) {
281283 auto regionLoc = parser.getCurrentLocation ();
282- if (parser.parseRegion (region ))
284+ if (parser.parseRegion (scopeRegion ))
283285 return failure ();
284- if (ensureRegionTerm (parser, region , regionLoc).failed ())
286+ if (ensureRegionTerm (parser, scopeRegion , regionLoc).failed ())
285287 return failure ();
288+
289+ // Parse optional cleanup region.
290+ if (parser.parseOptionalKeyword (" cleanup" ).succeeded ()) {
291+ if (parser.parseRegion (cleanupRegion, /* arguments=*/ {}, /* argTypes=*/ {}))
292+ return failure ();
293+ if (ensureRegionTerm (parser, cleanupRegion, regionLoc).failed ())
294+ return failure ();
295+ }
296+
286297 return success ();
287298}
288299
289300static void printOmittedTerminatorRegion (mlir::OpAsmPrinter &printer,
290301 cir::ScopeOp &op,
291- mlir::Region ®ion) {
292- printer.printRegion (region,
302+ mlir::Region &scopeRegion,
303+ mlir::Region &cleanupRegion) {
304+ printer.printRegion (scopeRegion,
293305 /* printEntryBlockArgs=*/ false ,
294- /* printBlockTerminators=*/ !omitRegionTerm (region));
306+ /* printBlockTerminators=*/ !omitRegionTerm (scopeRegion));
307+ if (!op.getCleanupRegion ().empty ()) {
308+ printer << " cleanup " ;
309+ printer.printRegion (
310+ cleanupRegion,
311+ /* printEntryBlockArgs=*/ false ,
312+ /* printBlockTerminators=*/ !omitRegionTerm (cleanupRegion));
313+ }
295314}
296315
297316// ===----------------------------------------------------------------------===//
@@ -1251,6 +1270,7 @@ void cir::ScopeOp::getSuccessorRegions(
12511270
12521271 // If the condition isn't constant, both regions may be executed.
12531272 regions.push_back (RegionSuccessor (&getScopeRegion ()));
1273+ regions.push_back (RegionSuccessor (&getCleanupRegion ()));
12541274}
12551275
12561276void cir::ScopeOp::build (
@@ -1261,6 +1281,8 @@ void cir::ScopeOp::build(
12611281 OpBuilder::InsertionGuard guard (builder);
12621282 Region *scopeRegion = result.addRegion ();
12631283 builder.createBlock (scopeRegion);
1284+ // cleanup region, do not eagarly create blocks, do it upon demand.
1285+ (void )result.addRegion ();
12641286
12651287 mlir::Type yieldTy;
12661288 scopeBuilder (builder, yieldTy, result.location );
@@ -1276,17 +1298,22 @@ void cir::ScopeOp::build(
12761298 OpBuilder::InsertionGuard guard (builder);
12771299 Region *scopeRegion = result.addRegion ();
12781300 builder.createBlock (scopeRegion);
1301+ // cleanup region, do not eagarly create blocks, do it upon demand.
1302+ (void )result.addRegion ();
12791303 scopeBuilder (builder, result.location );
12801304}
12811305
12821306LogicalResult cir::ScopeOp::verify () {
1283- if (getRegion ().empty ()) {
1307+ if (getScopeRegion ().empty ()) {
12841308 return emitOpError () << " cir.scope must not be empty since it should "
12851309 " include at least an implicit cir.yield " ;
12861310 }
12871311
1288- if (getRegion ().back ().empty () ||
1289- !getRegion ().back ().getTerminator ()->hasTrait <OpTrait::IsTerminator>())
1312+ if (getScopeRegion ().back ().empty () ||
1313+ !getScopeRegion ()
1314+ .back ()
1315+ .getTerminator ()
1316+ ->hasTrait <OpTrait::IsTerminator>())
12901317 return emitOpError () << " last block of cir.scope must be terminated" ;
12911318 return success ();
12921319}
0 commit comments