Skip to content

Commit 63c9273

Browse files
[mlir] Implement OpAsmAttrInterface for some Builtin Attributes
1 parent 5e26fb1 commit 63c9273

File tree

7 files changed

+209
-171
lines changed

7 files changed

+209
-171
lines changed

mlir/include/mlir/IR/BuiltinAttributeInterfaces.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "mlir/IR/AffineMap.h"
1313
#include "mlir/IR/Attributes.h"
1414
#include "mlir/IR/BuiltinTypeInterfaces.h"
15+
#include "mlir/IR/OpAsmDialectInterface.h"
1516
#include "mlir/IR/Types.h"
1617
#include "llvm/Support/raw_ostream.h"
1718
#include <complex>
@@ -279,6 +280,7 @@ verifyAffineMapAsLayout(AffineMap m, ArrayRef<int64_t> shape,
279280
//===----------------------------------------------------------------------===//
280281

281282
#include "mlir/IR/BuiltinAttributeInterfaces.h.inc"
283+
#include "mlir/IR/OpAsmAttrInterface.h.inc"
282284

283285
//===----------------------------------------------------------------------===//
284286
// ElementsAttr

mlir/include/mlir/IR/BuiltinAttributes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define MLIR_IR_BUILTINATTRIBUTES_H
1111

1212
#include "mlir/IR/BuiltinAttributeInterfaces.h"
13+
#include "mlir/IR/OpAsmDialectInterface.h"
1314
#include "llvm/ADT/APFloat.h"
1415
#include "llvm/ADT/Sequence.h"
1516
#include <complex>

mlir/include/mlir/IR/BuiltinAttributes.td

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ class Builtin_Attr<string name, string attrMnemonic, list<Trait> traits = [],
3737
//===----------------------------------------------------------------------===//
3838

3939
def Builtin_AffineMapAttr : Builtin_Attr<"AffineMap", "affine_map", [
40-
MemRefLayoutAttrInterface
40+
MemRefLayoutAttrInterface,
41+
OpAsmAttrInterface
4142
]> {
4243
let summary = "An Attribute containing an AffineMap object";
4344
let description = [{
@@ -63,6 +64,16 @@ def Builtin_AffineMapAttr : Builtin_Attr<"AffineMap", "affine_map", [
6364
let extraClassDeclaration = [{
6465
using ValueType = AffineMap;
6566
AffineMap getAffineMap() const { return getValue(); }
67+
68+
//===------------------------------------------------------------------===//
69+
// OpAsmAttrInterface Methods
70+
//===------------------------------------------------------------------===//
71+
72+
/// Get a name to use when generating an alias for this attribute.
73+
::mlir::OpAsmDialectInterface::AliasResult getAlias(::llvm::raw_ostream &os) const {
74+
os << "map";
75+
return ::mlir::OpAsmDialectInterface::AliasResult::OverridableAlias;
76+
}
6677
}];
6778
let skipDefaultBuilders = 1;
6879
}
@@ -755,7 +766,7 @@ def Builtin_IntegerAttr : Builtin_Attr<"Integer", "integer",
755766
// IntegerSetAttr
756767
//===----------------------------------------------------------------------===//
757768

758-
def Builtin_IntegerSetAttr : Builtin_Attr<"IntegerSet", "integer_set"> {
769+
def Builtin_IntegerSetAttr : Builtin_Attr<"IntegerSet", "integer_set", [OpAsmAttrInterface]> {
759770
let summary = "An Attribute containing an IntegerSet object";
760771
let description = [{
761772
Syntax:
@@ -776,7 +787,19 @@ def Builtin_IntegerSetAttr : Builtin_Attr<"IntegerSet", "integer_set"> {
776787
return $_get(value.getContext(), value);
777788
}]>
778789
];
779-
let extraClassDeclaration = "using ValueType = IntegerSet;";
790+
let extraClassDeclaration = [{
791+
using ValueType = IntegerSet;
792+
793+
//===------------------------------------------------------------------===//
794+
// OpAsmAttrInterface Methods
795+
//===------------------------------------------------------------------===//
796+
797+
/// Get a name to use when generating an alias for this attribute.
798+
::mlir::OpAsmDialectInterface::AliasResult getAlias(::llvm::raw_ostream &os) const {
799+
os << "set";
800+
return ::mlir::OpAsmDialectInterface::AliasResult::OverridableAlias;
801+
}
802+
}];
780803
let skipDefaultBuilders = 1;
781804
}
782805

mlir/include/mlir/IR/BuiltinTypeInterfaces.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#ifndef MLIR_IR_BUILTINTYPEINTERFACES_H
1010
#define MLIR_IR_BUILTINTYPEINTERFACES_H
1111

12+
#include "mlir/IR/OpAsmDialectInterface.h"
1213
#include "mlir/IR/Types.h"
1314

1415
namespace llvm {
@@ -21,5 +22,6 @@ class MLIRContext;
2122
} // namespace mlir
2223

2324
#include "mlir/IR/BuiltinTypeInterfaces.h.inc"
25+
#include "mlir/IR/OpAsmTypeInterface.h.inc"
2426

2527
#endif // MLIR_IR_BUILTINTYPEINTERFACES_H
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
//===- OpAsmDialectInterface.h - OpAsm Dialect Interface --------*- C++ -*-===//
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_IR_OPASMDIALECTINTERFACE_H
10+
#define MLIR_IR_OPASMDIALECTINTERFACE_H
11+
12+
#include "mlir/IR/DialectInterface.h"
13+
#include "mlir/IR/Types.h"
14+
#include "mlir/IR/Value.h"
15+
16+
namespace mlir {
17+
class AsmParsedResourceEntry;
18+
class AsmResourceBuilder;
19+
20+
//===----------------------------------------------------------------------===//
21+
// AsmDialectResourceHandle
22+
//===----------------------------------------------------------------------===//
23+
24+
/// This class represents an opaque handle to a dialect resource entry.
25+
class AsmDialectResourceHandle {
26+
public:
27+
AsmDialectResourceHandle() = default;
28+
AsmDialectResourceHandle(void *resource, TypeID resourceID, Dialect *dialect)
29+
: resource(resource), opaqueID(resourceID), dialect(dialect) {}
30+
bool operator==(const AsmDialectResourceHandle &other) const {
31+
return resource == other.resource;
32+
}
33+
34+
/// Return an opaque pointer to the referenced resource.
35+
void *getResource() const { return resource; }
36+
37+
/// Return the type ID of the resource.
38+
TypeID getTypeID() const { return opaqueID; }
39+
40+
/// Return the dialect that owns the resource.
41+
Dialect *getDialect() const { return dialect; }
42+
43+
private:
44+
/// The opaque handle to the dialect resource.
45+
void *resource = nullptr;
46+
/// The type of the resource referenced.
47+
TypeID opaqueID;
48+
/// The dialect owning the given resource.
49+
Dialect *dialect;
50+
};
51+
52+
/// This class represents a CRTP base class for dialect resource handles. It
53+
/// abstracts away various utilities necessary for defined derived resource
54+
/// handles.
55+
template <typename DerivedT, typename ResourceT, typename DialectT>
56+
class AsmDialectResourceHandleBase : public AsmDialectResourceHandle {
57+
public:
58+
using Dialect = DialectT;
59+
60+
/// Construct a handle from a pointer to the resource. The given pointer
61+
/// should be guaranteed to live beyond the life of this handle.
62+
AsmDialectResourceHandleBase(ResourceT *resource, DialectT *dialect)
63+
: AsmDialectResourceHandle(resource, TypeID::get<DerivedT>(), dialect) {}
64+
AsmDialectResourceHandleBase(AsmDialectResourceHandle handle)
65+
: AsmDialectResourceHandle(handle) {
66+
assert(handle.getTypeID() == TypeID::get<DerivedT>());
67+
}
68+
69+
/// Return the resource referenced by this handle.
70+
ResourceT *getResource() {
71+
return static_cast<ResourceT *>(AsmDialectResourceHandle::getResource());
72+
}
73+
const ResourceT *getResource() const {
74+
return const_cast<AsmDialectResourceHandleBase *>(this)->getResource();
75+
}
76+
77+
/// Return the dialect that owns the resource.
78+
DialectT *getDialect() const {
79+
return static_cast<DialectT *>(AsmDialectResourceHandle::getDialect());
80+
}
81+
82+
/// Support llvm style casting.
83+
static bool classof(const AsmDialectResourceHandle *handle) {
84+
return handle->getTypeID() == TypeID::get<DerivedT>();
85+
}
86+
};
87+
88+
inline llvm::hash_code hash_value(const AsmDialectResourceHandle &param) {
89+
return llvm::hash_value(param.getResource());
90+
}
91+
92+
//===--------------------------------------------------------------------===//
93+
// Dialect OpAsm interface.
94+
//===--------------------------------------------------------------------===//
95+
96+
/// A functor used to set the name of the result. See 'getAsmResultNames' below
97+
/// for more details.
98+
using OpAsmSetNameFn = function_ref<void(StringRef)>;
99+
100+
/// A functor used to set the name of the start of a result group of an
101+
/// operation. See 'getAsmResultNames' below for more details.
102+
using OpAsmSetValueNameFn = function_ref<void(Value, StringRef)>;
103+
104+
/// A functor used to set the name of blocks in regions directly nested under
105+
/// an operation.
106+
using OpAsmSetBlockNameFn = function_ref<void(Block *, StringRef)>;
107+
108+
class OpAsmDialectInterface
109+
: public DialectInterface::Base<OpAsmDialectInterface> {
110+
public:
111+
OpAsmDialectInterface(Dialect *dialect) : Base(dialect) {}
112+
113+
//===------------------------------------------------------------------===//
114+
// Aliases
115+
//===------------------------------------------------------------------===//
116+
117+
/// Holds the result of `getAlias` hook call.
118+
enum class AliasResult {
119+
/// The object (type or attribute) is not supported by the hook
120+
/// and an alias was not provided.
121+
NoAlias,
122+
/// An alias was provided, but it might be overriden by other hook.
123+
OverridableAlias,
124+
/// An alias was provided and it should be used
125+
/// (no other hooks will be checked).
126+
FinalAlias
127+
};
128+
129+
/// Hooks for getting an alias identifier alias for a given symbol, that is
130+
/// not necessarily a part of this dialect. The identifier is used in place of
131+
/// the symbol when printing textual IR. These aliases must not contain `.` or
132+
/// end with a numeric digit([0-9]+).
133+
virtual AliasResult getAlias(Attribute attr, raw_ostream &os) const {
134+
return AliasResult::NoAlias;
135+
}
136+
virtual AliasResult getAlias(Type type, raw_ostream &os) const {
137+
return AliasResult::NoAlias;
138+
}
139+
140+
//===--------------------------------------------------------------------===//
141+
// Resources
142+
//===--------------------------------------------------------------------===//
143+
144+
/// Declare a resource with the given key, returning a handle to use for any
145+
/// references of this resource key within the IR during parsing. The result
146+
/// of `getResourceKey` on the returned handle is permitted to be different
147+
/// than `key`.
148+
virtual FailureOr<AsmDialectResourceHandle>
149+
declareResource(StringRef key) const {
150+
return failure();
151+
}
152+
153+
/// Return a key to use for the given resource. This key should uniquely
154+
/// identify this resource within the dialect.
155+
virtual std::string
156+
getResourceKey(const AsmDialectResourceHandle &handle) const {
157+
llvm_unreachable(
158+
"Dialect must implement `getResourceKey` when defining resources");
159+
}
160+
161+
/// Hook for parsing resource entries. Returns failure if the entry was not
162+
/// valid, or could otherwise not be processed correctly. Any necessary errors
163+
/// can be emitted via the provided entry.
164+
virtual LogicalResult parseResource(AsmParsedResourceEntry &entry) const;
165+
166+
/// Hook for building resources to use during printing. The given `op` may be
167+
/// inspected to help determine what information to include.
168+
/// `referencedResources` contains all of the resources detected when printing
169+
/// 'op'.
170+
virtual void
171+
buildResources(Operation *op,
172+
const SetVector<AsmDialectResourceHandle> &referencedResources,
173+
AsmResourceBuilder &builder) const {}
174+
};
175+
} // namespace mlir
176+
177+
#endif

0 commit comments

Comments
 (0)