[LLVMdev] Which pass converts call printf to puts?

Christoph Erhardt christoph at sicherha.de
Mon Jun 18 01:08:41 PDT 2012


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



More information about the llvm-dev mailing list