diff options
| -rw-r--r-- | flang/tools/tco/tco.cpp | 2 | ||||
| -rw-r--r-- | mlir/docs/OpDefinitions.md | 11 | ||||
| -rw-r--r-- | mlir/include/mlir/Dialect/Affine/IR/AffineOps.h | 4 | ||||
| -rw-r--r-- | mlir/include/mlir/IR/OpBase.td | 11 | ||||
| -rw-r--r-- | mlir/include/mlir/IR/OpDefinition.h | 20 | ||||
| -rw-r--r-- | mlir/include/mlir/Parser.h | 2 | ||||
| -rw-r--r-- | mlir/lib/Dialect/Affine/IR/AffineOps.cpp | 4 | ||||
| -rw-r--r-- | mlir/lib/Target/SPIRV/Serialization/Serializer.cpp | 2 | ||||
| -rw-r--r-- | mlir/test/lib/Dialect/Test/TestDialect.cpp | 20 | ||||
| -rw-r--r-- | mlir/test/lib/Dialect/Test/TestOps.td | 15 | ||||
| -rw-r--r-- | mlir/test/mlir-tblgen/op-decl-and-defs.td | 2 | ||||
| -rw-r--r-- | mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp | 14 |
12 files changed, 65 insertions, 42 deletions
diff --git a/flang/tools/tco/tco.cpp b/flang/tools/tco/tco.cpp index e363394..d242e70 100644 --- a/flang/tools/tco/tco.cpp +++ b/flang/tools/tco/tco.cpp @@ -86,7 +86,7 @@ compileFIR(const mlir::PassPipelineCLParser &passPipeline) { errs() << "Error can't load file " << inputFilename << '\n'; return mlir::failure(); } - if (mlir::failed(owningRef->verify())) { + if (mlir::failed(owningRef->verifyInvariants())) { errs() << "Error verifying FIR module\n"; return mlir::failure(); } diff --git a/mlir/docs/OpDefinitions.md b/mlir/docs/OpDefinitions.md index f26afa5..1058b33 100644 --- a/mlir/docs/OpDefinitions.md +++ b/mlir/docs/OpDefinitions.md @@ -564,14 +564,13 @@ Verification code will be automatically generated for _additional_ verification, you can use ```tablegen -let verifier = [{ - ... -}]; +let hasVerifier = 1; ``` -Code placed in `verifier` will be called after the auto-generated verification -code. The order of trait verification excluding those of `verifier` should not -be relied upon. +This will generate a `LogicalResult verify()` method declaration on the op class +that can be defined with any additional verification constraints. This method +will be invoked after the auto-generated verification code. The order of trait +verification excluding those of `hasVerifier` should not be relied upon. ### Declarative Assembly Format diff --git a/mlir/include/mlir/Dialect/Affine/IR/AffineOps.h b/mlir/include/mlir/Dialect/Affine/IR/AffineOps.h index c350a53..bcfc327b 100644 --- a/mlir/include/mlir/Dialect/Affine/IR/AffineOps.h +++ b/mlir/include/mlir/Dialect/Affine/IR/AffineOps.h @@ -225,7 +225,7 @@ public: static StringRef getOperationName() { return "affine.dma_start"; } static ParseResult parse(OpAsmParser &parser, OperationState &result); void print(OpAsmPrinter &p); - LogicalResult verify(); + LogicalResult verifyInvariants(); LogicalResult fold(ArrayRef<Attribute> cstOperands, SmallVectorImpl<OpFoldResult> &results); @@ -313,7 +313,7 @@ public: static StringRef getTagMapAttrName() { return "tag_map"; } static ParseResult parse(OpAsmParser &parser, OperationState &result); void print(OpAsmPrinter &p); - LogicalResult verify(); + LogicalResult verifyInvariants(); LogicalResult fold(ArrayRef<Attribute> cstOperands, SmallVectorImpl<OpFoldResult> &results); }; diff --git a/mlir/include/mlir/IR/OpBase.td b/mlir/include/mlir/IR/OpBase.td index 992ae35..92c9d52 100644 --- a/mlir/include/mlir/IR/OpBase.td +++ b/mlir/include/mlir/IR/OpBase.td @@ -2451,7 +2451,16 @@ class Op<Dialect dialect, string mnemonic, list<Trait> props = []> { // Custom assembly format. string assemblyFormat = ?; - // Custom verifier. + // A bit indicating if the operation has additional invariants that need to + // verified (aside from those verified by other ODS constructs). If set to `1`, + // an additional `LogicalResult verify()` declaration will be generated on the + // operation class. The operation should implement this method and verify the + // additional necessary invariants. + bit hasVerifier = 0; + // A custom code block corresponding to the extra verification code of the + // operation. + // NOTE: This field is deprecated in favor of `hasVerifier` and is slated for + // deletion. code verifier = ?; // Whether this op has associated canonicalization patterns. diff --git a/mlir/include/mlir/IR/OpDefinition.h b/mlir/include/mlir/IR/OpDefinition.h index d1400c8..d83a7be 100644 --- a/mlir/include/mlir/IR/OpDefinition.h +++ b/mlir/include/mlir/IR/OpDefinition.h @@ -201,7 +201,7 @@ public: protected: /// If the concrete type didn't implement a custom verifier hook, just fall /// back to this one which accepts everything. - LogicalResult verify() { return success(); } + LogicalResult verifyInvariants() { return success(); } /// Parse the custom form of an operation. Unless overridden, this method will /// first try to get an operation parser from the op's dialect. Otherwise the @@ -1604,6 +1604,7 @@ class Op : public OpState, public Traits<ConcreteType>... { public: /// Inherit getOperation from `OpState`. using OpState::getOperation; + using OpState::verifyInvariants; /// Return if this operation contains the provided trait. template <template <typename T> class Trait> @@ -1834,8 +1835,15 @@ private: return cast<ConcreteType>(op).print(p); } /// Implementation of `VerifyInvariantsFn` OperationName hook. + static LogicalResult verifyInvariants(Operation *op) { + static_assert(hasNoDataMembers(), + "Op class shouldn't define new data members"); + return failure( + failed(op_definition_impl::verifyTraits<VerifiableTraitsTupleT>(op)) || + failed(cast<ConcreteType>(op).verifyInvariants())); + } static OperationName::VerifyInvariantsFn getVerifyInvariantsFn() { - return &verifyInvariants; + return static_cast<LogicalResult (*)(Operation *)>(&verifyInvariants); } static constexpr bool hasNoDataMembers() { @@ -1845,14 +1853,6 @@ private: return sizeof(ConcreteType) == sizeof(EmptyOp); } - static LogicalResult verifyInvariants(Operation *op) { - static_assert(hasNoDataMembers(), - "Op class shouldn't define new data members"); - return failure( - failed(op_definition_impl::verifyTraits<VerifiableTraitsTupleT>(op)) || - failed(cast<ConcreteType>(op).verify())); - } - /// Allow access to internal implementation methods. friend RegisteredOperationName; }; diff --git a/mlir/include/mlir/Parser.h b/mlir/include/mlir/Parser.h index 908c118..9bf55fe 100644 --- a/mlir/include/mlir/Parser.h +++ b/mlir/include/mlir/Parser.h @@ -67,7 +67,7 @@ inline OwningOpRef<ContainerOpT> constructContainerOpForParserIfNecessary( // After splicing, verify just this operation to ensure it can properly // contain the operations inside of it. - if (failed(op.verify())) + if (failed(op.verifyInvariants())) return OwningOpRef<ContainerOpT>(); return opRef; } diff --git a/mlir/lib/Dialect/Affine/IR/AffineOps.cpp b/mlir/lib/Dialect/Affine/IR/AffineOps.cpp index 958c532..1d11ed6 100644 --- a/mlir/lib/Dialect/Affine/IR/AffineOps.cpp +++ b/mlir/lib/Dialect/Affine/IR/AffineOps.cpp @@ -1119,7 +1119,7 @@ ParseResult AffineDmaStartOp::parse(OpAsmParser &parser, return success(); } -LogicalResult AffineDmaStartOp::verify() { +LogicalResult AffineDmaStartOp::verifyInvariants() { if (!getOperand(getSrcMemRefOperandIndex()).getType().isa<MemRefType>()) return emitOpError("expected DMA source to be of memref type"); if (!getOperand(getDstMemRefOperandIndex()).getType().isa<MemRefType>()) @@ -1221,7 +1221,7 @@ ParseResult AffineDmaWaitOp::parse(OpAsmParser &parser, return success(); } -LogicalResult AffineDmaWaitOp::verify() { +LogicalResult AffineDmaWaitOp::verifyInvariants() { if (!getOperand(0).getType().isa<MemRefType>()) return emitOpError("expected DMA tag to be of memref type"); Region *scope = getAffineScope(*this); diff --git a/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp b/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp index d6df234..7405821 100644 --- a/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp +++ b/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp @@ -86,7 +86,7 @@ Serializer::Serializer(spirv::ModuleOp module, LogicalResult Serializer::serialize() { LLVM_DEBUG(llvm::dbgs() << "+++ starting serialization +++\n"); - if (failed(module.verify())) + if (failed(module.verifyInvariants())) return failure(); // TODO: handle the other sections diff --git a/mlir/test/lib/Dialect/Test/TestDialect.cpp b/mlir/test/lib/Dialect/Test/TestDialect.cpp index 21db4e0..e23173d 100644 --- a/mlir/test/lib/Dialect/Test/TestDialect.cpp +++ b/mlir/test/lib/Dialect/Test/TestDialect.cpp @@ -1119,6 +1119,26 @@ void StringAttrPrettyNameOp::getAsmResultNames( } //===----------------------------------------------------------------------===// +// ResultTypeWithTraitOp +//===----------------------------------------------------------------------===// + +LogicalResult ResultTypeWithTraitOp::verify() { + if ((*this)->getResultTypes()[0].hasTrait<TypeTrait::TestTypeTrait>()) + return success(); + return emitError("result type should have trait 'TestTypeTrait'"); +} + +//===----------------------------------------------------------------------===// +// AttrWithTraitOp +//===----------------------------------------------------------------------===// + +LogicalResult AttrWithTraitOp::verify() { + if (getAttr().hasTrait<AttributeTrait::TestAttrTrait>()) + return success(); + return emitError("'attr' attribute should have trait 'TestAttrTrait'"); +} + +//===----------------------------------------------------------------------===// // RegionIfOp //===----------------------------------------------------------------------===// diff --git a/mlir/test/lib/Dialect/Test/TestOps.td b/mlir/test/lib/Dialect/Test/TestOps.td index c37007f..6e14b62 100644 --- a/mlir/test/lib/Dialect/Test/TestOps.td +++ b/mlir/test/lib/Dialect/Test/TestOps.td @@ -666,27 +666,16 @@ def DefaultDialectOp : TEST_Op<"default_dialect", [OpAsmOpInterface]> { // This operation requires its return type to have the trait 'TestTypeTrait'. def ResultTypeWithTraitOp : TEST_Op<"result_type_with_trait", []> { let results = (outs AnyType); - - let verifier = [{ - if((*this)->getResultTypes()[0].hasTrait<TypeTrait::TestTypeTrait>()) - return success(); - return this->emitError("result type should have trait 'TestTypeTrait'"); - }]; + let hasVerifier = 1; } // This operation requires its "attr" attribute to have the // trait 'TestAttrTrait'. def AttrWithTraitOp : TEST_Op<"attr_with_trait", []> { let arguments = (ins AnyAttr:$attr); - - let verifier = [{ - if (this->getAttr().hasTrait<AttributeTrait::TestAttrTrait>()) - return success(); - return this->emitError("'attr' attribute should have trait 'TestAttrTrait'"); - }]; + let hasVerifier = 1; } - //===----------------------------------------------------------------------===// // Test Locations //===----------------------------------------------------------------------===// diff --git a/mlir/test/mlir-tblgen/op-decl-and-defs.td b/mlir/test/mlir-tblgen/op-decl-and-defs.td index aace7cb..0f801b6 100644 --- a/mlir/test/mlir-tblgen/op-decl-and-defs.td +++ b/mlir/test/mlir-tblgen/op-decl-and-defs.td @@ -98,7 +98,7 @@ def NS_AOp : NS_Op<"a_op", [IsolatedFromAbove, IsolatedFromAbove]> { // CHECK: static void build(::mlir::OpBuilder &, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes, unsigned numRegions) // CHECK: static ::mlir::ParseResult parse(::mlir::OpAsmParser &parser, ::mlir::OperationState &result); // CHECK: void print(::mlir::OpAsmPrinter &p); -// CHECK: ::mlir::LogicalResult verify(); +// CHECK: ::mlir::LogicalResult verifyInvariants(); // CHECK: static void getCanonicalizationPatterns(::mlir::RewritePatternSet &results, ::mlir::MLIRContext *context); // CHECK: ::mlir::LogicalResult fold(::llvm::ArrayRef<::mlir::Attribute> operands, ::llvm::SmallVectorImpl<::mlir::OpFoldResult> &results); // CHECK: // Display a graph for debugging purposes. diff --git a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp index 870a7e9..c11f848 100644 --- a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp +++ b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp @@ -2208,8 +2208,8 @@ static void genNativeTraitAttrVerifier(MethodBody &body, } void OpEmitter::genVerifier() { - auto *method = opClass.addMethod("::mlir::LogicalResult", "verify"); - ERROR_IF_PRUNED(method, "verify", op); + auto *method = opClass.addMethod("::mlir::LogicalResult", "verifyInvariants"); + ERROR_IF_PRUNED(method, "verifyInvariants", op); auto &body = method->body(); OpOrAdaptorHelper emitHelper(op, /*isOp=*/true); @@ -2217,7 +2217,7 @@ void OpEmitter::genVerifier() { auto *valueInit = def.getValueInit("verifier"); StringInit *stringInit = dyn_cast<StringInit>(valueInit); - bool hasCustomVerify = stringInit && !stringInit->getValue().empty(); + bool hasCustomVerifyCodeBlock = stringInit && !stringInit->getValue().empty(); populateSubstitutions(emitHelper, verifyCtx); genAttributeVerifier(emitHelper, verifyCtx, body, staticVerifierEmitter); @@ -2236,7 +2236,13 @@ void OpEmitter::genVerifier() { genRegionVerifier(body); genSuccessorVerifier(body); - if (hasCustomVerify) { + if (def.getValueAsBit("hasVerifier")) { + auto *method = opClass.declareMethod<Method::Private>( + "::mlir::LogicalResult", "verify"); + ERROR_IF_PRUNED(method, "verify", op); + body << " return verify();\n"; + + } else if (hasCustomVerifyCodeBlock) { FmtContext fctx; fctx.addSubst("cppClass", opClass.getClassName()); auto printer = stringInit->getValue().ltrim().rtrim(" \t\v\f\r"); |
