Search code examples
clangllvmcompiler-optimizationllvm-clang

LLVM module-level inliner `ModuleInlinerWrapperPass` usage


From reading the source code of LLVM in lib/Transforms/IPO/Inliner.cpp I found that LLVM designed the actual inliner pass as a CGSCC pass, and then there is ModuleInlinerWrapperPass that wraps around the CGSCC pass to do per-module inlining.

Peeking inside PassBuilder.cpp, I found the module-level inliner wrapper pass is typically run at the PGO-instrumentation stage (as part of the addPGOInstrPipeline pipeline), as well as the LTO stage.

I was interested in the differences between the CGSCC pass and the module-level pass and which one is scheduled earlier, so I added some LLVM_DEBUG statements to print from the initializer of the module-level pass. seems like by default opt -O2 does not run the module-level inliner; instead, it runs the CGSCC pass quite early in the optimization pipeline.

My question is: When is the module-level inliner pass run in the optimization pipeline (if ever), and what is its relationship with the CGSCC inliner pass?


Solution

  • This question boils down to the difference between the new PassManager and old PassManager in LLVM.

    Essentially, there are two ways to write a pass: either we can use the new PassManager (with pass classes extending PassInfoMixin<...>) or use the legacy PassManager (with pass classes extending ModulePass/CGSCCPass/FunctionPass...).

    The new PassManager uses the PassBuilder class to schedule passes into pipelines and then run the pipeline in the sequence it is scheduled. The ModuleInlinerWrapperPass is essentially a module-level wrapper pass in order for the new PassManager to schedule inliner into its existing module-level optimization pipeline.