diff --git a/llvm/lib/Transforms/Scalar/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Scalar/SimplifyLibCalls.cpp index 68a3fb609350..e186601505c2 100644 --- a/llvm/lib/Transforms/Scalar/SimplifyLibCalls.cpp +++ b/llvm/lib/Transforms/Scalar/SimplifyLibCalls.cpp @@ -57,9 +57,9 @@ public: /// performed. If it returns CI, then it transformed the call and CI is to be /// deleted. If it returns something else, replace CI with the new value and /// delete CI. - virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) + virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) =0; - + Value *OptimizeCall(CallInst *CI, const TargetData *TD, IRBuilder<> &B) { Caller = CI->getParent()->getParent(); this->TD = TD; @@ -75,12 +75,12 @@ public: /// specified pointer. Ptr is required to be some pointer type, and the /// return value has 'intptr_t' type. Value *EmitStrLen(Value *Ptr, IRBuilder<> &B); - + /// EmitMemCpy - Emit a call to the memcpy function to the builder. This /// always expects that the size has type 'intptr_t' and Dst/Src are pointers. - Value *EmitMemCpy(Value *Dst, Value *Src, Value *Len, + Value *EmitMemCpy(Value *Dst, Value *Src, Value *Len, unsigned Align, IRBuilder<> &B); - + /// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is /// a pointer, Val is an i32 value, and Len is an 'intptr_t' value. Value *EmitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B); @@ -97,27 +97,27 @@ public: /// is added as the suffix of name, if 'Op' is a float, we add a 'f' suffix. Value *EmitUnaryFloatFnCall(Value *Op, const char *Name, IRBuilder<> &B, const AttrListPtr &Attrs); - + /// EmitPutChar - Emit a call to the putchar function. This assumes that Char /// is an integer. void EmitPutChar(Value *Char, IRBuilder<> &B); - + /// EmitPutS - Emit a call to the puts function. This assumes that Str is /// some pointer. void EmitPutS(Value *Str, IRBuilder<> &B); - + /// EmitFPutC - Emit a call to the fputc function. This assumes that Char is /// an i32, and File is a pointer to FILE. void EmitFPutC(Value *Char, Value *File, IRBuilder<> &B); - + /// EmitFPutS - Emit a call to the puts function. Str is required to be a /// pointer and File is a pointer to FILE. void EmitFPutS(Value *Str, Value *File, IRBuilder<> &B); - + /// EmitFWrite - Emit a call to the fwrite function. This assumes that Ptr is /// a pointer, Size is an 'intptr_t', and File is a pointer to FILE. void EmitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B); - + }; } // End anonymous namespace. @@ -138,7 +138,7 @@ Value *LibCallOptimization::EmitStrLen(Value *Ptr, IRBuilder<> &B) { Constant *StrLen =M->getOrInsertFunction("strlen", AttrListPtr::get(AWI, 2), TD->getIntPtrType(*Context), - Type::getInt8PtrTy(*Context), + Type::getInt8PtrTy(*Context), NULL); CallInst *CI = B.CreateCall(StrLen, CastToCStr(Ptr, B), "strlen"); if (const Function *F = dyn_cast(StrLen->stripPointerCasts())) @@ -169,9 +169,10 @@ Value *LibCallOptimization::EmitMemChr(Value *Ptr, Value *Val, AWI = AttributeWithIndex::get(~0u, Attribute::ReadOnly | Attribute::NoUnwind); Value *MemChr = M->getOrInsertFunction("memchr", AttrListPtr::get(&AWI, 1), - Type::getInt8PtrTy(*Context), - Type::getInt8PtrTy(*Context), - Type::getInt32Ty(*Context), TD->getIntPtrType(*Context), + Type::getInt8PtrTy(*Context), + Type::getInt8PtrTy(*Context), + Type::getInt32Ty(*Context), + TD->getIntPtrType(*Context), NULL); CallInst *CI = B.CreateCall3(MemChr, CastToCStr(Ptr, B), Val, Len, "memchr"); @@ -256,7 +257,9 @@ void LibCallOptimization::EmitPutChar(Value *Char, IRBuilder<> &B) { Value *PutChar = M->getOrInsertFunction("putchar", Type::getInt32Ty(*Context), Type::getInt32Ty(*Context), NULL); CallInst *CI = B.CreateCall(PutChar, - B.CreateIntCast(Char, Type::getInt32Ty(*Context), "chari"), + B.CreateIntCast(Char, + Type::getInt32Ty(*Context), + "chari"), "putchar"); if (const Function *F = dyn_cast(PutChar->stripPointerCasts())) @@ -290,10 +293,14 @@ void LibCallOptimization::EmitFPutC(Value *Char, Value *File, IRBuilder<> &B) { AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind); Constant *F; if (isa(File->getType())) - F = M->getOrInsertFunction("fputc", AttrListPtr::get(AWI, 2), Type::getInt32Ty(*Context), - Type::getInt32Ty(*Context), File->getType(), NULL); + F = M->getOrInsertFunction("fputc", AttrListPtr::get(AWI, 2), + Type::getInt32Ty(*Context), + Type::getInt32Ty(*Context), File->getType(), + NULL); else - F = M->getOrInsertFunction("fputc", Type::getInt32Ty(*Context), Type::getInt32Ty(*Context), + F = M->getOrInsertFunction("fputc", + Type::getInt32Ty(*Context), + Type::getInt32Ty(*Context), File->getType(), NULL); Char = B.CreateIntCast(Char, Type::getInt32Ty(*Context), "chari"); CallInst *CI = B.CreateCall2(F, Char, File, "fputc"); @@ -312,7 +319,8 @@ void LibCallOptimization::EmitFPutS(Value *Str, Value *File, IRBuilder<> &B) { AWI[2] = AttributeWithIndex::get(~0u, Attribute::NoUnwind); Constant *F; if (isa(File->getType())) - F = M->getOrInsertFunction("fputs", AttrListPtr::get(AWI, 3), Type::getInt32Ty(*Context), + F = M->getOrInsertFunction("fputs", AttrListPtr::get(AWI, 3), + Type::getInt32Ty(*Context), Type::getInt8PtrTy(*Context), File->getType(), NULL); else @@ -339,12 +347,14 @@ void LibCallOptimization::EmitFWrite(Value *Ptr, Value *Size, Value *File, F = M->getOrInsertFunction("fwrite", AttrListPtr::get(AWI, 3), TD->getIntPtrType(*Context), Type::getInt8PtrTy(*Context), - TD->getIntPtrType(*Context), TD->getIntPtrType(*Context), + TD->getIntPtrType(*Context), + TD->getIntPtrType(*Context), File->getType(), NULL); else F = M->getOrInsertFunction("fwrite", TD->getIntPtrType(*Context), Type::getInt8PtrTy(*Context), - TD->getIntPtrType(*Context), TD->getIntPtrType(*Context), + TD->getIntPtrType(*Context), + TD->getIntPtrType(*Context), File->getType(), NULL); CallInst *CI = B.CreateCall4(F, CastToCStr(Ptr, B), Size, ConstantInt::get(TD->getIntPtrType(*Context), 1), File); @@ -363,30 +373,30 @@ static uint64_t GetStringLengthH(Value *V, SmallPtrSet &PHIs) { // Look through noop bitcast instructions. if (BitCastInst *BCI = dyn_cast(V)) return GetStringLengthH(BCI->getOperand(0), PHIs); - + // If this is a PHI node, there are two cases: either we have already seen it // or we haven't. if (PHINode *PN = dyn_cast(V)) { if (!PHIs.insert(PN)) return ~0ULL; // already in the set. - + // If it was new, see if all the input strings are the same length. uint64_t LenSoFar = ~0ULL; for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { uint64_t Len = GetStringLengthH(PN->getIncomingValue(i), PHIs); if (Len == 0) return 0; // Unknown length -> unknown. - + if (Len == ~0ULL) continue; - + if (Len != LenSoFar && LenSoFar != ~0ULL) return 0; // Disagree -> unknown. LenSoFar = Len; } - + // Success, all agree. return LenSoFar; } - + // strlen(select(c,x,y)) -> strlen(x) ^ strlen(y) if (SelectInst *SI = dyn_cast(V)) { uint64_t Len1 = GetStringLengthH(SI->getTrueValue(), PHIs); @@ -398,7 +408,7 @@ static uint64_t GetStringLengthH(Value *V, SmallPtrSet &PHIs) { if (Len1 != Len2) return 0; return Len1; } - + // If the value is not a GEP instruction nor a constant expression with a // GEP instruction, then return unknown. User *GEP = 0; @@ -411,11 +421,11 @@ static uint64_t GetStringLengthH(Value *V, SmallPtrSet &PHIs) { } else { return 0; } - + // Make sure the GEP has exactly three arguments. if (GEP->getNumOperands() != 3) return 0; - + // Check to make sure that the first operand of the GEP is an integer and // has value 0 so that we are sure we're indexing into the initializer. if (ConstantInt *Idx = dyn_cast(GEP->getOperand(1))) { @@ -423,7 +433,7 @@ static uint64_t GetStringLengthH(Value *V, SmallPtrSet &PHIs) { return 0; } else return 0; - + // If the second index isn't a ConstantInt, then this is a variable index // into the array. If this occurs, we can't say anything meaningful about // the string. @@ -432,7 +442,7 @@ static uint64_t GetStringLengthH(Value *V, SmallPtrSet &PHIs) { StartIdx = CI->getZExtValue(); else return 0; - + // The GEP instruction, constant or instruction, must reference a global // variable that is a constant and is initialized. The referenced constant // initializer is the array that we'll use for optimization. @@ -441,21 +451,21 @@ static uint64_t GetStringLengthH(Value *V, SmallPtrSet &PHIs) { GV->mayBeOverridden()) return 0; Constant *GlobalInit = GV->getInitializer(); - + // Handle the ConstantAggregateZero case, which is a degenerate case. The // initializer is constant zero so the length of the string must be zero. if (isa(GlobalInit)) return 1; // Len = 0 offset by 1. - + // Must be a Constant Array ConstantArray *Array = dyn_cast(GlobalInit); if (!Array || Array->getType()->getElementType() != Type::getInt8Ty(V->getContext())) return false; - + // Get the number of elements in the array uint64_t NumElts = Array->getType()->getNumElements(); - + // Traverse the constant array from StartIdx (derived above) which is // the place the GEP refers to in the array. for (unsigned i = StartIdx; i != NumElts; ++i) { @@ -466,7 +476,7 @@ static uint64_t GetStringLengthH(Value *V, SmallPtrSet &PHIs) { if (CI->isZero()) return i-StartIdx+1; // We found end of string, success! } - + return 0; // The array isn't null terminated, conservatively return 'unknown'. } @@ -474,7 +484,7 @@ static uint64_t GetStringLengthH(Value *V, SmallPtrSet &PHIs) { /// the specified pointer, return 'len+1'. If we can't, return 0. static uint64_t GetStringLength(Value *V) { if (!isa(V->getType())) return 0; - + SmallPtrSet PHIs; uint64_t Len = GetStringLengthH(V, PHIs); // If Len is ~0ULL, we had an infinite phi cycle: this is dead code, so return @@ -483,7 +493,7 @@ static uint64_t GetStringLength(Value *V) { } /// IsOnlyUsedInZeroEqualityComparison - Return true if it only matters that the -/// value is equal or not-equal to zero. +/// value is equal or not-equal to zero. static bool IsOnlyUsedInZeroEqualityComparison(Value *V) { for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; ++UI) { @@ -514,16 +524,16 @@ struct StrCatOpt : public LibCallOptimization { FT->getParamType(0) != FT->getReturnType() || FT->getParamType(1) != FT->getReturnType()) return 0; - + // Extract some information from the instruction Value *Dst = CI->getOperand(1); Value *Src = CI->getOperand(2); - + // See if we can get the length of the input string. uint64_t Len = GetStringLength(Src); if (Len == 0) return 0; --Len; // Unbias length. - + // Handle the simple, do-nothing case: strcat(x, "") -> x if (Len == 0) return Dst; @@ -539,12 +549,12 @@ struct StrCatOpt : public LibCallOptimization { // We need to find the end of the destination string. That's where the // memory is to be moved to. We just generate a call to strlen. Value *DstLen = EmitStrLen(Dst, B); - + // Now that we have the destination's length, we must index into the // destination's pointer to get the actual memcpy destination (end of // the string .. we're concatenating). Value *CpyDst = B.CreateGEP(Dst, DstLen, "endptr"); - + // We have enough information to now generate the memcpy call to do the // concatenation for us. Make a memcpy to copy the nul byte with align = 1. EmitMemCpy(CpyDst, Src, @@ -611,9 +621,9 @@ struct StrChrOpt : public LibCallOptimization { FT->getReturnType() != Type::getInt8PtrTy(*Context) || FT->getParamType(0) != FT->getReturnType()) return 0; - + Value *SrcStr = CI->getOperand(1); - + // If the second operand is non-constant, see if we can compute the length // of the input string and turn this into memchr. ConstantInt *CharC = dyn_cast(CI->getOperand(2)); @@ -625,7 +635,7 @@ struct StrChrOpt : public LibCallOptimization { if (Len == 0 || FT->getParamType(1) != Type::getInt32Ty(*Context)) // memchr needs i32. return 0; - + return EmitMemChr(SrcStr, CI->getOperand(2), // include nul. ConstantInt::get(TD->getIntPtrType(*Context), Len), B); } @@ -635,11 +645,11 @@ struct StrChrOpt : public LibCallOptimization { std::string Str; if (!GetConstantStringInfo(SrcStr, Str)) return 0; - + // strchr can find the nul character. Str += '\0'; char CharValue = CharC->getSExtValue(); - + // Compute the offset. uint64_t i = 0; while (1) { @@ -650,7 +660,7 @@ struct StrChrOpt : public LibCallOptimization { break; ++i; } - + // strchr(s+n,c) -> gep(s+n+i,c) Value *Idx = ConstantInt::get(Type::getInt64Ty(*Context), i); return B.CreateGEP(SrcStr, Idx, "strchr"); @@ -664,28 +674,29 @@ struct StrCmpOpt : public LibCallOptimization { virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { // Verify the "strcmp" function prototype. const FunctionType *FT = Callee->getFunctionType(); - if (FT->getNumParams() != 2 || FT->getReturnType() != Type::getInt32Ty(*Context) || + if (FT->getNumParams() != 2 || + FT->getReturnType() != Type::getInt32Ty(*Context) || FT->getParamType(0) != FT->getParamType(1) || FT->getParamType(0) != Type::getInt8PtrTy(*Context)) return 0; - + Value *Str1P = CI->getOperand(1), *Str2P = CI->getOperand(2); if (Str1P == Str2P) // strcmp(x,x) -> 0 return ConstantInt::get(CI->getType(), 0); - + std::string Str1, Str2; bool HasStr1 = GetConstantStringInfo(Str1P, Str1); bool HasStr2 = GetConstantStringInfo(Str2P, Str2); - + if (HasStr1 && Str1.empty()) // strcmp("", x) -> *x return B.CreateZExt(B.CreateLoad(Str2P, "strcmpload"), CI->getType()); - + if (HasStr2 && Str2.empty()) // strcmp(x,"") -> *x return B.CreateZExt(B.CreateLoad(Str1P, "strcmpload"), CI->getType()); - + // strcmp(x, y) -> cnst (if both x and y are constant strings) if (HasStr1 && HasStr2) - return ConstantInt::get(CI->getType(), + return ConstantInt::get(CI->getType(), strcmp(Str1.c_str(),Str2.c_str())); // strcmp(P, "x") -> memcmp(P, "x", 2) @@ -711,36 +722,37 @@ struct StrNCmpOpt : public LibCallOptimization { virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { // Verify the "strncmp" function prototype. const FunctionType *FT = Callee->getFunctionType(); - if (FT->getNumParams() != 3 || FT->getReturnType() != Type::getInt32Ty(*Context) || + if (FT->getNumParams() != 3 || + FT->getReturnType() != Type::getInt32Ty(*Context) || FT->getParamType(0) != FT->getParamType(1) || FT->getParamType(0) != Type::getInt8PtrTy(*Context) || !isa(FT->getParamType(2))) return 0; - + Value *Str1P = CI->getOperand(1), *Str2P = CI->getOperand(2); if (Str1P == Str2P) // strncmp(x,x,n) -> 0 return ConstantInt::get(CI->getType(), 0); - + // Get the length argument if it is constant. uint64_t Length; if (ConstantInt *LengthArg = dyn_cast(CI->getOperand(3))) Length = LengthArg->getZExtValue(); else return 0; - + if (Length == 0) // strncmp(x,y,0) -> 0 return ConstantInt::get(CI->getType(), 0); - + std::string Str1, Str2; bool HasStr1 = GetConstantStringInfo(Str1P, Str1); bool HasStr2 = GetConstantStringInfo(Str2P, Str2); - + if (HasStr1 && Str1.empty()) // strncmp("", x, n) -> *x return B.CreateZExt(B.CreateLoad(Str2P, "strcmpload"), CI->getType()); - + if (HasStr2 && Str2.empty()) // strncmp(x, "", n) -> *x return B.CreateZExt(B.CreateLoad(Str1P, "strcmpload"), CI->getType()); - + // strncmp(x, y) -> cnst (if both x and y are constant strings) if (HasStr1 && HasStr2) return ConstantInt::get(CI->getType(), @@ -761,18 +773,18 @@ struct StrCpyOpt : public LibCallOptimization { FT->getParamType(0) != FT->getParamType(1) || FT->getParamType(0) != Type::getInt8PtrTy(*Context)) return 0; - + Value *Dst = CI->getOperand(1), *Src = CI->getOperand(2); if (Dst == Src) // strcpy(x,x) -> x return Src; - + // These optimizations require TargetData. if (!TD) return 0; // See if we can get the length of the input string. uint64_t Len = GetStringLength(Src); if (Len == 0) return 0; - + // We have enough information to now generate the memcpy call to do the // concatenation for us. Make a memcpy to copy the nul byte with align = 1. EmitMemCpy(Dst, Src, @@ -804,7 +816,8 @@ struct StrNCpyOpt : public LibCallOptimization { if (SrcLen == 0) { // strncpy(x, "", y) -> memset(x, '\0', y, 1) - EmitMemSet(Dst, ConstantInt::get(Type::getInt8Ty(*Context), '\0'), LenOp, B); + EmitMemSet(Dst, ConstantInt::get(Type::getInt8Ty(*Context), '\0'), LenOp, + B); return Dst; } @@ -840,7 +853,7 @@ struct StrLenOpt : public LibCallOptimization { FT->getParamType(0) != Type::getInt8PtrTy(*Context) || !isa(FT->getReturnType())) return 0; - + Value *Src = CI->getOperand(1); // Constant folding: strlen("xyz") -> 3 @@ -992,7 +1005,8 @@ struct MemSetOpt : public LibCallOptimization { return 0; // memset(p, v, n) -> llvm.memset(p, v, n, 1) - Value *Val = B.CreateIntCast(CI->getOperand(2), Type::getInt8Ty(*Context), false); + Value *Val = B.CreateIntCast(CI->getOperand(2), Type::getInt8Ty(*Context), + false); EmitMemSet(CI->getOperand(1), Val, CI->getOperand(3), B); return CI->getOperand(1); } @@ -1014,7 +1028,7 @@ struct PowOpt : public LibCallOptimization { FT->getParamType(0) != FT->getParamType(1) || !FT->getParamType(0)->isFloatingPoint()) return 0; - + Value *Op1 = CI->getOperand(1), *Op2 = CI->getOperand(2); if (ConstantFP *Op1C = dyn_cast(Op1)) { if (Op1C->isExactlyValue(1.0)) // pow(1.0, x) -> 1.0 @@ -1022,13 +1036,13 @@ struct PowOpt : public LibCallOptimization { if (Op1C->isExactlyValue(2.0)) // pow(2.0, x) -> exp2(x) return EmitUnaryFloatFnCall(Op2, "exp2", B, Callee->getAttributes()); } - + ConstantFP *Op2C = dyn_cast(Op2); if (Op2C == 0) return 0; - + if (Op2C->getValueAPF().isZero()) // pow(x, 0.0) -> 1.0 return ConstantFP::get(CI->getType(), 1.0); - + if (Op2C->isExactlyValue(0.5)) { // Expand pow(x, 0.5) to (x == -infinity ? +infinity : fabs(sqrt(x))). // This is faster than calling pow, and still handles negative zero @@ -1045,7 +1059,7 @@ struct PowOpt : public LibCallOptimization { Value *Sel = B.CreateSelect(FCmp, Inf, FAbs, "tmp"); return Sel; } - + if (Op2C->isExactlyValue(1.0)) // pow(x, 1.0) -> x return Op1; if (Op2C->isExactlyValue(2.0)) // pow(x, 2.0) -> x*x @@ -1068,17 +1082,19 @@ struct Exp2Opt : public LibCallOptimization { if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) || !FT->getParamType(0)->isFloatingPoint()) return 0; - + Value *Op = CI->getOperand(1); // Turn exp2(sitofp(x)) -> ldexp(1.0, sext(x)) if sizeof(x) <= 32 // Turn exp2(uitofp(x)) -> ldexp(1.0, zext(x)) if sizeof(x) < 32 Value *LdExpArg = 0; if (SIToFPInst *OpC = dyn_cast(Op)) { if (OpC->getOperand(0)->getType()->getPrimitiveSizeInBits() <= 32) - LdExpArg = B.CreateSExt(OpC->getOperand(0), Type::getInt32Ty(*Context), "tmp"); + LdExpArg = B.CreateSExt(OpC->getOperand(0), + Type::getInt32Ty(*Context), "tmp"); } else if (UIToFPInst *OpC = dyn_cast(Op)) { if (OpC->getOperand(0)->getType()->getPrimitiveSizeInBits() < 32) - LdExpArg = B.CreateZExt(OpC->getOperand(0), Type::getInt32Ty(*Context), "tmp"); + LdExpArg = B.CreateZExt(OpC->getOperand(0), + Type::getInt32Ty(*Context), "tmp"); } if (LdExpArg) { @@ -1096,7 +1112,8 @@ struct Exp2Opt : public LibCallOptimization { Module *M = Caller->getParent(); Value *Callee = M->getOrInsertFunction(Name, Op->getType(), - Op->getType(), Type::getInt32Ty(*Context),NULL); + Op->getType(), + Type::getInt32Ty(*Context),NULL); CallInst *CI = B.CreateCall2(Callee, One, LdExpArg); if (const Function *F = dyn_cast(Callee->stripPointerCasts())) CI->setCallingConv(F->getCallingConv()); @@ -1142,12 +1159,13 @@ struct FFSOpt : public LibCallOptimization { const FunctionType *FT = Callee->getFunctionType(); // Just make sure this has 2 arguments of the same FP type, which match the // result type. - if (FT->getNumParams() != 1 || FT->getReturnType() != Type::getInt32Ty(*Context) || + if (FT->getNumParams() != 1 || + FT->getReturnType() != Type::getInt32Ty(*Context) || !isa(FT->getParamType(0))) return 0; - + Value *Op = CI->getOperand(1); - + // Constant fold. if (ConstantInt *CI = dyn_cast(Op)) { if (CI->getValue() == 0) // ffs(0) -> 0. @@ -1155,7 +1173,7 @@ struct FFSOpt : public LibCallOptimization { return ConstantInt::get(Type::getInt32Ty(*Context), // ffs(c) -> cttz(c)+1 CI->getValue().countTrailingZeros()+1); } - + // ffs(x) -> x != 0 ? (i32)llvm.cttz(x)+1 : 0 const Type *ArgType = Op->getType(); Value *F = Intrinsic::getDeclaration(Callee->getParent(), @@ -1163,9 +1181,10 @@ struct FFSOpt : public LibCallOptimization { Value *V = B.CreateCall(F, Op, "cttz"); V = B.CreateAdd(V, ConstantInt::get(V->getType(), 1), "tmp"); V = B.CreateIntCast(V, Type::getInt32Ty(*Context), false, "tmp"); - + Value *Cond = B.CreateICmpNE(Op, Constant::getNullValue(ArgType), "tmp"); - return B.CreateSelect(Cond, V, ConstantInt::get(Type::getInt32Ty(*Context), 0)); + return B.CreateSelect(Cond, V, + ConstantInt::get(Type::getInt32Ty(*Context), 0)); } }; @@ -1179,12 +1198,12 @@ struct IsDigitOpt : public LibCallOptimization { if (FT->getNumParams() != 1 || !isa(FT->getReturnType()) || FT->getParamType(0) != Type::getInt32Ty(*Context)) return 0; - + // isdigit(c) -> (c-'0') getOperand(1); - Op = B.CreateSub(Op, ConstantInt::get(Type::getInt32Ty(*Context), '0'), + Op = B.CreateSub(Op, ConstantInt::get(Type::getInt32Ty(*Context), '0'), "isdigittmp"); - Op = B.CreateICmpULT(Op, ConstantInt::get(Type::getInt32Ty(*Context), 10), + Op = B.CreateICmpULT(Op, ConstantInt::get(Type::getInt32Ty(*Context), 10), "isdigit"); return B.CreateZExt(Op, CI->getType()); } @@ -1200,7 +1219,7 @@ struct IsAsciiOpt : public LibCallOptimization { if (FT->getNumParams() != 1 || !isa(FT->getReturnType()) || FT->getParamType(0) != Type::getInt32Ty(*Context)) return 0; - + // isascii(c) -> c getOperand(1); Op = B.CreateICmpULT(Op, ConstantInt::get(Type::getInt32Ty(*Context), 128), @@ -1208,7 +1227,7 @@ struct IsAsciiOpt : public LibCallOptimization { return B.CreateZExt(Op, CI->getType()); } }; - + //===---------------------------------------===// // 'abs', 'labs', 'llabs' Optimizations @@ -1219,17 +1238,17 @@ struct AbsOpt : public LibCallOptimization { if (FT->getNumParams() != 1 || !isa(FT->getReturnType()) || FT->getParamType(0) != FT->getReturnType()) return 0; - + // abs(x) -> x >s -1 ? x : -x Value *Op = CI->getOperand(1); - Value *Pos = B.CreateICmpSGT(Op, + Value *Pos = B.CreateICmpSGT(Op, Constant::getAllOnesValue(Op->getType()), "ispos"); Value *Neg = B.CreateNeg(Op, "neg"); return B.CreateSelect(Pos, Op, Neg); } }; - + //===---------------------------------------===// // 'toascii' Optimizations @@ -1241,7 +1260,7 @@ struct ToAsciiOpt : public LibCallOptimization { if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) || FT->getParamType(0) != Type::getInt32Ty(*Context)) return 0; - + // isascii(c) -> c & 0x7f return B.CreateAnd(CI->getOperand(1), ConstantInt::get(CI->getType(),0x7F)); @@ -1263,7 +1282,7 @@ struct PrintFOpt : public LibCallOptimization { !(isa(FT->getReturnType()) || FT->getReturnType()->isVoidTy())) return 0; - + // Check for a fixed format string. std::string FormatStr; if (!GetConstantStringInfo(CI->getOperand(1), FormatStr)) @@ -1271,16 +1290,16 @@ struct PrintFOpt : public LibCallOptimization { // Empty format string -> noop. if (FormatStr.empty()) // Tolerate printf's declared void. - return CI->use_empty() ? (Value*)CI : + return CI->use_empty() ? (Value*)CI : ConstantInt::get(CI->getType(), 0); - + // printf("x") -> putchar('x'), even for '%'. if (FormatStr.size() == 1) { EmitPutChar(ConstantInt::get(Type::getInt32Ty(*Context), FormatStr[0]), B); - return CI->use_empty() ? (Value*)CI : + return CI->use_empty() ? (Value*)CI : ConstantInt::get(CI->getType(), 1); } - + // printf("foo\n") --> puts("foo") if (FormatStr[FormatStr.size()-1] == '\n' && FormatStr.find('%') == std::string::npos) { // no format characters. @@ -1291,19 +1310,19 @@ struct PrintFOpt : public LibCallOptimization { C = new GlobalVariable(*Callee->getParent(), C->getType(), true, GlobalVariable::InternalLinkage, C, "str"); EmitPutS(C, B); - return CI->use_empty() ? (Value*)CI : + return CI->use_empty() ? (Value*)CI : ConstantInt::get(CI->getType(), FormatStr.size()+1); } - + // Optimize specific format strings. // printf("%c", chr) --> putchar(*(i8*)dst) if (FormatStr == "%c" && CI->getNumOperands() > 2 && isa(CI->getOperand(2)->getType())) { EmitPutChar(CI->getOperand(2), B); - return CI->use_empty() ? (Value*)CI : + return CI->use_empty() ? (Value*)CI : ConstantInt::get(CI->getType(), 1); } - + // printf("%s\n", str) --> puts(str) if (FormatStr == "%s\n" && CI->getNumOperands() > 2 && isa(CI->getOperand(2)->getType()) && @@ -1331,7 +1350,7 @@ struct SPrintFOpt : public LibCallOptimization { std::string FormatStr; if (!GetConstantStringInfo(CI->getOperand(2), FormatStr)) return 0; - + // If we just have a format string (nothing else crazy) transform it. if (CI->getNumOperands() == 3) { // Make sure there's no % in the constant array. We could try to handle @@ -1348,25 +1367,27 @@ struct SPrintFOpt : public LibCallOptimization { ConstantInt::get(TD->getIntPtrType(*Context), FormatStr.size()+1),1,B); return ConstantInt::get(CI->getType(), FormatStr.size()); } - + // The remaining optimizations require the format string to be "%s" or "%c" // and have an extra operand. if (FormatStr.size() != 2 || FormatStr[0] != '%' || CI->getNumOperands() <4) return 0; - + // Decode the second character of the format string. if (FormatStr[1] == 'c') { // sprintf(dst, "%c", chr) --> *(i8*)dst = chr; *((i8*)dst+1) = 0 if (!isa(CI->getOperand(3)->getType())) return 0; - Value *V = B.CreateTrunc(CI->getOperand(3), Type::getInt8Ty(*Context), "char"); + Value *V = B.CreateTrunc(CI->getOperand(3), + Type::getInt8Ty(*Context), "char"); Value *Ptr = CastToCStr(CI->getOperand(1), B); B.CreateStore(V, Ptr); - Ptr = B.CreateGEP(Ptr, ConstantInt::get(Type::getInt32Ty(*Context), 1), "nul"); + Ptr = B.CreateGEP(Ptr, ConstantInt::get(Type::getInt32Ty(*Context), 1), + "nul"); B.CreateStore(Constant::getNullValue(Type::getInt8Ty(*Context)), Ptr); - + return ConstantInt::get(CI->getType(), 1); } - + if (FormatStr[1] == 's') { // These optimizations require TargetData. if (!TD) return 0; @@ -1379,7 +1400,7 @@ struct SPrintFOpt : public LibCallOptimization { ConstantInt::get(Len->getType(), 1), "leninc"); EmitMemCpy(CI->getOperand(1), CI->getOperand(3), IncLen, 1, B); - + // The sprintf result is the unincremented number of bytes in the string. return B.CreateIntCast(Len, CI->getType(), false); } @@ -1400,17 +1421,17 @@ struct FWriteOpt : public LibCallOptimization { !isa(FT->getParamType(3)) || !isa(FT->getReturnType())) return 0; - + // Get the element size and count. ConstantInt *SizeC = dyn_cast(CI->getOperand(2)); ConstantInt *CountC = dyn_cast(CI->getOperand(3)); if (!SizeC || !CountC) return 0; uint64_t Bytes = SizeC->getZExtValue()*CountC->getZExtValue(); - + // If this is writing zero records, remove the call (it's a noop). if (Bytes == 0) return ConstantInt::get(CI->getType(), 0); - + // If this is writing one byte, turn it into fputc. if (Bytes == 1) { // fwrite(S,1,1,F) -> fputc(S[0],F) Value *Char = B.CreateLoad(CastToCStr(CI->getOperand(1), B), "char"); @@ -1436,7 +1457,7 @@ struct FPutsOpt : public LibCallOptimization { !isa(FT->getParamType(1)) || !CI->use_empty()) return 0; - + // fputs(s,F) --> fwrite(s,1,strlen(s),F) uint64_t Len = GetStringLength(CI->getOperand(1)); if (!Len) return 0; @@ -1458,7 +1479,7 @@ struct FPrintFOpt : public LibCallOptimization { !isa(FT->getParamType(1)) || !isa(FT->getReturnType())) return 0; - + // All the optimizations depend on the format string. std::string FormatStr; if (!GetConstantStringInfo(CI->getOperand(2), FormatStr)) @@ -1478,12 +1499,12 @@ struct FPrintFOpt : public LibCallOptimization { CI->getOperand(1), B); return ConstantInt::get(CI->getType(), FormatStr.size()); } - + // The remaining optimizations require the format string to be "%s" or "%c" // and have an extra operand. if (FormatStr.size() != 2 || FormatStr[0] != '%' || CI->getNumOperands() <4) return 0; - + // Decode the second character of the format string. if (FormatStr[1] == 'c') { // fprintf(F, "%c", chr) --> *(i8*)dst = chr @@ -1491,7 +1512,7 @@ struct FPrintFOpt : public LibCallOptimization { EmitFPutC(CI->getOperand(3), CI->getOperand(1), B); return ConstantInt::get(CI->getType(), 1); } - + if (FormatStr[1] == 's') { // fprintf(F, "%s", str) -> fputs(str, F) if (!isa(CI->getOperand(3)->getType()) || !CI->use_empty()) @@ -1554,7 +1575,7 @@ X("simplify-libcalls", "Simplify well-known library calls"); // Public interface to the Simplify LibCalls pass. FunctionPass *llvm::createSimplifyLibCallsPass() { - return new SimplifyLibCalls(); + return new SimplifyLibCalls(); } /// Optimizations - Populate the Optimizations map with all the optimizations @@ -1580,7 +1601,7 @@ void SimplifyLibCalls::InitOptimizations() { Optimizations["memcpy"] = &MemCpy; Optimizations["memmove"] = &MemMove; Optimizations["memset"] = &MemSet; - + // Math Library Optimizations Optimizations["powf"] = &Pow; Optimizations["pow"] = &Pow; @@ -1598,7 +1619,7 @@ void SimplifyLibCalls::InitOptimizations() { Optimizations["llvm.exp2.f80"] = &Exp2; Optimizations["llvm.exp2.f64"] = &Exp2; Optimizations["llvm.exp2.f32"] = &Exp2; - + #ifdef HAVE_FLOORF Optimizations["floor"] = &UnaryDoubleFP; #endif @@ -1614,7 +1635,7 @@ void SimplifyLibCalls::InitOptimizations() { #ifdef HAVE_NEARBYINTF Optimizations["nearbyint"] = &UnaryDoubleFP; #endif - + // Integer Optimizations Optimizations["ffs"] = &FFS; Optimizations["ffsl"] = &FFS; @@ -1625,7 +1646,7 @@ void SimplifyLibCalls::InitOptimizations() { Optimizations["isdigit"] = &IsDigit; Optimizations["isascii"] = &IsAscii; Optimizations["toascii"] = &ToAscii; - + // Formatting and IO Optimizations Optimizations["sprintf"] = &SPrintF; Optimizations["printf"] = &PrintF; @@ -1640,9 +1661,9 @@ void SimplifyLibCalls::InitOptimizations() { bool SimplifyLibCalls::runOnFunction(Function &F) { if (Optimizations.empty()) InitOptimizations(); - + const TargetData *TD = getAnalysisIfAvailable(); - + IRBuilder<> Builder(F.getContext()); bool Changed = false; @@ -1651,35 +1672,35 @@ bool SimplifyLibCalls::runOnFunction(Function &F) { // Ignore non-calls. CallInst *CI = dyn_cast(I++); if (!CI) continue; - + // Ignore indirect calls and calls to non-external functions. Function *Callee = CI->getCalledFunction(); if (Callee == 0 || !Callee->isDeclaration() || !(Callee->hasExternalLinkage() || Callee->hasDLLImportLinkage())) continue; - + // Ignore unknown calls. LibCallOptimization *LCO = Optimizations.lookup(Callee->getName()); if (!LCO) continue; - + // Set the builder to the instruction after the call. Builder.SetInsertPoint(BB, I); - + // Try to optimize this call. Value *Result = LCO->OptimizeCall(CI, TD, Builder); if (Result == 0) continue; DEBUG(errs() << "SimplifyLibCalls simplified: " << *CI; errs() << " 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())