I’d like to have an initialization and finalization step for a bunch of custom out-of-tree Function/ModulePasses. I was thinking of having a single ModulePass (call it Scheduler) that would take care of that:
// Pseudocode
struct Scheduler: ModulePass {
runOnModule(Module module) {
if (!is_relevant(module)) {
// Skip non-relevant modules
return true;
}
function_pass_1 = create_function_pass_1()
function_pass_1.doInitialization(module);
for (auto func: module.getFunctionList()) {
function_pass_1.runOnFunction(func);
}
function_pass_2 = create_function_pass_2()
function_pass_2.doInitialization(module);
for (auto func: module.getFunctionList()) {
function_pass_2.runOnFunction(func);
}
function_pass_3 = create_function_pass_3()
function_pass_3.doInitialization(module);
for (auto func: module.getFunctionList()) {
function_pass_3.runOnFunction(func);
}
Error err = run_diagnostics(module);
if (err) {
// Something bad happened
return false;
}
}
}
As you can see, some initialization and finalization relevant to specific passes is relevant here.
My question is: did LLVM solve this problem already (maybe using PassDependencies? Do they work for out-of-tree passes?)? Are there any clear drawbacks to using this approach?
Many thanks!