<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Mar 7, 2016, at 5:01 PM, Mehdi Amini <<a href="mailto:mehdi.amini@apple.com" class="">mehdi.amini@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class=""><br class=""><blockquote type="cite" class="">On Mar 7, 2016, at 4:44 PM, Pete Cooper <<a href="mailto:peter_cooper@apple.com" class="">peter_cooper@apple.com</a>> wrote:<br class=""><br class="">Hi all<br class=""><br class="">After codegen for a given function, the IR should no longer be needed. In the AsmPrinter we convert from MI->MCInstr, and then we never go back and look at the IR during the MC layer.<br class=""><br class="">I’ve prototyped a simple pass which can be (optionally) scheduled to do just this. It is added at the end of addPassesToEmitFile. It is optional so that clang can continue to leak the IR with --disable-free, but i would propose that all other tools, and especially LTO, would enable it. The savings are 20% of peak memory in LTO of clang itself.<br class=""></blockquote><br class="">I think such a pass is worth it. <br class="">I see a conceptual issue with it though, it would have to be FunctionPass, and such pass are not allowed to delete globals and Functions (see <a href="http://llvm.org/docs/WritingAnLLVMPass.html#the-functionpass-class" class="">http://llvm.org/docs/WritingAnLLVMPass.html#the-functionpass-class</a> ).<br class=""></div></div></blockquote>Ah, yeah this is tricky. So my pass isn’t deleting the function value, but it is deleting all the BBs/Instrs inside. When you read the IR it actually prints it as a declaration because the AsmWriter thinks that no body implies a declaration.</div><div><br class=""></div><div>One issue this this is that FPPassManager::runOnFunction starts by checking for declarations and skipping them. So that means that if a function pass was to run after my pass, then it would get a function with no body which is not what it expects.</div><div><br class=""></div><div>One option I considered was to replace the function body with a single BB and an unreachable/return, but I didn’t want to create useless IR.<br class=""><blockquote type="cite" class=""><div class=""><div class="">That said the CodeGen could be made a CallGraphSCCPass (which is something we thought about investigating to help register allocation at call site when you have already CodeGen the callee and can infer what is preserved). I'm not sure your feature alone justify such a change though.<br class=""></div></div></blockquote>I would certainly like to see CodeGen work this way. If my work requires it then I have no problem with it, but i’d love to land my changes without this if its possible, just in case its troublesome to make this change.<br class=""><blockquote type="cite" class=""><div class=""><div class=""><br class="">Out of curiosity, how do you expose it to the client by the way:<br class=""><br class="">Target->addPassesToEmitFile(PM, ....)<br class="">if (deleteFunctionAfterCodeGen)<br class=""><span class="Apple-tab-span" style="white-space:pre"> </span>PM.addPass(createFunctionDeletionPass())<br class="">or <br class=""><br class="">Target->addPassesToEmitFile(PM, ...., deleteFunctionAfterCodeGen);<br class=""></div></div></blockquote>The above. The specific lines I changed on the function prototype are this, which means that I’m opting everyone in to my change, but then as I said we’d probably change clang to propagate its DisableFree flag in here:</div><div><br class=""></div><div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">virtual bool addPassesToEmitFile(</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> PassManagerBase &, raw_pwrite_stream &, CodeGenFileType,</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(195, 55, 32);" class="">- bool /*DisableVerify*/ = true, AnalysisID /*StartBefore*/ = nullptr,</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(52, 189, 38);" class="">+ bool /*DisableVerify*/ = true, bool /*FreeFunctionIR*/ = true,</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(52, 189, 38);" class="">+ AnalysisID /*StartBefore*/ = nullptr,</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> AnalysisID /*StartAfter*/ = nullptr, AnalysisID /*StopAfter*/ = nullptr,</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> MachineFunctionInitializer * /*MFInitializer*/ = nullptr)</div></div><div><br class=""></div><div>Cheers,</div><div>Pete<br class=""><blockquote type="cite" class=""><div class=""><div class=""><br class="">-- <br class="">Mehdi<br class=""><br class=""><br class=""><br class=""><blockquote type="cite" class=""><br class="">I could attach a patch, but first i’d really like to know if anyone is fundamentally opposed to this.<br class=""><br class="">I should note, a couple of issues have come up in the prototype.<br class="">- llvm::getDISubprogram was walking the function body to find the subprogram. This is trivial to fix as functions now have !dbg on them.<br class="">- The AsmPrinter is calling canBeOmittedFromSymbolTable on GlobalValue’s which then walks all their uses. I think this should be done earlier in codegen as an analysis whose results are available to the AsmPrinter.<br class="">- BB’s whose addresses are taken, i.e. jump tables, can’t be deleted. Those functions will just keep their IR around so no changes there.<br class=""><br class="">With the above issues fixed, I can run make check and pass all the tests.<br class=""><br class="">Comments very welcome.<br class=""><br class="">Cheers,<br class="">Pete<br class=""></blockquote><br class=""></div></div></blockquote></div><br class=""></body></html>