llvm.org GIT mirror llvm / 022708f
Optimize fprintf -> iprintf if there are no floating point arguments and siprintf is available on the target. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@126940 91177308-0d34-0410-b5e6-96231b3b80d8 Richard Osborne 8 years ago
4 changed file(s) with 53 addition(s) and 8 deletion(s). Raw diff Collapse all Expand all
3030
3131 /// int siprintf(char *str, const char *format, ...);
3232 siprintf,
33
34 /// int fiprintf(FILE *stream, const char *format, ...);
35 fiprintf,
3336
3437 NumLibFuncs
3538 };
3434 if (T.getArch() != Triple::xcore) {
3535 TLI.setUnavailable(LibFunc::iprintf);
3636 TLI.setUnavailable(LibFunc::siprintf);
37 TLI.setUnavailable(LibFunc::fiprintf);
3738 }
3839 }
3940
13291329 // 'fprintf' Optimizations
13301330
13311331 struct FPrintFOpt : public LibCallOptimization {
1332 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1333 // Require two fixed paramters as pointers and integer result.
1334 const FunctionType *FT = Callee->getFunctionType();
1335 if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() ||
1336 !FT->getParamType(1)->isPointerTy() ||
1337 !FT->getReturnType()->isIntegerTy())
1338 return 0;
1339
1332 Value *OptimizeFixedFormatString(Function *Callee, CallInst *CI,
1333 IRBuilder<> &B) {
13401334 // All the optimizations depend on the format string.
13411335 std::string FormatStr;
13421336 if (!GetConstantStringInfo(CI->getArgOperand(1), FormatStr))
13781372 return 0;
13791373 EmitFPutS(CI->getArgOperand(2), CI->getArgOperand(0), B, TD);
13801374 return CI;
1375 }
1376 return 0;
1377 }
1378
1379 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1380 // Require two fixed paramters as pointers and integer result.
1381 const FunctionType *FT = Callee->getFunctionType();
1382 if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() ||
1383 !FT->getParamType(1)->isPointerTy() ||
1384 !FT->getReturnType()->isIntegerTy())
1385 return 0;
1386
1387 if (Value *V = OptimizeFixedFormatString(Callee, CI, B)) {
1388 return V;
1389 }
1390
1391 // fprintf(stream, format, ...) -> fiprintf(stream, format, ...) if no
1392 // floating point arguments.
1393 if (TLI->has(LibFunc::fiprintf) && !CallHasFloatingPointArgument(CI)) {
1394 Module *M = B.GetInsertBlock()->getParent()->getParent();
1395 Constant *FIPrintFFn =
1396 M->getOrInsertFunction("fiprintf", FT, Callee->getAttributes());
1397 CallInst *New = cast(CI->clone());
1398 New->setCalledFunction(FIPrintFFn);
1399 B.Insert(New);
1400 return New;
13811401 }
13821402 return 0;
13831403 }
4545 ret i32 %0
4646 }
4747
48 ; Verify fprintf with no floating point arguments is transformed to fiprintf
49 define i32 @f4(i8* %p, i32 %x) nounwind {
50 entry:
51 ; CHECK: define i32 @f4
52 ; CHECK: @fiprintf
53 ; CHECK: }
54 %0 = tail call i32 (i8*, i8*, ...)* @fprintf(i8 *%p, i8* getelementptr ([4 x i8]* @.str1, i32 0, i32 0), i32 %x)
55 ret i32 %0
56 }
57
58 ; Verify we don't turn this into an fiprintf call
59 define i32 @f5(i8* %p, double %x) nounwind {
60 entry:
61 ; CHECK: define i32 @f5
62 ; CHECK: @fprintf
63 ; CHECK: }
64 %0 = tail call i32 (i8*, i8*, ...)* @fprintf(i8 *%p, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), double %x)
65 ret i32 %0
66 }
67
4868 declare i32 @printf(i8* nocapture, ...) nounwind
4969 declare i32 @sprintf(i8* nocapture, i8* nocapture, ...) nounwind
70 declare i32 @fprintf(i8* nocapture, i8* nocapture, ...) nounwind