/// Returns true if this dialect allows for unregistered operations, i.e.
/// operations prefixed with the dialect namespace but not registered with
/// addOperation.
- bool allowsUnknownOperations() const { return allowUnknownOps; }
+ bool allowsUnknownOperations() const { return unknownOpsAllowed; }
+
+ /// Return true if this dialect allows for unregistered types, i.e., types
+ /// prefixed with the dialect namespace but not registered with addType.
+ /// These are represented with OpaqueType.
+ bool allowsUnknownTypes() const { return unknownTypesAllowed; }
//===--------------------------------------------------------------------===//
// Constant Hooks
}
};
- // Enable support for unregistered operations.
- void allowUnknownOperations(bool allow = true) { allowUnknownOps = allow; }
+ /// Enable support for unregistered operations.
+ void allowUnknownOperations(bool allow = true) { unknownOpsAllowed = allow; }
+
+ /// Enable support for unregistered types.
+ void allowUnknownTypes(bool allow = true) { unknownTypesAllowed = allow; }
private:
// Register a symbol(e.g. type) with its given unique class identifier.
/// This is the context that owns this Dialect object.
MLIRContext *context;
- /// Flag that toggles if this dialect supports unregistered operations, i.e.
- /// operations prefixed with the dialect namespace but not registered with
- /// addOperation.
- bool allowUnknownOps;
+ /// Flag that specifies whether this dialect supports unregistered operations,
+ /// i.e. operations prefixed with the dialect namespace but not registered
+ /// with addOperation.
+ bool unknownOpsAllowed = false;
+
+ /// Flag that specifies whether this dialect allows unregistered types, i.e.
+ /// types prefixed with the dialect namespace but not registered with addType.
+ /// These types are represented with OpaqueType.
+ bool unknownTypesAllowed = false;
};
using DialectAllocatorFunction = std::function<void(MLIRContext *)>;
def BF16 : Type<CPred<"$_self.isBF16()">, "bfloat16 type">,
BuildableType<"getBF16Type()">;
+class OpaqueType<string dialect, string name, string description>
+ : Type<CPred<"isOpaqueTypeWithName($_self, \""#dialect#"\", \""#name#"\")">,
+ description>;
+
// Function Type
// Any function type.
/// handles storage concerns, which is tricky to do in tablegen.
SmallVector<Type, 10> getFlattenedTypes(TupleType t);
+/// Return true if the specified type is an opaque type with the specified
+/// dialect and typeData.
+bool isOpaqueTypeWithName(Type type, StringRef dialect, StringRef typeData);
+
//===----------------------------------------------------------------------===//
// Utility Iterators
//===----------------------------------------------------------------------===//
}
Dialect::Dialect(StringRef name, MLIRContext *context)
- : name(name), context(context), allowUnknownOps(false) {
+ : name(name), context(context) {
assert(isValidNamespace(name) && "invalid dialect namespace");
registerDialect(context);
}
/// Parse a type registered to this dialect.
Type Dialect::parseType(StringRef tyData, Location loc) const {
+ // If this dialect allows unknown types, then represent this with OpaqueType.
+ if (allowsUnknownTypes()) {
+ auto ns = Identifier::get(getNamespace(), getContext());
+ return OpaqueType::get(ns, tyData, getContext());
+ }
+
emitError(loc) << "dialect '" << getNamespace()
<< "' provides no type parsing hook";
return Type();
return fTypes;
}
+/// Return true if the specified type is an opaque type with the specified
+/// dialect and typeData.
+bool mlir::isOpaqueTypeWithName(Type type, StringRef dialect,
+ StringRef typeData) {
+ if (auto opaque = type.dyn_cast<mlir::OpaqueType>())
+ return opaque.getDialectNamespace().is(dialect) &&
+ opaque.getTypeData() == typeData;
+ return false;
+}
+
OperandElementTypeIterator::OperandElementTypeIterator(OperandIterator it)
: llvm::mapped_iterator<OperandIterator, Type (*)(Value *)>(it, &unwrap) {}