reusing FunctionPassManager with different Modules

Hi,

Is it generally safe to cache a FunctionPassManager and reuse it on modules other than the one it was constructed with (assuming they have the same target triple)?

paul

No. FunctionPass has a pair of methods, doInitialization and doFinalization, which take Module& and are allowed to read or modify it outside runOnFunction.

Nick

Thanks.

The reason I ask is because I'm looking at some code that does just that. A single FunctionPassManager is constructed with a dummy Module and createStandardFunctionPasses is called on it. The FunctionPassManager cached and run on Functions in other Modules. So far I haven't noticed any problems but I guess that is because the passes added by createStandardFunctionPasses don't touch the Module.

paul

Thanks.

The reason I ask is because I'm looking at some code that does just that. A single FunctionPassManager is constructed with a dummy Module and createStandardFunctionPasses is called on it. The FunctionPassManager cached and run on Functions in other Modules. So far I haven't noticed any problems but I guess that is because the passes added by createStandardFunctionPasses don't touch the Module.

Right, don't do that. There aren't many passes that do anything at all with doInitialization/doFinalization, but:
  - the inliner uses it to initialize the set of noinline functions from llvm.noinline
  - the inliner uses it to clean up dead functions after inlining
  - SimplifyLibCalls adds missing function attributes to "well-known" (ie. standardized) functions
  - LowerInvoke uses it to create a linked list of jmpbuf and ensure that the Module has an abort() function to call

So you might not notice the problem, but it may harm you in subtle ways. (And even if it doesn't now, LLVM is patient and may try again tomorrow.)

If the time to construct the FPM is a problem, please quantify it and file a bug for that.

Nick