[LLVMdev] (Possibly buggy?) doFinalization method behavior of FunctionPass

Kuperstein, Michael M michael.m.kuperstein at intel.com
Sun May 10 22:49:15 PDT 2015


From: Cristianno Martins [mailto:cristiannomartins at gmail.com]
Sent: Thursday, May 07, 2015 21:10
To: Kuperstein, Michael M
Cc: John Criswell; Lista LLVM-dev
Subject: Re: [LLVMdev] (Possibly buggy?) doFinalization method behavior of FunctionPass

Well, to be fair, the main idea of having FunctionPasses in the first place is that (please, correct me if I'm mistaken) opt could be running different passes on different functions at the same time, so the compilation process could be sped up. I know the parallel part of this is not yet implemented on LLVM, but I think I can assume that my pass is going to work on a function, and other passes will work over the same function after mine, even before my pass can start again its work over the next function. In a way, doesn't it mean that my pass keeps "half-baking" its work one function at a time until it finishes all of them for a given module?

As long as the pass’s modifications for each function don’t depend on modifications made to another function, that function is “fully-baked”. :-)
And if these modifications do depend on what you do to another function, then I’d suggest the pass should be a ModulePass.

This is actually why I think doFinalization should have a different perspective between Module and "TheRestOfThe"-Passes: given that a module is the basic unit of compilation for opt, doFinalization is going to be called as many times as runOnModule for every module you try to transform/analyze on a ModulePass. This is not true for FunctionPass, for example: if I have to do some work only once, and preferably after finishing with all functions, I would have to insert some if clause into my runOnFunction that checks a counter of functions and would effectively run only if I already ran NumberOfFunctionsWithoutConsideringDefinitions times -- which is hardly a good programming method. Besides, if what I assumed above is really true (that there is no guarantee that your FunctionPass finishes with the module before other FunctionPasses run over some of the functions), even this strategy is worthless: the code could be changed by other passes between the first and last execution of my pass runOnFunction =/

That’s exactly my point – if you have to do some work only once, and that work has module-wide impact (as opposed to function-wide), then I believe you ought to be using a ModulePass. Yes, this imposes a constraint on scheduling that’s probably stronger than you want, but I don’t think there’s a way to express “run my pass over functions in parallel (in theory), then run another part of it over the module, but make sure nothing bad happens in between”.

a. AsmPrinter: a MachineFunctionPass who's doFinalization is defined at line 1004 of lib/CodeGen/AsmPrinter.cpp
b. Inliner: a CallGraphSCCPass, having doFinalization defined at lib/Transforms/IPO/Inliner.cpp:621
c. BBPassManager: a FunctionPass, at lib/IR/LegacyPassManager.cpp:1344
d. FunctionPassManager: a Pass, at lib/IR/LegacyPassManager.cpp:1441

(a) is not an IR-to-IR pass. It only reads the module to generate output, it doesn’t actually write to the module.
(c) and (d) are part of the PassManager infrastructure, and can make assumptions about ordering that a regular pass shouldn’t. And, in any case, the only thing they seem to do with the module/function they get is to pass it on to the doFinalization() methods of their contained passes.
(b) seems to be the only real example of this in-tree, and it’s insanely old code by LLVM standards (written by Chris in 2004). So, perhaps, originally this is the way it was meant to work. But I’m fairly certain this is not a preferred practice today.
Again, I’d really appreciate it if anyone with more in-depth knowledge of the infrastructure could comment.


On the other hand, assuming the documentation is actually wrong, and doFinalization shouldn't be allowed to change the module, I still couldn't see why exactly doFinalization functions have a Module& as argument (at least the FunctionPass one), or a boolean return type for that matter; in other words, I would guess the signature of this function is wrongly defined anyways.

cheers,

--
Cristianno Martins
PhD Student of Computer Science
University of Campinas
cmartins at ic.unicamp.br<mailto:cmartins at ic.unicamp.br>


---------------------------------------------------------------------
Intel Israel (74) Limited

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150511/1447af49/attachment.html>


More information about the llvm-dev mailing list