Skip to content

Commit fbcd09d

Browse files
committed
Sharing is caring
1 parent d95c6ed commit fbcd09d

File tree

12 files changed

+251
-59
lines changed

12 files changed

+251
-59
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//===-- LLVMAttrDefs.td - Solely LLVM Attribute and Enum definitions ----*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
include "mlir/Dialect/LLVMIR/LLVMAttrDefs.td"
10+
include "mlir/Dialect/LLVMIR/LLVMEnums.td"

mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,6 @@ include "mlir/IR/AttrTypeBase.td"
1515
include "mlir/IR/CommonAttrConstraints.td"
1616
include "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-
2618
//===----------------------------------------------------------------------===//
2719
// CConvAttr
2820
//===----------------------------------------------------------------------===//
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
//===-- LLVMAttrDefs.td - LLVM Attributes definition file --*- tablegen -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVMIR_TARGETFEATURESATTRDEFS
10+
#define LLVMIR_TARGETFEATURESATTRDEFS
11+
12+
include "mlir/Dialect/LLVMIR/LLVMDialect.td"
13+
include "mlir/Interfaces/DataLayoutInterfaces.td"
14+
15+
//===----------------------------------------------------------------------===//
16+
// TargetFeaturesAttr
17+
//===----------------------------------------------------------------------===//
18+
19+
def LLVM_TargetFeaturesAttr : LLVM_Attr<"TargetFeatures", "target_features",
20+
[DLTIQueryInterface]>
21+
{
22+
let summary = "LLVM target features attribute";
23+
24+
let description = [{
25+
Represents the LLVM target features as a list that can be checked within
26+
passes/rewrites.
27+
28+
Example:
29+
```mlir
30+
#llvm.target_features<["+sme", "+sve", "+sme-f64f64"]>
31+
```
32+
33+
Then within a pass or rewrite the features active at an op can be queried:
34+
35+
```c++
36+
auto targetFeatures = LLVM::TargetFeaturesAttr::featuresAt(op);
37+
38+
if (!targetFeatures.contains("+sme-f64f64"))
39+
return failure();
40+
```
41+
}];
42+
43+
let parameters = (ins OptionalArrayRefParameter<"StringAttr">:$features);
44+
45+
let builders = [
46+
TypeBuilder<(ins "::llvm::StringRef":$features)>,
47+
TypeBuilder<(ins "::llvm::ArrayRef<::llvm::StringRef>":$features)>
48+
];
49+
50+
let extraClassDeclaration = [{
51+
/// Checks if a feature is contained within the features list.
52+
/// Note: Using a StringAttr allows doing pointer-comparisons.
53+
bool contains(::mlir::StringAttr feature) const;
54+
bool contains(::llvm::StringRef feature) const;
55+
56+
bool nullOrEmpty() const {
57+
// Checks if this attribute is null, or the features are empty.
58+
return !bool(*this) || getFeatures().empty();
59+
}
60+
61+
/// Returns the list of features as an LLVM-compatible string.
62+
std::string getFeaturesString() const;
63+
64+
/// Finds the target features on the parent FunctionOpInterface.
65+
/// Note: This assumes the attribute name matches the return value of
66+
/// `getAttributeName()`.
67+
static TargetFeaturesAttr featuresAt(Operation* op);
68+
69+
/// Canonical name for this attribute within MLIR.
70+
static constexpr StringLiteral getAttributeName() {
71+
return StringLiteral("target_features");
72+
}
73+
74+
/// Returns the attribute associated with the key.
75+
FailureOr<Attribute> query(DataLayoutEntryKey key);
76+
}];
77+
78+
let assemblyFormat = "`<` `[` (`]`) : ($features^ `]`)? `>`";
79+
let genVerifyDecl = 1;
80+
}
81+
82+
#endif // LLVMIR_TARGETFEATURESATTRDEFS

