@@ -1409,6 +1409,67 @@ LogicalResult ModuleImport::convertIFunc(llvm::GlobalIFunc *ifunc) {
14091409 return success ();
14101410}
14111411
1412+ // / Converts LLVM string, integer, and enum attributes into MLIR attributes,
1413+ // / skipping those in `attributesToSkip` and emitting a warning at `loc` for
1414+ // / any other unsupported attributes.
1415+ static ArrayAttr
1416+ convertLLVMAttributesToMLIR (Location loc, MLIRContext *context,
1417+ llvm::AttributeSet attributes,
1418+ ArrayRef<StringLiteral> attributesToSkip = {}) {
1419+ SmallVector<Attribute> mlirAttributes;
1420+ for (llvm::Attribute attr : attributes) {
1421+ StringRef attrName;
1422+ if (attr.isStringAttribute ())
1423+ attrName = attr.getKindAsString ();
1424+ else
1425+ attrName = llvm::Attribute::getNameFromAttrKind (attr.getKindAsEnum ());
1426+ if (llvm::is_contained (attributesToSkip, attrName))
1427+ continue ;
1428+
1429+ auto keyAttr = StringAttr::get (context, attrName);
1430+ if (attr.isStringAttribute ()) {
1431+ StringRef val = attr.getValueAsString ();
1432+ if (val.empty ()) {
1433+ // For string attributes without values, add only the attribute name.
1434+ mlirAttributes.push_back (keyAttr);
1435+ continue ;
1436+ }
1437+ // For string attributes with a value, create a [name, value] pair.
1438+ mlirAttributes.push_back (
1439+ ArrayAttr::get (context, {keyAttr, StringAttr::get (context, val)}));
1440+ continue ;
1441+ }
1442+ if (attr.isIntAttribute ()) {
1443+ // For integer attributes, convert the value to a string and create a
1444+ // [name, value] pair.
1445+ auto val = std::to_string (attr.getValueAsInt ());
1446+ mlirAttributes.push_back (
1447+ ArrayAttr::get (context, {keyAttr, StringAttr::get (context, val)}));
1448+ continue ;
1449+ }
1450+ if (attr.isEnumAttribute ()) {
1451+ // For enum attributes, add only the attribute name.
1452+ mlirAttributes.push_back (keyAttr);
1453+ continue ;
1454+ }
1455+
1456+ emitWarning (loc)
1457+ << " '" << attrName
1458+ << " ' attribute is invalid on current operation, skipping it" ;
1459+ }
1460+ return ArrayAttr::get (context, mlirAttributes);
1461+ }
1462+
1463+ // / Converts LLVM attributes from `globalVar` into MLIR attributes and adds them
1464+ // / to `globalOp` as target-specific attributes.
1465+ static void processTargetSpecificAttrs (llvm::GlobalVariable *globalVar,
1466+ GlobalOp globalOp) {
1467+ ArrayAttr targetSpecificAttrs = convertLLVMAttributesToMLIR (
1468+ globalOp.getLoc (), globalOp.getContext (), globalVar->getAttributes ());
1469+ if (!targetSpecificAttrs.empty ())
1470+ globalOp.setTargetSpecificAttrsAttr (targetSpecificAttrs);
1471+ }
1472+
14121473LogicalResult ModuleImport::convertGlobal (llvm::GlobalVariable *globalVar) {
14131474 // Insert the global after the last one or at the start of the module.
14141475 OpBuilder::InsertionGuard guard = setGlobalInsertionPoint ();
@@ -1474,6 +1535,8 @@ LogicalResult ModuleImport::convertGlobal(llvm::GlobalVariable *globalVar) {
14741535 if (globalVar->hasComdat ())
14751536 globalOp.setComdatAttr (comdatMapping.lookup (globalVar->getComdat ()));
14761537
1538+ processTargetSpecificAttrs (globalVar, globalOp);
1539+
14771540 return success ();
14781541}
14791542
@@ -2526,7 +2589,7 @@ static void processMemoryEffects(llvm::Function *func, LLVMFuncOp funcOp) {
25262589
25272590// List of LLVM IR attributes that map to an explicit attribute on the MLIR
25282591// LLVMFuncOp.
2529- static constexpr std::array kExplicitAttributes {
2592+ static constexpr std::array kExplicitLLVMFuncOpAttributes {
25302593 StringLiteral (" aarch64_in_za" ),
25312594 StringLiteral (" aarch64_inout_za" ),
25322595 StringLiteral (" aarch64_new_za" ),
@@ -2543,6 +2606,7 @@ static constexpr std::array kExplicitAttributes{
25432606 StringLiteral (" frame-pointer" ),
25442607 StringLiteral (" instrument-function-entry" ),
25452608 StringLiteral (" instrument-function-exit" ),
2609+ StringLiteral (" memory" ),
25462610 StringLiteral (" no-infs-fp-math" ),
25472611 StringLiteral (" no-nans-fp-math" ),
25482612 StringLiteral (" no-signed-zeros-fp-math" ),
@@ -2557,61 +2621,17 @@ static constexpr std::array kExplicitAttributes{
25572621 StringLiteral (" willreturn" ),
25582622};
25592623
2624+ // / Converts LLVM attributes from `func` into MLIR attributes and adds them
2625+ // / to `funcOp` as passthrough attributes, skipping those listed in
2626+ // / `kExplicitLLVMFuncAttributes`.
25602627static void processPassthroughAttrs (llvm::Function *func, LLVMFuncOp funcOp) {
2561- MLIRContext *context = funcOp.getContext ();
2562- SmallVector<Attribute> passthroughs;
25632628 llvm::AttributeSet funcAttrs = func->getAttributes ().getAttributes (
25642629 llvm::AttributeList::AttrIndex::FunctionIndex);
2565- for (llvm::Attribute attr : funcAttrs) {
2566- // Skip the memory attribute since the LLVMFuncOp has an explicit memory
2567- // attribute.
2568- if (attr.hasAttribute (llvm::Attribute::Memory))
2569- continue ;
2570-
2571- // Skip invalid type attributes.
2572- if (attr.isTypeAttribute ()) {
2573- emitWarning (funcOp.getLoc (),
2574- " type attributes on a function are invalid, skipping it" );
2575- continue ;
2576- }
2577-
2578- StringRef attrName;
2579- if (attr.isStringAttribute ())
2580- attrName = attr.getKindAsString ();
2581- else
2582- attrName = llvm::Attribute::getNameFromAttrKind (attr.getKindAsEnum ());
2583- auto keyAttr = StringAttr::get (context, attrName);
2584-
2585- // Skip attributes that map to an explicit attribute on the LLVMFuncOp.
2586- if (llvm::is_contained (kExplicitAttributes , attrName))
2587- continue ;
2588-
2589- if (attr.isStringAttribute ()) {
2590- StringRef val = attr.getValueAsString ();
2591- if (val.empty ()) {
2592- passthroughs.push_back (keyAttr);
2593- continue ;
2594- }
2595- passthroughs.push_back (
2596- ArrayAttr::get (context, {keyAttr, StringAttr::get (context, val)}));
2597- continue ;
2598- }
2599- if (attr.isIntAttribute ()) {
2600- auto val = std::to_string (attr.getValueAsInt ());
2601- passthroughs.push_back (
2602- ArrayAttr::get (context, {keyAttr, StringAttr::get (context, val)}));
2603- continue ;
2604- }
2605- if (attr.isEnumAttribute ()) {
2606- passthroughs.push_back (keyAttr);
2607- continue ;
2608- }
2609-
2610- llvm_unreachable (" unexpected attribute kind" );
2611- }
2612-
2613- if (!passthroughs.empty ())
2614- funcOp.setPassthroughAttr (ArrayAttr::get (context, passthroughs));
2630+ ArrayAttr passthroughAttr =
2631+ convertLLVMAttributesToMLIR (funcOp.getLoc (), funcOp.getContext (),
2632+ funcAttrs, kExplicitLLVMFuncOpAttributes );
2633+ if (!passthroughAttr.empty ())
2634+ funcOp.setPassthroughAttr (passthroughAttr);
26152635}
26162636
26172637void ModuleImport::processFunctionAttributes (llvm::Function *func,
0 commit comments