[Mlir-commits] [mlir] [MLIR][LLVMIR][DLTI] Pass for updating target features per TargetMachine (PR #154938)
Rolf Morel
llvmlistbot at llvm.org
Fri Aug 22 07:33:48 PDT 2025
https://github.com/rolfmorel updated https://github.com/llvm/llvm-project/pull/154938
>From d95c6ed430642f6b8c07c850c0ba5dd0633cf59b Mon Sep 17 00:00:00 2001
From: Rolf Morel <rolf.morel at intel.com>
Date: Thu, 21 Aug 2025 10:15:28 -0700
Subject: [PATCH 1/3] [MLIR][LLVMIR][DLTI] Pass for updating target features
per TargetMachine
---
.../mlir/Dialect/LLVMIR/CMakeLists.txt | 18 ++++-
.../mlir/Dialect/LLVMIR/LLVMAttrDefs.td | 67 +------------------
mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h | 5 ++
.../mlir/Dialect/LLVMIR/LLVMDialect.td | 9 +++
.../mlir/Dialect/LLVMIR/LLVMInterfaces.td | 2 +-
mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td | 1 +
.../mlir/Target/LLVMIR/Transforms/Passes.td | 14 ++++
mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp | 14 ++++
.../Target/LLVMIR/Transforms/CMakeLists.txt | 1 +
.../LLVMIR/Transforms/TargetToDataLayout.cpp | 3 +-
.../Dialect/LLVMIR/target-to-data-layout.mlir | 6 +-
11 files changed, 68 insertions(+), 72 deletions(-)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/CMakeLists.txt b/mlir/include/mlir/Dialect/LLVMIR/CMakeLists.txt
index cfad07e57021f..f1385cdff62be 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/CMakeLists.txt
+++ b/mlir/include/mlir/Dialect/LLVMIR/CMakeLists.txt
@@ -7,12 +7,26 @@ mlir_tablegen(LLVMOpsDialect.h.inc -gen-dialect-decls)
mlir_tablegen(LLVMOpsDialect.cpp.inc -gen-dialect-defs)
mlir_tablegen(LLVMOpsEnums.h.inc -gen-enum-decls)
mlir_tablegen(LLVMOpsEnums.cpp.inc -gen-enum-defs)
-mlir_tablegen(LLVMOpsAttrDefs.h.inc -gen-attrdef-decls
- -attrdefs-dialect=llvm)
+#For LLVMOpsAttrDefs.h.inc, see below.
mlir_tablegen(LLVMOpsAttrDefs.cpp.inc -gen-attrdef-defs
-attrdefs-dialect=llvm)
add_public_tablegen_target(MLIRLLVMOpsIncGen)
+# NB: Separate out LLVMOpsAttrDefs.h.inc generation as generating it
+# through LLVMOps.td ends up defining LLVMTargetFeaturesAttr even
+# though LLVMTargetFeaturesAttrDefs.* is responsible for that.
+set(LLVM_TARGET_DEFINITIONS LLVMAttrAndEnumDefs.td)
+mlir_tablegen(LLVMOpsAttrDefs.h.inc -gen-attrdef-decls -attrdefs-dialect=llvm)
+add_public_tablegen_target(MLIRLLVMAttrsIncGen)
+
+# NB: LLVMTargetFeaturesAttr is split out into its own file
+# to break a recursive dependency: LLVMInterfaces depends
+# on it, and other LLVMAttrs depending on LLVMInterfaces.
+set(LLVM_TARGET_DEFINITIONS LLVMTargetFeaturesAttrDefs.td)
+mlir_tablegen(LLVMTargetFeaturesAttrDefs.h.inc -gen-attrdef-decls)
+mlir_tablegen(LLVMTargetFeaturesAttrDefs.cpp.inc -gen-attrdef-defs)
+add_public_tablegen_target(MLIRLLVMTargetFeaturesAttrsIncGen)
+
set(LLVM_TARGET_DEFINITIONS LLVMTypes.td)
mlir_tablegen(LLVMTypes.h.inc -gen-typedef-decls -typedefs-dialect=llvm)
mlir_tablegen(LLVMTypes.cpp.inc -gen-typedef-defs -typedefs-dialect=llvm)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
index 138dd7703a5e7..b149f4d334665 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
@@ -1243,70 +1243,7 @@ def LLVM_VScaleRangeAttr : LLVM_Attr<"VScaleRange", "vscale_range"> {
}
//===----------------------------------------------------------------------===//
-// TargetFeaturesAttr
-//===----------------------------------------------------------------------===//
-
-def LLVM_TargetFeaturesAttr : LLVM_Attr<"TargetFeatures", "target_features">
-{
- let summary = "LLVM target features attribute";
-
- let description = [{
- Represents the LLVM target features as a list that can be checked within
- passes/rewrites.
-
- Example:
- ```mlir
- #llvm.target_features<["+sme", "+sve", "+sme-f64f64"]>
- ```
-
- Then within a pass or rewrite the features active at an op can be queried:
-
- ```c++
- auto targetFeatures = LLVM::TargetFeaturesAttr::featuresAt(op);
-
- if (!targetFeatures.contains("+sme-f64f64"))
- return failure();
- ```
- }];
-
- let parameters = (ins OptionalArrayRefParameter<"StringAttr">:$features);
-
- let builders = [
- TypeBuilder<(ins "::llvm::StringRef":$features)>,
- TypeBuilder<(ins "::llvm::ArrayRef<::llvm::StringRef>":$features)>
- ];
-
- let extraClassDeclaration = [{
- /// Checks if a feature is contained within the features list.
- /// Note: Using a StringAttr allows doing pointer-comparisons.
- bool contains(::mlir::StringAttr feature) const;
- bool contains(::llvm::StringRef feature) const;
-
- bool nullOrEmpty() const {
- // Checks if this attribute is null, or the features are empty.
- return !bool(*this) || getFeatures().empty();
- }
-
- /// Returns the list of features as an LLVM-compatible string.
- std::string getFeaturesString() const;
-
- /// Finds the target features on the parent FunctionOpInterface.
- /// Note: This assumes the attribute name matches the return value of
- /// `getAttributeName()`.
- static TargetFeaturesAttr featuresAt(Operation* op);
-
- /// Canonical name for this attribute within MLIR.
- static constexpr StringLiteral getAttributeName() {
- return StringLiteral("target_features");
- }
- }];
-
- let assemblyFormat = "`<` `[` (`]`) : ($features^ `]`)? `>`";
- let genVerifyDecl = 1;
-}
-
-//===----------------------------------------------------------------------===//
-// LLVM_TargetAttr
+// TargetAttr
//===----------------------------------------------------------------------===//
def LLVM_TargetAttr : LLVM_Attr<"Target", "target",
@@ -1324,7 +1261,7 @@ def LLVM_TargetAttr : LLVM_Attr<"Target", "target",
}];
let parameters = (ins "StringAttr":$triple,
"StringAttr":$chip,
- OptionalParameter<"StringAttr", "">:$features);
+ OptionalParameter<"TargetFeaturesAttr", "">:$features);
let assemblyFormat = [{`<` struct($triple, $chip, $features) `>`}];
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h
index 1ceeb7e4ba2a5..4a24a9146fb72 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h
@@ -92,9 +92,14 @@ class TBAANodeAttr : public Attribute {
using cconv::CConv;
using linkage::Linkage;
using tailcallkind::TailCallKind;
+
+class TargetFeaturesAttr;
} // namespace LLVM
} // namespace mlir
+#define GET_ATTRDEF_CLASSES
+#include "mlir/Dialect/LLVMIR/LLVMTargetFeaturesAttrDefs.h.inc"
+
#include "mlir/Dialect/LLVMIR/LLVMAttrInterfaces.h.inc"
#define GET_ATTRDEF_CLASSES
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td
index ab0462f945a33..541df23784c01 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td
@@ -10,6 +10,7 @@
#define LLVMIR_DIALECT
include "mlir/IR/DialectBase.td"
+include "mlir/IR/AttrTypeBase.td"
def LLVM_Dialect : Dialect {
let name = "llvm";
@@ -127,4 +128,12 @@ def LLVM_Dialect : Dialect {
}];
}
+// All of the attributes will extend this class.
+class LLVM_Attr<string name, string attrMnemonic,
+ list<Trait> traits = [],
+ string baseCppClass = "::mlir::Attribute">
+ : AttrDef<LLVM_Dialect, name, traits, baseCppClass> {
+ let mnemonic = attrMnemonic;
+}
+
#endif // LLVMIR_DIALECT
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMInterfaces.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMInterfaces.td
index 64600e86bedfb..dab2af75d071e 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMInterfaces.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMInterfaces.td
@@ -561,7 +561,7 @@ def LLVM_TargetAttrInterface
>,
InterfaceMethod<
/*description=*/"Returns the target features as a string.",
- /*retTy=*/"StringAttr",
+ /*retTy=*/"LLVM::TargetFeaturesAttr",
/*methodName=*/"getFeatures",
/*args=*/(ins)
>
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index 3f27f6d9ae8b7..6e6e5b0aa75b1 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -14,6 +14,7 @@
#define LLVMIR_OPS
include "mlir/Dialect/LLVMIR/LLVMAttrDefs.td"
+include "mlir/Dialect/LLVMIR/LLVMTargetFeaturesAttrDefs.td"
include "mlir/Dialect/LLVMIR/LLVMEnums.td"
include "mlir/Dialect/LLVMIR/LLVMOpBase.td"
include "mlir/IR/EnumAttr.td"
diff --git a/mlir/include/mlir/Target/LLVMIR/Transforms/Passes.td b/mlir/include/mlir/Target/LLVMIR/Transforms/Passes.td
index 906f6e82efa50..d082503feb4bc 100644
--- a/mlir/include/mlir/Target/LLVMIR/Transforms/Passes.td
+++ b/mlir/include/mlir/Target/LLVMIR/Transforms/Passes.td
@@ -27,4 +27,18 @@ def LLVMTargetToDataLayout : Pass<"llvm-target-to-data-layout"> {
];
}
+def LLVMFeaturesFromTarget : Pass<"llvm-features-from-target"> {
+ let summary = "TODO";
+ let dependentDialects = ["mlir::DLTIDialect"];
+ let description = [{
+ TODO
+ }];
+ let options = [
+ Option<"initializeLLVMTargets", "initialize-llvm-targets", "bool",
+ /*default=*/"true",
+ "Whether to pre-load all available target machines, that LLVM is "
+ "configured to support, into the TargetRegistry.">
+ ];
+}
+
#endif // MLIR_TARGET_LLVMIR_TRANSFORMS_PASSES
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
index 634efcaea794e..8860b82d48a39 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
@@ -403,6 +403,20 @@ ModuleFlagAttr::verify(function_ref<InFlightDiagnostic()> emitError,
<< key << "'";
}
+FailureOr<Attribute> TargetFeaturesAttr::query(DataLayoutEntryKey key) {
+ if (auto stringKey = dyn_cast<StringAttr>(key)) {
+ if (contains(stringKey))
+ return UnitAttr::get(getContext());
+
+ if (contains((std::string("+") + stringKey.strref()).str()))
+ return BoolAttr::get(getContext(), true);
+
+ if (contains((std::string("-") + stringKey.strref()).str()))
+ return BoolAttr::get(getContext(), false);
+ }
+ return failure();
+}
+
//===----------------------------------------------------------------------===//
// LLVM_TargetAttr
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Target/LLVMIR/Transforms/CMakeLists.txt b/mlir/lib/Target/LLVMIR/Transforms/CMakeLists.txt
index a0232601c5f9c..6ef2d621af401 100644
--- a/mlir/lib/Target/LLVMIR/Transforms/CMakeLists.txt
+++ b/mlir/lib/Target/LLVMIR/Transforms/CMakeLists.txt
@@ -1,5 +1,6 @@
add_mlir_dialect_library(MLIRTargetLLVMIRTransforms
TargetToDataLayout.cpp
+ FeaturesFromTarget.cpp
DEPENDS
MLIRTargetLLVMIRTransformsIncGen
diff --git a/mlir/lib/Target/LLVMIR/Transforms/TargetToDataLayout.cpp b/mlir/lib/Target/LLVMIR/Transforms/TargetToDataLayout.cpp
index d41d441812039..95363c85bc6de 100644
--- a/mlir/lib/Target/LLVMIR/Transforms/TargetToDataLayout.cpp
+++ b/mlir/lib/Target/LLVMIR/Transforms/TargetToDataLayout.cpp
@@ -33,7 +33,8 @@ static FailureOr<std::unique_ptr<llvm::TargetMachine>>
getTargetMachine(LLVM::TargetAttrInterface attr) {
StringRef triple = attr.getTriple();
StringRef chipAKAcpu = attr.getChip();
- StringRef features = attr.getFeatures() ? attr.getFeatures().getValue() : "";
+ std::string features =
+ attr.getFeatures() ? attr.getFeatures().getFeaturesString() : "";
std::string error;
const llvm::Target *target =
diff --git a/mlir/test/Dialect/LLVMIR/target-to-data-layout.mlir b/mlir/test/Dialect/LLVMIR/target-to-data-layout.mlir
index 45bfd6a465d7c..17db9bc5e114b 100644
--- a/mlir/test/Dialect/LLVMIR/target-to-data-layout.mlir
+++ b/mlir/test/Dialect/LLVMIR/target-to-data-layout.mlir
@@ -25,7 +25,7 @@ module attributes { llvm.target = #llvm.target<triple = "x86_64-unknown-linux",
module attributes { llvm.target = #llvm.target<triple = "x86_64-unknown-linux",
chip = "",
- features = "+mmx,+sse"> } {
+ features = <["+mmx","+sse"]>> } {
}
// -----
@@ -54,7 +54,7 @@ module attributes { llvm.target = #llvm.target<triple = "x86_64-unknown-linux",
module attributes { llvm.target = #llvm.target<triple = "x86_64-unknown-linux",
chip = "skylake",
- features = "+mmx,+sse"> } {
+ features = <["+mmx","+sse"]>> } {
}
// -----
@@ -71,5 +71,5 @@ module attributes { llvm.target = #llvm.target<triple = "x86_64-unknown-linux",
module attributes { dlti.dl_spec = #dlti.dl_spec<index = 32>,
llvm.target = #llvm.target<triple = "x86_64-unknown-linux",
chip = "skylake",
- features = "+mmx,+sse"> } {
+ features = <["+mmx","+sse"]>> } {
}
>From fbcd09dd5870286d9c8100cd1af304fe0c670fbd Mon Sep 17 00:00:00 2001
From: Rolf Morel <rolf.morel at intel.com>
Date: Fri, 22 Aug 2025 05:04:50 -0700
Subject: [PATCH 2/3] Sharing is caring
---
.../Dialect/LLVMIR/LLVMAttrAndEnumDefs.td | 10 +++
.../mlir/Dialect/LLVMIR/LLVMAttrDefs.td | 8 --
.../LLVMIR/LLVMTargetFeaturesAttrDefs.td | 82 +++++++++++++++++++
.../mlir/Target/LLVMIR/Transforms/Passes.h | 14 ++++
.../mlir/Target/LLVMIR/Transforms/Passes.td | 2 +-
.../Target/LLVMIR/Transforms/CMakeLists.txt | 3 +-
.../LLVMIR/Transforms/TargetToDataLayout.cpp | 54 ++----------
.../Transforms/TargetToTargetFeatures.cpp | 67 +++++++++++++++
.../Target/LLVMIR/Transforms/TargetUtils.cpp | 70 ++++++++++++++++
.../LLVMIR/target-to-data-layout-invalid.mlir | 0
.../LLVMIR/target-to-data-layout-no-init.mlir | 0
.../LLVMIR/target-to-data-layout.mlir | 0
12 files changed, 251 insertions(+), 59 deletions(-)
create mode 100644 mlir/include/mlir/Dialect/LLVMIR/LLVMAttrAndEnumDefs.td
create mode 100644 mlir/include/mlir/Dialect/LLVMIR/LLVMTargetFeaturesAttrDefs.td
create mode 100644 mlir/lib/Target/LLVMIR/Transforms/TargetToTargetFeatures.cpp
create mode 100644 mlir/lib/Target/LLVMIR/Transforms/TargetUtils.cpp
rename mlir/test/{Dialect => Target}/LLVMIR/target-to-data-layout-invalid.mlir (100%)
rename mlir/test/{Dialect => Target}/LLVMIR/target-to-data-layout-no-init.mlir (100%)
rename mlir/test/{Dialect => Target}/LLVMIR/target-to-data-layout.mlir (100%)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrAndEnumDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrAndEnumDefs.td
new file mode 100644
index 0000000000000..e34375076ffd1
--- /dev/null
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrAndEnumDefs.td
@@ -0,0 +1,10 @@
+//===-- LLVMAttrDefs.td - Solely LLVM Attribute and Enum definitions ----*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+include "mlir/Dialect/LLVMIR/LLVMAttrDefs.td"
+include "mlir/Dialect/LLVMIR/LLVMEnums.td"
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
index b149f4d334665..af469d3eb8be2 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
@@ -15,14 +15,6 @@ include "mlir/IR/AttrTypeBase.td"
include "mlir/IR/CommonAttrConstraints.td"
include "mlir/Interfaces/DataLayoutInterfaces.td"
-// All of the attributes will extend this class.
-class LLVM_Attr<string name, string attrMnemonic,
- list<Trait> traits = [],
- string baseCppClass = "::mlir::Attribute">
- : AttrDef<LLVM_Dialect, name, traits, baseCppClass> {
- let mnemonic = attrMnemonic;
-}
-
//===----------------------------------------------------------------------===//
// CConvAttr
//===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMTargetFeaturesAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMTargetFeaturesAttrDefs.td
new file mode 100644
index 0000000000000..bc60591514c28
--- /dev/null
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMTargetFeaturesAttrDefs.td
@@ -0,0 +1,82 @@
+//===-- LLVMAttrDefs.td - LLVM Attributes definition file --*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVMIR_TARGETFEATURESATTRDEFS
+#define LLVMIR_TARGETFEATURESATTRDEFS
+
+include "mlir/Dialect/LLVMIR/LLVMDialect.td"
+include "mlir/Interfaces/DataLayoutInterfaces.td"
+
+//===----------------------------------------------------------------------===//
+// TargetFeaturesAttr
+//===----------------------------------------------------------------------===//
+
+def LLVM_TargetFeaturesAttr : LLVM_Attr<"TargetFeatures", "target_features",
+ [DLTIQueryInterface]>
+{
+ let summary = "LLVM target features attribute";
+
+ let description = [{
+ Represents the LLVM target features as a list that can be checked within
+ passes/rewrites.
+
+ Example:
+ ```mlir
+ #llvm.target_features<["+sme", "+sve", "+sme-f64f64"]>
+ ```
+
+ Then within a pass or rewrite the features active at an op can be queried:
+
+ ```c++
+ auto targetFeatures = LLVM::TargetFeaturesAttr::featuresAt(op);
+
+ if (!targetFeatures.contains("+sme-f64f64"))
+ return failure();
+ ```
+ }];
+
+ let parameters = (ins OptionalArrayRefParameter<"StringAttr">:$features);
+
+ let builders = [
+ TypeBuilder<(ins "::llvm::StringRef":$features)>,
+ TypeBuilder<(ins "::llvm::ArrayRef<::llvm::StringRef>":$features)>
+ ];
+
+ let extraClassDeclaration = [{
+ /// Checks if a feature is contained within the features list.
+ /// Note: Using a StringAttr allows doing pointer-comparisons.
+ bool contains(::mlir::StringAttr feature) const;
+ bool contains(::llvm::StringRef feature) const;
+
+ bool nullOrEmpty() const {
+ // Checks if this attribute is null, or the features are empty.
+ return !bool(*this) || getFeatures().empty();
+ }
+
+ /// Returns the list of features as an LLVM-compatible string.
+ std::string getFeaturesString() const;
+
+ /// Finds the target features on the parent FunctionOpInterface.
+ /// Note: This assumes the attribute name matches the return value of
+ /// `getAttributeName()`.
+ static TargetFeaturesAttr featuresAt(Operation* op);
+
+ /// Canonical name for this attribute within MLIR.
+ static constexpr StringLiteral getAttributeName() {
+ return StringLiteral("target_features");
+ }
+
+ /// Returns the attribute associated with the key.
+ FailureOr<Attribute> query(DataLayoutEntryKey key);
+ }];
+
+ let assemblyFormat = "`<` `[` (`]`) : ($features^ `]`)? `>`";
+ let genVerifyDecl = 1;
+}
+
+#endif // LLVMIR_TARGETFEATURESATTRDEFS
diff --git a/mlir/include/mlir/Target/LLVMIR/Transforms/Passes.h b/mlir/include/mlir/Target/LLVMIR/Transforms/Passes.h
index 1e6419154108c..db8feb3ae2396 100644
--- a/mlir/include/mlir/Target/LLVMIR/Transforms/Passes.h
+++ b/mlir/include/mlir/Target/LLVMIR/Transforms/Passes.h
@@ -9,12 +9,26 @@
#ifndef MLIR_TARGET_LLVMIR_TRANSFORMS_PASSES_H
#define MLIR_TARGET_LLVMIR_TRANSFORMS_PASSES_H
+#include "mlir/Dialect/LLVMIR/LLVMInterfaces.h"
#include "mlir/Pass/Pass.h"
+#include "llvm/Support/Threading.h"
+#include "llvm/Target/TargetMachine.h"
namespace mlir {
namespace LLVM {
+namespace detail {
+
+void initializeBackendsOnce();
+
+FailureOr<std::unique_ptr<llvm::TargetMachine>>
+getTargetMachine(mlir::LLVM::TargetAttrInterface attr);
+
+FailureOr<llvm::DataLayout> getDataLayout(mlir::LLVM::TargetAttrInterface attr);
+
+} // namespace detail
+
#define GEN_PASS_DECL
#define GEN_PASS_REGISTRATION
#include "mlir/Target/LLVMIR/Transforms/Passes.h.inc"
diff --git a/mlir/include/mlir/Target/LLVMIR/Transforms/Passes.td b/mlir/include/mlir/Target/LLVMIR/Transforms/Passes.td
index d082503feb4bc..b01baa8744ee3 100644
--- a/mlir/include/mlir/Target/LLVMIR/Transforms/Passes.td
+++ b/mlir/include/mlir/Target/LLVMIR/Transforms/Passes.td
@@ -27,7 +27,7 @@ def LLVMTargetToDataLayout : Pass<"llvm-target-to-data-layout"> {
];
}
-def LLVMFeaturesFromTarget : Pass<"llvm-features-from-target"> {
+def LLVMTargetToTargetFeatures : Pass<"llvm-target-to-target-features"> {
let summary = "TODO";
let dependentDialects = ["mlir::DLTIDialect"];
let description = [{
diff --git a/mlir/lib/Target/LLVMIR/Transforms/CMakeLists.txt b/mlir/lib/Target/LLVMIR/Transforms/CMakeLists.txt
index 6ef2d621af401..044da1c442049 100644
--- a/mlir/lib/Target/LLVMIR/Transforms/CMakeLists.txt
+++ b/mlir/lib/Target/LLVMIR/Transforms/CMakeLists.txt
@@ -1,6 +1,7 @@
add_mlir_dialect_library(MLIRTargetLLVMIRTransforms
TargetToDataLayout.cpp
- FeaturesFromTarget.cpp
+ TargetToTargetFeatures.cpp
+ TargetUtils.cpp
DEPENDS
MLIRTargetLLVMIRTransformsIncGen
diff --git a/mlir/lib/Target/LLVMIR/Transforms/TargetToDataLayout.cpp b/mlir/lib/Target/LLVMIR/Transforms/TargetToDataLayout.cpp
index 95363c85bc6de..250d6162fd780 100644
--- a/mlir/lib/Target/LLVMIR/Transforms/TargetToDataLayout.cpp
+++ b/mlir/lib/Target/LLVMIR/Transforms/TargetToDataLayout.cpp
@@ -5,21 +5,13 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+
#include "mlir/Target/LLVMIR/Transforms/Passes.h"
#include "mlir/Dialect/DLTI/DLTI.h"
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "mlir/Target/LLVMIR/Import.h"
-#include "llvm/MC/TargetRegistry.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/TargetSelect.h"
-#include "llvm/Target/TargetMachine.h"
-
-#define DEBUG_TYPE "mlir-llvm-target-to-data-layout"
-#define DBGS() (llvm::dbgs() << '[' << DEBUG_TYPE << "] ")
-#define LDBG(X) LLVM_DEBUG(DBGS() << X << "\n")
-
namespace mlir {
namespace LLVM {
#define GEN_PASS_DEF_LLVMTARGETTODATALAYOUT
@@ -29,36 +21,6 @@ namespace LLVM {
using namespace mlir;
-static FailureOr<std::unique_ptr<llvm::TargetMachine>>
-getTargetMachine(LLVM::TargetAttrInterface attr) {
- StringRef triple = attr.getTriple();
- StringRef chipAKAcpu = attr.getChip();
- std::string features =
- attr.getFeatures() ? attr.getFeatures().getFeaturesString() : "";
-
- std::string error;
- const llvm::Target *target =
- llvm::TargetRegistry::lookupTarget(triple, error);
- if (!target || !error.empty()) {
- LDBG("Looking up target '" << triple << "' failed: " << error << "\n");
- return failure();
- }
-
- return std::unique_ptr<llvm::TargetMachine>(target->createTargetMachine(
- llvm::Triple(triple), chipAKAcpu, features, {}, {}));
-}
-
-static FailureOr<llvm::DataLayout>
-getDataLayout(LLVM::TargetAttrInterface attr) {
- FailureOr<std::unique_ptr<llvm::TargetMachine>> targetMachine =
- getTargetMachine(attr);
- if (failed(targetMachine)) {
- LDBG("Failed to retrieve the target machine for data layout.\n");
- return failure();
- }
- return (targetMachine.value())->createDataLayout();
-}
-
struct TargetToDataLayoutPass
: public LLVM::impl::LLVMTargetToDataLayoutBase<TargetToDataLayoutPass> {
using LLVM::impl::LLVMTargetToDataLayoutBase<
@@ -67,15 +29,8 @@ struct TargetToDataLayoutPass
void runOnOperation() override {
Operation *op = getOperation();
- if (initializeLLVMTargets) {
- static llvm::once_flag initializeBackendsOnce;
- llvm::call_once(initializeBackendsOnce, []() {
- // Ensure that the targets, that LLVM has been configured to support,
- // are loaded into the TargetRegistry.
- llvm::InitializeAllTargets();
- llvm::InitializeAllTargetMCs();
- });
- }
+ if (initializeLLVMTargets)
+ LLVM::detail::initializeBackendsOnce();
auto targetAttr = op->getAttrOfType<LLVM::TargetAttrInterface>(
LLVM::LLVMDialect::getTargetAttrName());
@@ -86,7 +41,8 @@ struct TargetToDataLayoutPass
return signalPassFailure();
}
- FailureOr<llvm::DataLayout> dataLayout = getDataLayout(targetAttr);
+ FailureOr<llvm::DataLayout> dataLayout =
+ LLVM::detail::getDataLayout(targetAttr);
if (failed(dataLayout)) {
op->emitError() << "failed to obtain llvm::DataLayout for " << targetAttr;
return signalPassFailure();
diff --git a/mlir/lib/Target/LLVMIR/Transforms/TargetToTargetFeatures.cpp b/mlir/lib/Target/LLVMIR/Transforms/TargetToTargetFeatures.cpp
new file mode 100644
index 0000000000000..22153fc883aaa
--- /dev/null
+++ b/mlir/lib/Target/LLVMIR/Transforms/TargetToTargetFeatures.cpp
@@ -0,0 +1,67 @@
+//===- TargetToTargetFeatures.cpp - extract features from TargetMachine ---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Target/LLVMIR/Transforms/Passes.h"
+
+#include "mlir/Dialect/DLTI/DLTI.h"
+#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "mlir/Target/LLVMIR/Import.h"
+
+#include "llvm/MC/MCSubtargetInfo.h"
+
+namespace mlir {
+namespace LLVM {
+#define GEN_PASS_DEF_LLVMTARGETTOTARGETFEATURES
+#include "mlir/Target/LLVMIR/Transforms/Passes.h.inc"
+} // namespace LLVM
+} // namespace mlir
+
+using namespace mlir;
+
+struct TargetToTargetFeaturesPass
+ : public LLVM::impl::LLVMTargetToTargetFeaturesBase<TargetToTargetFeaturesPass> {
+ using LLVM::impl::LLVMTargetToTargetFeaturesBase<
+ TargetToTargetFeaturesPass>::LLVMTargetToTargetFeaturesBase;
+
+ void runOnOperation() override {
+ Operation *op = getOperation();
+
+ if (initializeLLVMTargets)
+ LLVM::detail::initializeBackendsOnce();
+
+ auto targetAttr = op->getAttrOfType<LLVM::TargetAttr>(
+ LLVM::LLVMDialect::getTargetAttrName());
+ if (!targetAttr) {
+ op->emitError() << "no LLVM::TargetAttr attribute at key \""
+ << LLVM::LLVMDialect::getTargetAttrName() << "\"";
+ return signalPassFailure();
+ }
+
+ FailureOr<std::unique_ptr<llvm::TargetMachine>> targetMachine =
+ LLVM::detail::getTargetMachine(targetAttr);
+ if (failed(targetMachine)) {
+ op->emitError() << "failed to obtain llvm::TargetMachine for "
+ << targetAttr;
+ return signalPassFailure();
+ }
+
+ llvm::MCSubtargetInfo const *subTargetInfo =
+ (*targetMachine)->getMCSubtargetInfo();
+
+ StringRef fullTargetFeaturesStr = subTargetInfo->getFeatureString();
+
+ auto fullTargetFeaturesAttr =
+ LLVM::TargetFeaturesAttr::get(&getContext(), fullTargetFeaturesStr);
+
+ auto updatedTargetAttr =
+ LLVM::TargetAttr::get(&getContext(), targetAttr.getTriple(),
+ targetAttr.getChip(), fullTargetFeaturesAttr);
+
+ op->setAttr(LLVM::LLVMDialect::getTargetAttrName(), updatedTargetAttr);
+ }
+};
diff --git a/mlir/lib/Target/LLVMIR/Transforms/TargetUtils.cpp b/mlir/lib/Target/LLVMIR/Transforms/TargetUtils.cpp
new file mode 100644
index 0000000000000..5c12ec125c845
--- /dev/null
+++ b/mlir/lib/Target/LLVMIR/Transforms/TargetUtils.cpp
@@ -0,0 +1,70 @@
+//===- TargetUtils.cpp - utils for obtaining generic target backend info --===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#include "mlir/Target/LLVMIR/Transforms/Passes.h"
+
+#include "mlir/Dialect/DLTI/DLTI.h"
+#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "mlir/Target/LLVMIR/Import.h"
+
+#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/Target/TargetMachine.h"
+
+#define DEBUG_TYPE "mlir-llvm-target-utils"
+#define DBGS() (llvm::dbgs() << '[' << DEBUG_TYPE << "] ")
+#define LDBG(X) LLVM_DEBUG(DBGS() << X << "\n")
+
+llvm::once_flag initializeBackendsOnce;
+
+namespace mlir {
+namespace LLVM {
+namespace detail {
+void initializeBackendsOnce() {
+ static llvm::once_flag initializeOnceFlag;
+ llvm::call_once(initializeOnceFlag, []() {
+ // Ensure that the targets, that LLVM has been configured to support,
+ // are loaded into the TargetRegistry.
+ llvm::InitializeAllTargets();
+ llvm::InitializeAllTargetMCs();
+ });
+}
+
+FailureOr<std::unique_ptr<llvm::TargetMachine>>
+getTargetMachine(mlir::LLVM::TargetAttrInterface attr) {
+ StringRef triple = attr.getTriple();
+ StringRef chipAKAcpu = attr.getChip();
+ std::string features =
+ attr.getFeatures() ? attr.getFeatures().getFeaturesString() : "";
+
+ std::string error;
+ const llvm::Target *target =
+ llvm::TargetRegistry::lookupTarget(triple, error);
+ if (!target || !error.empty()) {
+ LDBG("Looking up target '" << triple << "' failed: " << error << "\n");
+ return failure();
+ }
+
+ return std::unique_ptr<llvm::TargetMachine>(target->createTargetMachine(
+ llvm::Triple(triple), chipAKAcpu, features, {}, {}));
+}
+
+FailureOr<llvm::DataLayout>
+getDataLayout(mlir::LLVM::TargetAttrInterface attr) {
+ FailureOr<std::unique_ptr<llvm::TargetMachine>> targetMachine =
+ getTargetMachine(attr);
+ if (failed(targetMachine)) {
+ LDBG("Failed to retrieve the target machine for data layout.\n");
+ return failure();
+ }
+ return (targetMachine.value())->createDataLayout();
+}
+
+} // namespace detail
+} // namespace LLVM
+} // namespace mlir
diff --git a/mlir/test/Dialect/LLVMIR/target-to-data-layout-invalid.mlir b/mlir/test/Target/LLVMIR/target-to-data-layout-invalid.mlir
similarity index 100%
rename from mlir/test/Dialect/LLVMIR/target-to-data-layout-invalid.mlir
rename to mlir/test/Target/LLVMIR/target-to-data-layout-invalid.mlir
diff --git a/mlir/test/Dialect/LLVMIR/target-to-data-layout-no-init.mlir b/mlir/test/Target/LLVMIR/target-to-data-layout-no-init.mlir
similarity index 100%
rename from mlir/test/Dialect/LLVMIR/target-to-data-layout-no-init.mlir
rename to mlir/test/Target/LLVMIR/target-to-data-layout-no-init.mlir
diff --git a/mlir/test/Dialect/LLVMIR/target-to-data-layout.mlir b/mlir/test/Target/LLVMIR/target-to-data-layout.mlir
similarity index 100%
rename from mlir/test/Dialect/LLVMIR/target-to-data-layout.mlir
rename to mlir/test/Target/LLVMIR/target-to-data-layout.mlir
>From ec157172dbf280212ccd5c9c02372e4296703376 Mon Sep 17 00:00:00 2001
From: Rolf Morel <rolf.morel at intel.com>
Date: Fri, 22 Aug 2025 07:33:18 -0700
Subject: [PATCH 3/3] Get feature flags from proper source
Thanks Renato!
---
.../LLVMIR/Transforms/TargetToTargetFeatures.cpp | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/mlir/lib/Target/LLVMIR/Transforms/TargetToTargetFeatures.cpp b/mlir/lib/Target/LLVMIR/Transforms/TargetToTargetFeatures.cpp
index 22153fc883aaa..34d1981ee11df 100644
--- a/mlir/lib/Target/LLVMIR/Transforms/TargetToTargetFeatures.cpp
+++ b/mlir/lib/Target/LLVMIR/Transforms/TargetToTargetFeatures.cpp
@@ -24,7 +24,8 @@ namespace LLVM {
using namespace mlir;
struct TargetToTargetFeaturesPass
- : public LLVM::impl::LLVMTargetToTargetFeaturesBase<TargetToTargetFeaturesPass> {
+ : public LLVM::impl::LLVMTargetToTargetFeaturesBase<
+ TargetToTargetFeaturesPass> {
using LLVM::impl::LLVMTargetToTargetFeaturesBase<
TargetToTargetFeaturesPass>::LLVMTargetToTargetFeaturesBase;
@@ -53,10 +54,19 @@ struct TargetToTargetFeaturesPass
llvm::MCSubtargetInfo const *subTargetInfo =
(*targetMachine)->getMCSubtargetInfo();
- StringRef fullTargetFeaturesStr = subTargetInfo->getFeatureString();
+ const std::vector<llvm::SubtargetFeatureKV> enabledFeatures =
+ subTargetInfo->getEnabledProcessorFeatures();
+
+ auto plussedFeatures = llvm::to_vector(
+ llvm::map_range(enabledFeatures, [](llvm::SubtargetFeatureKV feature) {
+ return std::string("+") + feature.Key;
+ }));
+
+ auto plussedFeaturesRefs = llvm::to_vector(llvm::map_range(
+ plussedFeatures, [](auto &it) { return StringRef(it.c_str()); }));
auto fullTargetFeaturesAttr =
- LLVM::TargetFeaturesAttr::get(&getContext(), fullTargetFeaturesStr);
+ LLVM::TargetFeaturesAttr::get(&getContext(), plussedFeaturesRefs);
auto updatedTargetAttr =
LLVM::TargetAttr::get(&getContext(), targetAttr.getTriple(),
More information about the Mlir-commits
mailing list