forked from OSchip/llvm-project
Add a 'verifyPasses' flag to the PassManager that specifies if the IR should be verified after each pass. This also adds a "verify-each" flag to mlir-opt to optionally disable running the verifier after each pass.
PiperOrigin-RevId: 236703760
This commit is contained in:
parent
d42ef78a75
commit
50efe0fc85
|
@ -34,7 +34,8 @@ class ModulePassExecutor;
|
||||||
/// The main pass manager and pipeline builder.
|
/// The main pass manager and pipeline builder.
|
||||||
class PassManager {
|
class PassManager {
|
||||||
public:
|
public:
|
||||||
PassManager();
|
// If verifyPasses is true, the verifier is run after each pass.
|
||||||
|
PassManager(bool verifyPasses = true);
|
||||||
~PassManager();
|
~PassManager();
|
||||||
|
|
||||||
/// Add an opaque pass pointer to the current manager. This takes ownership
|
/// Add an opaque pass pointer to the current manager. This takes ownership
|
||||||
|
@ -61,6 +62,9 @@ private:
|
||||||
|
|
||||||
/// The top level module pass executor.
|
/// The top level module pass executor.
|
||||||
std::unique_ptr<detail::ModulePassExecutor> mpe;
|
std::unique_ptr<detail::ModulePassExecutor> mpe;
|
||||||
|
|
||||||
|
/// Flag that specifies if the IR should be verified after each pass has run.
|
||||||
|
bool verifyPasses;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace mlir
|
} // end namespace mlir
|
||||||
|
|
|
@ -144,27 +144,20 @@ private:
|
||||||
/// Run all of the passes in this manager over the current function.
|
/// Run all of the passes in this manager over the current function.
|
||||||
bool detail::FunctionPassExecutor::run(Function *function,
|
bool detail::FunctionPassExecutor::run(Function *function,
|
||||||
FunctionAnalysisManager &fam) {
|
FunctionAnalysisManager &fam) {
|
||||||
for (auto &pass : passes) {
|
// Run each of the held passes.
|
||||||
/// Create an execution state for this pass.
|
for (auto &pass : passes)
|
||||||
if (!pass->run(function, fam))
|
if (!pass->run(function, fam))
|
||||||
return false;
|
return false;
|
||||||
// TODO: This should be opt-out and handled separately.
|
|
||||||
if (function->verify())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run all of the passes in this manager over the current module.
|
/// Run all of the passes in this manager over the current module.
|
||||||
bool detail::ModulePassExecutor::run(Module *module,
|
bool detail::ModulePassExecutor::run(Module *module,
|
||||||
ModuleAnalysisManager &mam) {
|
ModuleAnalysisManager &mam) {
|
||||||
for (auto &pass : passes) {
|
// Run each of the held passes.
|
||||||
|
for (auto &pass : passes)
|
||||||
if (!pass->run(module, mam))
|
if (!pass->run(module, mam))
|
||||||
return false;
|
return false;
|
||||||
// TODO: This should be opt-out and handled separately.
|
|
||||||
if (module->verify())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,7 +217,28 @@ void ModuleToFunctionPassAdaptor::runOnModule() {
|
||||||
// PassManager
|
// PassManager
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
PassManager::PassManager() : mpe(new ModulePassExecutor()) {}
|
namespace {
|
||||||
|
/// Pass to verify a function and signal failure if necessary.
|
||||||
|
class FunctionVerifier : public FunctionPass<FunctionVerifier> {
|
||||||
|
void runOnFunction() {
|
||||||
|
if (getFunction().verify())
|
||||||
|
signalPassFailure();
|
||||||
|
markAllAnalysesPreserved();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Pass to verify a module and signal failure if necessary.
|
||||||
|
class ModuleVerifier : public ModulePass<ModuleVerifier> {
|
||||||
|
void runOnModule() {
|
||||||
|
if (getModule().verify())
|
||||||
|
signalPassFailure();
|
||||||
|
markAllAnalysesPreserved();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // end anonymous namespace
|
||||||
|
|
||||||
|
PassManager::PassManager(bool verifyPasses)
|
||||||
|
: mpe(new ModulePassExecutor()), verifyPasses(verifyPasses) {}
|
||||||
|
|
||||||
PassManager::~PassManager() {}
|
PassManager::~PassManager() {}
|
||||||
|
|
||||||
|
@ -246,6 +260,10 @@ void PassManager::addPass(Pass *pass) {
|
||||||
void PassManager::addPass(ModulePassBase *pass) {
|
void PassManager::addPass(ModulePassBase *pass) {
|
||||||
nestedExecutorStack.clear();
|
nestedExecutorStack.clear();
|
||||||
mpe->addPass(pass);
|
mpe->addPass(pass);
|
||||||
|
|
||||||
|
// Add a verifier run if requested.
|
||||||
|
if (verifyPasses)
|
||||||
|
mpe->addPass(new ModuleVerifier());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a function pass to the current manager. This takes ownership over the
|
/// Add a function pass to the current manager. This takes ownership over the
|
||||||
|
@ -256,7 +274,7 @@ void PassManager::addPass(FunctionPassBase *pass) {
|
||||||
if (nestedExecutorStack.empty()) {
|
if (nestedExecutorStack.empty()) {
|
||||||
/// Create an executor adaptor for this pass.
|
/// Create an executor adaptor for this pass.
|
||||||
auto *adaptor = new ModuleToFunctionPassAdaptor();
|
auto *adaptor = new ModuleToFunctionPassAdaptor();
|
||||||
mpe->addPass(adaptor);
|
addPass(adaptor);
|
||||||
|
|
||||||
/// Add the executor to the stack.
|
/// Add the executor to the stack.
|
||||||
fpe = &adaptor->getFunctionExecutor();
|
fpe = &adaptor->getFunctionExecutor();
|
||||||
|
@ -265,6 +283,10 @@ void PassManager::addPass(FunctionPassBase *pass) {
|
||||||
fpe = cast<detail::FunctionPassExecutor>(nestedExecutorStack.back());
|
fpe = cast<detail::FunctionPassExecutor>(nestedExecutorStack.back());
|
||||||
}
|
}
|
||||||
fpe->addPass(pass);
|
fpe->addPass(pass);
|
||||||
|
|
||||||
|
// Add a verifier run if requested.
|
||||||
|
if (verifyPasses)
|
||||||
|
fpe->addPass(new FunctionVerifier());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run the passes within this manager on the provided module.
|
/// Run the passes within this manager on the provided module.
|
||||||
|
|
|
@ -68,6 +68,11 @@ static cl::opt<bool>
|
||||||
"expected-* lines on the corresponding line"),
|
"expected-* lines on the corresponding line"),
|
||||||
cl::init(false));
|
cl::init(false));
|
||||||
|
|
||||||
|
static cl::opt<bool>
|
||||||
|
verifyPasses("verify-each",
|
||||||
|
cl::desc("Run the verifier after each transformation pass"),
|
||||||
|
cl::init(true));
|
||||||
|
|
||||||
static std::vector<const mlir::PassRegistryEntry *> *passList;
|
static std::vector<const mlir::PassRegistryEntry *> *passList;
|
||||||
|
|
||||||
enum OptResult { OptSuccess, OptFailure };
|
enum OptResult { OptSuccess, OptFailure };
|
||||||
|
@ -126,9 +131,7 @@ static OptResult performActions(SourceMgr &sourceMgr, MLIRContext *context) {
|
||||||
return OptFailure;
|
return OptFailure;
|
||||||
|
|
||||||
// Run each of the passes that were selected.
|
// Run each of the passes that were selected.
|
||||||
// TODO(riverriddle) Make sure that the verifer is run after each pass when it
|
PassManager pm(verifyPasses);
|
||||||
// is no longer run by default within the PassManager.
|
|
||||||
PassManager pm;
|
|
||||||
for (const auto *passEntry : *passList)
|
for (const auto *passEntry : *passList)
|
||||||
passEntry->addToPipeline(pm);
|
passEntry->addToPipeline(pm);
|
||||||
if (!pm.run(module.get()))
|
if (!pm.run(module.get()))
|
||||||
|
|
Loading…
Reference in New Issue