@@ -2307,8 +2307,9 @@ mlir::LogicalResult CIRToLLVMSwitchFlatOpLowering::matchAndRewrite(
2307
2307
2308
2308
// / Replace CIR global with a region initialized LLVM global and update
2309
2309
// / insertion point to the end of the initializer block.
2310
- void CIRToLLVMGlobalOpLowering::setupRegionInitializedLLVMGlobalOp (
2311
- cir::GlobalOp op, mlir::ConversionPatternRewriter &rewriter) const {
2310
+ void CIRToLLVMGlobalOpLowering::createRegionInitializedLLVMGlobalOp (
2311
+ cir::GlobalOp op, mlir::Attribute attr,
2312
+ mlir::ConversionPatternRewriter &rewriter) const {
2312
2313
const auto llvmType =
2313
2314
convertTypeForMemory (*getTypeConverter (), dataLayout, op.getSymType ());
2314
2315
SmallVector<mlir::NamedAttribute> attributes;
@@ -2321,6 +2322,10 @@ void CIRToLLVMGlobalOpLowering::setupRegionInitializedLLVMGlobalOp(
2321
2322
/* comdat*/ mlir::SymbolRefAttr (), attributes);
2322
2323
newGlobalOp.getRegion ().push_back (new mlir::Block ());
2323
2324
rewriter.setInsertionPointToEnd (newGlobalOp.getInitializerBlock ());
2325
+
2326
+ rewriter.create <mlir::LLVM::ReturnOp>(
2327
+ op->getLoc (),
2328
+ lowerCirAttrAsValue (op, attr, rewriter, typeConverter, dataLayout));
2324
2329
}
2325
2330
2326
2331
mlir::LogicalResult CIRToLLVMGlobalOpLowering::matchAndRewrite (
@@ -2350,109 +2355,82 @@ mlir::LogicalResult CIRToLLVMGlobalOpLowering::matchAndRewrite(
2350
2355
2351
2356
attributes.push_back (rewriter.getNamedAttr (" visibility_" , visibility));
2352
2357
2353
- // Check for missing funcionalities.
2354
- if (!init.has_value ()) {
2355
- rewriter.replaceOpWithNewOp <mlir::LLVM::GlobalOp>(
2356
- op, llvmType, isConst, linkage, symbol, mlir::Attribute (),
2357
- /* alignment*/ 0 ,
2358
- /* addrSpace*/ getGlobalOpTargetAddrSpace (rewriter, typeConverter, op),
2359
- /* dsoLocal*/ isDsoLocal, /* threadLocal*/ (bool )op.getTlsModelAttr (),
2360
- /* comdat*/ mlir::SymbolRefAttr (), attributes);
2361
- return mlir::success ();
2362
- }
2363
-
2364
- // Initializer is a constant array: convert it to a compatible llvm init.
2365
- if (auto constArr = mlir::dyn_cast<cir::ConstArrayAttr>(init.value ())) {
2366
- if (auto attr = mlir::dyn_cast<mlir::StringAttr>(constArr.getElts ())) {
2367
- llvm::SmallString<256 > literal (attr.getValue ());
2368
- if (constArr.getTrailingZerosNum ())
2369
- literal.append (constArr.getTrailingZerosNum (), ' \0 ' );
2370
- init = rewriter.getStringAttr (literal);
2371
- } else if (auto attr =
2372
- mlir::dyn_cast<mlir::ArrayAttr>(constArr.getElts ())) {
2373
- // Failed to use a compact attribute as an initializer:
2374
- // initialize elements individually.
2375
- if (!(init = lowerConstArrayAttr (constArr, getTypeConverter ()))) {
2376
- setupRegionInitializedLLVMGlobalOp (op, rewriter);
2377
- rewriter.create <mlir::LLVM::ReturnOp>(
2378
- op->getLoc (), lowerCirAttrAsValue (op, constArr, rewriter,
2379
- typeConverter, dataLayout));
2380
- return mlir::success ();
2358
+ if (init.has_value ()) {
2359
+ if (mlir::isa<cir::FPAttr, cir::IntAttr, cir::BoolAttr>(init.value ())) {
2360
+ // If a directly equivalent attribute is available, use it.
2361
+ init =
2362
+ llvm::TypeSwitch<mlir::Attribute, mlir::Attribute>(init.value ())
2363
+ .Case <cir::FPAttr>([&](cir::FPAttr attr) {
2364
+ return rewriter.getFloatAttr (llvmType, attr.getValue ());
2365
+ })
2366
+ .Case <cir::IntAttr>([&](cir::IntAttr attr) {
2367
+ return rewriter.getIntegerAttr (llvmType, attr.getValue ());
2368
+ })
2369
+ .Case <cir::BoolAttr>([&](cir::BoolAttr attr) {
2370
+ return rewriter.getBoolAttr (attr.getValue ());
2371
+ })
2372
+ .Default ([&](mlir::Attribute attr) { return mlir::Attribute (); });
2373
+ // If initRewriter returned a null attribute, init will have a value but
2374
+ // the value will be null. If that happens, initRewriter didn't handle the
2375
+ // attribute type. It probably needs to be added to
2376
+ // GlobalInitAttrRewriter.
2377
+ if (!init.value ()) {
2378
+ op.emitError () << " unsupported initializer '" << init.value () << " '" ;
2379
+ return mlir::failure ();
2381
2380
}
2381
+ } else if (mlir::isa<cir::ZeroAttr, cir::ConstPtrAttr, cir::UndefAttr,
2382
+ cir::ConstStructAttr, cir::GlobalViewAttr,
2383
+ cir::VTableAttr, cir::TypeInfoAttr>(init.value ())) {
2384
+ // TODO(cir): once LLVM's dialect has proper equivalent attributes this
2385
+ // should be updated. For now, we use a custom op to initialize globals
2386
+ // to the appropriate value.
2387
+ createRegionInitializedLLVMGlobalOp (op, init.value (), rewriter);
2388
+ return mlir::success ();
2389
+ } else if (auto constArr =
2390
+ mlir::dyn_cast<cir::ConstArrayAttr>(init.value ())) {
2391
+ // Initializer is a constant array: convert it to a compatible llvm init.
2392
+ if (auto attr = mlir::dyn_cast<mlir::StringAttr>(constArr.getElts ())) {
2393
+ llvm::SmallString<256 > literal (attr.getValue ());
2394
+ if (constArr.getTrailingZerosNum ())
2395
+ literal.append (constArr.getTrailingZerosNum (), ' \0 ' );
2396
+ init = rewriter.getStringAttr (literal);
2397
+ } else if (auto attr =
2398
+ mlir::dyn_cast<mlir::ArrayAttr>(constArr.getElts ())) {
2399
+ // Failed to use a compact attribute as an initializer:
2400
+ // initialize elements individually.
2401
+ if (!(init = lowerConstArrayAttr (constArr, getTypeConverter ()))) {
2402
+ createRegionInitializedLLVMGlobalOp (op, constArr, rewriter);
2403
+ return mlir::success ();
2404
+ }
2405
+ } else {
2406
+ op.emitError ()
2407
+ << " unsupported lowering for #cir.const_array with value "
2408
+ << constArr.getElts ();
2409
+ return mlir::failure ();
2410
+ }
2411
+ } else if (auto dataMemberAttr =
2412
+ mlir::dyn_cast<cir::DataMemberAttr>(init.value ())) {
2413
+ assert (lowerMod && " lower module is not available" );
2414
+ mlir::DataLayout layout (op->getParentOfType <mlir::ModuleOp>());
2415
+ mlir::TypedAttr abiValue = lowerMod->getCXXABI ().lowerDataMemberConstant (
2416
+ dataMemberAttr, layout, *typeConverter);
2417
+ auto abiOp = mlir::cast<GlobalOp>(rewriter.clone (*op.getOperation ()));
2418
+ abiOp.setInitialValueAttr (abiValue);
2419
+ abiOp.setSymType (abiValue.getType ());
2420
+ rewriter.replaceOp (op, abiOp);
2421
+ return mlir::success ();
2382
2422
} else {
2383
- op.emitError () << " unsupported lowering for #cir.const_array with value "
2384
- << constArr.getElts ();
2423
+ op.emitError () << " unsupported initializer '" << init.value () << " '" ;
2385
2424
return mlir::failure ();
2386
2425
}
2387
- } else if (auto fltAttr = mlir::dyn_cast<cir::FPAttr>(init.value ())) {
2388
- // Initializer is a constant floating-point number: convert to MLIR
2389
- // builtin constant.
2390
- init = rewriter.getFloatAttr (llvmType, fltAttr.getValue ());
2391
- }
2392
- // Initializer is a constant integer: convert to MLIR builtin constant.
2393
- else if (auto intAttr = mlir::dyn_cast<cir::IntAttr>(init.value ())) {
2394
- init = rewriter.getIntegerAttr (llvmType, intAttr.getValue ());
2395
- } else if (auto boolAttr = mlir::dyn_cast<cir::BoolAttr>(init.value ())) {
2396
- init = rewriter.getBoolAttr (boolAttr.getValue ());
2397
- } else if (isa<cir::ZeroAttr, cir::ConstPtrAttr, cir::UndefAttr>(
2398
- init.value ())) {
2399
- // TODO(cir): once LLVM's dialect has proper equivalent attributes this
2400
- // should be updated. For now, we use a custom op to initialize globals
2401
- // to the appropriate value.
2402
- setupRegionInitializedLLVMGlobalOp (op, rewriter);
2403
- auto value = lowerCirAttrAsValue (op, init.value (), rewriter, typeConverter,
2404
- dataLayout);
2405
- rewriter.create <mlir::LLVM::ReturnOp>(loc, value);
2406
- return mlir::success ();
2407
- } else if (auto dataMemberAttr =
2408
- mlir::dyn_cast<cir::DataMemberAttr>(init.value ())) {
2409
- assert (lowerMod && " lower module is not available" );
2410
- mlir::DataLayout layout (op->getParentOfType <mlir::ModuleOp>());
2411
- mlir::TypedAttr abiValue = lowerMod->getCXXABI ().lowerDataMemberConstant (
2412
- dataMemberAttr, layout, *typeConverter);
2413
- auto abiOp = mlir::cast<GlobalOp>(rewriter.clone (*op.getOperation ()));
2414
- abiOp.setInitialValueAttr (abiValue);
2415
- abiOp.setSymType (abiValue.getType ());
2416
- rewriter.replaceOp (op, abiOp);
2417
- return mlir::success ();
2418
- } else if (const auto structAttr =
2419
- mlir::dyn_cast<cir::ConstStructAttr>(init.value ())) {
2420
- setupRegionInitializedLLVMGlobalOp (op, rewriter);
2421
- rewriter.create <mlir::LLVM::ReturnOp>(
2422
- op->getLoc (), lowerCirAttrAsValue (op, structAttr, rewriter,
2423
- typeConverter, dataLayout));
2424
- return mlir::success ();
2425
- } else if (auto attr = mlir::dyn_cast<cir::GlobalViewAttr>(init.value ())) {
2426
- setupRegionInitializedLLVMGlobalOp (op, rewriter);
2427
- rewriter.create <mlir::LLVM::ReturnOp>(
2428
- loc,
2429
- lowerCirAttrAsValue (op, attr, rewriter, typeConverter, dataLayout));
2430
- return mlir::success ();
2431
- } else if (const auto vtableAttr =
2432
- mlir::dyn_cast<cir::VTableAttr>(init.value ())) {
2433
- setupRegionInitializedLLVMGlobalOp (op, rewriter);
2434
- rewriter.create <mlir::LLVM::ReturnOp>(
2435
- op->getLoc (), lowerCirAttrAsValue (op, vtableAttr, rewriter,
2436
- typeConverter, dataLayout));
2437
- return mlir::success ();
2438
- } else if (const auto typeinfoAttr =
2439
- mlir::dyn_cast<cir::TypeInfoAttr>(init.value ())) {
2440
- setupRegionInitializedLLVMGlobalOp (op, rewriter);
2441
- rewriter.create <mlir::LLVM::ReturnOp>(
2442
- op->getLoc (), lowerCirAttrAsValue (op, typeinfoAttr, rewriter,
2443
- typeConverter, dataLayout));
2444
- return mlir::success ();
2445
- } else {
2446
- op.emitError () << " unsupported initializer '" << init.value () << " '" ;
2447
- return mlir::failure ();
2448
2426
}
2449
2427
2450
2428
// Rewrite op.
2451
2429
auto llvmGlobalOp = rewriter.replaceOpWithNewOp <mlir::LLVM::GlobalOp>(
2452
- op, llvmType, isConst, linkage, symbol, init.value ( ),
2430
+ op, llvmType, isConst, linkage, symbol, init.value_or ( mlir::Attribute () ),
2453
2431
/* alignment*/ op.getAlignment ().value_or (0 ),
2454
2432
/* addrSpace*/ getGlobalOpTargetAddrSpace (rewriter, typeConverter, op),
2455
- /* dsoLocal*/ false , /* threadLocal*/ (bool )op.getTlsModelAttr (),
2433
+ /* dsoLocal*/ isDsoLocal , /* threadLocal*/ (bool )op.getTlsModelAttr (),
2456
2434
/* comdat*/ mlir::SymbolRefAttr (), attributes);
2457
2435
2458
2436
auto mod = op->getParentOfType <mlir::ModuleOp>();
0 commit comments