From 1316db3baa13f0d84350b9c57a752f728959ad24 Mon Sep 17 00:00:00 2001 From: River Riddle Date: Sat, 27 Apr 2019 18:35:04 -0700 Subject: [PATCH] Add support for a NoneType. none-type ::= `none` The `none` type is a unit type, i.e. a type with exactly one possible value, where its value does not have a defined dynamic representation. -- PiperOrigin-RevId: 245599248 --- mlir/g3doc/LangRef.md | 12 ++++++++++++ mlir/include/mlir/IR/Builders.h | 2 ++ mlir/include/mlir/IR/StandardTypes.h | 14 ++++++++++++++ mlir/include/mlir/Support/LLVM.h | 1 - mlir/lib/IR/AsmPrinter.cpp | 3 +++ mlir/lib/IR/Builders.cpp | 2 ++ mlir/lib/IR/MLIRContext.cpp | 14 ++++++++------ mlir/lib/Parser/Parser.cpp | 7 +++++++ mlir/lib/Parser/TokenKinds.def | 1 + mlir/test/IR/parser.mlir | 7 +++++++ 10 files changed, 56 insertions(+), 7 deletions(-) diff --git a/mlir/g3doc/LangRef.md b/mlir/g3doc/LangRef.md index 542b2ef..84a1089 100644 --- a/mlir/g3doc/LangRef.md +++ b/mlir/g3doc/LangRef.md @@ -513,6 +513,7 @@ non-function-type ::= integer-type | type-alias | complex-type | tuple-type + | none-type type-list-no-parens ::= type (`,` type)* type-list-parens ::= `(` `)` @@ -911,6 +912,17 @@ tuple tuple, i5> ``` +#### None Type + +Syntax: + +``` {.ebnf} +none-type ::= `none` +``` + +The `none` type is a unit type, i.e. a type with exactly one possible value, +where its value does not have a defined dynamic representation. + ## Attributes Syntax: diff --git a/mlir/include/mlir/IR/Builders.h b/mlir/include/mlir/IR/Builders.h index a2bfcf2..1ee6c48 100644 --- a/mlir/include/mlir/IR/Builders.h +++ b/mlir/include/mlir/IR/Builders.h @@ -38,6 +38,7 @@ class VectorType; class RankedTensorType; class UnrankedTensorType; class TupleType; +class NoneType; class BoolAttr; class IntegerAttr; class FloatAttr; @@ -90,6 +91,7 @@ public: RankedTensorType getTensorType(ArrayRef shape, Type elementType); UnrankedTensorType getTensorType(Type elementType); TupleType getTupleType(ArrayRef elementTypes); + NoneType getNoneType(); /// Get or construct an instance of the type 'ty' with provided arguments. template Ty getType(Args... args) { diff --git a/mlir/include/mlir/IR/StandardTypes.h b/mlir/include/mlir/IR/StandardTypes.h index 97062ab..849c6d2 100644 --- a/mlir/include/mlir/IR/StandardTypes.h +++ b/mlir/include/mlir/IR/StandardTypes.h @@ -67,6 +67,7 @@ enum Kind { MemRef, Complex, Tuple, + None, }; } // namespace StandardTypes @@ -492,6 +493,19 @@ public: static bool kindof(unsigned kind) { return kind == StandardTypes::Tuple; } }; +/// NoneType is a unit type, i.e. a type with exactly one possible value, where +/// its value does not have a defined dynamic representation. +class NoneType : public Type::TypeBase { +public: + using Base::Base; + + /// Get or create a NoneType instance. + static NoneType get(MLIRContext *context) { + return Base::get(context, StandardTypes::None); + } + + static bool kindof(unsigned kind) { return kind == StandardTypes::None; } +}; } // end namespace mlir #endif // MLIR_IR_STANDARDTYPES_H diff --git a/mlir/include/mlir/Support/LLVM.h b/mlir/include/mlir/Support/LLVM.h index 2f60d59..031dceb 100644 --- a/mlir/include/mlir/Support/LLVM.h +++ b/mlir/include/mlir/Support/LLVM.h @@ -92,7 +92,6 @@ using llvm::Twine; // Other common classes. using llvm::APFloat; using llvm::APInt; -using llvm::NoneType; using llvm::raw_ostream; } // namespace mlir diff --git a/mlir/lib/IR/AsmPrinter.cpp b/mlir/lib/IR/AsmPrinter.cpp index 8b1410e..504bf68 100644 --- a/mlir/lib/IR/AsmPrinter.cpp +++ b/mlir/lib/IR/AsmPrinter.cpp @@ -909,6 +909,9 @@ void ModulePrinter::printType(Type type) { os << '>'; return; } + case StandardTypes::None: + os << "none"; + return; } } diff --git a/mlir/lib/IR/Builders.cpp b/mlir/lib/IR/Builders.cpp index d999b14..af066ba 100644 --- a/mlir/lib/IR/Builders.cpp +++ b/mlir/lib/IR/Builders.cpp @@ -101,6 +101,8 @@ TupleType Builder::getTupleType(ArrayRef elementTypes) { return TupleType::get(elementTypes, context); } +NoneType Builder::getNoneType() { return NoneType::get(context); } + //===----------------------------------------------------------------------===// // Attributes. //===----------------------------------------------------------------------===// diff --git a/mlir/lib/IR/MLIRContext.cpp b/mlir/lib/IR/MLIRContext.cpp index 29ac989..7b88414 100644 --- a/mlir/lib/IR/MLIRContext.cpp +++ b/mlir/lib/IR/MLIRContext.cpp @@ -44,7 +44,9 @@ using namespace mlir; using namespace mlir::detail; -using namespace llvm; + +using llvm::hash_combine; +using llvm::hash_combine_range; /// A utility function to safely get or create a uniqued instance within the /// given set container. @@ -135,7 +137,7 @@ struct BuiltinDialect : public Dialect { BuiltinDialect(MLIRContext *context) : Dialect(/*name=*/"", context) { addTypes(); + ComplexType, TupleType, NoneType>(); } }; @@ -426,7 +428,7 @@ public: /// This is a mapping from operation name to AbstractOperation for registered /// operations. - StringMap registeredOperations; + llvm::StringMap registeredOperations; /// This is a mapping from type identifier to Dialect for registered types. DenseMap registeredTypes; @@ -499,7 +501,7 @@ public: BoolAttributeStorage *boolAttrs[2] = {nullptr}; DenseSet integerAttrs; DenseSet floatAttrs; - StringMap stringAttrs; + llvm::StringMap stringAttrs; using ArrayAttrSet = DenseSet; ArrayAttrSet arrayAttrs; DenseMap affineMapAttrs; @@ -670,7 +672,7 @@ std::vector MLIRContext::getRegisteredOperations() { // We just have the operations in a non-deterministic hash table order. Dump // into a temporary array, then sort it by operation name to get a stable // ordering. - StringMap ®isteredOps = + llvm::StringMap ®isteredOps = getImpl().registeredOperations; opsToSort.reserve(registeredOps.size()); @@ -822,7 +824,7 @@ Location FusedLoc::get(ArrayRef locs, MLIRContext *context) { Location FusedLoc::get(ArrayRef locs, Attribute metadata, MLIRContext *context) { // Unique the set of locations to be fused. - SmallSetVector decomposedLocs; + llvm::SmallSetVector decomposedLocs; for (auto loc : locs) { // If the location is a fused location we decompose it if it has no // metadata or the metadata is the same as the top level metadata. diff --git a/mlir/lib/Parser/Parser.cpp b/mlir/lib/Parser/Parser.cpp index 6dc6550..5d6dad2 100644 --- a/mlir/lib/Parser/Parser.cpp +++ b/mlir/lib/Parser/Parser.cpp @@ -324,9 +324,11 @@ ParseResult Parser::parseCommaSeparatedListUntil( /// | memref-type /// | complex-type /// | tuple-type +/// | none-type /// /// index-type ::= `index` /// float-type ::= `f16` | `bf16` | `f32` | `f64` +/// none-type ::= `none` /// Type Parser::parseNonFunctionType() { switch (getToken().getKind()) { @@ -371,6 +373,11 @@ Type Parser::parseNonFunctionType() { consumeToken(Token::kw_index); return builder.getIndexType(); + // none-type + case Token::kw_none: + consumeToken(Token::kw_none); + return builder.getNoneType(); + // extended type case Token::exclamation_identifier: return parseExtendedType(); diff --git a/mlir/lib/Parser/TokenKinds.def b/mlir/lib/Parser/TokenKinds.def index 52a7fdc..98ab481 100644 --- a/mlir/lib/Parser/TokenKinds.def +++ b/mlir/lib/Parser/TokenKinds.def @@ -108,6 +108,7 @@ TOK_KEYWORD(max) TOK_KEYWORD(memref) TOK_KEYWORD(min) TOK_KEYWORD(mod) +TOK_KEYWORD(none) TOK_KEYWORD(opaque) TOK_KEYWORD(size) TOK_KEYWORD(sparse) diff --git a/mlir/test/IR/parser.mlir b/mlir/test/IR/parser.mlir index 77a4889..e56ad97 100644 --- a/mlir/test/IR/parser.mlir +++ b/mlir/test/IR/parser.mlir @@ -883,3 +883,10 @@ func @pretty_dialect_type() { return } + +// CHECK-LABEL: func @none_type +func @none_type() { + // CHECK: "foo.unknown_op"() : () -> none + %none_val = "foo.unknown_op"() : () -> none + return +} -- 2.7.4