@@ -1355,9 +1355,11 @@ mlir::LogicalResult cir::GlobalOp::verify() {
1355
1355
return success ();
1356
1356
}
1357
1357
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) {
1361
1363
odsState.addAttribute (getSymNameAttrName (odsState.name ),
1362
1364
odsBuilder.getStringAttr (sym_name));
1363
1365
odsState.addAttribute (getSymTypeAttrName (odsState.name ),
@@ -1370,43 +1372,127 @@ void cir::GlobalOp::build(OpBuilder &odsBuilder, OperationState &odsState,
1370
1372
cir::GlobalLinkageKindAttr::get (odsBuilder.getContext (), linkage);
1371
1373
odsState.addAttribute (getLinkageAttrName (odsState.name ), linkageAttr);
1372
1374
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
+
1373
1387
odsState.addAttribute (getGlobalVisibilityAttrName (odsState.name ),
1374
1388
cir::VisibilityAttr::get (odsBuilder.getContext ()));
1375
1389
}
1376
1390
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
+
1377
1421
static 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; };
1380
1426
if (!op.isDeclaration ()) {
1381
1427
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
+ }
1385
1447
} else {
1386
- p << " : " << type ;
1448
+ printType () ;
1387
1449
}
1388
1450
}
1389
1451
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) {
1393
1457
mlir::Type opTy;
1394
1458
if (parser.parseOptionalEqual ().failed ()) {
1395
1459
// Absence of equal means a declaration, so we need to parse the type.
1396
1460
// cir.global @a : !cir.int<s, 32>
1397
1461
if (parser.parseColonType (opTy))
1398
1462
return failure ();
1399
1463
} 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
+ }
1405
1486
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
+ }
1410
1496
}
1411
1497
1412
1498
typeAttr = TypeAttr::get (opTy);
0 commit comments