[mlir] Making verification after parsing optional
This is very useful when you want to parse IR even if its invalid (e.g. bytecode). It's also useful if you don't want to pay the cost of verification in certain situations. Differential Revision: https://reviews.llvm.org/D134847
This commit is contained in:
parent
b947e15a57
commit
1ae60e044e
|
@ -456,17 +456,22 @@ private:
|
|||
class ParserConfig {
|
||||
public:
|
||||
/// Construct a parser configuration with the given context.
|
||||
/// `verifyAfterParse` indicates if the IR should be verified after parsing.
|
||||
/// `fallbackResourceMap` is an optional fallback handler that can be used to
|
||||
/// parse external resources not explicitly handled by another parser.
|
||||
ParserConfig(MLIRContext *context,
|
||||
ParserConfig(MLIRContext *context, bool verifyAfterParse = true,
|
||||
FallbackAsmResourceMap *fallbackResourceMap = nullptr)
|
||||
: context(context), fallbackResourceMap(fallbackResourceMap) {
|
||||
: context(context), verifyAfterParse(verifyAfterParse),
|
||||
fallbackResourceMap(fallbackResourceMap) {
|
||||
assert(context && "expected valid MLIR context");
|
||||
}
|
||||
|
||||
/// Return the MLIRContext to be used when parsing.
|
||||
MLIRContext *getContext() const { return context; }
|
||||
|
||||
/// Returns if the parser should verify the IR after parsing.
|
||||
bool shouldVerifyAfterParse() const { return verifyAfterParse; }
|
||||
|
||||
/// Return the resource parser registered to the given name, or nullptr if no
|
||||
/// parser with `name` is registered.
|
||||
AsmResourceParser *getResourceParser(StringRef name) const {
|
||||
|
@ -498,6 +503,7 @@ public:
|
|||
|
||||
private:
|
||||
MLIRContext *context;
|
||||
bool verifyAfterParse;
|
||||
DenseMap<StringRef, std::unique_ptr<AsmResourceParser>> resourceParsers;
|
||||
FallbackAsmResourceMap *fallbackResourceMap;
|
||||
};
|
||||
|
|
|
@ -802,7 +802,7 @@ ParseResult OperationParser::finalize() {
|
|||
return failure();
|
||||
|
||||
// Verify that the parsed operations are valid.
|
||||
if (failed(verify(topLevelOp)))
|
||||
if (state.config.shouldVerifyAfterParse() && failed(verify(topLevelOp)))
|
||||
return failure();
|
||||
|
||||
// If we are populating the parser state, finalize the top-level operation.
|
||||
|
|
|
@ -1408,7 +1408,7 @@ LogicalResult BytecodeReader::parseIRSection(ArrayRef<uint8_t> sectionData,
|
|||
}
|
||||
|
||||
// Verify that the parsed operations are valid.
|
||||
if (failed(verify(*moduleOp)))
|
||||
if (config.shouldVerifyAfterParse() && failed(verify(*moduleOp)))
|
||||
return failure();
|
||||
|
||||
// Splice the parsed operations over to the provided top-level block.
|
||||
|
|
|
@ -342,7 +342,8 @@ MLIRDocument::MLIRDocument(MLIRContext &context, const lsp::URIForFile &uri,
|
|||
return;
|
||||
}
|
||||
|
||||
ParserConfig config(&context, &fallbackResourceMap);
|
||||
ParserConfig config(&context, /*verifyAfterParse=*/true,
|
||||
&fallbackResourceMap);
|
||||
sourceMgr.AddNewSourceBuffer(std::move(memBuffer), SMLoc());
|
||||
if (failed(parseAsmSourceFile(sourceMgr, &parsedIR, config, &asmState))) {
|
||||
// If parsing failed, clear out any of the current state.
|
||||
|
@ -1296,7 +1297,8 @@ lsp::MLIRServer::convertFromBytecode(const URIForFile &uri) {
|
|||
FallbackAsmResourceMap fallbackResourceMap;
|
||||
|
||||
// Setup the parser config.
|
||||
ParserConfig parserConfig(&tempContext, &fallbackResourceMap);
|
||||
ParserConfig parserConfig(&tempContext, /*verifyAfterParse=*/true,
|
||||
&fallbackResourceMap);
|
||||
|
||||
// Try to parse the given source file.
|
||||
Block parsedBlock;
|
||||
|
|
|
@ -66,7 +66,7 @@ static LogicalResult performActions(raw_ostream &os, bool verifyDiagnostics,
|
|||
// untouched.
|
||||
PassReproducerOptions reproOptions;
|
||||
FallbackAsmResourceMap fallbackResourceMap;
|
||||
ParserConfig config(context, &fallbackResourceMap);
|
||||
ParserConfig config(context, /*verifyAfterParse=*/true, &fallbackResourceMap);
|
||||
reproOptions.attachResourceParser(config);
|
||||
|
||||
// Parse the input file and reset the context threading state.
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
add_mlir_unittest(MLIRParserTests
|
||||
ParserTest.cpp
|
||||
ResourceTest.cpp
|
||||
|
||||
DEPENDS
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
//===- ParserTest.cpp -----------------------------------------------------===//
|
||||
//
|
||||
// This file is licensed under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "mlir/Parser/Parser.h"
|
||||
#include "mlir/IR/BuiltinOps.h"
|
||||
#include "mlir/IR/Verifier.h"
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
using namespace mlir;
|
||||
|
||||
namespace {
|
||||
TEST(MLIRParser, ParseInvalidIR) {
|
||||
std::string moduleStr = R"mlir(
|
||||
module attributes {bad} {}
|
||||
)mlir";
|
||||
|
||||
MLIRContext context;
|
||||
ParserConfig config(&context, /*verifyAfterParse=*/false);
|
||||
|
||||
// Check that we properly parse the op, but it fails the verifier.
|
||||
OwningOpRef<ModuleOp> module = parseSourceString<ModuleOp>(moduleStr, config);
|
||||
ASSERT_TRUE(module);
|
||||
ASSERT_TRUE(failed(verify(*module)));
|
||||
}
|
||||
} // namespace
|
Loading…
Reference in New Issue