mlir/include/mlir/Target/LLVMIR/Transforms/Passes.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,26 @@
99
#ifndef MLIR_TARGET_LLVMIR_TRANSFORMS_PASSES_H
1010
#define MLIR_TARGET_LLVMIR_TRANSFORMS_PASSES_H
1111

12+
#include "mlir/Dialect/LLVMIR/LLVMInterfaces.h"
1213
#include "mlir/Pass/Pass.h"
14+
#include "llvm/Support/Threading.h"
15+
#include "llvm/Target/TargetMachine.h"
1316

1417
namespace mlir {
1518

1619
namespace LLVM {
1720

21+
namespace detail {
22+
23+
void initializeBackendsOnce();
24+
25+
FailureOr<std::unique_ptr<llvm::TargetMachine>>
26+
getTargetMachine(mlir::LLVM::TargetAttrInterface attr);
27+
28+
FailureOr<llvm::DataLayout> getDataLayout(mlir::LLVM::TargetAttrInterface attr);
29+
30+
} // namespace detail
31+
1832
#define GEN_PASS_DECL
1933
#define GEN_PASS_REGISTRATION
2034
#include "mlir/Target/LLVMIR/Transforms/Passes.h.inc"

mlir/include/mlir/Target/LLVMIR/Transforms/Passes.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def LLVMTargetToDataLayout : Pass<"llvm-target-to-data-layout"> {
2727
];
2828
}
2929

30-
def LLVMFeaturesFromTarget : Pass<"llvm-features-from-target"> {
30+
def LLVMTargetToTargetFeatures : Pass<"llvm-target-to-target-features"> {
3131
let summary = "TODO";
3232
let dependentDialects = ["mlir::DLTIDialect"];
3333
let description = [{

mlir/lib/Target/LLVMIR/Transforms/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
add_mlir_dialect_library(MLIRTargetLLVMIRTransforms
22
TargetToDataLayout.cpp
3-
FeaturesFromTarget.cpp
3+
TargetToTargetFeatures.cpp
4+
TargetUtils.cpp
45

56
DEPENDS
67
MLIRTargetLLVMIRTransformsIncGen

mlir/lib/Target/LLVMIR/Transforms/TargetToDataLayout.cpp

Lines changed: 5 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,13 @@
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
//===----------------------------------------------------------------------===//
8+
89
#include "mlir/Target/LLVMIR/Transforms/Passes.h"
910

1011
#include "mlir/Dialect/DLTI/DLTI.h"
1112
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
1213
#include "mlir/Target/LLVMIR/Import.h"
1314

14-
#include "llvm/MC/TargetRegistry.h"
15-
#include "llvm/Support/Debug.h"
16-
#include "llvm/Support/TargetSelect.h"
17-
#include "llvm/Target/TargetMachine.h"
18-
19-
#define DEBUG_TYPE "mlir-llvm-target-to-data-layout"
20-
#define DBGS() (llvm::dbgs() << '[' << DEBUG_TYPE << "] ")
21-
#define LDBG(X) LLVM_DEBUG(DBGS() << X << "\n")
22-
2315
namespace mlir {
2416
namespace LLVM {
2517
#define GEN_PASS_DEF_LLVMTARGETTODATALAYOUT
@@ -29,36 +21,6 @@ namespace LLVM {
2921

3022
using namespace mlir;
3123

32-
static FailureOr<std::unique_ptr<llvm::TargetMachine>>
33-
getTargetMachine(LLVM::TargetAttrInterface attr) {
34-
StringRef triple = attr.getTriple();
35-
StringRef chipAKAcpu = attr.getChip();
36-
std::string features =
37-
attr.getFeatures() ? attr.getFeatures().getFeaturesString() : "";
38-
39-
std::string error;
40-
const llvm::Target *target =
41-
llvm::TargetRegistry::lookupTarget(triple, error);
42-
if (!target || !error.empty()) {
43-
LDBG("Looking up target '" << triple << "' failed: " << error << "\n");
44-
return failure();
45-
}
46-
47-
return std::unique_ptr<llvm::TargetMachine>(target->createTargetMachine(
48-
llvm::Triple(triple), chipAKAcpu, features, {}, {}));
49-
}
50-
51-
static FailureOr<llvm::DataLayout>
52-
getDataLayout(LLVM::TargetAttrInterface attr) {
53-
FailureOr<std::unique_ptr<llvm::TargetMachine>> targetMachine =
54-
getTargetMachine(attr);
55-
if (failed(targetMachine)) {
56-
LDBG("Failed to retrieve the target machine for data layout.\n");
57-
return failure();
58-
}
59-
return (targetMachine.value())->createDataLayout();
60-
}
61-
6224
struct TargetToDataLayoutPass
6325
: public LLVM::impl::LLVMTargetToDataLayoutBase<TargetToDataLayoutPass> {
6426
using LLVM::impl::LLVMTargetToDataLayoutBase<
@@ -67,15 +29,8 @@ struct TargetToDataLayoutPass
6729
void runOnOperation() override {
6830
Operation *op = getOperation();
6931

70-
if (initializeLLVMTargets) {
71-
static llvm::once_flag initializeBackendsOnce;
72-
llvm::call_once(initializeBackendsOnce, []() {
73-
// Ensure that the targets, that LLVM has been configured to support,
74-
// are loaded into the TargetRegistry.
75-
llvm::InitializeAllTargets();
76-
llvm::InitializeAllTargetMCs();
77-
});
78-
}
32+
if (initializeLLVMTargets)
33+
LLVM::detail::initializeBackendsOnce();
7934

8035
auto targetAttr = op->getAttrOfType<LLVM::TargetAttrInterface>(
8136
LLVM::LLVMDialect::getTargetAttrName());
@@ -86,7 +41,8 @@ struct TargetToDataLayoutPass
8641
return signalPassFailure();
8742
}
8843

89-
FailureOr<llvm::DataLayout> dataLayout = getDataLayout(targetAttr);
44+
FailureOr<llvm::DataLayout> dataLayout =
45+
LLVM::detail::getDataLayout(targetAttr);
9046
if (failed(dataLayout)) {
9147
op->emitError() << "failed to obtain llvm::DataLayout for " << targetAttr;
9248
return signalPassFailure();
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
//===- TargetToTargetFeatures.cpp - extract features from TargetMachine ---===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "mlir/Target/LLVMIR/Transforms/Passes.h"
10+
11+
#include "mlir/Dialect/DLTI/DLTI.h"
12+
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
13+
#include "mlir/Target/LLVMIR/Import.h"
14+
15+
#include "llvm/MC/MCSubtargetInfo.h"
16+
17+
namespace mlir {
18+
namespace LLVM {
19+
#define GEN_PASS_DEF_LLVMTARGETTOTARGETFEATURES
20+
#include "mlir/Target/LLVMIR/Transforms/Passes.h.inc"
21+
} // namespace LLVM
22+
} // namespace mlir
23+
24+
using namespace mlir;
25+
26+
struct TargetToTargetFeaturesPass
27+
: public LLVM::impl::LLVMTargetToTargetFeaturesBase<TargetToTargetFeaturesPass> {
28+
using LLVM::impl::LLVMTargetToTargetFeaturesBase<
29+
TargetToTargetFeaturesPass>::LLVMTargetToTargetFeaturesBase;
30+
31+
void runOnOperation() override {
32+
Operation *op = getOperation();
33+
34+
if (initializeLLVMTargets)
35+
LLVM::detail::initializeBackendsOnce();
36+
37+
auto targetAttr = op->getAttrOfType<LLVM::TargetAttr>(
38+
LLVM::LLVMDialect::getTargetAttrName());
39+
if (!targetAttr) {
40+
op->emitError() << "no LLVM::TargetAttr attribute at key \""
41+
<< LLVM::LLVMDialect::getTargetAttrName() << "\"";
42+
return signalPassFailure();
43+
}
44+
45+
FailureOr<std::unique_ptr<llvm::TargetMachine>> targetMachine =
46+
LLVM::detail::getTargetMachine(targetAttr);
47+
if (failed(targetMachine)) {
48+
op->emitError() << "failed to obtain llvm::TargetMachine for "
49+
<< targetAttr;
50+
return signalPassFailure();
51+
}
52+
53+
llvm::MCSubtargetInfo const *subTargetInfo =
54+
(*targetMachine)->getMCSubtargetInfo();
55+
56+
StringRef fullTargetFeaturesStr = subTargetInfo->getFeatureString();
57+
58+
auto fullTargetFeaturesAttr =
59+
LLVM::TargetFeaturesAttr::get(&getContext(), fullTargetFeaturesStr);
60+
61+
auto updatedTargetAttr =
62+
LLVM::TargetAttr::get(&getContext(), targetAttr.getTriple(),
63+
targetAttr.getChip(), fullTargetFeaturesAttr);
64+
65+
op->setAttr(LLVM::LLVMDialect::getTargetAttrName(), updatedTargetAttr);
66+
}
67+
};
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
//===- TargetUtils.cpp - utils for obtaining generic target backend info --===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
#include "mlir/Target/LLVMIR/Transforms/Passes.h"
9+
10+
#include "mlir/Dialect/DLTI/DLTI.h"
11+
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
12+
#include "mlir/Target/LLVMIR/Import.h"
13+
14+
#include "llvm/MC/TargetRegistry.h"
15+
#include "llvm/Support/Debug.h"
16+
#include "llvm/Support/TargetSelect.h"
17+
#include "llvm/Target/TargetMachine.h"
18+
19+
#define DEBUG_TYPE "mlir-llvm-target-utils"
20+
#define DBGS() (llvm::dbgs() << '[' << DEBUG_TYPE << "] ")
21+
#define LDBG(X) LLVM_DEBUG(DBGS() << X << "\n")
22+
23+
llvm::once_flag initializeBackendsOnce;
24+
25+
namespace mlir {
26+
namespace LLVM {
27+
namespace detail {
28+
void initializeBackendsOnce() {
29+
static llvm::once_flag initializeOnceFlag;
30+
llvm::call_once(initializeOnceFlag, []() {
31+
// Ensure that the targets, that LLVM has been configured to support,
32+
// are loaded into the TargetRegistry.
33+
llvm::InitializeAllTargets();
34+
llvm::InitializeAllTargetMCs();
35+
});
36+
}
37+
38+
FailureOr<std::unique_ptr<llvm::TargetMachine>>
39+
getTargetMachine(mlir::LLVM::TargetAttrInterface attr) {
40+
StringRef triple = attr.getTriple();
41+
StringRef chipAKAcpu = attr.getChip();
42+
std::string features =
43+
attr.getFeatures() ? attr.getFeatures().getFeaturesString() : "";
44+
45+
std::string error;
46+
const llvm::Target *target =
47+
llvm::TargetRegistry::lookupTarget(triple, error);
48+
if (!target || !error.empty()) {
49+
LDBG("Looking up target '" << triple << "' failed: " << error << "\n");
50+
return failure();
51+
}
52+
53+
return std::unique_ptr<llvm::TargetMachine>(target->createTargetMachine(
54+
llvm::Triple(triple), chipAKAcpu, features, {}, {}));
55+
}
56+
57+
FailureOr<llvm::DataLayout>
58+
getDataLayout(mlir::LLVM::TargetAttrInterface attr) {
59+
FailureOr<std::unique_ptr<llvm::TargetMachine>> targetMachine =
60+
getTargetMachine(attr);
61+
if (failed(targetMachine)) {
62+
LDBG("Failed to retrieve the target machine for data layout.\n");
63+
return failure();
64+
}
65+
return (targetMachine.value())->createDataLayout();
66+
}
67+
68+
} // namespace detail
69+
} // namespace LLVM
70+
} // namespace mlir

0 commit comments

Comments
 (0)