NFC: Move the Function/Module/Operation::verify methods out-of-line.

As Functions/Modules becomes operations, these methods will conflict with the 'verify' hook already on derived operation types.

PiperOrigin-RevId: 256246112
This commit is contained in:
River Riddle 2019-07-02 15:00:38 -07:00 committed by Mehdi Amini
parent 516188bf1c
commit d3f743252d
19 changed files with 103 additions and 63 deletions

View File

@ -20,6 +20,7 @@
#include "mlir/AffineOps/AffineOps.h"
#include "mlir/Analysis/SliceAnalysis.h"
#include "mlir/Analysis/Verifier.h"
#include "mlir/EDSC/Builders.h"
#include "mlir/EDSC/Helpers.h"
#include "mlir/EDSC/Intrinsics.h"
@ -92,7 +93,7 @@ inline void cleanupAndPrintFunction(mlir::Function f) {
}
};
auto pm = cleanupPassManager();
check(f.getModule().verify());
check(mlir::verify(f.getModule()));
check(pm->run(f.getModule()));
if (printToOuts)
f.print(llvm::outs());

View File

@ -23,6 +23,7 @@
#include "toy/MLIRGen.h"
#include "toy/AST.h"
#include "mlir/Analysis/Verifier.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/Location.h"
@ -81,7 +82,7 @@ public:
// FIXME: (in the next chapter...) without registering a dialect in MLIR,
// this won't do much, but it should at least check some structural
// properties.
if (failed(theModule.verify())) {
if (failed(mlir::verify(theModule))) {
emitError(mlir::UnknownLoc::get(&context), "Module verification error");
return nullptr;
}

View File

@ -23,6 +23,7 @@
#include "toy/Parser.h"
#include <memory>
#include "mlir/Analysis/Verifier.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/Module.h"
#include "mlir/Parser.h"
@ -91,7 +92,7 @@ int dumpMLIR() {
llvm::errs() << "Error can't load file " << inputFilename << "\n";
return 3;
}
if (failed(module->verify())) {
if (failed(mlir::verify(*module))) {
llvm::errs() << "Error verifying MLIR module\n";
return 4;
}

View File

@ -24,6 +24,7 @@
#include "toy/AST.h"
#include "toy/Dialect.h"
#include "mlir/Analysis/Verifier.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/Location.h"
@ -82,7 +83,7 @@ public:
// FIXME: (in the next chapter...) without registering a dialect in MLIR,
// this won't do much, but it should at least check some structural
// properties.
if (failed(theModule->verify())) {
if (failed(mlir::verify(*theModule))) {
emitError(mlir::UnknownLoc::get(&context), "Module verification error");
return nullptr;
}

View File

@ -24,6 +24,7 @@
#include "toy/Parser.h"
#include <memory>
#include "mlir/Analysis/Verifier.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/Module.h"
#include "mlir/Parser.h"
@ -95,7 +96,7 @@ int dumpMLIR() {
llvm::errs() << "Error can't load file " << inputFilename << "\n";
return 3;
}
if (failed(module->verify())) {
if (failed(mlir::verify(*module))) {
llvm::errs() << "Error verifying MLIR module\n";
return 4;
}

View File

@ -24,6 +24,7 @@
#include "toy/AST.h"
#include "toy/Dialect.h"
#include "mlir/Analysis/Verifier.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/Location.h"
@ -82,7 +83,7 @@ public:
// FIXME: (in the next chapter...) without registering a dialect in MLIR,
// this won't do much, but it should at least check some structural
// properties.
if (failed(theModule->verify())) {
if (failed(mlir::verify(*theModule))) {
emitError(mlir::UnknownLoc::get(&context), "Module verification error");
return nullptr;
}

View File

@ -22,6 +22,7 @@
#include "toy/Dialect.h"
#include "mlir/Analysis/Verifier.h"
#include "mlir/IR/BlockAndValueMapping.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/StandardTypes.h"
@ -195,7 +196,7 @@ public:
argList[0]->replaceAllUsesWith(argList[blockArgSize]);
entryBlock.eraseArgument(0);
}
assert(succeeded(f.verify()));
assert(succeeded(mlir::verify(f)));
}
LLVM_DEBUG(llvm::dbgs()
<< "Run shape inference on : '" << f.getName() << "'\n");
@ -361,7 +362,7 @@ public:
auto newType =
mlir::FunctionType::get(argumentsType, retTy, &getContext());
f.setType(newType);
assert(succeeded(f.verify()));
assert(succeeded(mlir::verify(f)));
break;
}
return mlir::success();

View File

@ -24,6 +24,7 @@
#include "toy/Parser.h"
#include "toy/Passes.h"
#include "mlir/Analysis/Verifier.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/Module.h"
#include "mlir/Parser.h"
@ -113,7 +114,7 @@ int dumpMLIR() {
llvm::errs() << "Error can't load file " << inputFilename << "\n";
return 3;
}
if (failed(module->verify())) {
if (failed(mlir::verify(*module))) {
llvm::errs() << "Error verifying MLIR module\n";
return 4;
}

View File

@ -24,6 +24,7 @@
#include "toy/AST.h"
#include "toy/Dialect.h"
#include "mlir/Analysis/Verifier.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/Location.h"
@ -82,7 +83,7 @@ public:
// FIXME: (in the next chapter...) without registering a dialect in MLIR,
// this won't do much, but it should at least check some structural
// properties.
if (failed(theModule->verify())) {
if (failed(mlir::verify(*theModule))) {
emitError(mlir::UnknownLoc::get(&context), "Module verification error");
return nullptr;
}

View File

@ -22,6 +22,7 @@
#include "toy/Dialect.h"
#include "mlir/Analysis/Verifier.h"
#include "mlir/IR/BlockAndValueMapping.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/StandardTypes.h"
@ -197,7 +198,7 @@ public:
argList[0]->replaceAllUsesWith(argList[blockArgSize]);
entryBlock.eraseArgument(0);
}
assert(succeeded(f.verify()));
assert(succeeded(verify(f)));
}
LLVM_DEBUG(llvm::dbgs()
<< "Run shape inference on : '" << f.getName() << "'\n");
@ -361,7 +362,7 @@ public:
auto newType =
mlir::FunctionType::get(argumentsType, retTy, &getContext());
f.setType(newType);
assert(succeeded(f.verify()));
assert(succeeded(verify(f)));
break;
}
return mlir::success();

View File

@ -26,6 +26,7 @@
#include "toy/Passes.h"
#include "linalg1/Dialect.h"
#include "mlir/Analysis/Verifier.h"
#include "mlir/ExecutionEngine/ExecutionEngine.h"
#include "mlir/ExecutionEngine/OptUtils.h"
#include "mlir/IR/MLIRContext.h"
@ -150,7 +151,7 @@ mlir::OwningModuleRef loadFileAndProcessModule(
llvm::errs() << "Error can't load file " << inputFilename << "\n";
return nullptr;
}
if (failed(module->verify())) {
if (failed(mlir::verify(*module))) {
llvm::errs() << "Error verifying MLIR module\n";
return nullptr;
}

View File

@ -0,0 +1,39 @@
//===- Verifier.h - Verifier analysis for MLIR structures -------*- C++ -*-===//
//
// Copyright 2019 The MLIR Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// =============================================================================
#ifndef MLIR_ANALYSIS_VERIFIER_H
#define MLIR_ANALYSIS_VERIFIER_H
namespace mlir {
class Function;
class LogicalResult;
class Module;
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);
/// Perform (potentially expensive) checks of invariants, used to detect
/// compiler bugs, on this IR unit and any nested below. On error, this
/// reports the error through the MLIRContext and returns failure.
LogicalResult verify(Function fn);
LogicalResult verify(Module module);
} // end namespace mlir
#endif

View File

@ -302,11 +302,6 @@ public:
// Other
//===--------------------------------------------------------------------===//
/// Perform (potentially expensive) checks of invariants, used to detect
/// compiler bugs. On error, this reports the error through the MLIRContext
/// and returns failure.
LogicalResult verify();
void print(raw_ostream &os);
void dump();

View File

@ -120,11 +120,6 @@ public:
return it == functions.end() ? nullptr : &*it;
}
/// Perform (potentially expensive) checks of invariants, used to detect
/// compiler bugs. On error, this reports the error through the MLIRContext
/// and returns failure.
LogicalResult verify();
void print(raw_ostream &os);
void dump();

