Refactor Attribute and Type to use 'classof' instead of 'kindof' internally. If a 'classof' method is not defined, a default implementation will invoke 'kindof' on a derived type. This allows for defining supplementary Attribute/Type classes that expose additional functionality, but do not have a specific kind value. An example of this can be seen in the 'Constant(Float|Index|Int)Ops' that derive from 'ConstantOp'.

--

PiperOrigin-RevId: 248724093
This commit is contained in:
River Riddle 2019-05-17 08:28:41 -07:00 committed by Mehdi Amini
parent 7e11eb1f87
commit 9829294558
5 changed files with 27 additions and 19 deletions

View File

@ -81,9 +81,9 @@ public:
int64_t storageTypeMin, int64_t storageTypeMax);
/// Support method to enable LLVM-style type casting.
static bool kindof(unsigned kind) {
return kind >= Type::FIRST_QUANTIZATION_TYPE &&
kind <= QuantizationTypes::LAST_USED_QUANTIZATION_TYPE;
static bool classof(Type type) {
return type.getKind() >= Type::FIRST_QUANTIZATION_TYPE &&
type.getKind() <= QuantizationTypes::LAST_USED_QUANTIZATION_TYPE;
}
/// Gets the minimum possible stored by a storageType. storageTypeMin must

View File

@ -104,7 +104,7 @@ public:
template <typename U> U cast() const;
// Support dyn_cast'ing Attribute to itself.
static bool kindof(unsigned) { return true; }
static bool classof(Attribute) { return true; }
/// Return the classification for this attribute.
unsigned getKind() const { return impl->getKind(); }
@ -424,9 +424,9 @@ public:
Attribute getValue(ArrayRef<uint64_t> index) const;
/// Method for support type inquiry through isa, cast and dyn_cast.
static bool kindof(unsigned kind) {
return kind >= StandardAttributes::FIRST_ELEMENTS_ATTR &&
kind <= StandardAttributes::LAST_ELEMENTS_ATTR;
static bool classof(Attribute attr) {
return attr.getKind() >= StandardAttributes::FIRST_ELEMENTS_ATTR &&
attr.getKind() <= StandardAttributes::LAST_ELEMENTS_ATTR;
}
};
@ -483,9 +483,9 @@ public:
static APInt readBits(const char *rawData, size_t bitPos, size_t bitWidth);
/// Method for support type inquiry through isa, cast and dyn_cast.
static bool kindof(unsigned kind) {
return kind == StandardAttributes::DenseIntElements ||
kind == StandardAttributes::DenseFPElements;
static bool classof(Attribute attr) {
return attr.getKind() == StandardAttributes::DenseIntElements ||
attr.getKind() == StandardAttributes::DenseFPElements;
}
protected:
@ -698,7 +698,7 @@ public:
template <typename U> bool Attribute::isa() const {
assert(impl && "isa<> used on a null attribute.");
return U::kindof(getKind());
return U::classof(*this);
}
template <typename U> U Attribute::dyn_cast() const {
return isa<U>() ? U(impl) : U(nullptr);

View File

@ -227,10 +227,10 @@ public:
int64_t getSizeInBits() const;
/// Methods for support type inquiry through isa, cast, and dyn_cast.
static bool kindof(unsigned kind) {
return kind == StandardTypes::Vector ||
kind == StandardTypes::RankedTensor ||
kind == StandardTypes::UnrankedTensor;
static bool classof(Type type) {
return type.getKind() == StandardTypes::Vector ||
type.getKind() == StandardTypes::RankedTensor ||
type.getKind() == StandardTypes::UnrankedTensor;
}
};
@ -285,9 +285,9 @@ public:
}
/// Methods for support type inquiry through isa, cast, and dyn_cast.
static bool kindof(unsigned kind) {
return kind == StandardTypes::RankedTensor ||
kind == StandardTypes::UnrankedTensor;
static bool classof(Type type) {
return type.getKind() == StandardTypes::RankedTensor ||
type.getKind() == StandardTypes::UnrankedTensor;
}
};

View File

@ -45,6 +45,14 @@ public:
/// Return a unique identifier for the concrete type.
static ClassID *getClassID() { return ClassID::getID<ConcreteT>(); }
/// Provide a default implementation of 'classof' that invokes a 'kindof'
/// method on the concrete type.
template <typename T> static bool classof(T val) {
static_assert(std::is_convertible<ConcreteT, T>::value,
"casting from a non-convertible type");
return ConcreteT::kindof(val.getKind());
}
protected:
/// Get or create a new ConcreteT instance within the ctx. This
/// function is guaranteed to return a non null object and will assert if

View File

@ -261,7 +261,7 @@ inline ::llvm::hash_code hash_value(Type arg) {
template <typename U> bool Type::isa() const {
assert(impl && "isa<> used on a null type.");
return U::kindof(getKind());
return U::classof(*this);
}
template <typename U> U Type::dyn_cast() const {
return isa<U>() ? U(impl) : U(nullptr);