/// preferred when a pipeline is largely of one type, but one or just a few
/// passes are of different types(See PassBuilder.cpp for examples).
Error parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText,
- bool VerifyEachPass = true,
bool DebugLogging = false);
/// {{@ Parse a textual pass pipeline description into a specific PassManager
///
/// function(lpass)
Error parsePassPipeline(CGSCCPassManager &CGPM, StringRef PipelineText,
- bool VerifyEachPass = true,
bool DebugLogging = false);
Error parsePassPipeline(FunctionPassManager &FPM, StringRef PipelineText,
- bool VerifyEachPass = true,
bool DebugLogging = false);
Error parsePassPipeline(LoopPassManager &LPM, StringRef PipelineText,
- bool VerifyEachPass = true,
bool DebugLogging = false);
/// @}}
/// PassManagers and populate the passed ModulePassManager.
void registerParseTopLevelPipelineCallback(
const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>,
- bool VerifyEachPass, bool DebugLogging)> &C) {
+ bool DebugLogging)> &C) {
TopLevelPipelineParsingCallbacks.push_back(C);
}
+ /// {{@ Register callbacks for before/after parsing passes.
+ /// For example, to add a verifier pass after each parsed pass.
+ void registerBeforeParsingModulePassCallback(
+ const std::function<void(ModulePassManager &)> &C) {
+ ModulePassBeforeParsingCallbacks.push_back(C);
+ }
+ void registerBeforeParsingCGSCCPassCallback(
+ const std::function<void(CGSCCPassManager &)> &C) {
+ CGSCCPassBeforeParsingCallbacks.push_back(C);
+ }
+ void registerBeforeParsingFunctionPassCallback(
+ const std::function<void(FunctionPassManager &)> &C) {
+ FunctionPassBeforeParsingCallbacks.push_back(C);
+ }
+ void registerBeforeParsingLoopPassCallback(
+ const std::function<void(LoopPassManager &)> &C) {
+ LoopPassBeforeParsingCallbacks.push_back(C);
+ }
+ void registerAfterParsingModulePassCallback(
+ const std::function<void(ModulePassManager &)> &C) {
+ ModulePassAfterParsingCallbacks.push_back(C);
+ }
+ void registerAfterParsingCGSCCPassCallback(
+ const std::function<void(CGSCCPassManager &)> &C) {
+ CGSCCPassAfterParsingCallbacks.push_back(C);
+ }
+ void registerAfterParsingFunctionPassCallback(
+ const std::function<void(FunctionPassManager &)> &C) {
+ FunctionPassAfterParsingCallbacks.push_back(C);
+ }
+ void registerAfterParsingLoopPassCallback(
+ const std::function<void(LoopPassManager &)> &C) {
+ LoopPassAfterParsingCallbacks.push_back(C);
+ }
+ /// @}}
+
/// Add PGOInstrumenation passes for O0 only.
void addPGOInstrPassesForO0(ModulePassManager &MPM, bool DebugLogging,
bool RunProfileGen, bool IsCS,
parsePipelineText(StringRef Text);
Error parseModulePass(ModulePassManager &MPM, const PipelineElement &E,
- bool VerifyEachPass, bool DebugLogging);
+ bool DebugLogging);
Error parseCGSCCPass(CGSCCPassManager &CGPM, const PipelineElement &E,
- bool VerifyEachPass, bool DebugLogging);
+ bool DebugLogging);
Error parseFunctionPass(FunctionPassManager &FPM, const PipelineElement &E,
- bool VerifyEachPass, bool DebugLogging);
+ bool DebugLogging);
Error parseLoopPass(LoopPassManager &LPM, const PipelineElement &E,
- bool VerifyEachPass, bool DebugLogging);
+ bool DebugLogging);
bool parseAAPassName(AAManager &AA, StringRef Name);
Error parseLoopPassPipeline(LoopPassManager &LPM,
ArrayRef<PipelineElement> Pipeline,
- bool VerifyEachPass, bool DebugLogging);
+ bool DebugLogging);
Error parseFunctionPassPipeline(FunctionPassManager &FPM,
ArrayRef<PipelineElement> Pipeline,
- bool VerifyEachPass, bool DebugLogging);
+ bool DebugLogging);
Error parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
ArrayRef<PipelineElement> Pipeline,
- bool VerifyEachPass, bool DebugLogging);
+ bool DebugLogging);
Error parseModulePassPipeline(ModulePassManager &MPM,
ArrayRef<PipelineElement> Pipeline,
- bool VerifyEachPass, bool DebugLogging);
+ bool DebugLogging);
void addPGOInstrPasses(ModulePassManager &MPM, bool DebugLogging,
OptimizationLevel Level, bool RunProfileGen, bool IsCS,
2>
ModulePipelineParsingCallbacks;
SmallVector<std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>,
- bool VerifyEachPass, bool DebugLogging)>,
+ bool DebugLogging)>,
2>
TopLevelPipelineParsingCallbacks;
// CGSCC callbacks
// AA callbacks
SmallVector<std::function<bool(StringRef Name, AAManager &AA)>, 2>
AAParsingCallbacks;
+ // Before/after pass parsing callbacks
+ SmallVector<std::function<void(ModulePassManager &)>, 2>
+ ModulePassBeforeParsingCallbacks;
+ SmallVector<std::function<void(ModulePassManager &)>, 2>
+ ModulePassAfterParsingCallbacks;
+ SmallVector<std::function<void(CGSCCPassManager &)>, 2>
+ CGSCCPassBeforeParsingCallbacks;
+ SmallVector<std::function<void(CGSCCPassManager &)>, 2>
+ CGSCCPassAfterParsingCallbacks;
+ SmallVector<std::function<void(FunctionPassManager &)>, 2>
+ FunctionPassBeforeParsingCallbacks;
+ SmallVector<std::function<void(FunctionPassManager &)>, 2>
+ FunctionPassAfterParsingCallbacks;
+ SmallVector<std::function<void(LoopPassManager &)>, 2>
+ LoopPassBeforeParsingCallbacks;
+ SmallVector<std::function<void(LoopPassManager &)>, 2>
+ LoopPassAfterParsingCallbacks;
};
/// This utility template takes care of adding require<> and invalidate<>
Error PassBuilder::parseModulePass(ModulePassManager &MPM,
const PipelineElement &E,
- bool VerifyEachPass, bool DebugLogging) {
+ bool DebugLogging) {
auto &Name = E.Name;
auto &InnerPipeline = E.InnerPipeline;
if (!InnerPipeline.empty()) {
if (Name == "module") {
ModulePassManager NestedMPM(DebugLogging);
- if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline,
- VerifyEachPass, DebugLogging))
+ if (auto Err =
+ parseModulePassPipeline(NestedMPM, InnerPipeline, DebugLogging))
return Err;
MPM.addPass(std::move(NestedMPM));
return Error::success();
}
if (Name == "cgscc") {
CGSCCPassManager CGPM(DebugLogging);
- if (auto Err = parseCGSCCPassPipeline(CGPM, InnerPipeline, VerifyEachPass,
- DebugLogging))
+ if (auto Err = parseCGSCCPassPipeline(CGPM, InnerPipeline, DebugLogging))
return Err;
MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
return Error::success();
}
if (Name == "function") {
FunctionPassManager FPM(DebugLogging);
- if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline,
- VerifyEachPass, DebugLogging))
+ if (auto Err =
+ parseFunctionPassPipeline(FPM, InnerPipeline, DebugLogging))
return Err;
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
return Error::success();
}
if (auto Count = parseRepeatPassName(Name)) {
ModulePassManager NestedMPM(DebugLogging);
- if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline,
- VerifyEachPass, DebugLogging))
+ if (auto Err =
+ parseModulePassPipeline(NestedMPM, InnerPipeline, DebugLogging))
return Err;
MPM.addPass(createRepeatedPass(*Count, std::move(NestedMPM)));
return Error::success();
}
Error PassBuilder::parseCGSCCPass(CGSCCPassManager &CGPM,
- const PipelineElement &E, bool VerifyEachPass,
- bool DebugLogging) {
+ const PipelineElement &E, bool DebugLogging) {
auto &Name = E.Name;
auto &InnerPipeline = E.InnerPipeline;
if (!InnerPipeline.empty()) {
if (Name == "cgscc") {
CGSCCPassManager NestedCGPM(DebugLogging);
- if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline,
- VerifyEachPass, DebugLogging))
+ if (auto Err =
+ parseCGSCCPassPipeline(NestedCGPM, InnerPipeline, DebugLogging))
return Err;
// Add the nested pass manager with the appropriate adaptor.
CGPM.addPass(std::move(NestedCGPM));
}
if (Name == "function") {
FunctionPassManager FPM(DebugLogging);
- if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline,
- VerifyEachPass, DebugLogging))
+ if (auto Err =
+ parseFunctionPassPipeline(FPM, InnerPipeline, DebugLogging))
return Err;
// Add the nested pass manager with the appropriate adaptor.
CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM)));
}
if (auto Count = parseRepeatPassName(Name)) {
CGSCCPassManager NestedCGPM(DebugLogging);
- if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline,
- VerifyEachPass, DebugLogging))
+ if (auto Err =
+ parseCGSCCPassPipeline(NestedCGPM, InnerPipeline, DebugLogging))
return Err;
CGPM.addPass(createRepeatedPass(*Count, std::move(NestedCGPM)));
return Error::success();
}
if (auto MaxRepetitions = parseDevirtPassName(Name)) {
CGSCCPassManager NestedCGPM(DebugLogging);
- if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline,
- VerifyEachPass, DebugLogging))
+ if (auto Err =
+ parseCGSCCPassPipeline(NestedCGPM, InnerPipeline, DebugLogging))
return Err;
CGPM.addPass(
createDevirtSCCRepeatedPass(std::move(NestedCGPM), *MaxRepetitions));
Error PassBuilder::parseFunctionPass(FunctionPassManager &FPM,
const PipelineElement &E,
- bool VerifyEachPass, bool DebugLogging) {
+ bool DebugLogging) {
auto &Name = E.Name;
auto &InnerPipeline = E.InnerPipeline;
if (!InnerPipeline.empty()) {
if (Name == "function") {
FunctionPassManager NestedFPM(DebugLogging);
- if (auto Err = parseFunctionPassPipeline(NestedFPM, InnerPipeline,
- VerifyEachPass, DebugLogging))
+ if (auto Err =
+ parseFunctionPassPipeline(NestedFPM, InnerPipeline, DebugLogging))
return Err;
// Add the nested pass manager with the appropriate adaptor.
FPM.addPass(std::move(NestedFPM));
}
if (Name == "loop" || Name == "loop-mssa") {
LoopPassManager LPM(DebugLogging);
- if (auto Err = parseLoopPassPipeline(LPM, InnerPipeline, VerifyEachPass,
- DebugLogging))
+ if (auto Err = parseLoopPassPipeline(LPM, InnerPipeline, DebugLogging))
return Err;
// Add the nested pass manager with the appropriate adaptor.
bool UseMemorySSA = (Name == "loop-mssa");
}
if (auto Count = parseRepeatPassName(Name)) {
FunctionPassManager NestedFPM(DebugLogging);
- if (auto Err = parseFunctionPassPipeline(NestedFPM, InnerPipeline,
- VerifyEachPass, DebugLogging))
+ if (auto Err =
+ parseFunctionPassPipeline(NestedFPM, InnerPipeline, DebugLogging))
return Err;
FPM.addPass(createRepeatedPass(*Count, std::move(NestedFPM)));
return Error::success();
}
Error PassBuilder::parseLoopPass(LoopPassManager &LPM, const PipelineElement &E,
- bool VerifyEachPass, bool DebugLogging) {
+ bool DebugLogging) {
StringRef Name = E.Name;
auto &InnerPipeline = E.InnerPipeline;
if (!InnerPipeline.empty()) {
if (Name == "loop") {
LoopPassManager NestedLPM(DebugLogging);
- if (auto Err = parseLoopPassPipeline(NestedLPM, InnerPipeline,
- VerifyEachPass, DebugLogging))
+ if (auto Err =
+ parseLoopPassPipeline(NestedLPM, InnerPipeline, DebugLogging))
return Err;
// Add the nested pass manager with the appropriate adaptor.
LPM.addPass(std::move(NestedLPM));
}
if (auto Count = parseRepeatPassName(Name)) {
LoopPassManager NestedLPM(DebugLogging);
- if (auto Err = parseLoopPassPipeline(NestedLPM, InnerPipeline,
- VerifyEachPass, DebugLogging))
+ if (auto Err =
+ parseLoopPassPipeline(NestedLPM, InnerPipeline, DebugLogging))
return Err;
LPM.addPass(createRepeatedPass(*Count, std::move(NestedLPM)));
return Error::success();
Error PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM,
ArrayRef<PipelineElement> Pipeline,
- bool VerifyEachPass,
bool DebugLogging) {
for (const auto &Element : Pipeline) {
- if (auto Err = parseLoopPass(LPM, Element, VerifyEachPass, DebugLogging))
+ for (auto &C : LoopPassBeforeParsingCallbacks)
+ C(LPM);
+ if (auto Err = parseLoopPass(LPM, Element, DebugLogging))
return Err;
- // FIXME: No verifier support for Loop passes!
+ for (auto &C : LoopPassAfterParsingCallbacks)
+ C(LPM);
}
return Error::success();
}
Error PassBuilder::parseFunctionPassPipeline(FunctionPassManager &FPM,
ArrayRef<PipelineElement> Pipeline,
- bool VerifyEachPass,
bool DebugLogging) {
for (const auto &Element : Pipeline) {
- if (auto Err =
- parseFunctionPass(FPM, Element, VerifyEachPass, DebugLogging))
+ for (auto &C : FunctionPassBeforeParsingCallbacks)
+ C(FPM);
+ if (auto Err = parseFunctionPass(FPM, Element, DebugLogging))
return Err;
- if (VerifyEachPass)
- FPM.addPass(VerifierPass());
+ for (auto &C : FunctionPassAfterParsingCallbacks)
+ C(FPM);
}
return Error::success();
}
Error PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
ArrayRef<PipelineElement> Pipeline,
- bool VerifyEachPass,
bool DebugLogging) {
for (const auto &Element : Pipeline) {
- if (auto Err = parseCGSCCPass(CGPM, Element, VerifyEachPass, DebugLogging))
+ for (auto &C : CGSCCPassBeforeParsingCallbacks)
+ C(CGPM);
+ if (auto Err = parseCGSCCPass(CGPM, Element, DebugLogging))
return Err;
- // FIXME: No verifier support for CGSCC passes!
+ for (auto &C : CGSCCPassAfterParsingCallbacks)
+ C(CGPM);
}
return Error::success();
}
Error PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
ArrayRef<PipelineElement> Pipeline,
- bool VerifyEachPass,
bool DebugLogging) {
for (const auto &Element : Pipeline) {
- if (auto Err = parseModulePass(MPM, Element, VerifyEachPass, DebugLogging))
+ for (auto &C : ModulePassBeforeParsingCallbacks)
+ C(MPM);
+ if (auto Err = parseModulePass(MPM, Element, DebugLogging))
return Err;
- if (VerifyEachPass)
- MPM.addPass(VerifierPass());
+ for (auto &C : ModulePassAfterParsingCallbacks)
+ C(MPM);
}
return Error::success();
}
// pre-populate the analysis managers with target-specific stuff?
Error PassBuilder::parsePassPipeline(ModulePassManager &MPM,
StringRef PipelineText,
- bool VerifyEachPass, bool DebugLogging) {
+ bool DebugLogging) {
auto Pipeline = parsePipelineText(PipelineText);
if (!Pipeline || Pipeline->empty())
return make_error<StringError>(
Pipeline = {{"function", {{"loop", std::move(*Pipeline)}}}};
} else {
for (auto &C : TopLevelPipelineParsingCallbacks)
- if (C(MPM, *Pipeline, VerifyEachPass, DebugLogging))
+ if (C(MPM, *Pipeline, DebugLogging))
return Error::success();
// Unknown pass or pipeline name!
}
}
- if (auto Err =
- parseModulePassPipeline(MPM, *Pipeline, VerifyEachPass, DebugLogging))
+ if (auto Err = parseModulePassPipeline(MPM, *Pipeline, DebugLogging))
return Err;
return Error::success();
}
// Primary pass pipeline description parsing routine for a \c CGSCCPassManager
Error PassBuilder::parsePassPipeline(CGSCCPassManager &CGPM,
StringRef PipelineText,
- bool VerifyEachPass, bool DebugLogging) {
+ bool DebugLogging) {
auto Pipeline = parsePipelineText(PipelineText);
if (!Pipeline || Pipeline->empty())
return make_error<StringError>(
.str(),
inconvertibleErrorCode());
- if (auto Err =
- parseCGSCCPassPipeline(CGPM, *Pipeline, VerifyEachPass, DebugLogging))
+ if (auto Err = parseCGSCCPassPipeline(CGPM, *Pipeline, DebugLogging))
return Err;
return Error::success();
}
// FunctionPassManager
Error PassBuilder::parsePassPipeline(FunctionPassManager &FPM,
StringRef PipelineText,
- bool VerifyEachPass, bool DebugLogging) {
+ bool DebugLogging) {
auto Pipeline = parsePipelineText(PipelineText);
if (!Pipeline || Pipeline->empty())
return make_error<StringError>(
.str(),
inconvertibleErrorCode());
- if (auto Err = parseFunctionPassPipeline(FPM, *Pipeline, VerifyEachPass,
- DebugLogging))
+ if (auto Err = parseFunctionPassPipeline(FPM, *Pipeline, DebugLogging))
return Err;
return Error::success();
}
// Primary pass pipeline description parsing routine for a \c LoopPassManager
Error PassBuilder::parsePassPipeline(LoopPassManager &CGPM,
StringRef PipelineText,
- bool VerifyEachPass, bool DebugLogging) {
+ bool DebugLogging) {
auto Pipeline = parsePipelineText(PipelineText);
if (!Pipeline || Pipeline->empty())
return make_error<StringError>(
formatv("invalid pipeline '{0}'", PipelineText).str(),
inconvertibleErrorCode());
- if (auto Err =
- parseLoopPassPipeline(CGPM, *Pipeline, VerifyEachPass, DebugLogging))
+ if (auto Err = parseLoopPassPipeline(CGPM, *Pipeline, DebugLogging))
return Err;
return Error::success();
PB.registerLoopAnalyses(LAM);
PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
- auto Err = PB.parsePassPipeline(MPM, PassPipeline, false, false);
+ auto Err = PB.parsePassPipeline(MPM, PassPipeline, false);
assert(!Err && "Should have been checked during fuzzer initialization");
// Only fail with assert above, otherwise ignore the parsing error.
consumeError(std::move(Err));
PassBuilder PB(TM.get());
ModulePassManager MPM;
- if (auto Err = PB.parsePassPipeline(MPM, PassPipeline, false, false)) {
+ if (auto Err = PB.parsePassPipeline(MPM, PassPipeline, false)) {
errs() << *argv[0] << ": " << toString(std::move(Err)) << "\n";
exit(1);
}
/// If one of the EPPipeline command line options was given, register callbacks
/// for parsing and inserting the given pipeline
-static void registerEPCallbacks(PassBuilder &PB, bool VerifyEachPass,
- bool DebugLogging) {
+static void registerEPCallbacks(PassBuilder &PB, bool DebugLogging) {
if (tryParsePipelineText<FunctionPassManager>(PB, PeepholeEPPipeline))
PB.registerPeepholeEPCallback(
- [&PB, VerifyEachPass, DebugLogging](
- FunctionPassManager &PM, PassBuilder::OptimizationLevel Level) {
+ [&PB, DebugLogging](FunctionPassManager &PM,
+ PassBuilder::OptimizationLevel Level) {
ExitOnError Err("Unable to parse PeepholeEP pipeline: ");
- Err(PB.parsePassPipeline(PM, PeepholeEPPipeline, VerifyEachPass,
- DebugLogging));
+ Err(PB.parsePassPipeline(PM, PeepholeEPPipeline, DebugLogging));
});
if (tryParsePipelineText<LoopPassManager>(PB,
LateLoopOptimizationsEPPipeline))
PB.registerLateLoopOptimizationsEPCallback(
- [&PB, VerifyEachPass, DebugLogging](
- LoopPassManager &PM, PassBuilder::OptimizationLevel Level) {
+ [&PB, DebugLogging](LoopPassManager &PM,
+ PassBuilder::OptimizationLevel Level) {
ExitOnError Err("Unable to parse LateLoopOptimizationsEP pipeline: ");
Err(PB.parsePassPipeline(PM, LateLoopOptimizationsEPPipeline,
- VerifyEachPass, DebugLogging));
+ DebugLogging));
});
if (tryParsePipelineText<LoopPassManager>(PB, LoopOptimizerEndEPPipeline))
PB.registerLoopOptimizerEndEPCallback(
- [&PB, VerifyEachPass, DebugLogging](
- LoopPassManager &PM, PassBuilder::OptimizationLevel Level) {
+ [&PB, DebugLogging](LoopPassManager &PM,
+ PassBuilder::OptimizationLevel Level) {
ExitOnError Err("Unable to parse LoopOptimizerEndEP pipeline: ");
Err(PB.parsePassPipeline(PM, LoopOptimizerEndEPPipeline,
- VerifyEachPass, DebugLogging));
+ DebugLogging));
});
if (tryParsePipelineText<FunctionPassManager>(PB,
ScalarOptimizerLateEPPipeline))
PB.registerScalarOptimizerLateEPCallback(
- [&PB, VerifyEachPass, DebugLogging](
- FunctionPassManager &PM, PassBuilder::OptimizationLevel Level) {
+ [&PB, DebugLogging](FunctionPassManager &PM,
+ PassBuilder::OptimizationLevel Level) {
ExitOnError Err("Unable to parse ScalarOptimizerLateEP pipeline: ");
Err(PB.parsePassPipeline(PM, ScalarOptimizerLateEPPipeline,
- VerifyEachPass, DebugLogging));
+ DebugLogging));
});
if (tryParsePipelineText<CGSCCPassManager>(PB, CGSCCOptimizerLateEPPipeline))
PB.registerCGSCCOptimizerLateEPCallback(
- [&PB, VerifyEachPass, DebugLogging](
- CGSCCPassManager &PM, PassBuilder::OptimizationLevel Level) {
+ [&PB, DebugLogging](CGSCCPassManager &PM,
+ PassBuilder::OptimizationLevel Level) {
ExitOnError Err("Unable to parse CGSCCOptimizerLateEP pipeline: ");
Err(PB.parsePassPipeline(PM, CGSCCOptimizerLateEPPipeline,
- VerifyEachPass, DebugLogging));
+ DebugLogging));
});
if (tryParsePipelineText<FunctionPassManager>(PB, VectorizerStartEPPipeline))
PB.registerVectorizerStartEPCallback(
- [&PB, VerifyEachPass, DebugLogging](
- FunctionPassManager &PM, PassBuilder::OptimizationLevel Level) {
+ [&PB, DebugLogging](FunctionPassManager &PM,
+ PassBuilder::OptimizationLevel Level) {
ExitOnError Err("Unable to parse VectorizerStartEP pipeline: ");
Err(PB.parsePassPipeline(PM, VectorizerStartEPPipeline,
- VerifyEachPass, DebugLogging));
+ DebugLogging));
});
if (tryParsePipelineText<ModulePassManager>(PB, PipelineStartEPPipeline))
PB.registerPipelineStartEPCallback(
- [&PB, VerifyEachPass, DebugLogging](ModulePassManager &PM) {
+ [&PB, DebugLogging](ModulePassManager &PM) {
ExitOnError Err("Unable to parse PipelineStartEP pipeline: ");
- Err(PB.parsePassPipeline(PM, PipelineStartEPPipeline, VerifyEachPass,
- DebugLogging));
+ Err(PB.parsePassPipeline(PM, PipelineStartEPPipeline, DebugLogging));
});
if (tryParsePipelineText<FunctionPassManager>(PB, OptimizerLastEPPipeline))
PB.registerOptimizerLastEPCallback(
- [&PB, VerifyEachPass, DebugLogging](ModulePassManager &PM,
- PassBuilder::OptimizationLevel) {
+ [&PB, DebugLogging](ModulePassManager &PM,
+ PassBuilder::OptimizationLevel) {
ExitOnError Err("Unable to parse OptimizerLastEP pipeline: ");
- Err(PB.parsePassPipeline(PM, OptimizerLastEPPipeline, VerifyEachPass,
- DebugLogging));
+ Err(PB.parsePassPipeline(PM, OptimizerLastEPPipeline, DebugLogging));
});
}
PTO.LoopUnrolling = !DisableLoopUnrolling;
PTO.Coroutines = Coroutines;
PassBuilder PB(TM, PTO, P, &PIC);
- registerEPCallbacks(PB, VerifyEachPass, DebugPM);
+ registerEPCallbacks(PB, DebugPM);
+
+ if (VerifyEachPass) {
+ // No verifier support for CGSCC/Loop passes.
+ PB.registerAfterParsingFunctionPassCallback(
+ [](FunctionPassManager &FPM) { FPM.addPass(VerifierPass()); });
+ PB.registerAfterParsingModulePassCallback(
+ [](ModulePassManager &MPM) { MPM.addPass(VerifierPass()); });
+ }
// Load requested pass plugins and let them register pass builder callbacks
for (auto &PluginFN : PassPlugins) {
if (!PassPipeline.empty()) {
assert(Passes.empty() &&
"PassPipeline and Passes should not both contain passes");
- if (auto Err =
- PB.parsePassPipeline(MPM, PassPipeline, VerifyEachPass, DebugPM)) {
+ if (auto Err = PB.parsePassPipeline(MPM, PassPipeline, DebugPM)) {
errs() << Arg0 << ": " << toString(std::move(Err)) << "\n";
return false;
}
std::string ModifiedPassName(PassName.begin(), PassName.end());
if (PB.isAnalysisPassName(PassName))
ModifiedPassName = "require<" + ModifiedPassName + ">";
- if (auto Err = PB.parsePassPipeline(MPM, ModifiedPassName, VerifyEachPass,
- DebugPM)) {
+ if (auto Err = PB.parsePassPipeline(MPM, ModifiedPassName, DebugPM)) {
errs() << Arg0 << ": " << toString(std::move(Err)) << "\n";
return false;
}
.WillOnce(Invoke(getAnalysisResult));
StringRef PipelineText = "test-transform";
- ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded())
+ ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded())
<< "Pipeline was: " << PipelineText;
PM.run(*M, AM);
.Times(0);
StringRef PipelineText = "test-transform";
- ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded())
+ ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded())
<< "Pipeline was: " << PipelineText;
PM.run(*M, AM);
StringRef PipelineText = "test-transform,function(test-transform),cgscc("
"function(loop(test-transform)))";
- ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded())
+ ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded())
<< "Pipeline was: " << PipelineText;
PM.run(*M, AM);
.WillOnce(Invoke(getAnalysisResult));
StringRef PipelineText = "test-transform";
- ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded())
+ ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded())
<< "Pipeline was: " << PipelineText;
PM.run(*M, AM);
}
.Times(0);
StringRef PipelineText = "test-transform";
- ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded())
+ ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded())
<< "Pipeline was: " << PipelineText;
PM.run(*M, AM);
}
.Times(0);
StringRef PipelineText = "test-transform";
- ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded())
+ ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded())
<< "Pipeline was: " << PipelineText;
PM.run(*M, AM);
}
.WillOnce(WithArgs<0, 1, 2>(Invoke(getAnalysisResult)));
StringRef PipelineText = "test-transform";
- ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded())
+ ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded())
<< "Pipeline was: " << PipelineText;
PM.run(*M, AM);
}
.Times(0);
StringRef PipelineText = "test-transform";
- ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded())
+ ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded())
<< "Pipeline was: " << PipelineText;
PM.run(*M, AM);
}
.Times(0);
StringRef PipelineText = "test-transform";
- ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded())
+ ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded())
<< "Pipeline was: " << PipelineText;
PM.run(*M, AM);
}
.Times(0);
StringRef PipelineText = "test-transform";
- ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded())
+ ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded())
<< "Pipeline was: " << PipelineText;
PM.run(*M, AM);
}
.WillOnce(WithArgs<0, 1, 2>(Invoke(getAnalysisResult)));
StringRef PipelineText = "test-transform";
- ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded())
+ ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded())
<< "Pipeline was: " << PipelineText;
PM.run(*M, AM);
}
.Times(0);
StringRef PipelineText = "test-transform";
- ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded())
+ ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded())
<< "Pipeline was: " << PipelineText;
PM.run(*M, AM);
}
.Times(0);
StringRef PipelineText = "test-transform";
- ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded())
+ ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded())
<< "Pipeline was: " << PipelineText;
PM.run(*M, AM);
}
.Times(0);
StringRef PipelineText = "test-transform";
- ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded())
+ ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded())
<< "Pipeline was: " << PipelineText;
PM.run(*M, AM);
}
EXPECT_CALL(AnalysisHandle, invalidate(HasName("<string>"), _, _));
StringRef PipelineText = "require<test-analysis>,invalidate<test-analysis>";
- ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded())
+ ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded())
<< "Pipeline was: " << PipelineText;
PM.run(*M, AM);
}
EXPECT_CALL(AnalysisHandle, invalidate(HasName("(foo)"), _, _));
StringRef PipelineText = "require<test-analysis>,invalidate<test-analysis>";
- ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded())
+ ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded())
<< "Pipeline was: " << PipelineText;
PM.run(*M, AM);
}
EXPECT_CALL(AnalysisHandle, invalidate(HasName("foo"), _, _));
StringRef PipelineText = "require<test-analysis>,invalidate<test-analysis>";
- ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded())
+ ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded())
<< "Pipeline was: " << PipelineText;
PM.run(*M, AM);
}
StringRef PipelineText = "require<test-analysis>,invalidate<test-analysis>";
- ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded())
+ ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded())
<< "Pipeline was: " << PipelineText;
PM.run(*M, AM);
}
/// This test parses a pipeline named 'another-pipeline', whose only elements
/// may be the test-transform pass or the analysis utilities
TEST_F(ModuleCallbacksTest, ParseTopLevelPipeline) {
- PB.registerParseTopLevelPipelineCallback([this](
- ModulePassManager &MPM, ArrayRef<PassBuilder::PipelineElement> Pipeline,
- bool VerifyEachPass, bool DebugLogging) {
- auto &FirstName = Pipeline.front().Name;
- auto &InnerPipeline = Pipeline.front().InnerPipeline;
- if (FirstName == "another-pipeline") {
- for (auto &E : InnerPipeline) {
- if (parseAnalysisUtilityPasses<AnalysisT>("test-analysis", E.Name, PM))
- continue;
-
- if (E.Name == "test-transform") {
- PM.addPass(PassHandle.getPass());
- continue;
+ PB.registerParseTopLevelPipelineCallback(
+ [this](ModulePassManager &MPM,
+ ArrayRef<PassBuilder::PipelineElement> Pipeline,
+ bool DebugLogging) {
+ auto &FirstName = Pipeline.front().Name;
+ auto &InnerPipeline = Pipeline.front().InnerPipeline;
+ if (FirstName == "another-pipeline") {
+ for (auto &E : InnerPipeline) {
+ if (parseAnalysisUtilityPasses<AnalysisT>("test-analysis", E.Name,
+ PM))
+ continue;
+
+ if (E.Name == "test-transform") {
+ PM.addPass(PassHandle.getPass());
+ continue;
+ }
+ return false;
+ }
}
- return false;
- }
- }
- return true;
- });
+ return true;
+ });
EXPECT_CALL(AnalysisHandle, run(HasName("<string>"), _));
EXPECT_CALL(PassHandle, run(HasName("<string>"), _))
StringRef PipelineText =
"another-pipeline(test-transform,invalidate<test-analysis>)";
- ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded())
+ ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded())
<< "Pipeline was: " << PipelineText;
PM.run(*M, AM);
/// Test the negative case
PipelineText = "another-pipeline(instcombine)";
- ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Failed())
+ ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Failed())
<< "Pipeline was: " << PipelineText;
}
+
+struct CounterPass : PassInfoMixin<CounterPass> {
+ int &Counter;
+ int &I;
+
+ CounterPass(int &Counter, int &I) : Counter(Counter), I(I) {}
+
+ void impl() {
+ int C = Counter++;
+ // A pass can be run multiple times (e.g. passes added via before/after
+ // parsing passes callbacks when implicit pass managers are involved), so
+ // only take the first number.
+ if (I == 0)
+ I = C;
+ }
+
+ PreservedAnalyses run(Module &F, ModuleAnalysisManager &AM) {
+ impl();
+ return PreservedAnalyses::none();
+ }
+ PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
+ LazyCallGraph &CG, CGSCCUpdateResult &UR) {
+ impl();
+ return PreservedAnalyses::none();
+ }
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
+ impl();
+ return PreservedAnalyses::none();
+ }
+ PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR, LPMUpdater &U) {
+ impl();
+ return PreservedAnalyses::none();
+ }
+};
+
+TEST_F(ModuleCallbacksTest, AddPassCallbacks) {
+ int M1 = 0, M2 = 0, M3 = 0, C1 = 0, C2 = 0, C3 = 0, F1 = 0, F2 = 0, F3 = 0,
+ L1 = 0, L2 = 0, L3 = 0, Counter = 1;
+ PB.registerBeforeParsingModulePassCallback(
+ [&](ModulePassManager &MPM) { MPM.addPass(CounterPass(Counter, M1)); });
+ PB.registerAfterParsingModulePassCallback(
+ [&](ModulePassManager &MPM) { MPM.addPass(CounterPass(Counter, M3)); });
+ PB.registerBeforeParsingCGSCCPassCallback(
+ [&](CGSCCPassManager &MPM) { MPM.addPass(CounterPass(Counter, C1)); });
+ PB.registerAfterParsingCGSCCPassCallback(
+ [&](CGSCCPassManager &MPM) { MPM.addPass(CounterPass(Counter, C3)); });
+ PB.registerBeforeParsingFunctionPassCallback(
+ [&](FunctionPassManager &MPM) { MPM.addPass(CounterPass(Counter, F1)); });
+ PB.registerAfterParsingFunctionPassCallback(
+ [&](FunctionPassManager &MPM) { MPM.addPass(CounterPass(Counter, F3)); });
+ PB.registerBeforeParsingLoopPassCallback(
+ [&](LoopPassManager &MPM) { MPM.addPass(CounterPass(Counter, L1)); });
+ PB.registerAfterParsingLoopPassCallback(
+ [&](LoopPassManager &MPM) { MPM.addPass(CounterPass(Counter, L3)); });
+
+ PB.registerPipelineParsingCallback(
+ [&](StringRef Name, ModulePassManager &MPM,
+ ArrayRef<PassBuilder::PipelineElement>) {
+ if (Name == "test") {
+ MPM.addPass(CounterPass(Counter, M2));
+ return true;
+ }
+ return false;
+ });
+
+ PB.registerPipelineParsingCallback(
+ [&](StringRef Name, CGSCCPassManager &CGPM,
+ ArrayRef<PassBuilder::PipelineElement>) {
+ if (Name == "test") {
+ CGPM.addPass(CounterPass(Counter, C2));
+ return true;
+ }
+ return false;
+ });
+ PB.registerPipelineParsingCallback(
+ [&](StringRef Name, FunctionPassManager &FPM,
+ ArrayRef<PassBuilder::PipelineElement>) {
+ if (Name == "test") {
+ FPM.addPass(CounterPass(Counter, F2));
+ return true;
+ }
+ return false;
+ });
+ PB.registerPipelineParsingCallback(
+ [&](StringRef Name, LoopPassManager &LPM,
+ ArrayRef<PassBuilder::PipelineElement>) {
+ if (Name == "test") {
+ LPM.addPass(CounterPass(Counter, L2));
+ return true;
+ }
+ return false;
+ });
+
+ StringRef PipelineText = "test,cgscc(test,function(test,loop(test)))";
+ ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded())
+ << "Pipeline was: " << PipelineText;
+ PM.run(*M, AM);
+
+ ASSERT_LT(M1, M2);
+ ASSERT_LT(M2, M3);
+ ASSERT_LT(C1, C2);
+ ASSERT_LT(C2, C3);
+ ASSERT_LT(F1, F2);
+ ASSERT_LT(F2, F3);
+ ASSERT_LT(L1, L2);
+ ASSERT_LT(L2, L3);
+}
} // end anonymous namespace
static bool
parseTopLevelPipeline(ModulePassManager &MPM,
ArrayRef<PassBuilder::PipelineElement> Pipeline,
- bool VerifyEachPass, bool DebugLogging) {
+ bool DebugLogging) {
std::vector<PassBuilder::PipelineElement> FullPipeline;
StringRef FirstName = Pipeline.front().Name;
}
FPM.addPass(createFunctionToScopPassAdaptor(std::move(SPM)));
- if (VerifyEachPass)
- FPM.addPass(VerifierPass());
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
- if (VerifyEachPass)
- MPM.addPass(VerifierPass());
return true;
}