View File

@ -160,11 +160,6 @@ public:
/// take O(N) where N is the number of operations within the parent block.
bool isBeforeInBlock(Operation *other);
/// Perform (potentially expensive) checks of invariants, used to detect
/// compiler bugs. On error, this reports the error through the MLIRContext
/// and returns failure.
LogicalResult verify();
void print(raw_ostream &os);
void dump();

View File

@ -33,6 +33,7 @@
//
//===----------------------------------------------------------------------===//
#include "mlir/Analysis/Verifier.h"
#include "mlir/Analysis/Dominance.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/Dialect.h"
@ -292,84 +293,85 @@ LogicalResult OperationVerifier::verifyDominance(Operation &op) {
/// Perform (potentially expensive) checks of invariants, used to detect
/// compiler bugs. On error, this reports the error through the MLIRContext and
/// returns failure.
LogicalResult Function::verify() {
OperationVerifier opVerifier(getContext());
LogicalResult mlir::verify(Operation *op) {
return OperationVerifier(op->getContext()).verify(*op);
}
/// 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(Function fn) {
OperationVerifier opVerifier(fn.getContext());
llvm::PrettyStackTraceFormat fmt("MLIR Verifier: func @%s",
getName().c_str());
fn.getName().c_str());
// Check that the function name is valid.
if (!opVerifier.isValidName(getName().strref()))
return emitError("invalid function name '") << getName() << "'";
if (!opVerifier.isValidName(fn.getName().strref()))
return fn.emitError("invalid function name '") << fn.getName() << "'";
/// Verify that all of the attributes are okay.
for (auto attr : getAttrs()) {
for (auto attr : fn.getAttrs()) {
if (!opVerifier.isValidName(attr.first))
return emitError("invalid attribute name '") << attr.first << "'";
return fn.emitError("invalid attribute name '") << attr.first << "'";
/// Check that the attribute is a dialect attribute, i.e. contains a '.' for
/// the namespace.
if (!attr.first.strref().contains('.'))
return emitError("functions may only have dialect attributes");
return fn.emitError("functions may only have dialect attributes");
// Verify this attribute with the defining dialect.
if (auto *dialect = opVerifier.getDialectForAttribute(attr))
if (failed(dialect->verifyFunctionAttribute(*this, attr)))
if (failed(dialect->verifyFunctionAttribute(fn, attr)))
return failure();
}
/// Verify that all of the argument attributes are okay.
for (unsigned i = 0, e = getNumArguments(); i != e; ++i) {
for (auto attr : getArgAttrs(i)) {
for (unsigned i = 0, e = fn.getNumArguments(); i != e; ++i) {
for (auto attr : fn.getArgAttrs(i)) {
if (!opVerifier.isValidName(attr.first))
return emitError("invalid attribute name '")
return fn.emitError("invalid attribute name '")
<< attr.first << "' on argument " << i;
/// Check that the attribute is a dialect attribute, i.e. contains a '.'
/// for the namespace.
if (!attr.first.strref().contains('.'))
return emitError("function arguments may only have dialect attributes");
return fn.emitError(
"function arguments may only have dialect attributes");
// Verify this attribute with the defining dialect.
if (auto *dialect = opVerifier.getDialectForAttribute(attr))
if (failed(dialect->verifyFunctionArgAttribute(*this, i, attr)))
if (failed(dialect->verifyFunctionArgAttribute(fn, i, attr)))
return failure();
}
}
// External functions have nothing more to check.
if (isExternal())
if (fn.isExternal())
return success();
// Verify that the argument list of the function and the arg list of the first
// block line up.
auto *firstBB = &front();
auto fnInputTypes = getType().getInputs();
auto *firstBB = &fn.front();
auto fnInputTypes = fn.getType().getInputs();
if (fnInputTypes.size() != firstBB->getNumArguments())
return emitError("first block of function must have ")
return fn.emitError("first block of function must have ")
<< fnInputTypes.size() << " arguments to match function signature";
for (unsigned i = 0, e = firstBB->getNumArguments(); i != e; ++i)
if (fnInputTypes[i] != firstBB->getArgument(i)->getType())
return emitError("type of argument #")
return fn.emitError("type of argument #")
<< i << " must match corresponding argument in function signature";
// Finally, verify the body of the function.
return opVerifier.verify(*this);
return opVerifier.verify(fn);
}
/// Perform (potentially expensive) checks of invariants, used to detect
/// compiler bugs. On error, this reports the error through the MLIRContext and
/// returns failure.
LogicalResult Operation::verify() {
return OperationVerifier(getContext()).verify(*this);
}
/// Perform (potentially expensive) checks of invariants, used to detect
/// compiler bugs. On error, this reports the error through the MLIRContext and
/// returns failure.
LogicalResult Module::verify() {
LogicalResult mlir::verify(Module module) {
// Check that all functions are uniquely named.
llvm::StringMap<Location> nameToOrigLoc;
for (auto fn : *this) {
for (auto fn : module) {
auto it = nameToOrigLoc.try_emplace(fn.getName(), fn.getLoc());
if (!it.second)
return fn.emitError()
@ -379,8 +381,8 @@ LogicalResult Module::verify() {
}
// Check that each function is correct.
for (auto fn : *this)
if (failed(fn.verify()))
for (auto fn : module)
if (failed(verify(fn)))
return failure();
return success();

View File

@ -21,6 +21,7 @@
#include "mlir/Parser.h"
#include "Lexer.h"
#include "mlir/Analysis/Verifier.h"
#include "mlir/IR/AffineExpr.h"
#include "mlir/IR/AffineMap.h"
#include "mlir/IR/Attributes.h"
@ -4151,7 +4152,7 @@ Module mlir::parseSourceFile(const llvm::SourceMgr &sourceMgr,
// Make sure the parse module has no other structural problems detected by
// the verifier.
if (failed(module->verify()))
if (failed(verify(*module)))
return nullptr;
return module.release();

View File

@ -21,6 +21,7 @@
#include "mlir/Pass/Pass.h"
#include "PassDetail.h"
#include "mlir/Analysis/Verifier.h"
#include "mlir/IR/Diagnostics.h"
#include "mlir/IR/Module.h"
#include "mlir/Pass/PassManager.h"
@ -238,7 +239,7 @@ namespace {
/// Pass to verify a function and signal failure if necessary.
class FunctionVerifier : public FunctionPass<FunctionVerifier> {
void runOnFunction() {
if (failed(getFunction().verify()))
if (failed(verify(getFunction())))
signalPassFailure();
markAllAnalysesPreserved();
}
@ -247,7 +248,7 @@ class FunctionVerifier : public FunctionPass<FunctionVerifier> {
/// Pass to verify a module and signal failure if necessary.
class ModuleVerifier : public ModulePass<ModuleVerifier> {
void runOnModule() {
if (failed(getModule().verify()))
if (failed(verify(getModule())))
signalPassFailure();
markAllAnalysesPreserved();
}

View File

@ -21,6 +21,7 @@
#include "mlir/Support/TranslateClParser.h"
#include "mlir/Analysis/Verifier.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/Module.h"
#include "mlir/Parser.h"
@ -39,7 +40,7 @@ static llvm::SmallVector<TranslateFunction, 16> wrapperStorage;
static LogicalResult printMLIROutput(Module module,
llvm::StringRef outputFilename) {
if (failed(module.verify()))
if (failed(verify(module)))
return failure();
auto file = openOutputFile(outputFilename);
if (!file)