Skip to content

Commit ecb17da

Browse files
committed
[mlir] Update Attributes to use the new casting infra
This allows for using the llvm namespace cast methods instead of the ones on the Attribute class. The Attribute class methods are kept for now, but we'll want to remove these eventually (with a really long lead time). Differential Revision: https://reviews.llvm.org/D134327
1 parent 539fa1d commit ecb17da

File tree

1 file changed

+41
-18
lines changed

1 file changed

+41
-18
lines changed

mlir/include/mlir/IR/Attributes.h

+41-18
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,11 @@ class Attribute {
4747

4848
bool operator!() const { return impl == nullptr; }
4949

50-
template <typename U>
51-
bool isa() const;
52-
template <typename First, typename Second, typename... Rest>
50+
/// Casting utility functions. These are deprecated and will be removed,
51+
/// please prefer using the `llvm` namespace variants instead.
52+
template <typename... Tys>
5353
bool isa() const;
54-
template <typename First, typename... Rest>
54+
template <typename... Tys>
5555
bool isa_and_nonnull() const;
5656
template <typename U>
5757
U dyn_cast() const;
@@ -100,6 +100,9 @@ class Attribute {
100100
return impl->getAbstractAttribute();
101101
}
102102

103+
/// Return the internal Attribute implementation.
104+
ImplType *getImpl() const { return impl; }
105+
103106
protected:
104107
ImplType *impl{nullptr};
105108
};
@@ -109,34 +112,29 @@ inline raw_ostream &operator<<(raw_ostream &os, Attribute attr) {
109112
return os;
110113
}
111114

112-
template <typename U>
113-
bool Attribute::isa() const {
114-
assert(impl && "isa<> used on a null attribute.");
115-
return U::classof(*this);
116-
}
117-
118-
template <typename First, typename Second, typename... Rest>
115+
template <typename... Tys>
119116
bool Attribute::isa() const {
120-
return isa<First>() || isa<Second, Rest...>();
117+
return llvm::isa<Tys...>(*this);
121118
}
122119

123-
template <typename First, typename... Rest>
120+
template <typename... Tys>
124121
bool Attribute::isa_and_nonnull() const {
125-
return impl && isa<First, Rest...>();
122+
return llvm::isa_and_present<Tys...>(*this);
126123
}
127124

128125
template <typename U>
129126
U Attribute::dyn_cast() const {
130-
return isa<U>() ? U(impl) : U(nullptr);
127+
return llvm::dyn_cast<U>(*this);
131128
}
129+
132130
template <typename U>
133131
U Attribute::dyn_cast_or_null() const {
134-
return (impl && isa<U>()) ? U(impl) : U(nullptr);
132+
return llvm::dyn_cast_if_present<U>(*this);
135133
}
134+
136135
template <typename U>
137136
U Attribute::cast() const {
138-
assert(isa<U>());
139-
return U(impl);
137+
return llvm::cast<U>(*this);
140138
}
141139

142140
inline ::llvm::hash_code hash_value(Attribute arg) {
@@ -318,6 +316,31 @@ struct DenseMapInfo<mlir::NamedAttribute> {
318316
}
319317
};
320318

319+
/// Add support for llvm style casts. We provide a cast between To and From if
320+
/// From is mlir::Attribute or derives from it.
321+
template <typename To, typename From>
322+
struct CastInfo<To, From,
323+
std::enable_if_t<std::is_same_v<mlir::Attribute,
324+
std::remove_const_t<From>> ||
325+
std::is_base_of_v<mlir::Attribute, From>>>
326+
: NullableValueCastFailed<To>,
327+
DefaultDoCastIfPossible<To, From, CastInfo<To, From>> {
328+
/// Arguments are taken as mlir::Attribute here and not as `From`, because
329+
/// when casting from an intermediate type of the hierarchy to one of its
330+
/// children, the val.getTypeID() inside T::classof will use the static
331+
/// getTypeID of the parent instead of the non-static Type::getTypeID that
332+
/// returns the dynamic ID. This means that T::classof would end up comparing
333+
/// the static TypeID of the children to the static TypeID of its parent,
334+
/// making it impossible to downcast from the parent to the child.
335+
static inline bool isPossible(mlir::Attribute ty) {
336+
/// Return a constant true instead of a dynamic true when casting to self or
337+
/// up the hierarchy.
338+
return std::is_same_v<To, std::remove_const_t<From>> ||
339+
std::is_base_of_v<To, From> || To::classof(ty);
340+
}
341+
static inline To doCast(mlir::Attribute attr) { return To(attr.getImpl()); }
342+
};
343+
321344
} // namespace llvm
322345

323346
#endif

0 commit comments

Comments
 (0)