@@ -1355,9 +1355,11 @@ mlir::LogicalResult cir::GlobalOp::verify() {
13551355 return success ();
13561356}
13571357
1358- void cir::GlobalOp::build (OpBuilder &odsBuilder, OperationState &odsState,
1359- llvm::StringRef sym_name, mlir::Type sym_type,
1360- bool isConstant, cir::GlobalLinkageKind linkage) {
1358+ void cir::GlobalOp::build (
1359+ OpBuilder &odsBuilder, OperationState &odsState, llvm::StringRef sym_name,
1360+ mlir::Type sym_type, bool isConstant, cir::GlobalLinkageKind linkage,
1361+ function_ref<void (OpBuilder &, Location)> ctorBuilder,
1362+ function_ref<void(OpBuilder &, Location)> dtorBuilder) {
13611363 odsState.addAttribute (getSymNameAttrName (odsState.name ),
13621364 odsBuilder.getStringAttr (sym_name));
13631365 odsState.addAttribute (getSymTypeAttrName (odsState.name ),
@@ -1370,43 +1372,127 @@ void cir::GlobalOp::build(OpBuilder &odsBuilder, OperationState &odsState,
13701372 cir::GlobalLinkageKindAttr::get (odsBuilder.getContext (), linkage);
13711373 odsState.addAttribute (getLinkageAttrName (odsState.name ), linkageAttr);
13721374
1375+ Region *ctorRegion = odsState.addRegion ();
1376+ if (ctorBuilder) {
1377+ odsBuilder.createBlock (ctorRegion);
1378+ ctorBuilder (odsBuilder, odsState.location );
1379+ }
1380+
1381+ Region *dtorRegion = odsState.addRegion ();
1382+ if (dtorBuilder) {
1383+ odsBuilder.createBlock (dtorRegion);
1384+ dtorBuilder (odsBuilder, odsState.location );
1385+ }
1386+
13731387 odsState.addAttribute (getGlobalVisibilityAttrName (odsState.name ),
13741388 cir::VisibilityAttr::get (odsBuilder.getContext ()));
13751389}
13761390
1391+ // / Given the region at `index`, or the parent operation if `index` is None,
1392+ // / return the successor regions. These are the regions that may be selected
1393+ // / during the flow of control. `operands` is a set of optional attributes that
1394+ // / correspond to a constant value for each operand, or null if that operand is
1395+ // / not a constant.
1396+ void cir::GlobalOp::getSuccessorRegions (
1397+ mlir::RegionBranchPoint point, SmallVectorImpl<RegionSuccessor> ®ions) {
1398+ // The `ctor` and `dtor` regions always branch back to the parent operation.
1399+ if (!point.isParent ()) {
1400+ regions.push_back (RegionSuccessor ());
1401+ return ;
1402+ }
1403+
1404+ // Don't consider the ctor region if it is empty.
1405+ Region *ctorRegion = &this ->getCtorRegion ();
1406+ if (ctorRegion->empty ())
1407+ ctorRegion = nullptr ;
1408+
1409+ // Don't consider the dtor region if it is empty.
1410+ Region *dtorRegion = &this ->getCtorRegion ();
1411+ if (dtorRegion->empty ())
1412+ dtorRegion = nullptr ;
1413+
1414+ // If the condition isn't constant, both regions may be executed.
1415+ if (ctorRegion)
1416+ regions.push_back (RegionSuccessor (ctorRegion));
1417+ if (dtorRegion)
1418+ regions.push_back (RegionSuccessor (dtorRegion));
1419+ }
1420+
13771421static void printGlobalOpTypeAndInitialValue (OpAsmPrinter &p, cir::GlobalOp op,
1378- TypeAttr type,
1379- Attribute initAttr) {
1422+ TypeAttr type, Attribute initAttr,
1423+ mlir::Region &ctorRegion,
1424+ mlir::Region &dtorRegion) {
1425+ auto printType = [&]() { p << " : " << type; };
13801426 if (!op.isDeclaration ()) {
13811427 p << " = " ;
1382- // This also prints the type...
1383- if (initAttr)
1384- printConstant (p, initAttr);
1428+ if (!ctorRegion.empty ()) {
1429+ p << " ctor " ;
1430+ printType ();
1431+ p << " " ;
1432+ p.printRegion (ctorRegion,
1433+ /* printEntryBlockArgs=*/ false ,
1434+ /* printBlockTerminators=*/ false );
1435+ } else {
1436+ // This also prints the type...
1437+ if (initAttr)
1438+ printConstant (p, initAttr);
1439+ }
1440+
1441+ if (!dtorRegion.empty ()) {
1442+ p << " dtor " ;
1443+ p.printRegion (dtorRegion,
1444+ /* printEntryBlockArgs=*/ false ,
1445+ /* printBlockTerminators=*/ false );
1446+ }
13851447 } else {
1386- p << " : " << type ;
1448+ printType () ;
13871449 }
13881450}
13891451
1390- static ParseResult
1391- parseGlobalOpTypeAndInitialValue (OpAsmParser &parser, TypeAttr &typeAttr,
1392- Attribute &initialValueAttr) {
1452+ static ParseResult parseGlobalOpTypeAndInitialValue (OpAsmParser &parser,
1453+ TypeAttr &typeAttr,
1454+ Attribute &initialValueAttr,
1455+ mlir::Region &ctorRegion,
1456+ mlir::Region &dtorRegion) {
13931457 mlir::Type opTy;
13941458 if (parser.parseOptionalEqual ().failed ()) {
13951459 // Absence of equal means a declaration, so we need to parse the type.
13961460 // cir.global @a : !cir.int<s, 32>
13971461 if (parser.parseColonType (opTy))
13981462 return failure ();
13991463 } else {
1400- // Parse constant with initializer, examples:
1401- // cir.global @y = #cir.fp<1.250000e+00> : !cir.double
1402- // cir.global @rgb = #cir.const_array<[...] : !cir.array<i8 x 3>>
1403- if (parseConstantValue (parser, initialValueAttr).failed ())
1404- return failure ();
1464+ // Parse contructor, example:
1465+ // cir.global @rgb = ctor : type { ... }
1466+ if (!parser.parseOptionalKeyword (" ctor" )) {
1467+ if (parser.parseColonType (opTy))
1468+ return failure ();
1469+ auto parseLoc = parser.getCurrentLocation ();
1470+ if (parser.parseRegion (ctorRegion, /* arguments=*/ {}, /* argTypes=*/ {}))
1471+ return failure ();
1472+ if (ensureRegionTerm (parser, ctorRegion, parseLoc).failed ())
1473+ return failure ();
1474+ } else {
1475+ // Parse constant with initializer, examples:
1476+ // cir.global @y = 3.400000e+00 : f32
1477+ // cir.global @rgb = #cir.const_array<[...] : !cir.array<i8 x 3>>
1478+ if (parseConstantValue (parser, initialValueAttr).failed ())
1479+ return failure ();
1480+
1481+ assert (mlir::isa<mlir::TypedAttr>(initialValueAttr) &&
1482+ " Non-typed attrs shouldn't appear here." );
1483+ auto typedAttr = mlir::cast<mlir::TypedAttr>(initialValueAttr);
1484+ opTy = typedAttr.getType ();
1485+ }
14051486
1406- assert (mlir::isa<mlir::TypedAttr>(initialValueAttr) &&
1407- " Non-typed attrs shouldn't appear here." );
1408- auto typedAttr = mlir::cast<mlir::TypedAttr>(initialValueAttr);
1409- opTy = typedAttr.getType ();
1487+ // Parse destructor, example:
1488+ // dtor { ... }
1489+ if (!parser.parseOptionalKeyword (" dtor" )) {
1490+ auto parseLoc = parser.getCurrentLocation ();
1491+ if (parser.parseRegion (dtorRegion, /* arguments=*/ {}, /* argTypes=*/ {}))
1492+ return failure ();
1493+ if (ensureRegionTerm (parser, dtorRegion, parseLoc).failed ())
1494+ return failure ();
1495+ }
14101496 }
14111497
14121498 typeAttr = TypeAttr::get (opTy);
0 commit comments