I found that LLVM optimized the IR by replacing printf with puts. I wondered which pass did this optimization? And is it common that puts is faster (and some other metric) than printf? -- Thanks Thomson -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20120617/08aa6c45/attachment.html>
I think it is called simplifylibcalls or something like that. Sent from my iPhone On Jun 17, 2012, at 11:59 AM, "Thomson" <lilotom at gmail.com<mailto:lilotom at gmail.com>> wrote: I found that LLVM optimized the IR by replacing printf with puts. I wondered which pass did this optimization? And is it common that puts is faster (and some other metric) than printf? -- Thanks Thomson _______________________________________________ LLVM Developers mailing list LLVMdev at cs.uiuc.edu<mailto:LLVMdev at cs.uiuc.edu> http://llvm.cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20120617/e1933887/attachment.html>
Joerg Sonnenberger
2012-Jun-17 16:15 UTC
[LLVMdev] Which pass converts call printf to puts?
On Sun, Jun 17, 2012 at 11:58:05PM +0800, Thomson wrote:> I found that LLVM optimized the IR by replacing printf with puts. I > wondered which pass did this optimization? And is it common that puts is > faster (and some other metric) than printf?As mentioned already, it is part of the library simplification pass. puts is faster than printf, because it doesn't have to parse the input string, it only needs to compute the size. Joerg
Christoph Erhardt
2012-Jun-17 16:54 UTC
[LLVMdev] Which pass converts call printf to puts?
Hi Thomson,> I found that LLVM optimized the IR by replacing printf with puts. I > wondered which pass did this optimization? And is it common that puts > is faster (and some other metric) than printf?yes, it's safe to assume that puts() is always faster than printf() because it doesn't have to perform all the format-string parsing. Also, the implementation of puts() is a lot smaller - which might matter if the binary is linked statically and code size is important. Best regards, Christoph
Christoph Erhardt
2012-Jun-18 08:08 UTC
[LLVMdev] Which pass converts call printf to puts?
Hi Thomson, the new call to puts() is inserted right away, whereas the old call to printf() is removed a bit later in SimplifyLibCalls::runOnFunction(). If you browse the code a bit and backtrack the call stack to see what happens with the return value of PrintFOpt::OptimizeFixedFormatString(), you will stumble upon this segment in SimplifyLibCalls.cpp:1703ff.: // Try to optimize this call. Value *Result = LCO->OptimizeCall(CI, TD, TLI, Builder); if (Result == 0) continue; DEBUG(dbgs() << "SimplifyLibCalls simplified: " << *CI; dbgs() << " into: " << *Result << "\n"); // Something changed! Changed = true; ++NumSimplified; // Inspect the instruction after the call (which was potentially just // added) next. I = CI; ++I; if (CI != Result && !CI->use_empty()) { CI->replaceAllUsesWith(Result); if (!Result->hasName()) Result->takeName(CI); } CI->eraseFromParent(); Best regards, Christoph P.S. When answering, don't forget to CC the mailing list. On 18/06/2012 09:22, Thomson wrote:> Thanks for all your information. I got the pass in SimplifyLibCalls.cpp. > > I looked at the code, but am still a little confused about the IR > instruction replacement model. Use the following specific optimization > as example, it looks to me that even if a new call instruction (puts) is > created in EmitPutS, but the returned one is still the original one > (CI). So I am very curious about how the call instruction is replaced here. > > // printf("%s\n", str) --> puts(str) > if (FormatStr == "%s\n" && CI->getNumArgOperands() > 1 && > CI->getArgOperand(1)->getType()->isPointerTy()) { > EmitPutS(CI->getArgOperand(1), B, TD); > return CI; > } > > -Thomson
Ok. So it seems CI->eraseFromParent() removed the old instruction and the new one is inserted right after this one in the inner function in the case of printf->puts. There is another line CI->repalceAllUsesWith(Result). I think this line could also do the replacement besides inserting the new one in the inner function. What's the difference of these 2 replacement methods? Also thanks for your reminder of CC the mailing list. -Thomson On Mon, Jun 18, 2012 at 4:08 PM, Christoph Erhardt <christoph at sicherha.de>wrote:> Hi Thomson, > > the new call to puts() is inserted right away, whereas the old call to > printf() is removed a bit later in SimplifyLibCalls::runOnFunction(). If > you browse the code a bit and backtrack the call stack to see what > happens with the return value of PrintFOpt::OptimizeFixedFormatString(), > you will stumble upon this segment in SimplifyLibCalls.cpp:1703ff.: > > // Try to optimize this call. > Value *Result = LCO->OptimizeCall(CI, TD, TLI, Builder); > if (Result == 0) continue; > > DEBUG(dbgs() << "SimplifyLibCalls simplified: " << *CI; > dbgs() << " into: " << *Result << "\n"); > > // Something changed! > Changed = true; > ++NumSimplified; > > // Inspect the instruction after the call (which was potentially just > // added) next. > I = CI; ++I; > > if (CI != Result && !CI->use_empty()) { > CI->replaceAllUsesWith(Result); > if (!Result->hasName()) > Result->takeName(CI); > } > CI->eraseFromParent(); > > Best regards, > Christoph > > P.S. When answering, don't forget to CC the mailing list. > > On 18/06/2012 09:22, Thomson wrote: > > Thanks for all your information. I got the pass in SimplifyLibCalls.cpp. > > > > I looked at the code, but am still a little confused about the IR > > instruction replacement model. Use the following specific optimization > > as example, it looks to me that even if a new call instruction (puts) is > > created in EmitPutS, but the returned one is still the original one > > (CI). So I am very curious about how the call instruction is replaced > here. > > > > // printf("%s\n", str) --> puts(str) > > if (FormatStr == "%s\n" && CI->getNumArgOperands() > 1 && > > CI->getArgOperand(1)->getType()->isPointerTy()) { > > EmitPutS(CI->getArgOperand(1), B, TD); > > return CI; > > } > > > > -Thomson >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20120618/6505dcc2/attachment.html>