Skip to content

Commit cbfa265

Browse files
authored
[MLIR][LLVMIR][DLTI] Add LLVM::TargetAttrInterface and #llvm.target attr (llvm#145899)
Adds the `#llvm.target<triple = $TRIPLE, chip = $CHIP, features = $FEATURES>` attribute and along with a `-llvm-target-to-data-layout` pass to derive a MLIR data layout from the LLVM data layout string (using the existing `DataLayoutImporter`). The attribute implements the relevant DLTI-interfaces, to expose the `triple`, `chip` (AKA `cpu`) and `features` on `#llvm.target` and the full `DataLayoutSpecInterface`. The pass combines the generated `#dlti.dl_spec` with an existing `dl_spec` in case one is already present, e.g. a `dl_spec` which is there to specify size of the `index` type. Adds a `TargetAttrInterface` which can be implemented by all attributes representing LLVM targets. Similar to the Draft PR llvm#78073. RFC on which this PR is based: https://discourse.llvm.org/t/mandatory-data-layout-in-the-llvm-dialect/85875
1 parent 2a66ce5 commit cbfa265

22 files changed

+434
-61
lines changed

mlir/include/mlir/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ add_subdirectory(Dialect)
44
add_subdirectory(IR)
55
add_subdirectory(Interfaces)
66
add_subdirectory(Reducer)
7+
add_subdirectory(Target)
78
add_subdirectory(Transforms)

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ include "mlir/Dialect/LLVMIR/LLVMDialect.td"
1313
include "mlir/Dialect/LLVMIR/LLVMInterfaces.td"
1414
include "mlir/IR/AttrTypeBase.td"
1515
include "mlir/IR/CommonAttrConstraints.td"
16+
include "mlir/Interfaces/DataLayoutInterfaces.td"
1617

1718
// All of the attributes will extend this class.
1819
class LLVM_Attr<string name, string attrMnemonic,
@@ -1304,6 +1305,34 @@ def LLVM_TargetFeaturesAttr : LLVM_Attr<"TargetFeatures", "target_features">
13041305
let genVerifyDecl = 1;
13051306
}
13061307

1308+
//===----------------------------------------------------------------------===//
1309+
// LLVM_TargetAttr
1310+
//===----------------------------------------------------------------------===//
1311+
1312+
def LLVM_TargetAttr : LLVM_Attr<"Target", "target",
1313+
[LLVM_TargetAttrInterface]> {
1314+
let summary = "LLVM target info: triple, chip, features";
1315+
let description = [{
1316+
An attribute to hold LLVM target information, specifying LLVM's target
1317+
`triple` string, the target `chip` string (i.e. the `cpu` string), and
1318+
target `features` string as an attribute. The latter is optional.
1319+
1320+
Responds to DLTI-queries on the keys:
1321+
* A query for `"triple"` returns the `StringAttr` for the `triple`.
1322+
* A query for `"chip"` returns the `StringAttr` for the `chip`/`cpu`.
1323+
* A query for `"features"` returns the `StringAttr`, if provided.
1324+
}];
1325+
let parameters = (ins "StringAttr":$triple,
1326+
"StringAttr":$chip,
1327+
OptionalParameter<"StringAttr", "">:$features);
1328+
1329+
let assemblyFormat = [{`<` struct($triple, $chip, $features) `>`}];
1330+
1331+
let extraClassDeclaration = [{
1332+
FailureOr<Attribute> query(DataLayoutEntryKey key);
1333+
}];
1334+
}
1335+
13071336
//===----------------------------------------------------------------------===//
13081337
// UndefAttr
13091338
//===----------------------------------------------------------------------===//

mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
1818
#include "mlir/IR/OpImplementation.h"
19+
#include "mlir/Interfaces/DataLayoutInterfaces.h"
1920
#include <optional>
2021

2122
#include "mlir/Dialect/LLVMIR/LLVMOpsEnums.h.inc"
@@ -89,8 +90,8 @@ class TBAANodeAttr : public Attribute {
8990
// TODO: this shouldn't be needed after we unify the attribute generation, i.e.
9091
// --gen-attr-* and --gen-attrdef-*.
9192
using cconv::CConv;
92-
using tailcallkind::TailCallKind;
9393
using linkage::Linkage;
94+
using tailcallkind::TailCallKind;
9495
} // namespace LLVM
9596
} // namespace mlir
9697

mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ def LLVM_Dialect : Dialect {
2727
);
2828

2929
let extraClassDeclaration = [{
30+
static StringRef getTargetAttrName() { return "llvm.target"; }
3031
/// Name of the data layout attributes.
3132
static StringRef getDataLayoutAttrName() { return "llvm.data_layout"; }
3233
static StringRef getNoAliasScopesAttrName() { return "noalias_scopes"; }

mlir/include/mlir/Dialect/LLVMIR/LLVMInterfaces.td

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#define LLVMIR_INTERFACES
1515

1616
include "mlir/IR/OpBase.td"
17+
include "mlir/Interfaces/DataLayoutInterfaces.td"
1718

1819
def FastmathFlagsInterface : OpInterface<"FastmathFlagsInterface"> {
1920
let description = [{
@@ -532,4 +533,39 @@ def LLVM_DIRecursiveTypeAttrInterface
532533
];
533534
}
534535

536+
def LLVM_TargetAttrInterface
537+
: AttrInterface<"TargetAttrInterface", [DLTIQueryInterface]> {
538+
let description = [{
539+
Interface for attributes that describe LLVM targets.
540+
541+
These attributes should be able to return the specified target `triple`,
542+
`chip` and `features`.
543+
544+
Implementing attributes should provide a `DLTIQueryInterface::query()`
545+
implementation which responds to keys `"triple"`, `"chip"` and `"features"`
546+
by returning appropriate `StringAttr`s.
547+
}];
548+
let cppNamespace = "::mlir::LLVM";
549+
let methods = [
550+
InterfaceMethod<
551+
/*description=*/"Returns the target triple identifier.",
552+
/*retTy=*/"StringAttr",
553+
/*methodName=*/"getTriple",
554+
/*args=*/(ins)
555+
>,
556+
InterfaceMethod<
557+
/*description=*/"Returns the target chip (i.e. \"cpu\") identifier.",
558+
/*retTy=*/"StringAttr",
559+
/*methodName=*/"getChip",
560+
/*args=*/(ins)
561+
>,
562+
InterfaceMethod<
563+
/*description=*/"Returns the target features as a string.",
564+
/*retTy=*/"StringAttr",
565+
/*methodName=*/"getFeatures",
566+
/*args=*/(ins)
567+
>
568+
];
569+
}
570+
535571
#endif // LLVMIR_INTERFACES
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
add_subdirectory(LLVMIR)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
add_subdirectory(Transforms)

mlir/lib/Target/LLVMIR/DataLayoutImporter.h renamed to mlir/include/mlir/Target/LLVMIR/DataLayoutImporter.h

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
//
1212
//===----------------------------------------------------------------------===//
1313

14-
#ifndef MLIR_LIB_TARGET_LLVMIR_DATALAYOUTIMPORTER_H_
15-
#define MLIR_LIB_TARGET_LLVMIR_DATALAYOUTIMPORTER_H_
14+
#ifndef MLIR_TARGET_LLVMIR_DATALAYOUTIMPORTER_H
15+
#define MLIR_TARGET_LLVMIR_DATALAYOUTIMPORTER_H
1616

1717
#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
1818
#include "mlir/IR/BuiltinAttributes.h"
@@ -38,23 +38,31 @@ namespace detail {
3838
/// null if the bit width is not supported.
3939
FloatType getFloatType(MLIRContext *context, unsigned width);
4040

41-
/// Helper class that translates an LLVM data layout to an MLIR data layout
42-
/// specification. Only integer, float, pointer, alloca memory space, stack
43-
/// alignment, and endianness entries are translated. The class also returns all
44-
/// entries from the default data layout specification found in the language
45-
/// reference (https://llvm.org/docs/LangRef.html#data-layout) if they are not
46-
/// overwritten by the provided data layout.
41+
/// Helper class that translates an LLVM data layout string to an MLIR data
42+
/// layout specification. Only integer, float, pointer, alloca memory space,
43+
/// stack alignment, and endianness entries are translated. The class also
44+
/// returns all entries from the default data layout specification found in the
45+
/// language reference (https://llvm.org/docs/LangRef.html#data-layout) if they
46+
/// are not overwritten by the provided data layout.
4747
class DataLayoutImporter {
4848
public:
49-
DataLayoutImporter(MLIRContext *context,
50-
const llvm::DataLayout &llvmDataLayout)
51-
: context(context) {
52-
translateDataLayout(llvmDataLayout);
49+
DataLayoutImporter(MLIRContext *context, StringRef dataLayoutStr)
50+
: dataLayoutStr(dataLayoutStr), context(context) {
51+
// Translate the `dataLayoutStr`. First, append the default data layout
52+
// string specified in the language reference
53+
// (https://llvm.org/docs/LangRef.html#data-layout) to the supplied string.
54+
// The translation then parses the string and ignores the default value if a
55+
// specific kind occurs in both strings. Additionally, the following default
56+
// values exist:
57+
// - non-default address space pointer specifications default to the default
58+
// address space pointer specification
59+
// - the alloca address space defaults to the default address space.
60+
dataLayoutSpec = dataLayoutSpecFromDataLayoutStr();
5361
}
5462

5563
/// Returns the MLIR data layout specification translated from the LLVM
5664
/// data layout.
57-
DataLayoutSpecInterface getDataLayout() const { return dataLayout; }
65+
DataLayoutSpecInterface getDataLayoutSpec() const { return dataLayoutSpec; }
5866

5967
/// Returns the last data layout token that has been processed before
6068
/// the data layout translation failed.
@@ -65,8 +73,9 @@ class DataLayoutImporter {
6573
ArrayRef<StringRef> getUnhandledTokens() const { return unhandledTokens; }
6674

6775
private:
68-
/// Translates the LLVM `dataLayout` to an MLIR data layout specification.
69-
void translateDataLayout(const llvm::DataLayout &llvmDataLayout);
76+
/// Translate the LLVM data layout string to an MLIR data layout
77+
/// specification.
78+
DataLayoutSpecInterface dataLayoutSpecFromDataLayoutStr();
7079

7180
/// Tries to parse the letter only prefix that identifies the specification
7281
/// and removes the consumed characters from the beginning of the string.
@@ -116,17 +125,18 @@ class DataLayoutImporter {
116125
/// Adds legal int widths entry if there is none yet.
117126
LogicalResult tryToEmplaceLegalIntWidthsEntry(StringRef token);
118127

119-
std::string layoutStr = {};
128+
std::string dataLayoutStr = {};
129+
DataLayoutSpecInterface dataLayoutSpec;
130+
120131
StringRef lastToken = {};
121132
SmallVector<StringRef> unhandledTokens;
122133
llvm::MapVector<StringAttr, DataLayoutEntryInterface> keyEntries;
123134
llvm::MapVector<TypeAttr, DataLayoutEntryInterface> typeEntries;
124135
MLIRContext *context;
125-
DataLayoutSpecInterface dataLayout;
126136
};
127137

128138
} // namespace detail
129139
} // namespace LLVM
130140
} // namespace mlir
131141

132-
#endif // MLIR_LIB_TARGET_LLVMIR_DATALAYOUTIMPORTER_H_
142+
#endif // MLIR_TARGET_LLVMIR_DATALAYOUTIMPORTER_H
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
set(LLVM_TARGET_DEFINITIONS Passes.td)
2+
mlir_tablegen(Passes.h.inc -gen-pass-decls -name TargetLLVMIRTransforms)
3+
add_public_tablegen_target(MLIRTargetLLVMIRTransformsIncGen)
4+
5+
add_mlir_doc(Passes TargetLLVMIRTransforms ./ -gen-pass-doc)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//===- Passes.h - LLVM Target Pass Construction and Registration ----------===//
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 MLIR_TARGET_LLVMIR_TRANSFORMS_PASSES_H
10+
#define MLIR_TARGET_LLVMIR_TRANSFORMS_PASSES_H
11+
12+
#include "mlir/Pass/Pass.h"
13+
14+
namespace mlir {
15+
16+
namespace LLVM {
17+
18+
#define GEN_PASS_DECL
19+
#define GEN_PASS_REGISTRATION
20+
#include "mlir/Target/LLVMIR/Transforms/Passes.h.inc"
21+
22+
void registerTargetLLVMPasses();
23+
24+
} // namespace LLVM
25+
} // namespace mlir
26+
27+
#endif // MLIR_TARGET_LLVMIR_TRANSFORMS_PASSES_H

0 commit comments

Comments
 (0)