Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions mlir/include/mlir/Dialect/LLVMIR/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
10 changes: 10 additions & 0 deletions mlir/include/mlir/Dialect/LLVMIR/LLVMAttrAndEnumDefs.td
Original file line number Diff line number Diff line change
@@ -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"
75 changes: 2 additions & 73 deletions mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
Original file line number Diff line number Diff line change
Expand Up @@ -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
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -1243,70 +1235,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",
Expand All @@ -1324,7 +1253,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) `>`}];

Expand Down
5 changes: 5 additions & 0 deletions mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#define LLVMIR_DIALECT

include "mlir/IR/DialectBase.td"
include "mlir/IR/AttrTypeBase.td"

def LLVM_Dialect : Dialect {
let name = "llvm";
Expand Down Expand Up @@ -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
2 changes: 1 addition & 1 deletion mlir/include/mlir/Dialect/LLVMIR/LLVMInterfaces.td
Original file line number Diff line number Diff line change
Expand Up @@ -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)
>
Expand Down
1 change: 1 addition & 0 deletions mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
89 changes: 89 additions & 0 deletions mlir/include/mlir/Dialect/LLVMIR/LLVMTargetFeaturesAttrDefs.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
//===-- LLVMTargetFeaturesAttrDefs.td ----------------------*- 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
//
//===----------------------------------------------------------------------===//
//
// Separate out the LLVM_TargetFeaturesAttr definition from LLVMAttrDefs.td so
// as to break a circular dependency between LLVMInterfaces.td and LLVMAttrDefs.
// In particular, the TargetAttrInterface requires LLVMTargetFeaturesAttr
// and attrs in LLVMAttrDefs.td require interfaces from LLVMInterfaces.td.
//
//===----------------------------------------------------------------------===//

#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
1 change: 0 additions & 1 deletion mlir/include/mlir/Target/LLVMIR/Transforms/Passes.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include "mlir/Pass/Pass.h"

namespace mlir {

namespace LLVM {

#define GEN_PASS_DECL
Expand Down
17 changes: 17 additions & 0 deletions mlir/include/mlir/Target/LLVMIR/Transforms/Passes.td
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,21 @@ def LLVMTargetToDataLayout : Pass<"llvm-target-to-data-layout"> {
];
}

def LLVMTargetToTargetFeatures : Pass<"llvm-target-to-target-features"> {
let summary = "Update attached #llvm.target's features per the described target";
let dependentDialects = ["mlir::DLTIDialect"];
let description = [{
Obtain the TargetMachine specified by the attached #llvm.target's attributes
and obtain from it the full list of features of the selected target. Updates
the attached #llvm.target so that its features reflect the full list of
features.
}];
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
35 changes: 35 additions & 0 deletions mlir/include/mlir/Target/LLVMIR/Transforms/TargetUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//===- TargetUtils.h - Utils to obtain LLVM's TargetMachine and DataLayout ===//
//
// 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 MLIR_TARGET_LLVMIR_TRANSFORMS_TARGETUTILS_H
#define MLIR_TARGET_LLVMIR_TRANSFORMS_TARGETUTILS_H

#include "mlir/Dialect/LLVMIR/LLVMInterfaces.h"
#include "llvm/Support/Threading.h"
#include "llvm/Target/TargetMachine.h"

namespace mlir {
namespace LLVM {
namespace detail {
/// Idempotent helper to register/initialize all backends that LLVM has been
/// configured to support. Only runs the first time it is called.
void initializeBackendsOnce();

/// Helper to obtain the TargetMachine specified by the properties of the
/// TargetAttrInterface-implementing attribute.
FailureOr<std::unique_ptr<llvm::TargetMachine>>
getTargetMachine(mlir::LLVM::TargetAttrInterface attr);

/// Helper to obtain the DataLayout of the target specified by the properties of
/// the TargetAttrInterface-implementing attribute.
FailureOr<llvm::DataLayout> getDataLayout(mlir::LLVM::TargetAttrInterface attr);
} // namespace detail
} // namespace LLVM
} // namespace mlir

#endif // MLIR_TARGET_LLVMIR_TRANSFORMS_TARGETUTILS_H
14 changes: 14 additions & 0 deletions mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
//===----------------------------------------------------------------------===//
Expand Down
2 changes: 2 additions & 0 deletions mlir/lib/Target/LLVMIR/Transforms/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
add_mlir_dialect_library(MLIRTargetLLVMIRTransforms
TargetToDataLayout.cpp
TargetToTargetFeatures.cpp
TargetUtils.cpp

DEPENDS
MLIRTargetLLVMIRTransformsIncGen
Expand Down
Loading