Noticed PassManager::addPass
has an overload for pass manager to merge two same type pass managers, I’m wondering if we could do something like:
class TargetPassBuilder {
protected:
// Or shadow `PassManager`s and related `createXXXPassAdaptor`s
class ModulePassManagerWrapper {
public:
template<typename PassT>
std::enable_if_t<isNotModulePassManagerWrapper>
addPass(PassT &&P) {
static_assert(/* not pass manager or adaptor */);
PassNames.push_back(PassT::name());
PassManagers.push_back(ModulePassManager()
.addPass(std::forward<PassT>(P)));
}
template<typename PassT>
std::enable_if_t<isModulePassManagerWrapper>
addPass(PassT &&P) { /* merge two wrapper */}
void addFunctionPassManagerWrapper(FunctionPassManagerWrapper &&FPMW) {...}
private:
std::vector<StringRef> PassNames;
std::vector<std::variant<ModulePassManager, FunctionPassManager,
LoopPassManager, MachineFunctionPassManager>> PassManagers;
};
ModulePassManagerWrapper MainWrapper;
public:
ModulePassManager buildPipeline() {
ModulePassManagerWrapper MPMW;
// Do pipeline construction.
...
// Filter passes with MPMW because we have all pass names in order.
// Construct PassManager from MPMW manually,
// pass manager will merge pass manager automatically in `addPass`.
}
};
Users must do:
void TargetPassBuilder::buildSomePart() {
ModulePassManagerWrapper MPMW;
MPMW.addPass(Pass1);
MPMW.addPass(Pass2);
FunctionPassManagerWrapper FPMW;
FPMW.addPass(Pass1);
FPMW.addPass(Pass1);
MPWM.addFunctionPassWrapper(std::move(FPMW));
// Same for LoopPassManagerWrapper and MachineFunctionPassManagerWrapper.
MainWrapper.addPass(std::move(MPMW));
}
Then we can both filter the pipeline and force user concerning pass nesting explicitly.
We need a very flexible way to extend pass pipeline, we may introduce many extension points to emulate virtual functions in TargetPassConfig
. I considered methods like inject{Before,After}<SomePass>(...)
but it seems a bit too flexible.
Miscellaneous:
Currently codegen pipeline use its own optimization level implementation and it is overlapped with "llvm/Passes/OptimizationLevel.h"
, should we standardize on using OptimizationLevel
?
Ping @aeubanks