I wonder in what cases FunctionPass is better that Pass. For example, addPassesToEmitAssembly takes PassManger and addPassesToJITCompile takes FunctionPassManager. Another question is about FunctionPassManager::run(Function&) and FunctionPass(Function&). The former calls the later, which is fine, but the latter looks like this: bool FunctionPass::run(Function &F) { if (F.isExternal()) return false;// Passes are not run on external functions! return doInitialization(*F.getParent()) | runOnFunction(F) | doFinalization(*F.getParent()); } So, with FunctionPassManager, doInitializaton will be called once for each function, which is strange, given that that method takes Module&. When this behaviour is desirable? - Volodya
----- Original Message ----- From: "Vladimir Prus" <ghost at cs.msu.su> To: <llvmdev at cs.uiuc.edu> Sent: Thursday, June 24, 2004 8:37 AM Subject: [LLVMdev] Pass vs. FunctionPass> > I wonder in what cases FunctionPass is better that Pass. For example, > addPassesToEmitAssembly takes PassManger and addPassesToJITCompile takes > FunctionPassManager.It's just better from a software engineering perspective to use FunctionPass if you are doing things on the global (function) level rather than the module level. Also it allows passes to be scheduled in order on functions rather than whole modules.> Another question is about FunctionPassManager::run(Function&) and > FunctionPass(Function&). The former calls the later, which is fine, butthe> latter looks like this: > > bool FunctionPass::run(Function &F) { > if (F.isExternal()) return false;// Passes are not run on external > functions! > > return doInitialization(*F.getParent()) | runOnFunction(F) > | doFinalization(*F.getParent()); > } > > So, with FunctionPassManager, doInitializaton will be called once for each > function, which is strange, given that that method takes Module&. Whenthis> behaviour is desirable?I never looked at this code before. That explains why I've had issues with doFinalization before, because I always assumed it only ran once per module myself. It seems undesirable to me because not only is this a little counter intuitive, but it also repeats work that need only be done once. But maybe there is a good reason for this?> - Volodya > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev
On Thu, 24 Jun 2004, Vladimir Prus wrote:> I wonder in what cases FunctionPass is better that Pass. For example, > addPassesToEmitAssembly takes PassManger and addPassesToJITCompile takes > FunctionPassManager.Here's a simple way to look at it. Use a Function pass whenever you can. A function pass will always work where a Pass works (it derives from pass as you've noticed), but not the other way around. In particular, there are *strict* rules that must be followed by FunctionPass's, described in the HowToWriteAPass document. Like Patrick mentioned, these allow the pass manager to optimize the execution of passes on a module, and eventually will allow us to compile functions in parallel on different threads at the same time.> Another question is about FunctionPassManager::run(Function&) and > FunctionPass(Function&). The former calls the later, which is fine, but the > latter looks like this: > > bool FunctionPass::run(Function &F) { > if (F.isExternal()) return false;// Passes are not run on external > functions! > > return doInitialization(*F.getParent()) | runOnFunction(F) > | doFinalization(*F.getParent()); > } > > So, with FunctionPassManager, doInitializaton will be called once for > each function, which is strange, given that that method takes Module&. > When this behaviour is desirable?That *is* odd, I've never noticed that code before. I think that the FunctionPassManager is only used by the JIT. For normal optimization and static compiles, you will get a doInitialization once at the beginning of the module, a whole bunch of runOnFunctions, and a doFinalization call at the end (as you would expect). I'm not sure what the right semantics are in the JIT using the functionpassmanager. In any case your code should work correctly (because it is a function pass) it's a performance thing. What do you need to do in your doInit/finalize calls for codegeneration? -Chris -- http://llvm.cs.uiuc.edu/ http://www.nondot.org/~sabre/Projects/
----- Original Message ----- From: "Chris Lattner" <sabre at nondot.org> To: <llvmdev at cs.uiuc.edu> Sent: Thursday, June 24, 2004 1:23 PM Subject: Re: [LLVMdev] Pass vs. FunctionPass> On Thu, 24 Jun 2004, Vladimir Prus wrote: > > > I wonder in what cases FunctionPass is better that Pass. For example, > > addPassesToEmitAssembly takes PassManger and addPassesToJITCompile takes > > FunctionPassManager. > > Here's a simple way to look at it. Use a Function pass whenever you can. > A function pass will always work where a Pass works (it derives from pass > as you've noticed), but not the other way around. > > In particular, there are *strict* rules that must be followed by > FunctionPass's, described in the HowToWriteAPass document. Like Patrick > mentioned, these allow the pass manager to optimize the execution of > passes on a module, and eventually will allow us to compile functions in > parallel on different threads at the same time.One thing I was just thinking is that at some future date one may be able to specify which functions to run specific function passes on (leaving off costly optimizations on functions you know it will have little effect on and some such, especially optimizations that require heavy analysis). This would be especially useful in some kind of system that runs a bunch of passes and tests the output for speed (in large numbers, guided by some kind of search algorithm, though it would greatly increase the size of the search space).> > Another question is about FunctionPassManager::run(Function&) and > > FunctionPass(Function&). The former calls the later, which is fine, butthe> > latter looks like this: > > > > bool FunctionPass::run(Function &F) { > > if (F.isExternal()) return false;// Passes are not run on external > > functions! > > > > return doInitialization(*F.getParent()) | runOnFunction(F) > > | doFinalization(*F.getParent()); > > } > > > > So, with FunctionPassManager, doInitializaton will be called once for > > each function, which is strange, given that that method takes Module&. > > When this behaviour is desirable? > > That *is* odd, I've never noticed that code before. I think that the > FunctionPassManager is only used by the JIT. For normal optimization and > static compiles, you will get a doInitialization once at the beginning of > the module, a whole bunch of runOnFunctions, and a doFinalization call at > the end (as you would expect). > > I'm not sure what the right semantics are in the JIT using the > functionpassmanager. In any case your code should work correctly (because > it is a function pass) it's a performance thing. What do you need to do > in your doInit/finalize calls for codegeneration? > > -Chris > > -- > http://llvm.cs.uiuc.edu/ > http://www.nondot.org/~sabre/Projects/ > > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev