I'm aware of similar questions here and here, however, the LLVM codebase changes so quickly I'm here to ask if the state of things have changed since then.
So, currently I'm trying to write an out-of-tree pass that works on the whole program CFG (hence the need for the merged bitcode). I would prefer to use the legacy PassManager
as opposed to the Mixin-based NPM due to some other legacy passes my current pass relies on.
clang is called with these args:
clang -flto -Xclang -O0 -Xclang -load -Xclang ./mvxaa.so -fuse-ld=gold -o ./tests/target_app $(TARGET_SOURCES)
Will this register the pass as an LTO (full) pass? The pass never runs.
static void registerGlobalCollectionPass(const PassManagerBuilder &PB,
legacy::PassManagerBase &PM) {
PM.add(new CollectGlobals());
}
static RegisterStandardPasses
RegisterMyPass(PassManagerBuilder::EP_FullLinkTimeOptimizationEarly,
registerGlobalCollectionPass);
Looking deeper, it seems that PassManagerBuilder::addExtensionsToPM
is called by the individual populateXPassManager
functions and they will look through the GlobalExtensions
list to call the respective callback functions. For other non-LTO ExtensionPointTy
like EP_EnabledOnOptLevel0
there are entries, but when populateLTOPassManager
is called, there are no longer any entries in the GlobalExtensions
smallvector. Why is this the case?
Is it because LTO occurs at a later point after the linker runs and the -load argument given to dlopen the shared libraries only loads the shared objects at the compilation phase?