llvm.org GIT mirror llvm / 419454a
Optimize sprintf -> siprintf 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@126937 91177308-0d34-0410-b5e6-96231b3b80d8 Richard Osborne 8 years ago
4 changed file(s) with 56 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
2727
2828 /// int iprintf(const char *format, ...);
2929 iprintf,
30
31 /// int siprintf(char *str, const char *format, ...);
32 siprintf,
3033
3134 NumLibFuncs
3235 };
3030 if (T.getOS() != Triple::Darwin || T.getDarwinMajorNumber() < 9)
3131 TLI.setUnavailable(LibFunc::memset_pattern16);
3232
33 // iprintf is only available on XCore.
34 if (T.getArch() != Triple::xcore)
33 // iprintf and friends are only available on XCore.
34 if (T.getArch() != Triple::xcore) {
3535 TLI.setUnavailable(LibFunc::iprintf);
36 TLI.setUnavailable(LibFunc::siprintf);
37 }
3638 }
3739
3840
11751175 // 'sprintf' Optimizations
11761176
11771177 struct SPrintFOpt : public LibCallOptimization {
1178 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1179 // Require two fixed pointer arguments and an integer result.
1180 const FunctionType *FT = Callee->getFunctionType();
1181 if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() ||
1182 !FT->getParamType(1)->isPointerTy() ||
1183 !FT->getReturnType()->isIntegerTy())
1184 return 0;
1185
1178 Value *OptimizeFixedFormatString(Function *Callee, CallInst *CI,
1179 IRBuilder<> &B) {
11861180 // Check for a fixed format string.
11871181 std::string FormatStr;
11881182 if (!GetConstantStringInfo(CI->getArgOperand(1), FormatStr))
12401234
12411235 // The sprintf result is the unincremented number of bytes in the string.
12421236 return B.CreateIntCast(Len, CI->getType(), false);
1237 }
1238 return 0;
1239 }
1240
1241 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1242 // Require two fixed pointer arguments and an integer result.
1243 const FunctionType *FT = Callee->getFunctionType();
1244 if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() ||
1245 !FT->getParamType(1)->isPointerTy() ||
1246 !FT->getReturnType()->isIntegerTy())
1247 return 0;
1248
1249 if (Value *V = OptimizeFixedFormatString(Callee, CI, B)) {
1250 return V;
1251 }
1252
1253 // sprintf(str, format, ...) -> iprintf(str, format, ...) if no floating
1254 // point arguments.
1255 if (TLI->has(LibFunc::siprintf) && !CallHasFloatingPointArgument(CI)) {
1256 Module *M = B.GetInsertBlock()->getParent()->getParent();
1257 Constant *SIPrintFFn =
1258 M->getOrInsertFunction("siprintf", FT, Callee->getAttributes());
1259 CallInst *New = cast(CI->clone());
1260 New->setCalledFunction(SIPrintFFn);
1261 B.Insert(New);
1262 return New;
12431263 }
12441264 return 0;
12451265 }
2525 ret void
2626 }
2727
28 ; Verify sprintf with no floating point arguments is transformed to siprintf
29 define i32 @f2(i8* %p, i32 %x) nounwind {
30 entry:
31 ; CHECK: define i32 @f2
32 ; CHECK: @siprintf
33 ; CHECK: }
34 %0 = tail call i32 (i8*, i8*, ...)* @sprintf(i8 *%p, i8* getelementptr ([4 x i8]* @.str1, i32 0, i32 0), i32 %x)
35 ret i32 %0
36 }
37
38 ; Verify we don't turn this into an siprintf call
39 define i32 @f3(i8* %p, double %x) nounwind {
40 entry:
41 ; CHECK: define i32 @f3
42 ; CHECK: @sprintf
43 ; CHECK: }
44 %0 = tail call i32 (i8*, i8*, ...)* @sprintf(i8 *%p, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), double %x)
45 ret i32 %0
46 }
47
2848 declare i32 @printf(i8* nocapture, ...) nounwind
49 declare i32 @sprintf(i8* nocapture, i8* nocapture, ...) nounwind