A declaration inserted in doInitialization is cleaned up in
GlobalOptLegacyPass::runOnModule, which happens to run before my pass'
runOnFunction().
Do I need a ModulePass for this?
I see two possible solutions:
1. Inform the GlobalOptLegacyPass that it should not remove the function when you add it in doInitialization(). I believe adding the function to the llvm.used or llvm.compiler.used array will prevent the function from being removed. Skim the LLVM Language Reference Manual to see how to do this (http://llvm.org/docs/LangRef.html#the-llvm-compiler-used-global-variable)
I think the documentation is wrong. Existing function passes frequently insert new intrinsic function declarations, and we expect that to work. The loop vectorizer also inserts calls to non-intrinsic library functions.
The intention is that function passes don’t introduce new function definitions, because then an outer pass manager would need to discover them and add them to its worklist.