Implement a simple IR verifier, including support for custom ops adding their
own requirements.
PiperOrigin-RevId: 203497491
diff --git a/lib/Parser/Parser.cpp b/lib/Parser/Parser.cpp
index d97e18b..f9849a7 100644
--- a/lib/Parser/Parser.cpp
+++ b/lib/Parser/Parser.cpp
@@ -25,8 +25,9 @@
#include "mlir/IR/AffineMap.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/CFGFunction.h"
-#include "mlir/IR/Module.h"
#include "mlir/IR/MLFunction.h"
+#include "mlir/IR/Module.h"
+#include "mlir/IR/OperationSet.h"
#include "mlir/IR/Types.h"
#include "llvm/Support/SourceMgr.h"
using namespace mlir;
@@ -1243,10 +1244,18 @@
// Parse the list of operations that make up the body of the block.
while (curToken.isNot(Token::kw_return, Token::kw_br)) {
+ auto loc = curToken.getLoc();
auto *inst = parseCFGOperation(functionState);
if (!inst)
return ParseFailure;
+ // We just parsed an operation. If it is a recognized one, verify that it
+ // is structurally as we expect. If not, produce an error with a reasonable
+ // source location.
+ if (auto *opInfo = inst->getAbstractOperation(context))
+ if (auto error = opInfo->verifyInvariants(inst))
+ return emitError(loc, error);
+
block->getOperations().push_back(inst);
}
@@ -1516,7 +1525,14 @@
/// MLIR module if it was valid. If not, it emits diagnostics and returns null.
Module *mlir::parseSourceFile(llvm::SourceMgr &sourceMgr, MLIRContext *context,
SMDiagnosticHandlerTy errorReporter) {
- return Parser(sourceMgr, context,
- errorReporter ? std::move(errorReporter) : defaultErrorReporter)
- .parseModule();
+ auto *result =
+ Parser(sourceMgr, context,
+ errorReporter ? std::move(errorReporter) : defaultErrorReporter)
+ .parseModule();
+
+ // Make sure the parse module has no other structural problems detected by the
+ // verifier.
+ if (result)
+ result->verify();
+ return result;
}