Skip to content

Commit

Permalink
[CIR][IR] Refactor ScopeOp assembly format
Browse files Browse the repository at this point in the history
This simplifies and modularizes the assembly format for ScopeOp by
using the Tablegen assembly description and a new custom printer/parser
that handles regions with omitted terminators.

It also fixes an issue where the parser would not correctly handle
`cir.scopes` with a return value.

ghstack-source-id: c5b9be705113c21117363cb3bd78e19d133c3fc5
Pull Request resolved: #311
  • Loading branch information
sitio-couto committed Dec 6, 2023
1 parent b1ba7b0 commit 0fbf4d8
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 32 deletions.
6 changes: 4 additions & 2 deletions clang/include/clang/CIR/Dialect/IR/CIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -715,12 +715,14 @@ def ScopeOp : CIR_Op<"scope", [
will be inserted implicitly.
}];

let results = (outs Variadic<AnyType>:$results);
let results = (outs Optional<AnyType>:$results);
let regions = (region AnyRegion:$scopeRegion);

let hasCustomAssemblyFormat = 1;
let hasVerifier = 1;
let skipDefaultBuilders = 1;
let assemblyFormat = [{
custom<OmittedTerminatorRegion>($scopeRegion) (`:` type($results)^)? attr-dict
}];

let builders = [
// Scopes for yielding values.
Expand Down
53 changes: 23 additions & 30 deletions clang/lib/CIR/Dialect/IR/CIRDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,28 @@ bool omitRegionTerm(mlir::Region &r) {
return singleNonEmptyBlock && yieldsNothing();
}

//===----------------------------------------------------------------------===//
// CIR Custom Parsers/Printers
//===----------------------------------------------------------------------===//

static mlir::ParseResult
parseOmittedTerminatorRegion(mlir::OpAsmParser &parser, mlir::Region &region) {
auto regionLoc = parser.getCurrentLocation();
if (parser.parseRegion(region))
return failure();
if (ensureRegionTerm(parser, region, regionLoc).failed())
return failure();
return success();
}

static void printOmittedTerminatorRegion(mlir::OpAsmPrinter &printer,
mlir::cir::ScopeOp &op,
mlir::Region &region) {
printer.printRegion(region,
/*printEntryBlockArgs=*/false,
/*printBlockTerminators=*/!omitRegionTerm(region));
}

//===----------------------------------------------------------------------===//
// AllocaOp
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -581,35 +603,6 @@ LogicalResult IfOp::verify() { return success(); }
// ScopeOp
//===----------------------------------------------------------------------===//

ParseResult cir::ScopeOp::parse(OpAsmParser &parser, OperationState &result) {
// Create one region within 'scope'.
result.regions.reserve(1);
Region *scopeRegion = result.addRegion();
auto loc = parser.getCurrentLocation();

// Parse the scope region.
if (parser.parseRegion(*scopeRegion, /*arguments=*/{}, /*argTypes=*/{}))
return failure();

if (ensureRegionTerm(parser, *scopeRegion, loc).failed())
return failure();

// Parse the optional attribute list.
if (parser.parseOptionalAttrDict(result.attributes))
return failure();
return success();
}

void cir::ScopeOp::print(OpAsmPrinter &p) {
p << ' ';
auto &scopeRegion = this->getScopeRegion();
p.printRegion(scopeRegion,
/*printEntryBlockArgs=*/false,
/*printBlockTerminators=*/!omitRegionTerm(scopeRegion));

p.printOptionalAttrDict(getOperation()->getAttrs());
}

/// Given the region at `index`, or the parent operation if `index` is None,
/// return the successor regions. These are the regions that may be selected
/// during the flow of control. `operands` is a set of optional attributes that
Expand All @@ -619,7 +612,7 @@ void ScopeOp::getSuccessorRegions(mlir::RegionBranchPoint point,
SmallVectorImpl<RegionSuccessor> &regions) {
// The only region always branch back to the parent operation.
if (!point.isParent()) {
regions.push_back(RegionSuccessor(getResults()));
regions.push_back(RegionSuccessor(getODSResults(0)));
return;
}

Expand Down
27 changes: 27 additions & 0 deletions clang/test/CIR/IR/scope.cir
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// RUN: cir-opt %s -o %t.cir
// RUN: FileCheck --input-file=%t.cir %s
!u32i = !cir.int<u, 32>

module {
// Should properly print/parse scope with implicit empty yield.
cir.func @implicit_yield() {
cir.scope {
}
// CHECK: cir.scope {
// CHECK: }
cir.return
}

// Should properly print/parse scope with explicit yield.
cir.func @explicit_yield() {
%0 = cir.scope {
%1 = cir.alloca !u32i, cir.ptr <!u32i>, ["a", init] {alignment = 4 : i64}
cir.yield %1 : !cir.ptr<!u32i>
} : !cir.ptr<!u32i>
// CHECK: %0 = cir.scope {
// [...]
// CHECK: cir.yield %1 : !cir.ptr<!u32i>
// CHECK: } : !cir.ptr<!u32i>
cir.return
}
}

0 comments on commit 0fbf4d8

Please sign in to comment.