@@ -15,6 +15,14 @@ include "mlir/IR/AttrTypeBase.td"
1515include "mlir/IR/CommonAttrConstraints.td"
1616include "mlir/Interfaces/DataLayoutInterfaces.td"
1717
18+ // All of the attributes will extend this class.
19+ class LLVM_Attr<string name, string attrMnemonic,
20+ list<Trait> traits = [],
21+ string baseCppClass = "::mlir::Attribute">
22+ : AttrDef<LLVM_Dialect, name, traits, baseCppClass> {
23+ let mnemonic = attrMnemonic;
24+ }
25+
1826//===----------------------------------------------------------------------===//
1927// CConvAttr
2028//===----------------------------------------------------------------------===//
@@ -1234,6 +1242,73 @@ def LLVM_VScaleRangeAttr : LLVM_Attr<"VScaleRange", "vscale_range"> {
12341242 let assemblyFormat = "`<` struct(params) `>`";
12351243}
12361244
1245+ //===----------------------------------------------------------------------===//
1246+ // TargetFeaturesAttr
1247+ //===----------------------------------------------------------------------===//
1248+
1249+ def LLVM_TargetFeaturesAttr : LLVM_Attr<"TargetFeatures", "target_features",
1250+ [DLTIQueryInterface]>
1251+ {
1252+ let summary = "LLVM target features attribute";
1253+
1254+ let description = [{
1255+ Represents the LLVM target features as a list that can be checked within
1256+ passes/rewrites.
1257+
1258+ Example:
1259+ ```mlir
1260+ #llvm.target_features<["+sme", "+sve", "+sme-f64f64"]>
1261+ ```
1262+
1263+ Then within a pass or rewrite the features active at an op can be queried:
1264+
1265+ ```c++
1266+ auto targetFeatures = LLVM::TargetFeaturesAttr::featuresAt(op);
1267+
1268+ if (!targetFeatures.contains("+sme-f64f64"))
1269+ return failure();
1270+ ```
1271+ }];
1272+
1273+ let parameters = (ins OptionalArrayRefParameter<"StringAttr">:$features);
1274+
1275+ let builders = [
1276+ TypeBuilder<(ins "::llvm::StringRef":$features)>,
1277+ TypeBuilder<(ins "::llvm::ArrayRef<::llvm::StringRef>":$features)>
1278+ ];
1279+
1280+ let extraClassDeclaration = [{
1281+ /// Checks if a feature is contained within the features list.
1282+ /// Note: Using a StringAttr allows doing pointer-comparisons.
1283+ bool contains(::mlir::StringAttr feature) const;
1284+ bool contains(::llvm::StringRef feature) const;
1285+
1286+ bool nullOrEmpty() const {
1287+ // Checks if this attribute is null, or the features are empty.
1288+ return !bool(*this) || getFeatures().empty();
1289+ }
1290+
1291+ /// Returns the list of features as an LLVM-compatible string.
1292+ std::string getFeaturesString() const;
1293+
1294+ /// Finds the target features on the parent FunctionOpInterface.
1295+ /// Note: This assumes the attribute name matches the return value of
1296+ /// `getAttributeName()`.
1297+ static TargetFeaturesAttr featuresAt(Operation* op);
1298+
1299+ /// Canonical name for this attribute within MLIR.
1300+ static constexpr StringLiteral getAttributeName() {
1301+ return StringLiteral("target_features");
1302+ }
1303+
1304+ /// Returns the attribute associated with the key.
1305+ FailureOr<Attribute> query(DataLayoutEntryKey key);
1306+ }];
1307+
1308+ let assemblyFormat = "`<` `[` (`]`) : ($features^ `]`)? `>`";
1309+ let genVerifyDecl = 1;
1310+ }
1311+
12371312//===----------------------------------------------------------------------===//
12381313// TargetAttr
12391314//===----------------------------------------------------------------------===//
0 commit comments