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?