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>
Christoph Erhardt
2012-Jun-18 11:31 UTC
[LLVMdev] Which pass converts call printf to puts?
Hi 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?whenever an instruction is replaced, all other instructions that use its result (as an input operand) have to be told to use the result of the new instruction instead. That's what CI->replaceAllUsesWith(Result) does. Only then can the old instruction be removed from the basic block. Best regards, Christoph
Could you give an example of the old instruction cannot be removed safely? Since the new instruction would produce the same context/result of the old one, I suppose it is safe to remove the old one when the new instruction is ready (inserted after the old one). Anything I missed here? Thanks, -Thomson On Mon, Jun 18, 2012 at 7:31 PM, Christoph Erhardt <christoph at sicherha.de>wrote:> Hi 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? > whenever an instruction is replaced, all other instructions that use its > result (as an input operand) have to be told to use the result of the > new instruction instead. That's what CI->replaceAllUsesWith(Result) > does. Only then can the old instruction be removed from the basic block. > > Best regards, > Christoph >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20120618/f993ef47/attachment.html>