diff --git a/mlir/include/mlir/IR/OpDefinition.h b/mlir/include/mlir/IR/OpDefinition.h --- a/mlir/include/mlir/IR/OpDefinition.h +++ b/mlir/include/mlir/IR/OpDefinition.h @@ -173,6 +173,10 @@ /// back to this one which accepts everything. LogicalResult verify() { return success(); } + LogicalResult verifyAnalyzed(AnalysisManager *analysisManager) { + return verify(); + } + /// Unless overridden, the custom assembly form of an op is always rejected. /// Op implementations should implement this to return failure. /// On success, they should fill in result with the fields to use. @@ -1803,12 +1807,13 @@ return sizeof(ConcreteType) == sizeof(EmptyOp); } - static LogicalResult verifyInvariants(Operation *op) { + static LogicalResult verifyInvariants(Operation *op, + AnalysisManager *analysisManager) { static_assert(hasNoDataMembers(), "Op class shouldn't define new data members"); return failure( failed(op_definition_impl::verifyTraits(op)) || - failed(cast(op).verify())); + failed(cast(op).verifyAnalyzed(analysisManager))); } /// Allow access to internal implementation methods. diff --git a/mlir/include/mlir/IR/OperationSupport.h b/mlir/include/mlir/IR/OperationSupport.h --- a/mlir/include/mlir/IR/OperationSupport.h +++ b/mlir/include/mlir/IR/OperationSupport.h @@ -33,6 +33,7 @@ } // end namespace llvm namespace mlir { +class AnalysisManager; class Dialect; class DictionaryAttr; class ElementsAttr; @@ -78,8 +79,8 @@ llvm::unique_function; using PrintAssemblyFn = llvm::unique_function; - using VerifyInvariantsFn = - llvm::unique_function; + using VerifyInvariantsFn = llvm::unique_function; /// This is the name of the operation. const Identifier name; @@ -104,8 +105,9 @@ /// This hook implements the verifier for this operation. It should emits an /// error message and returns failure if a problem is detected, or returns /// success if everything is ok. - LogicalResult verifyInvariants(Operation *op) const { - return verifyInvariantsFn(op); + LogicalResult verifyInvariants(Operation *op, + AnalysisManager *analysisManager) const { + return verifyInvariantsFn(op, analysisManager); } /// This hook implements a generalized folder for this operation. Operations diff --git a/mlir/include/mlir/IR/Verifier.h b/mlir/include/mlir/IR/Verifier.h --- a/mlir/include/mlir/IR/Verifier.h +++ b/mlir/include/mlir/IR/Verifier.h @@ -10,13 +10,14 @@ #define MLIR_IR_VERIFIER_H namespace mlir { +class AnalysisManager; struct LogicalResult; class Operation; /// Perform (potentially expensive) checks of invariants, used to detect /// compiler bugs, on this operation and any nested operations. On error, this /// reports the error through the MLIRContext and returns failure. -LogicalResult verify(Operation *op); +LogicalResult verify(Operation *op, AnalysisManager *analysisManager = nullptr); } // end namespace mlir #endif diff --git a/mlir/lib/IR/Verifier.cpp b/mlir/lib/IR/Verifier.cpp --- a/mlir/lib/IR/Verifier.cpp +++ b/mlir/lib/IR/Verifier.cpp @@ -44,6 +44,9 @@ /// This class encapsulates all the state used to verify an operation region. class OperationVerifier { public: + explicit OperationVerifier(AnalysisManager *analysisManager) + : analysisManager(analysisManager) {} + /// Verify the given operation. LogicalResult verifyOpAndDominance(Operation &op); @@ -62,6 +65,8 @@ /// Operation. LogicalResult verifyDominanceOfContainedRegions(Operation &op, DominanceInfo &domInfo); + + AnalysisManager *analysisManager; }; } // end anonymous namespace @@ -179,7 +184,7 @@ // If we can get operation info for this, check the custom hook. OperationName opName = op.getName(); auto *opInfo = opName.getAbstractOperation(); - if (opInfo && failed(opInfo->verifyInvariants(&op))) + if (opInfo && failed(opInfo->verifyInvariants(&op, analysisManager))) return failure(); if (unsigned numRegions = op.getNumRegions()) { @@ -351,6 +356,6 @@ /// Perform (potentially expensive) checks of invariants, used to detect /// compiler bugs. On error, this reports the error through the MLIRContext and /// returns failure. -LogicalResult mlir::verify(Operation *op) { - return OperationVerifier().verifyOpAndDominance(*op); +LogicalResult mlir::verify(Operation *op, AnalysisManager *analysisManager) { + return OperationVerifier(analysisManager).verifyOpAndDominance(*op); } diff --git a/mlir/lib/Pass/Pass.cpp b/mlir/lib/Pass/Pass.cpp --- a/mlir/lib/Pass/Pass.cpp +++ b/mlir/lib/Pass/Pass.cpp @@ -407,7 +407,7 @@ !pass->passState->preservedAnalyses.isAll(); #endif if (runVerifierNow) - passFailed = failed(verify(op)); + passFailed = failed(verify(op, &am)); } // Instrument after the pass has run. diff --git a/mlir/test/lib/Dialect/Test/TestDialect.h b/mlir/test/lib/Dialect/Test/TestDialect.h --- a/mlir/test/lib/Dialect/Test/TestDialect.h +++ b/mlir/test/lib/Dialect/Test/TestDialect.h @@ -15,6 +15,7 @@ #define MLIR_TESTDIALECT_H #include "TestInterfaces.h" +#include "mlir/Analysis/DataLayoutAnalysis.h" #include "mlir/Dialect/DLTI/DLTI.h" #include "mlir/Dialect/DLTI/Traits.h" #include "mlir/Dialect/Traits.h" @@ -31,6 +32,7 @@ #include "mlir/Interfaces/DerivedAttributeOpInterface.h" #include "mlir/Interfaces/InferTypeOpInterface.h" #include "mlir/Interfaces/SideEffectInterfaces.h" +#include "mlir/Pass/AnalysisManager.h" namespace mlir { class DLTIDialect; diff --git a/mlir/test/lib/Dialect/Test/TestOps.td b/mlir/test/lib/Dialect/Test/TestOps.td --- a/mlir/test/lib/Dialect/Test/TestOps.td +++ b/mlir/test/lib/Dialect/Test/TestOps.td @@ -650,6 +650,20 @@ // Test Patterns //===----------------------------------------------------------------------===// +def OpWithAMVerifier : TEST_Op<"op_with_am_verifier"> { + let extraClassDeclaration = [{ + ::mlir::LogicalResult verifyAnalyzed(::mlir::AnalysisManager *am) { + if (am) { + llvm::errs() << "has analysis manager\n"; + llvm::errs() << &am->getAnalysis<::mlir::DataLayoutAnalysis>() << "\n"; + } else { + llvm::errs() << "no analysis manager\n"; + } + return ::mlir::success(); + } + }]; +} + def OpA : TEST_Op<"op_a"> { let arguments = (ins I32, I32Attr:$attr); let results = (outs I32); diff --git a/utils/bazel/llvm-project-overlay/mlir/test/BUILD.bazel b/utils/bazel/llvm-project-overlay/mlir/test/BUILD.bazel --- a/utils/bazel/llvm-project-overlay/mlir/test/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/mlir/test/BUILD.bazel @@ -219,6 +219,7 @@ ":TestOpsIncGen", ":TestTypeDefsIncGen", "//llvm:Support", + "//mlir:Analysis", "//mlir:ControlFlowInterfaces", "//mlir:CopyOpInterface", "//mlir:DLTIDialect",