@@ -2307,8 +2307,9 @@ mlir::LogicalResult CIRToLLVMSwitchFlatOpLowering::matchAndRewrite(
23072307
23082308// / Replace CIR global with a region initialized LLVM global and update
23092309// / 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 {
23122313 const auto llvmType =
23132314 convertTypeForMemory (*getTypeConverter (), dataLayout, op.getSymType ());
23142315 SmallVector<mlir::NamedAttribute> attributes;
@@ -2321,6 +2322,10 @@ void CIRToLLVMGlobalOpLowering::setupRegionInitializedLLVMGlobalOp(
23212322 /* comdat*/ mlir::SymbolRefAttr (), attributes);
23222323 newGlobalOp.getRegion ().push_back (new mlir::Block ());
23232324 rewriter.setInsertionPointToEnd (newGlobalOp.getInitializerBlock ());
2325+
2326+ rewriter.create <mlir::LLVM::ReturnOp>(
2327+ op->getLoc (),
2328+ lowerCirAttrAsValue (op, attr, rewriter, typeConverter, dataLayout));
23242329}
23252330
23262331mlir::LogicalResult CIRToLLVMGlobalOpLowering::matchAndRewrite (
@@ -2350,109 +2355,82 @@ mlir::LogicalResult CIRToLLVMGlobalOpLowering::matchAndRewrite(
23502355
23512356 attributes.push_back (rewriter.getNamedAttr (" visibility_" , visibility));
23522357
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 ();
23812380 }
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 ();
23822422 } else {
2383- op.emitError () << " unsupported lowering for #cir.const_array with value "
2384- << constArr.getElts ();
2423+ op.emitError () << " unsupported initializer '" << init.value () << " '" ;
23852424 return mlir::failure ();
23862425 }
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 ();
24482426 }
24492427
24502428 // Rewrite op.
24512429 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 () ),
24532431 /* alignment*/ op.getAlignment ().value_or (0 ),
24542432 /* addrSpace*/ getGlobalOpTargetAddrSpace (rewriter, typeConverter, op),
2455- /* dsoLocal*/ false , /* threadLocal*/ (bool )op.getTlsModelAttr (),
2433+ /* dsoLocal*/ isDsoLocal , /* threadLocal*/ (bool )op.getTlsModelAttr (),
24562434 /* comdat*/ mlir::SymbolRefAttr (), attributes);
24572435
24582436 auto mod = op->getParentOfType <mlir::ModuleOp>();
0 commit comments