llvm.org GIT mirror llvm / 3649824
Optimize printf -> iprintf if there are no floating point arguments and iprintf is available on the target. Currently iprintf is only marked as being available on the XCore. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@126935 91177308-0d34-0410-b5e6-96231b3b80d8 Richard Osborne 8 years ago
4 changed file(s) with 78 addition(s) and 11 deletion(s). Raw diff Collapse all Expand all
2424
2525 /// void memset_pattern16(void *b, const void *pattern16, size_t len);
2626 memset_pattern16,
27
28 /// int iprintf(const char *format, ...);
29 iprintf,
2730
2831 NumLibFuncs
2932 };
2929 // memset_pattern16 is only available on iOS 3.0 and Mac OS/X 10.5 and later.
3030 if (T.getOS() != Triple::Darwin || T.getDarwinMajorNumber() < 9)
3131 TLI.setUnavailable(LibFunc::memset_pattern16);
32
32
33 // iprintf is only available on XCore.
34 if (T.getArch() != Triple::xcore)
35 TLI.setUnavailable(LibFunc::iprintf);
3336 }
3437
3538
4848 protected:
4949 Function *Caller;
5050 const TargetData *TD;
51 const TargetLibraryInfo *TLI;
5152 LLVMContext* Context;
5253 public:
5354 LibCallOptimization() { }
6162 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B)
6263 =0;
6364
64 Value *OptimizeCall(CallInst *CI, const TargetData *TD, IRBuilder<> &B) {
65 Value *OptimizeCall(CallInst *CI, const TargetData *TD,
66 const TargetLibraryInfo *TLI, IRBuilder<> &B) {
6567 Caller = CI->getParent()->getParent();
6668 this->TD = TD;
69 this->TLI = TLI;
6770 if (CI->getCalledFunction())
6871 Context = &CI->getCalledFunction()->getContext();
6972
9598 return false;
9699 }
97100 return true;
101 }
102
103 static bool CallHasFloatingPointArgument(const CallInst *CI) {
104 for (CallInst::const_op_iterator it = CI->op_begin(), e = CI->op_end();
105 it != e; ++it) {
106 if ((*it)->getType()->isFloatingPointTy())
107 return true;
108 }
109 return false;
98110 }
99111
100112 /// IsOnlyUsedInEqualityComparison - Return true if it is only used in equality
10741086 // 'printf' Optimizations
10751087
10761088 struct PrintFOpt : public LibCallOptimization {
1077 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1078 // Require one fixed pointer argument and an integer/void result.
1079 const FunctionType *FT = Callee->getFunctionType();
1080 if (FT->getNumParams() < 1 || !FT->getParamType(0)->isPointerTy() ||
1081 !(FT->getReturnType()->isIntegerTy() ||
1082 FT->getReturnType()->isVoidTy()))
1083 return 0;
1084
1089 Value *OptimizeFixedFormatString(Function *Callee, CallInst *CI,
1090 IRBuilder<> &B) {
10851091 // Check for a fixed format string.
10861092 std::string FormatStr;
10871093 if (!GetConstantStringInfo(CI->getArgOperand(0), FormatStr))
11341140 CI->getArgOperand(1)->getType()->isPointerTy()) {
11351141 EmitPutS(CI->getArgOperand(1), B, TD);
11361142 return CI;
1143 }
1144 return 0;
1145 }
1146
1147 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1148 // Require one fixed pointer argument and an integer/void result.
1149 const FunctionType *FT = Callee->getFunctionType();
1150 if (FT->getNumParams() < 1 || !FT->getParamType(0)->isPointerTy() ||
1151 !(FT->getReturnType()->isIntegerTy() ||
1152 FT->getReturnType()->isVoidTy()))
1153 return 0;
1154
1155 if (Value *V = OptimizeFixedFormatString(Callee, CI, B)) {
1156 return V;
1157 }
1158
1159 // printf(format, ...) -> iprintf(format, ...) if no floating point
1160 // arguments.
1161 if (TLI->has(LibFunc::iprintf) && !CallHasFloatingPointArgument(CI)) {
1162 Module *M = B.GetInsertBlock()->getParent()->getParent();
1163 Constant *IPrintFFn =
1164 M->getOrInsertFunction("iprintf", FT, Callee->getAttributes());
1165 CallInst *New = cast(CI->clone());
1166 New->setCalledFunction(IPrintFFn);
1167 B.Insert(New);
1168 return New;
11371169 }
11381170 return 0;
11391171 }
15441576 Builder.SetInsertPoint(BB, I);
15451577
15461578 // Try to optimize this call.
1547 Value *Result = LCO->OptimizeCall(CI, TD, Builder);
1579 Value *Result = LCO->OptimizeCall(CI, TD, TLI, Builder);
15481580 if (Result == 0) continue;
15491581
15501582 DEBUG(dbgs() << "SimplifyLibCalls simplified: " << *CI;
0 ; RUN: opt < %s -simplify-libcalls -S -o %t
1 ; RUN: FileCheck < %t %s
2 target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:32"
3 target triple = "xcore-xmos-elf"
4
5 @.str = internal constant [4 x i8] c"%f\0A\00" ; <[4 x i8]*> [#uses=1]
6 @.str1 = internal constant [4 x i8] c"%d\0A\00" ; <[4 x i8]*> [#uses=1]
7
8 ; Verify printf with no floating point arguments is transformed to iprintf
9 define i32 @f0(i32 %x) nounwind {
10 entry:
11 ; CHECK: define i32 @f0
12 ; CHECK: @iprintf
13 ; CHECK: }
14 %0 = tail call i32 (i8*, ...)* @printf(i8* getelementptr ([4 x i8]* @.str1, i32 0, i32 0), i32 %x) ; [#uses=0]
15 ret i32 %0
16 }
17
18 ; Verify we don't turn this into an iprintf call
19 define void @f1(double %x) nounwind {
20 entry:
21 ; CHECK: define void @f1
22 ; CHECK: @printf
23 ; CHECK: }
24 %0 = tail call i32 (i8*, ...)* @printf(i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), double %x) nounwind ; [#uses=0]
25 ret void
26 }
27
28 declare i32 @printf(i8* nocapture, ...) nounwind