<div dir="ltr">Hi again,<div><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:'Times New Roman',serif"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">I think it’s wrongly documented. :-)</span></p></div></blockquote><div><br></div>It could be, and I guess it probably is, but as I'm going to discuss below, it should be interesting to have some function that bears this documented doFinalization behavior =)<div><span style="color:rgb(31,73,125);font-family:Calibri,sans-serif;font-size:11pt"> </span><br><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:'Times New Roman',serif"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">As a side note, I believe requiring transformation passes (as opposed to requiring analysis passes) is also not-quite-supported.</span></p></div></blockquote><div><div><br></div><div>I didn't know about that XD, and I think it makes sense (I don't even have to call getAnalysis from inside my FunctionPass, since I don't really mind at all about any data flowing from the ModulePass), but it apparently worked =/ I know I could just invoke both transformations from command line (just by adding a different cmd option to opt), but, idk, it sounded kind of weird having to write something like:</div></div></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div><div>opt -load MyPasses.dylib -myPass -myPass_Extras <...></div></div></div></blockquote><div><div>since I always HAD TO have both being enabled together anyways.</div><div><br></div></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:'Times New Roman',serif;color:black"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">It’s not just a question of other passes changing the module between your runOnFunction()-s and your doFinalization().</span></p></div></div><div><p class="MsoNormal" style="margin:0cm 0cm 0.0001pt;font-size:12pt;font-family:'Times New Roman',serif;color:black"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">In theory, you may also have something like code-generation (or something else with non-IR output) in the same PassManager as your pass. In this case, doFinalization() will run too late for it to matter. So leaving a module in a “half-baked” state until after doFinalization() runs seems ill-advised to me.</span></p></div></blockquote><div class="gmail_extra"><br clear="all"><div><div class="gmail_signature">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?</div><div class="gmail_signature"><br></div><div class="gmail_signature">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 =/</div><div class="gmail_signature"><br></div><div class="gmail_signature">Ok, but just for me not to be here only blabbing about "if we need to do this only once"-case, I've looked into LLVM's code and found some implementations of doFinalization that actually could hope the modifications would be applied:</div><div class="gmail_signature"><br></div><div class="gmail_signature">a. AsmPrinter: a MachineFunctionPass who's doFinalization is defined at line 1004 of lib/CodeGen/AsmPrinter.cpp</div><div class="gmail_signature">b. Inliner: a CallGraphSCCPass, having doFinalization defined at lib/Transforms/IPO/Inliner.cpp:621</div><div class="gmail_signature">c. BBPassManager: a FunctionPass, at lib/IR/LegacyPassManager.cpp:1344</div><div class="gmail_signature">d. FunctionPassManager: a Pass, at lib/IR/LegacyPassManager.cpp:1441</div><div class="gmail_signature"><br></div><div class="gmail_signature">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.</div><div class="gmail_signature"><br></div><div class="gmail_signature">cheers,</div><div class="gmail_signature"><br>--<br>Cristianno Martins<br>PhD Student of Computer Science<br>University of Campinas<br><a href="mailto:cmartins@ic.unicamp.br" target="_blank">cmartins@ic.unicamp.br</a></div></div></div></div>