15e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge//===------ SimplifyLibCalls.cpp - Library calls simplifier ---------------===// 25e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge// 35e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge// The LLVM Compiler Infrastructure 45e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge// 55e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge// This file is distributed under the University of Illinois Open Source 65e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge// License. See LICENSE.TXT for details. 75e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge// 85e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge//===----------------------------------------------------------------------===// 95e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge// 105e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge// This is a utility pass used for testing the InstructionSimplify analysis. 115e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge// The analysis is applied to every instruction, and if it simplifies then the 125e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge// instruction is replaced by the simplification. If you are looking for a pass 135e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge// that performs serious instruction folding, use the instcombine pass instead. 145e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge// 155e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge//===----------------------------------------------------------------------===// 165e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 175e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge#include "llvm/Transforms/Utils/SimplifyLibCalls.h" 1867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge#include "llvm/ADT/SmallString.h" 195e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge#include "llvm/ADT/StringMap.h" 205e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge#include "llvm/Analysis/ValueTracking.h" 210b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h" 220b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h" 230b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/IRBuilder.h" 2467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge#include "llvm/IR/IntrinsicInst.h" 250b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Intrinsics.h" 260b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/LLVMContext.h" 270b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h" 28f26b4f05b3fdd8618f75b8784388e8415a6eea0cNadav Rotem#include "llvm/Support/Allocator.h" 295e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge#include "llvm/Target/TargetLibraryInfo.h" 305e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge#include "llvm/Transforms/Utils/BuildLibCalls.h" 315e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 325e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingeusing namespace llvm; 335e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 345e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge/// This class is the abstract base class for the set of optimizations that 355e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge/// corresponds to one library call. 365e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingenamespace { 375e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingeclass LibCallOptimization { 385e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingeprotected: 395e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge Function *Caller; 405e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge const DataLayout *TD; 415e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge const TargetLibraryInfo *TLI; 42b69bf6be1b042a5f06a623fc546107fc6d9f46c4Meador Inge const LibCallSimplifier *LCS; 435e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge LLVMContext* Context; 445e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingepublic: 455e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge LibCallOptimization() { } 465e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge virtual ~LibCallOptimization() {} 475e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 485e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge /// callOptimizer - This pure virtual method is implemented by base classes to 495e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge /// do various optimizations. If this returns null then no transformation was 505e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge /// performed. If it returns CI, then it transformed the call and CI is to be 515e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge /// deleted. If it returns something else, replace CI with the new value and 525e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge /// delete CI. 535e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) 545e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge =0; 555e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 5633daeab1bb8df65273fd9ecbf1a261f96733732eChad Rosier /// ignoreCallingConv - Returns false if this transformation could possibly 5733daeab1bb8df65273fd9ecbf1a261f96733732eChad Rosier /// change the calling convention. 5833daeab1bb8df65273fd9ecbf1a261f96733732eChad Rosier virtual bool ignoreCallingConv() { return false; } 5933daeab1bb8df65273fd9ecbf1a261f96733732eChad Rosier 605e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge Value *optimizeCall(CallInst *CI, const DataLayout *TD, 61b69bf6be1b042a5f06a623fc546107fc6d9f46c4Meador Inge const TargetLibraryInfo *TLI, 62b69bf6be1b042a5f06a623fc546107fc6d9f46c4Meador Inge const LibCallSimplifier *LCS, IRBuilder<> &B) { 635e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge Caller = CI->getParent()->getParent(); 645e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge this->TD = TD; 655e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge this->TLI = TLI; 66b69bf6be1b042a5f06a623fc546107fc6d9f46c4Meador Inge this->LCS = LCS; 675e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge if (CI->getCalledFunction()) 685e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge Context = &CI->getCalledFunction()->getContext(); 695e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 705e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge // We never change the calling convention. 7133daeab1bb8df65273fd9ecbf1a261f96733732eChad Rosier if (!ignoreCallingConv() && CI->getCallingConv() != llvm::CallingConv::C) 725e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge return NULL; 735e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 745e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge return callOptimizer(CI->getCalledFunction(), CI, B); 755e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge } 765e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge}; 775e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 785e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge//===----------------------------------------------------------------------===// 7957cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge// Helper Functions 8057cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge//===----------------------------------------------------------------------===// 8157cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge 8257cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge/// isOnlyUsedInZeroEqualityComparison - Return true if it only matters that the 8357cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge/// value is equal or not-equal to zero. 8457cfd71f881ae381fa43667e003f595ffd70ea18Meador Ingestatic bool isOnlyUsedInZeroEqualityComparison(Value *V) { 8557cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); 8657cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge UI != E; ++UI) { 8757cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge if (ICmpInst *IC = dyn_cast<ICmpInst>(*UI)) 8857cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge if (IC->isEquality()) 8957cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge if (Constant *C = dyn_cast<Constant>(IC->getOperand(1))) 9057cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge if (C->isNullValue()) 9157cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge continue; 9257cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge // Unknown instruction. 9357cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge return false; 9457cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge } 9557cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge return true; 9657cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge} 9757cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge 986e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge/// isOnlyUsedInEqualityComparison - Return true if it is only used in equality 996e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge/// comparisons with With. 1006e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Ingestatic bool isOnlyUsedInEqualityComparison(Value *V, Value *With) { 1016e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); 1026e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge UI != E; ++UI) { 1036e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge if (ICmpInst *IC = dyn_cast<ICmpInst>(*UI)) 1046e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge if (IC->isEquality() && IC->getOperand(1) == With) 1056e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge continue; 1066e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge // Unknown instruction. 1076e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge return false; 1086e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge } 1096e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge return true; 1106e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge} 1116e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge 112d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Ingestatic bool callHasFloatingPointArgument(const CallInst *CI) { 113d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge for (CallInst::const_op_iterator it = CI->op_begin(), e = CI->op_end(); 114d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge it != e; ++it) { 115d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge if ((*it)->getType()->isFloatingPointTy()) 116d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge return true; 117d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge } 118d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge return false; 119d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge} 120d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge 12157cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge//===----------------------------------------------------------------------===// 1225e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge// Fortified Library Call Optimizations 1235e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge//===----------------------------------------------------------------------===// 1245e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 1255e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingestruct FortifiedLibCallOptimization : public LibCallOptimization { 1265e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingeprotected: 1275e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge virtual bool isFoldable(unsigned SizeCIOp, unsigned SizeArgOp, 1285e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge bool isString) const = 0; 1295e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge}; 1305e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 1315e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingestruct InstFortifiedLibCallOptimization : public FortifiedLibCallOptimization { 1325e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge CallInst *CI; 1335e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 1345e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge bool isFoldable(unsigned SizeCIOp, unsigned SizeArgOp, bool isString) const { 1355e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge if (CI->getArgOperand(SizeCIOp) == CI->getArgOperand(SizeArgOp)) 1365e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge return true; 1375e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge if (ConstantInt *SizeCI = 1385e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge dyn_cast<ConstantInt>(CI->getArgOperand(SizeCIOp))) { 1395e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge if (SizeCI->isAllOnesValue()) 1405e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge return true; 1415e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge if (isString) { 1425e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge uint64_t Len = GetStringLength(CI->getArgOperand(SizeArgOp)); 1435e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge // If the length is 0 we don't know how long it is and so we can't 1445e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge // remove the check. 1455e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge if (Len == 0) return false; 1465e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge return SizeCI->getZExtValue() >= Len; 1475e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge } 1485e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge if (ConstantInt *Arg = dyn_cast<ConstantInt>( 1495e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge CI->getArgOperand(SizeArgOp))) 1505e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge return SizeCI->getZExtValue() >= Arg->getZExtValue(); 1515e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge } 1525e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge return false; 1535e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge } 1545e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge}; 1555e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 1565e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingestruct MemCpyChkOpt : public InstFortifiedLibCallOptimization { 1575e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1585e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge this->CI = CI; 1595e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge FunctionType *FT = Callee->getFunctionType(); 160ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth LLVMContext &Context = CI->getParent()->getContext(); 1615e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 1625e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge // Check if this has the right signature. 1635e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) || 1645e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge !FT->getParamType(0)->isPointerTy() || 1655e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge !FT->getParamType(1)->isPointerTy() || 166ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth FT->getParamType(2) != TD->getIntPtrType(Context) || 167ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth FT->getParamType(3) != TD->getIntPtrType(Context)) 1685e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge return 0; 1695e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 1705e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge if (isFoldable(3, 2, false)) { 1715e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1), 1725e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge CI->getArgOperand(2), 1); 1735e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge return CI->getArgOperand(0); 1745e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge } 1755e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge return 0; 1765e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge } 1775e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge}; 1785e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 1795e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingestruct MemMoveChkOpt : public InstFortifiedLibCallOptimization { 1805e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1815e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge this->CI = CI; 1825e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge FunctionType *FT = Callee->getFunctionType(); 183ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth LLVMContext &Context = CI->getParent()->getContext(); 1845e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 1855e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge // Check if this has the right signature. 1865e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) || 1875e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge !FT->getParamType(0)->isPointerTy() || 1885e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge !FT->getParamType(1)->isPointerTy() || 189ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth FT->getParamType(2) != TD->getIntPtrType(Context) || 190ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth FT->getParamType(3) != TD->getIntPtrType(Context)) 1915e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge return 0; 1925e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 1935e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge if (isFoldable(3, 2, false)) { 1945e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge B.CreateMemMove(CI->getArgOperand(0), CI->getArgOperand(1), 1955e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge CI->getArgOperand(2), 1); 1965e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge return CI->getArgOperand(0); 1975e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge } 1985e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge return 0; 1995e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge } 2005e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge}; 2015e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 2025e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingestruct MemSetChkOpt : public InstFortifiedLibCallOptimization { 2035e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 2045e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge this->CI = CI; 2055e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge FunctionType *FT = Callee->getFunctionType(); 206ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth LLVMContext &Context = CI->getParent()->getContext(); 2075e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 2085e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge // Check if this has the right signature. 2095e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) || 2105e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge !FT->getParamType(0)->isPointerTy() || 2115e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge !FT->getParamType(1)->isIntegerTy() || 212ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth FT->getParamType(2) != TD->getIntPtrType(Context) || 213ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth FT->getParamType(3) != TD->getIntPtrType(Context)) 2145e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge return 0; 2155e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 2165e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge if (isFoldable(3, 2, false)) { 2175e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(), 2185e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge false); 2195e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge B.CreateMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), 1); 2205e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge return CI->getArgOperand(0); 2215e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge } 2225e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge return 0; 2235e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge } 2245e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge}; 2255e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 2265e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingestruct StrCpyChkOpt : public InstFortifiedLibCallOptimization { 2275e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 2285e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge this->CI = CI; 2295e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge StringRef Name = Callee->getName(); 2305e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge FunctionType *FT = Callee->getFunctionType(); 2315e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge LLVMContext &Context = CI->getParent()->getContext(); 2325e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 2335e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge // Check if this has the right signature. 2345e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge if (FT->getNumParams() != 3 || 2355e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge FT->getReturnType() != FT->getParamType(0) || 2365e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge FT->getParamType(0) != FT->getParamType(1) || 2375e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge FT->getParamType(0) != Type::getInt8PtrTy(Context) || 238ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth FT->getParamType(2) != TD->getIntPtrType(Context)) 2395e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge return 0; 2405e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 2410c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1); 2420c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge if (Dst == Src) // __strcpy_chk(x,x) -> x 2430c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge return Src; 2440c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge 2455e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge // If a) we don't have any length information, or b) we know this will 246fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge // fit then just lower to a plain strcpy. Otherwise we'll keep our 247fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge // strcpy_chk call which may fail at runtime if the size is too long. 2485e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge // TODO: It might be nice to get a maximum length out of the possible 2495e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge // string lengths for varying. 2505e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge if (isFoldable(2, 1, true)) { 2510c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge Value *Ret = EmitStrCpy(Dst, Src, B, TD, TLI, Name.substr(2, 6)); 2520c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge return Ret; 2530c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge } else { 2540c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge // Maybe we can stil fold __strcpy_chk to __memcpy_chk. 2550c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge uint64_t Len = GetStringLength(Src); 2560c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge if (Len == 0) return 0; 2570c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge 2580c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge // This optimization require DataLayout. 2590c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge if (!TD) return 0; 2600c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge 2610c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge Value *Ret = 2620c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge EmitMemCpyChk(Dst, Src, 263ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth ConstantInt::get(TD->getIntPtrType(Context), Len), 264ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth CI->getArgOperand(2), B, TD, TLI); 2655e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge return Ret; 2665e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge } 2675e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge return 0; 2685e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge } 2695e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge}; 2705e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 271fa9d1372c99e5b74406a606756ba77d620d575bbMeador Ingestruct StpCpyChkOpt : public InstFortifiedLibCallOptimization { 272fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 273fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge this->CI = CI; 274fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge StringRef Name = Callee->getName(); 275fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge FunctionType *FT = Callee->getFunctionType(); 276fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge LLVMContext &Context = CI->getParent()->getContext(); 277fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge 278fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge // Check if this has the right signature. 279fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge if (FT->getNumParams() != 3 || 280fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge FT->getReturnType() != FT->getParamType(0) || 281fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge FT->getParamType(0) != FT->getParamType(1) || 282fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge FT->getParamType(0) != Type::getInt8PtrTy(Context) || 283fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge FT->getParamType(2) != TD->getIntPtrType(FT->getParamType(0))) 284fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge return 0; 285fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge 286fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1); 287fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge if (Dst == Src) { // stpcpy(x,x) -> x+strlen(x) 288fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge Value *StrLen = EmitStrLen(Src, B, TD, TLI); 289fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge return StrLen ? B.CreateInBoundsGEP(Dst, StrLen) : 0; 290fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge } 291fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge 292fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge // If a) we don't have any length information, or b) we know this will 293fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge // fit then just lower to a plain stpcpy. Otherwise we'll keep our 294fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge // stpcpy_chk call which may fail at runtime if the size is too long. 295fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge // TODO: It might be nice to get a maximum length out of the possible 296fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge // string lengths for varying. 297fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge if (isFoldable(2, 1, true)) { 298fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge Value *Ret = EmitStrCpy(Dst, Src, B, TD, TLI, Name.substr(2, 6)); 299fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge return Ret; 300fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge } else { 301fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge // Maybe we can stil fold __stpcpy_chk to __memcpy_chk. 302fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge uint64_t Len = GetStringLength(Src); 303fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge if (Len == 0) return 0; 304fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge 305fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge // This optimization require DataLayout. 306fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge if (!TD) return 0; 307fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge 308fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge Type *PT = FT->getParamType(0); 309fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge Value *LenV = ConstantInt::get(TD->getIntPtrType(PT), Len); 310fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge Value *DstEnd = B.CreateGEP(Dst, 311fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge ConstantInt::get(TD->getIntPtrType(PT), 312fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge Len - 1)); 313fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge if (!EmitMemCpyChk(Dst, Src, LenV, CI->getArgOperand(2), B, TD, TLI)) 314fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge return 0; 315fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge return DstEnd; 316fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge } 317fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge return 0; 318fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge } 319fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge}; 320fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge 3215e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingestruct StrNCpyChkOpt : public InstFortifiedLibCallOptimization { 3225e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 3235e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge this->CI = CI; 3245e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge StringRef Name = Callee->getName(); 3255e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge FunctionType *FT = Callee->getFunctionType(); 3265e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge LLVMContext &Context = CI->getParent()->getContext(); 3275e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 3285e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge // Check if this has the right signature. 3295e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) || 3305e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge FT->getParamType(0) != FT->getParamType(1) || 3315e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge FT->getParamType(0) != Type::getInt8PtrTy(Context) || 3325e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge !FT->getParamType(2)->isIntegerTy() || 333ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth FT->getParamType(3) != TD->getIntPtrType(Context)) 3345e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge return 0; 3355e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 3365e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge if (isFoldable(3, 2, false)) { 3375e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge Value *Ret = EmitStrNCpy(CI->getArgOperand(0), CI->getArgOperand(1), 3385e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge CI->getArgOperand(2), B, TD, TLI, 3395e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge Name.substr(2, 7)); 3405e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge return Ret; 3415e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge } 3425e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge return 0; 3435e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge } 3445e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge}; 3455e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 34673d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge//===----------------------------------------------------------------------===// 34773d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge// String and Memory Library Call Optimizations 34873d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge//===----------------------------------------------------------------------===// 34973d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge 35073d8a5864fe8c52be2b710c10ec155019738aad5Meador Ingestruct StrCatOpt : public LibCallOptimization { 35173d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 35273d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge // Verify the "strcat" function prototype. 35373d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge FunctionType *FT = Callee->getFunctionType(); 35473d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge if (FT->getNumParams() != 2 || 35573d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge FT->getReturnType() != B.getInt8PtrTy() || 35673d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge FT->getParamType(0) != FT->getReturnType() || 35773d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge FT->getParamType(1) != FT->getReturnType()) 35873d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge return 0; 35973d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge 36073d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge // Extract some information from the instruction 36173d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge Value *Dst = CI->getArgOperand(0); 36273d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge Value *Src = CI->getArgOperand(1); 36373d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge 36473d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge // See if we can get the length of the input string. 36573d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge uint64_t Len = GetStringLength(Src); 36673d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge if (Len == 0) return 0; 36773d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge --Len; // Unbias length. 36873d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge 36973d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge // Handle the simple, do-nothing case: strcat(x, "") -> x 37073d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge if (Len == 0) 37173d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge return Dst; 37273d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge 37373d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge // These optimizations require DataLayout. 37473d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge if (!TD) return 0; 37573d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge 37673d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge return emitStrLenMemCpy(Src, Dst, Len, B); 37773d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge } 37873d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge 37973d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge Value *emitStrLenMemCpy(Value *Src, Value *Dst, uint64_t Len, 38073d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge IRBuilder<> &B) { 38173d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge // We need to find the end of the destination string. That's where the 38273d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge // memory is to be moved to. We just generate a call to strlen. 38373d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge Value *DstLen = EmitStrLen(Dst, B, TD, TLI); 38473d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge if (!DstLen) 38573d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge return 0; 38673d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge 38773d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge // Now that we have the destination's length, we must index into the 38873d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge // destination's pointer to get the actual memcpy destination (end of 38973d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge // the string .. we're concatenating). 39073d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge Value *CpyDst = B.CreateGEP(Dst, DstLen, "endptr"); 39173d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge 39273d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge // We have enough information to now generate the memcpy call to do the 39373d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge // concatenation for us. Make a memcpy to copy the nul byte with align = 1. 39473d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge B.CreateMemCpy(CpyDst, Src, 395ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth ConstantInt::get(TD->getIntPtrType(*Context), Len + 1), 1); 39673d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge return Dst; 39773d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge } 39873d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge}; 39973d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge 40073d8a5864fe8c52be2b710c10ec155019738aad5Meador Ingestruct StrNCatOpt : public StrCatOpt { 40173d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 40273d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge // Verify the "strncat" function prototype. 40373d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge FunctionType *FT = Callee->getFunctionType(); 40473d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge if (FT->getNumParams() != 3 || 40573d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge FT->getReturnType() != B.getInt8PtrTy() || 40673d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge FT->getParamType(0) != FT->getReturnType() || 40773d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge FT->getParamType(1) != FT->getReturnType() || 40873d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge !FT->getParamType(2)->isIntegerTy()) 40973d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge return 0; 41073d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge 41173d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge // Extract some information from the instruction 41273d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge Value *Dst = CI->getArgOperand(0); 41373d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge Value *Src = CI->getArgOperand(1); 41473d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge uint64_t Len; 41573d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge 41673d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge // We don't do anything if length is not constant 41773d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(CI->getArgOperand(2))) 41873d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge Len = LengthArg->getZExtValue(); 41973d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge else 42073d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge return 0; 42173d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge 42273d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge // See if we can get the length of the input string. 42373d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge uint64_t SrcLen = GetStringLength(Src); 42473d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge if (SrcLen == 0) return 0; 42573d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge --SrcLen; // Unbias length. 42673d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge 42773d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge // Handle the simple, do-nothing cases: 42873d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge // strncat(x, "", c) -> x 42973d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge // strncat(x, c, 0) -> x 43073d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge if (SrcLen == 0 || Len == 0) return Dst; 43173d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge 43273d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge // These optimizations require DataLayout. 43373d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge if (!TD) return 0; 43473d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge 43573d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge // We don't optimize this case 43673d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge if (Len < SrcLen) return 0; 43773d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge 43873d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge // strncat(x, s, c) -> strcat(x, s) 43973d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge // s is constant so the strcat can be optimized further 44073d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge return emitStrLenMemCpy(Src, Dst, SrcLen, B); 44173d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge } 44273d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge}; 44373d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge 444186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Ingestruct StrChrOpt : public LibCallOptimization { 445186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 446186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge // Verify the "strchr" function prototype. 447186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge FunctionType *FT = Callee->getFunctionType(); 448186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge if (FT->getNumParams() != 2 || 449186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge FT->getReturnType() != B.getInt8PtrTy() || 450186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge FT->getParamType(0) != FT->getReturnType() || 451186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge !FT->getParamType(1)->isIntegerTy(32)) 452186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge return 0; 453186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge 454186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge Value *SrcStr = CI->getArgOperand(0); 455186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge 456186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge // If the second operand is non-constant, see if we can compute the length 457186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge // of the input string and turn this into memchr. 458186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge ConstantInt *CharC = dyn_cast<ConstantInt>(CI->getArgOperand(1)); 459186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge if (CharC == 0) { 460186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge // These optimizations require DataLayout. 461186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge if (!TD) return 0; 462186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge 463186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge uint64_t Len = GetStringLength(SrcStr); 464186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge if (Len == 0 || !FT->getParamType(1)->isIntegerTy(32))// memchr needs i32. 465186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge return 0; 466186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge 467186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge return EmitMemChr(SrcStr, CI->getArgOperand(1), // include nul. 468ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth ConstantInt::get(TD->getIntPtrType(*Context), Len), 469186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge B, TD, TLI); 470186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge } 471186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge 472186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge // Otherwise, the character is a constant, see if the first argument is 473186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge // a string literal. If so, we can constant fold. 474186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge StringRef Str; 475186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge if (!getConstantStringInfo(SrcStr, Str)) 476186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge return 0; 477186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge 478186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge // Compute the offset, make sure to handle the case when we're searching for 479186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge // zero (a weird way to spell strlen). 480186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge size_t I = CharC->getSExtValue() == 0 ? 481186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge Str.size() : Str.find(CharC->getSExtValue()); 482186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge if (I == StringRef::npos) // Didn't find the char. strchr returns null. 483186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge return Constant::getNullValue(CI->getType()); 484186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge 485186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge // strchr(s+n,c) -> gep(s+n+i,c) 486186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge return B.CreateGEP(SrcStr, B.getInt64(I), "strchr"); 487186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge } 488186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge}; 489186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge 490186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Ingestruct StrRChrOpt : public LibCallOptimization { 491186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 492186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge // Verify the "strrchr" function prototype. 493186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge FunctionType *FT = Callee->getFunctionType(); 494186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge if (FT->getNumParams() != 2 || 495186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge FT->getReturnType() != B.getInt8PtrTy() || 496186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge FT->getParamType(0) != FT->getReturnType() || 497186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge !FT->getParamType(1)->isIntegerTy(32)) 498186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge return 0; 499186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge 500186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge Value *SrcStr = CI->getArgOperand(0); 501186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge ConstantInt *CharC = dyn_cast<ConstantInt>(CI->getArgOperand(1)); 502186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge 503186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge // Cannot fold anything if we're not looking for a constant. 504186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge if (!CharC) 505186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge return 0; 506186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge 507186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge StringRef Str; 508186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge if (!getConstantStringInfo(SrcStr, Str)) { 509186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge // strrchr(s, 0) -> strchr(s, 0) 510186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge if (TD && CharC->isZero()) 511186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge return EmitStrChr(SrcStr, '\0', B, TD, TLI); 512186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge return 0; 513186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge } 514186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge 515186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge // Compute the offset. 516186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge size_t I = CharC->getSExtValue() == 0 ? 517186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge Str.size() : Str.rfind(CharC->getSExtValue()); 518186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge if (I == StringRef::npos) // Didn't find the char. Return null. 519186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge return Constant::getNullValue(CI->getType()); 520186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge 521186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge // strrchr(s+n,c) -> gep(s+n+i,c) 522186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge return B.CreateGEP(SrcStr, B.getInt64(I), "strrchr"); 523186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge } 524186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge}; 525186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge 526a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Ingestruct StrCmpOpt : public LibCallOptimization { 527a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 528a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge // Verify the "strcmp" function prototype. 529a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge FunctionType *FT = Callee->getFunctionType(); 530a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge if (FT->getNumParams() != 2 || 531a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge !FT->getReturnType()->isIntegerTy(32) || 532a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge FT->getParamType(0) != FT->getParamType(1) || 533a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge FT->getParamType(0) != B.getInt8PtrTy()) 534a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge return 0; 535a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge 536a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge Value *Str1P = CI->getArgOperand(0), *Str2P = CI->getArgOperand(1); 537a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge if (Str1P == Str2P) // strcmp(x,x) -> 0 538a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge return ConstantInt::get(CI->getType(), 0); 539a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge 540a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge StringRef Str1, Str2; 541a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge bool HasStr1 = getConstantStringInfo(Str1P, Str1); 542a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge bool HasStr2 = getConstantStringInfo(Str2P, Str2); 543a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge 544a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge // strcmp(x, y) -> cnst (if both x and y are constant strings) 545a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge if (HasStr1 && HasStr2) 546a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge return ConstantInt::get(CI->getType(), Str1.compare(Str2)); 547a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge 548a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge if (HasStr1 && Str1.empty()) // strcmp("", x) -> -*x 549a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge return B.CreateNeg(B.CreateZExt(B.CreateLoad(Str2P, "strcmpload"), 550a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge CI->getType())); 551a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge 552a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge if (HasStr2 && Str2.empty()) // strcmp(x,"") -> *x 553a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge return B.CreateZExt(B.CreateLoad(Str1P, "strcmpload"), CI->getType()); 554a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge 555a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge // strcmp(P, "x") -> memcmp(P, "x", 2) 556a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge uint64_t Len1 = GetStringLength(Str1P); 557a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge uint64_t Len2 = GetStringLength(Str2P); 558a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge if (Len1 && Len2) { 559a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge // These optimizations require DataLayout. 560a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge if (!TD) return 0; 561a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge 562a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge return EmitMemCmp(Str1P, Str2P, 563ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth ConstantInt::get(TD->getIntPtrType(*Context), 564a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge std::min(Len1, Len2)), B, TD, TLI); 565a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge } 566a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge 567a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge return 0; 568a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge } 569a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge}; 570a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge 571a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Ingestruct StrNCmpOpt : public LibCallOptimization { 572a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 573a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge // Verify the "strncmp" function prototype. 574a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge FunctionType *FT = Callee->getFunctionType(); 575a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge if (FT->getNumParams() != 3 || 576a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge !FT->getReturnType()->isIntegerTy(32) || 577a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge FT->getParamType(0) != FT->getParamType(1) || 578a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge FT->getParamType(0) != B.getInt8PtrTy() || 579a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge !FT->getParamType(2)->isIntegerTy()) 580a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge return 0; 581a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge 582a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge Value *Str1P = CI->getArgOperand(0), *Str2P = CI->getArgOperand(1); 583a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge if (Str1P == Str2P) // strncmp(x,x,n) -> 0 584a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge return ConstantInt::get(CI->getType(), 0); 585a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge 586a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge // Get the length argument if it is constant. 587a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge uint64_t Length; 588a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(CI->getArgOperand(2))) 589a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge Length = LengthArg->getZExtValue(); 590a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge else 591a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge return 0; 592a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge 593a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge if (Length == 0) // strncmp(x,y,0) -> 0 594a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge return ConstantInt::get(CI->getType(), 0); 595a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge 596a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge if (TD && Length == 1) // strncmp(x,y,1) -> memcmp(x,y,1) 597a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge return EmitMemCmp(Str1P, Str2P, CI->getArgOperand(2), B, TD, TLI); 598a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge 599a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge StringRef Str1, Str2; 600a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge bool HasStr1 = getConstantStringInfo(Str1P, Str1); 601a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge bool HasStr2 = getConstantStringInfo(Str2P, Str2); 602a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge 603a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge // strncmp(x, y) -> cnst (if both x and y are constant strings) 604a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge if (HasStr1 && HasStr2) { 605a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge StringRef SubStr1 = Str1.substr(0, Length); 606a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge StringRef SubStr2 = Str2.substr(0, Length); 607a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge return ConstantInt::get(CI->getType(), SubStr1.compare(SubStr2)); 608a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge } 609a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge 610a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge if (HasStr1 && Str1.empty()) // strncmp("", x, n) -> -*x 611a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge return B.CreateNeg(B.CreateZExt(B.CreateLoad(Str2P, "strcmpload"), 612a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge CI->getType())); 613a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge 614a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge if (HasStr2 && Str2.empty()) // strncmp(x, "", n) -> *x 615a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge return B.CreateZExt(B.CreateLoad(Str1P, "strcmpload"), CI->getType()); 616a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge 617a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge return 0; 618a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge } 619a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge}; 620a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge 6210c41d57b09884b92f988cb88553eaa7c77819d4bMeador Ingestruct StrCpyOpt : public LibCallOptimization { 6220c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 6230c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge // Verify the "strcpy" function prototype. 6240c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge FunctionType *FT = Callee->getFunctionType(); 6250c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge if (FT->getNumParams() != 2 || 6260c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge FT->getReturnType() != FT->getParamType(0) || 6270c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge FT->getParamType(0) != FT->getParamType(1) || 6280c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge FT->getParamType(0) != B.getInt8PtrTy()) 6290c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge return 0; 6300c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge 6310c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1); 6320c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge if (Dst == Src) // strcpy(x,x) -> x 6330c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge return Src; 6340c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge 6350c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge // These optimizations require DataLayout. 6360c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge if (!TD) return 0; 6370c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge 6380c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge // See if we can get the length of the input string. 6390c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge uint64_t Len = GetStringLength(Src); 6400c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge if (Len == 0) return 0; 6410c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge 6420c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge // We have enough information to now generate the memcpy call to do the 6430c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge // copy for us. Make a memcpy to copy the nul byte with align = 1. 6440c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge B.CreateMemCpy(Dst, Src, 645ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth ConstantInt::get(TD->getIntPtrType(*Context), Len), 1); 6460c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge return Dst; 6470c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge } 6480c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge}; 6490c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge 650e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Ingestruct StpCpyOpt: public LibCallOptimization { 651e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 652e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge // Verify the "stpcpy" function prototype. 653e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge FunctionType *FT = Callee->getFunctionType(); 654e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge if (FT->getNumParams() != 2 || 655e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge FT->getReturnType() != FT->getParamType(0) || 656e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge FT->getParamType(0) != FT->getParamType(1) || 657e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge FT->getParamType(0) != B.getInt8PtrTy()) 658e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge return 0; 659e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge 660e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge // These optimizations require DataLayout. 661e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge if (!TD) return 0; 662e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge 663e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1); 664e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge if (Dst == Src) { // stpcpy(x,x) -> x+strlen(x) 665e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge Value *StrLen = EmitStrLen(Src, B, TD, TLI); 666e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge return StrLen ? B.CreateInBoundsGEP(Dst, StrLen) : 0; 667e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge } 668e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge 669e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge // See if we can get the length of the input string. 670e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge uint64_t Len = GetStringLength(Src); 671e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge if (Len == 0) return 0; 672e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge 673e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge Type *PT = FT->getParamType(0); 674e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge Value *LenV = ConstantInt::get(TD->getIntPtrType(PT), Len); 675e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge Value *DstEnd = B.CreateGEP(Dst, 676e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge ConstantInt::get(TD->getIntPtrType(PT), 677e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge Len - 1)); 678e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge 679e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge // We have enough information to now generate the memcpy call to do the 680e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge // copy for us. Make a memcpy to copy the nul byte with align = 1. 681e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge B.CreateMemCpy(Dst, Src, LenV, 1); 682e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge return DstEnd; 683e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge } 684e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge}; 685e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge 686a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Ingestruct StrNCpyOpt : public LibCallOptimization { 687a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 688a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge FunctionType *FT = Callee->getFunctionType(); 689a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) || 690a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge FT->getParamType(0) != FT->getParamType(1) || 691a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge FT->getParamType(0) != B.getInt8PtrTy() || 692a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge !FT->getParamType(2)->isIntegerTy()) 693a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge return 0; 694a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge 695a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge Value *Dst = CI->getArgOperand(0); 696a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge Value *Src = CI->getArgOperand(1); 697a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge Value *LenOp = CI->getArgOperand(2); 698a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge 699a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge // See if we can get the length of the input string. 700a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge uint64_t SrcLen = GetStringLength(Src); 701a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge if (SrcLen == 0) return 0; 702a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge --SrcLen; 703a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge 704a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge if (SrcLen == 0) { 705a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge // strncpy(x, "", y) -> memset(x, '\0', y, 1) 706a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge B.CreateMemSet(Dst, B.getInt8('\0'), LenOp, 1); 707a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge return Dst; 708a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge } 709a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge 710a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge uint64_t Len; 711a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(LenOp)) 712a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge Len = LengthArg->getZExtValue(); 713a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge else 714a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge return 0; 715a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge 716a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge if (Len == 0) return Dst; // strncpy(x, y, 0) -> x 717a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge 718a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge // These optimizations require DataLayout. 719a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge if (!TD) return 0; 720a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge 721a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge // Let strncpy handle the zero padding 722a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge if (Len > SrcLen+1) return 0; 723a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge 724a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge Type *PT = FT->getParamType(0); 725a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge // strncpy(x, s, c) -> memcpy(x, s, c, 1) [s and c are constant] 726a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge B.CreateMemCpy(Dst, Src, 727a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge ConstantInt::get(TD->getIntPtrType(PT), Len), 1); 728a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge 729a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge return Dst; 730a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge } 731a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge}; 732a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge 73357cfd71f881ae381fa43667e003f595ffd70ea18Meador Ingestruct StrLenOpt : public LibCallOptimization { 73433daeab1bb8df65273fd9ecbf1a261f96733732eChad Rosier virtual bool ignoreCallingConv() { return true; } 73557cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 73657cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge FunctionType *FT = Callee->getFunctionType(); 73757cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge if (FT->getNumParams() != 1 || 73857cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge FT->getParamType(0) != B.getInt8PtrTy() || 73957cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge !FT->getReturnType()->isIntegerTy()) 74057cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge return 0; 74157cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge 74257cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge Value *Src = CI->getArgOperand(0); 74357cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge 74457cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge // Constant folding: strlen("xyz") -> 3 74557cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge if (uint64_t Len = GetStringLength(Src)) 74657cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge return ConstantInt::get(CI->getType(), Len-1); 74757cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge 74857cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge // strlen(x) != 0 --> *x != 0 74957cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge // strlen(x) == 0 --> *x == 0 75057cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge if (isOnlyUsedInZeroEqualityComparison(CI)) 75157cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge return B.CreateZExt(B.CreateLoad(Src, "strlenfirst"), CI->getType()); 75257cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge return 0; 75357cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge } 75457cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge}; 75557cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge 75608684d1f069711692502d091669a6031c31cdd4aMeador Ingestruct StrPBrkOpt : public LibCallOptimization { 75708684d1f069711692502d091669a6031c31cdd4aMeador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 75808684d1f069711692502d091669a6031c31cdd4aMeador Inge FunctionType *FT = Callee->getFunctionType(); 75908684d1f069711692502d091669a6031c31cdd4aMeador Inge if (FT->getNumParams() != 2 || 76008684d1f069711692502d091669a6031c31cdd4aMeador Inge FT->getParamType(0) != B.getInt8PtrTy() || 76108684d1f069711692502d091669a6031c31cdd4aMeador Inge FT->getParamType(1) != FT->getParamType(0) || 76208684d1f069711692502d091669a6031c31cdd4aMeador Inge FT->getReturnType() != FT->getParamType(0)) 76308684d1f069711692502d091669a6031c31cdd4aMeador Inge return 0; 76408684d1f069711692502d091669a6031c31cdd4aMeador Inge 76508684d1f069711692502d091669a6031c31cdd4aMeador Inge StringRef S1, S2; 76608684d1f069711692502d091669a6031c31cdd4aMeador Inge bool HasS1 = getConstantStringInfo(CI->getArgOperand(0), S1); 76708684d1f069711692502d091669a6031c31cdd4aMeador Inge bool HasS2 = getConstantStringInfo(CI->getArgOperand(1), S2); 76808684d1f069711692502d091669a6031c31cdd4aMeador Inge 76908684d1f069711692502d091669a6031c31cdd4aMeador Inge // strpbrk(s, "") -> NULL 77008684d1f069711692502d091669a6031c31cdd4aMeador Inge // strpbrk("", s) -> NULL 77108684d1f069711692502d091669a6031c31cdd4aMeador Inge if ((HasS1 && S1.empty()) || (HasS2 && S2.empty())) 77208684d1f069711692502d091669a6031c31cdd4aMeador Inge return Constant::getNullValue(CI->getType()); 77308684d1f069711692502d091669a6031c31cdd4aMeador Inge 77408684d1f069711692502d091669a6031c31cdd4aMeador Inge // Constant folding. 77508684d1f069711692502d091669a6031c31cdd4aMeador Inge if (HasS1 && HasS2) { 77608684d1f069711692502d091669a6031c31cdd4aMeador Inge size_t I = S1.find_first_of(S2); 77708684d1f069711692502d091669a6031c31cdd4aMeador Inge if (I == std::string::npos) // No match. 77808684d1f069711692502d091669a6031c31cdd4aMeador Inge return Constant::getNullValue(CI->getType()); 77908684d1f069711692502d091669a6031c31cdd4aMeador Inge 78008684d1f069711692502d091669a6031c31cdd4aMeador Inge return B.CreateGEP(CI->getArgOperand(0), B.getInt64(I), "strpbrk"); 78108684d1f069711692502d091669a6031c31cdd4aMeador Inge } 78208684d1f069711692502d091669a6031c31cdd4aMeador Inge 78308684d1f069711692502d091669a6031c31cdd4aMeador Inge // strpbrk(s, "a") -> strchr(s, 'a') 78408684d1f069711692502d091669a6031c31cdd4aMeador Inge if (TD && HasS2 && S2.size() == 1) 78508684d1f069711692502d091669a6031c31cdd4aMeador Inge return EmitStrChr(CI->getArgOperand(0), S2[0], B, TD, TLI); 78608684d1f069711692502d091669a6031c31cdd4aMeador Inge 78708684d1f069711692502d091669a6031c31cdd4aMeador Inge return 0; 78808684d1f069711692502d091669a6031c31cdd4aMeador Inge } 78908684d1f069711692502d091669a6031c31cdd4aMeador Inge}; 79008684d1f069711692502d091669a6031c31cdd4aMeador Inge 791e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Ingestruct StrToOpt : public LibCallOptimization { 792e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 793e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge FunctionType *FT = Callee->getFunctionType(); 794e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge if ((FT->getNumParams() != 2 && FT->getNumParams() != 3) || 795e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge !FT->getParamType(0)->isPointerTy() || 796e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge !FT->getParamType(1)->isPointerTy()) 797e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge return 0; 798e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge 799e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge Value *EndPtr = CI->getArgOperand(1); 800e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge if (isa<ConstantPointerNull>(EndPtr)) { 801e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge // With a null EndPtr, this function won't capture the main argument. 802e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge // It would be readonly too, except that it still may write to errno. 803328d1b65002e68ae65ffef05eed19122cbf721f5Peter Collingbourne CI->addAttribute(1, Attribute::NoCapture); 804e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge } 805e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge 806e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge return 0; 807e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge } 808e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge}; 809e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge 8107629de3326318e533ab969abd1b0cbc569b3f3b7Meador Ingestruct StrSpnOpt : public LibCallOptimization { 8117629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 8127629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge FunctionType *FT = Callee->getFunctionType(); 8137629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge if (FT->getNumParams() != 2 || 8147629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge FT->getParamType(0) != B.getInt8PtrTy() || 8157629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge FT->getParamType(1) != FT->getParamType(0) || 8167629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge !FT->getReturnType()->isIntegerTy()) 8177629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge return 0; 8187629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge 8197629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge StringRef S1, S2; 8207629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge bool HasS1 = getConstantStringInfo(CI->getArgOperand(0), S1); 8217629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge bool HasS2 = getConstantStringInfo(CI->getArgOperand(1), S2); 8227629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge 8237629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge // strspn(s, "") -> 0 8247629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge // strspn("", s) -> 0 8257629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge if ((HasS1 && S1.empty()) || (HasS2 && S2.empty())) 8267629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge return Constant::getNullValue(CI->getType()); 8277629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge 8287629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge // Constant folding. 8297629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge if (HasS1 && HasS2) { 8307629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge size_t Pos = S1.find_first_not_of(S2); 8317629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge if (Pos == StringRef::npos) Pos = S1.size(); 8327629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge return ConstantInt::get(CI->getType(), Pos); 8337629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge } 8347629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge 8357629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge return 0; 8367629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge } 8377629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge}; 8387629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge 8395464ee7eaaf490444589d8716ae529827e29aa9bMeador Ingestruct StrCSpnOpt : public LibCallOptimization { 8405464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 8415464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge FunctionType *FT = Callee->getFunctionType(); 8425464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge if (FT->getNumParams() != 2 || 8435464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge FT->getParamType(0) != B.getInt8PtrTy() || 8445464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge FT->getParamType(1) != FT->getParamType(0) || 8455464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge !FT->getReturnType()->isIntegerTy()) 8465464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge return 0; 8475464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge 8485464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge StringRef S1, S2; 8495464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge bool HasS1 = getConstantStringInfo(CI->getArgOperand(0), S1); 8505464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge bool HasS2 = getConstantStringInfo(CI->getArgOperand(1), S2); 8515464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge 8525464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge // strcspn("", s) -> 0 8535464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge if (HasS1 && S1.empty()) 8545464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge return Constant::getNullValue(CI->getType()); 8555464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge 8565464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge // Constant folding. 8575464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge if (HasS1 && HasS2) { 8585464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge size_t Pos = S1.find_first_of(S2); 8595464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge if (Pos == StringRef::npos) Pos = S1.size(); 8605464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge return ConstantInt::get(CI->getType(), Pos); 8615464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge } 8625464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge 8635464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge // strcspn(s, "") -> strlen(s) 8645464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge if (TD && HasS2 && S2.empty()) 8655464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge return EmitStrLen(CI->getArgOperand(0), B, TD, TLI); 8665464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge 8675464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge return 0; 8685464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge } 8695464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge}; 8705464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge 8716e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Ingestruct StrStrOpt : public LibCallOptimization { 8726e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 8736e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge FunctionType *FT = Callee->getFunctionType(); 8746e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge if (FT->getNumParams() != 2 || 8756e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge !FT->getParamType(0)->isPointerTy() || 8766e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge !FT->getParamType(1)->isPointerTy() || 8776e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge !FT->getReturnType()->isPointerTy()) 8786e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge return 0; 8796e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge 8806e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge // fold strstr(x, x) -> x. 8816e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge if (CI->getArgOperand(0) == CI->getArgOperand(1)) 8826e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge return B.CreateBitCast(CI->getArgOperand(0), CI->getType()); 8836e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge 8846e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge // fold strstr(a, b) == a -> strncmp(a, b, strlen(b)) == 0 8856e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge if (TD && isOnlyUsedInEqualityComparison(CI, CI->getArgOperand(0))) { 8866e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge Value *StrLen = EmitStrLen(CI->getArgOperand(1), B, TD, TLI); 8876e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge if (!StrLen) 8886e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge return 0; 8896e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge Value *StrNCmp = EmitStrNCmp(CI->getArgOperand(0), CI->getArgOperand(1), 8906e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge StrLen, B, TD, TLI); 8916e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge if (!StrNCmp) 8926e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge return 0; 8936e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge for (Value::use_iterator UI = CI->use_begin(), UE = CI->use_end(); 8946e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge UI != UE; ) { 8956e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge ICmpInst *Old = cast<ICmpInst>(*UI++); 8966e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge Value *Cmp = B.CreateICmp(Old->getPredicate(), StrNCmp, 8976e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge ConstantInt::getNullValue(StrNCmp->getType()), 8986e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge "cmp"); 8996e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge LCS->replaceAllUsesWith(Old, Cmp); 9006e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge } 9016e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge return CI; 9026e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge } 9036e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge 9046e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge // See if either input string is a constant string. 9056e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge StringRef SearchStr, ToFindStr; 9066e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge bool HasStr1 = getConstantStringInfo(CI->getArgOperand(0), SearchStr); 9076e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge bool HasStr2 = getConstantStringInfo(CI->getArgOperand(1), ToFindStr); 9086e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge 9096e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge // fold strstr(x, "") -> x. 9106e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge if (HasStr2 && ToFindStr.empty()) 9116e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge return B.CreateBitCast(CI->getArgOperand(0), CI->getType()); 9126e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge 9136e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge // If both strings are known, constant fold it. 9146e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge if (HasStr1 && HasStr2) { 9156e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge std::string::size_type Offset = SearchStr.find(ToFindStr); 9166e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge 9176e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge if (Offset == StringRef::npos) // strstr("foo", "bar") -> null 9186e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge return Constant::getNullValue(CI->getType()); 9196e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge 9206e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge // strstr("abcd", "bc") -> gep((char*)"abcd", 1) 9216e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge Value *Result = CastToCStr(CI->getArgOperand(0), B); 9226e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge Result = B.CreateConstInBoundsGEP1_64(Result, Offset, "strstr"); 9236e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge return B.CreateBitCast(Result, CI->getType()); 9246e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge } 9256e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge 9266e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge // fold strstr(x, "y") -> strchr(x, 'y'). 9276e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge if (HasStr2 && ToFindStr.size() == 1) { 9286e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge Value *StrChr= EmitStrChr(CI->getArgOperand(0), ToFindStr[0], B, TD, TLI); 9296e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge return StrChr ? B.CreateBitCast(StrChr, CI->getType()) : 0; 9306e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge } 9316e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge return 0; 9326e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge } 9336e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge}; 9346e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge 935bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Ingestruct MemCmpOpt : public LibCallOptimization { 936bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 937bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge FunctionType *FT = Callee->getFunctionType(); 938bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge if (FT->getNumParams() != 3 || !FT->getParamType(0)->isPointerTy() || 939bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge !FT->getParamType(1)->isPointerTy() || 940bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge !FT->getReturnType()->isIntegerTy(32)) 941bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge return 0; 942bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge 943bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge Value *LHS = CI->getArgOperand(0), *RHS = CI->getArgOperand(1); 944bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge 945bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge if (LHS == RHS) // memcmp(s,s,x) -> 0 946bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge return Constant::getNullValue(CI->getType()); 947bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge 948bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge // Make sure we have a constant length. 949bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge ConstantInt *LenC = dyn_cast<ConstantInt>(CI->getArgOperand(2)); 950bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge if (!LenC) return 0; 951bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge uint64_t Len = LenC->getZExtValue(); 952bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge 953bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge if (Len == 0) // memcmp(s1,s2,0) -> 0 954bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge return Constant::getNullValue(CI->getType()); 955bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge 956bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge // memcmp(S1,S2,1) -> *(unsigned char*)LHS - *(unsigned char*)RHS 957bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge if (Len == 1) { 958bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge Value *LHSV = B.CreateZExt(B.CreateLoad(CastToCStr(LHS, B), "lhsc"), 959bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge CI->getType(), "lhsv"); 960bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge Value *RHSV = B.CreateZExt(B.CreateLoad(CastToCStr(RHS, B), "rhsc"), 961bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge CI->getType(), "rhsv"); 962bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge return B.CreateSub(LHSV, RHSV, "chardiff"); 963bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge } 964bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge 965bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge // Constant folding: memcmp(x, y, l) -> cnst (all arguments are constant) 966bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge StringRef LHSStr, RHSStr; 967bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge if (getConstantStringInfo(LHS, LHSStr) && 968bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge getConstantStringInfo(RHS, RHSStr)) { 969bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge // Make sure we're not reading out-of-bounds memory. 970bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge if (Len > LHSStr.size() || Len > RHSStr.size()) 971bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge return 0; 97230d8f0e9770db76f19273419c57fe112129b145aMeador Inge // Fold the memcmp and normalize the result. This way we get consistent 97330d8f0e9770db76f19273419c57fe112129b145aMeador Inge // results across multiple platforms. 97430d8f0e9770db76f19273419c57fe112129b145aMeador Inge uint64_t Ret = 0; 97530d8f0e9770db76f19273419c57fe112129b145aMeador Inge int Cmp = memcmp(LHSStr.data(), RHSStr.data(), Len); 97630d8f0e9770db76f19273419c57fe112129b145aMeador Inge if (Cmp < 0) 97730d8f0e9770db76f19273419c57fe112129b145aMeador Inge Ret = -1; 97830d8f0e9770db76f19273419c57fe112129b145aMeador Inge else if (Cmp > 0) 97930d8f0e9770db76f19273419c57fe112129b145aMeador Inge Ret = 1; 980bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge return ConstantInt::get(CI->getType(), Ret); 981bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge } 982bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge 983bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge return 0; 984bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge } 985bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge}; 986bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge 98711b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Ingestruct MemCpyOpt : public LibCallOptimization { 98811b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 98911b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge // These optimizations require DataLayout. 99011b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge if (!TD) return 0; 99111b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge 99211b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge FunctionType *FT = Callee->getFunctionType(); 99311b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) || 99411b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge !FT->getParamType(0)->isPointerTy() || 99511b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge !FT->getParamType(1)->isPointerTy() || 99611b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge FT->getParamType(2) != TD->getIntPtrType(*Context)) 99711b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge return 0; 99811b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge 99911b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge // memcpy(x, y, n) -> llvm.memcpy(x, y, n, 1) 100011b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1), 100111b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge CI->getArgOperand(2), 1); 100211b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge return CI->getArgOperand(0); 100311b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge } 100411b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge}; 100511b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge 1006d7cb600514a1d85e88ae873633bb42357babbc68Meador Ingestruct MemMoveOpt : public LibCallOptimization { 1007d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1008d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge // These optimizations require DataLayout. 1009d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge if (!TD) return 0; 1010d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge 1011d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge FunctionType *FT = Callee->getFunctionType(); 1012d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) || 1013d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge !FT->getParamType(0)->isPointerTy() || 1014d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge !FT->getParamType(1)->isPointerTy() || 1015d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge FT->getParamType(2) != TD->getIntPtrType(*Context)) 1016d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge return 0; 1017d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge 1018d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge // memmove(x, y, n) -> llvm.memmove(x, y, n, 1) 1019d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge B.CreateMemMove(CI->getArgOperand(0), CI->getArgOperand(1), 1020d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge CI->getArgOperand(2), 1); 1021d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge return CI->getArgOperand(0); 1022d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge } 1023d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge}; 1024d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge 102526ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Ingestruct MemSetOpt : public LibCallOptimization { 102626ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 102726ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge // These optimizations require DataLayout. 102826ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge if (!TD) return 0; 102926ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge 103026ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge FunctionType *FT = Callee->getFunctionType(); 103126ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) || 103226ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge !FT->getParamType(0)->isPointerTy() || 103326ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge !FT->getParamType(1)->isIntegerTy() || 103426ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge FT->getParamType(2) != TD->getIntPtrType(*Context)) 103526ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge return 0; 103626ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge 103726ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge // memset(p, v, n) -> llvm.memset(p, v, n, 1) 103826ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(), false); 103926ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge B.CreateMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), 1); 104026ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge return CI->getArgOperand(0); 104126ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge } 104226ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge}; 104326ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge 10442920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge//===----------------------------------------------------------------------===// 10452920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge// Math Library Optimizations 10462920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge//===----------------------------------------------------------------------===// 10472920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge 10482920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge//===----------------------------------------------------------------------===// 10492920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge// Double -> Float Shrinking Optimizations for Unary Functions like 'floor' 10502920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge 10512920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Ingestruct UnaryDoubleFPOpt : public LibCallOptimization { 10522920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge bool CheckRetType; 10532920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge UnaryDoubleFPOpt(bool CheckReturnType): CheckRetType(CheckReturnType) {} 10542920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 10552920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge FunctionType *FT = Callee->getFunctionType(); 10562920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge if (FT->getNumParams() != 1 || !FT->getReturnType()->isDoubleTy() || 10572920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge !FT->getParamType(0)->isDoubleTy()) 10582920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge return 0; 10592920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge 10602920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge if (CheckRetType) { 10612920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge // Check if all the uses for function like 'sin' are converted to float. 10622920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge for (Value::use_iterator UseI = CI->use_begin(); UseI != CI->use_end(); 10632920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge ++UseI) { 10642920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge FPTruncInst *Cast = dyn_cast<FPTruncInst>(*UseI); 10652920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge if (Cast == 0 || !Cast->getType()->isFloatTy()) 10662920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge return 0; 10672920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge } 10682920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge } 10692920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge 10702920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge // If this is something like 'floor((double)floatval)', convert to floorf. 10712920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge FPExtInst *Cast = dyn_cast<FPExtInst>(CI->getArgOperand(0)); 10722920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge if (Cast == 0 || !Cast->getOperand(0)->getType()->isFloatTy()) 10732920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge return 0; 10742920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge 10752920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge // floor((double)floatval) -> (double)floorf(floatval) 10762920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge Value *V = Cast->getOperand(0); 10772920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge V = EmitUnaryFloatFnCall(V, Callee->getName(), B, Callee->getAttributes()); 10782920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge return B.CreateFPExt(V, B.getDoubleTy()); 10792920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge } 10802920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge}; 10812920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge 10822920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Ingestruct UnsafeFPLibCallOptimization : public LibCallOptimization { 10832920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge bool UnsafeFPShrink; 10842920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge UnsafeFPLibCallOptimization(bool UnsafeFPShrink) { 10852920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge this->UnsafeFPShrink = UnsafeFPShrink; 10862920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge } 10872920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge}; 10882920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge 10892920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Ingestruct CosOpt : public UnsafeFPLibCallOptimization { 10902920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge CosOpt(bool UnsafeFPShrink) : UnsafeFPLibCallOptimization(UnsafeFPShrink) {} 10912920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 10922920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge Value *Ret = NULL; 10932920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge if (UnsafeFPShrink && Callee->getName() == "cos" && 10942920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge TLI->has(LibFunc::cosf)) { 10952920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge UnaryDoubleFPOpt UnsafeUnaryDoubleFP(true); 10962920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge Ret = UnsafeUnaryDoubleFP.callOptimizer(Callee, CI, B); 10972920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge } 10982920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge 10992920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge FunctionType *FT = Callee->getFunctionType(); 11002920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge // Just make sure this has 1 argument of FP type, which matches the 11012920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge // result type. 11022920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) || 11032920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge !FT->getParamType(0)->isFloatingPointTy()) 11042920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge return Ret; 11052920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge 11062920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge // cos(-x) -> cos(x) 11072920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge Value *Op1 = CI->getArgOperand(0); 11082920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge if (BinaryOperator::isFNeg(Op1)) { 11092920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge BinaryOperator *BinExpr = cast<BinaryOperator>(Op1); 11102920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge return B.CreateCall(Callee, BinExpr->getOperand(1), "cos"); 11112920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge } 11122920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge return Ret; 11132920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge } 11142920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge}; 11152920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge 11162920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Ingestruct PowOpt : public UnsafeFPLibCallOptimization { 11172920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge PowOpt(bool UnsafeFPShrink) : UnsafeFPLibCallOptimization(UnsafeFPShrink) {} 11182920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 11192920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge Value *Ret = NULL; 11202920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge if (UnsafeFPShrink && Callee->getName() == "pow" && 11212920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge TLI->has(LibFunc::powf)) { 11222920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge UnaryDoubleFPOpt UnsafeUnaryDoubleFP(true); 11232920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge Ret = UnsafeUnaryDoubleFP.callOptimizer(Callee, CI, B); 11242920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge } 11252920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge 11262920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge FunctionType *FT = Callee->getFunctionType(); 11272920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge // Just make sure this has 2 arguments of the same FP type, which match the 11282920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge // result type. 11292920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge if (FT->getNumParams() != 2 || FT->getReturnType() != FT->getParamType(0) || 11302920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge FT->getParamType(0) != FT->getParamType(1) || 11312920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge !FT->getParamType(0)->isFloatingPointTy()) 11322920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge return Ret; 11332920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge 11342920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge Value *Op1 = CI->getArgOperand(0), *Op2 = CI->getArgOperand(1); 11352920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge if (ConstantFP *Op1C = dyn_cast<ConstantFP>(Op1)) { 11362920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge if (Op1C->isExactlyValue(1.0)) // pow(1.0, x) -> 1.0 11372920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge return Op1C; 11382920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge if (Op1C->isExactlyValue(2.0)) // pow(2.0, x) -> exp2(x) 11392920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge return EmitUnaryFloatFnCall(Op2, "exp2", B, Callee->getAttributes()); 11402920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge } 11412920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge 11422920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge ConstantFP *Op2C = dyn_cast<ConstantFP>(Op2); 11432920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge if (Op2C == 0) return Ret; 11442920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge 11452920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge if (Op2C->getValueAPF().isZero()) // pow(x, 0.0) -> 1.0 11462920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge return ConstantFP::get(CI->getType(), 1.0); 11472920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge 11482920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge if (Op2C->isExactlyValue(0.5)) { 11492920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge // Expand pow(x, 0.5) to (x == -infinity ? +infinity : fabs(sqrt(x))). 11502920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge // This is faster than calling pow, and still handles negative zero 11512920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge // and negative infinity correctly. 11522920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge // TODO: In fast-math mode, this could be just sqrt(x). 11532920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge // TODO: In finite-only mode, this could be just fabs(sqrt(x)). 11542920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge Value *Inf = ConstantFP::getInfinity(CI->getType()); 11552920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge Value *NegInf = ConstantFP::getInfinity(CI->getType(), true); 11562920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge Value *Sqrt = EmitUnaryFloatFnCall(Op1, "sqrt", B, 11572920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge Callee->getAttributes()); 11582920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge Value *FAbs = EmitUnaryFloatFnCall(Sqrt, "fabs", B, 11592920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge Callee->getAttributes()); 11602920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge Value *FCmp = B.CreateFCmpOEQ(Op1, NegInf); 11612920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge Value *Sel = B.CreateSelect(FCmp, Inf, FAbs); 11622920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge return Sel; 11632920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge } 11642920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge 11652920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge if (Op2C->isExactlyValue(1.0)) // pow(x, 1.0) -> x 11662920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge return Op1; 11672920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge if (Op2C->isExactlyValue(2.0)) // pow(x, 2.0) -> x*x 11682920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge return B.CreateFMul(Op1, Op1, "pow2"); 11692920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge if (Op2C->isExactlyValue(-1.0)) // pow(x, -1.0) -> 1.0/x 11702920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge return B.CreateFDiv(ConstantFP::get(CI->getType(), 1.0), 11712920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge Op1, "powrecip"); 11722920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge return 0; 11732920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge } 11742920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge}; 11752920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge 11762920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Ingestruct Exp2Opt : public UnsafeFPLibCallOptimization { 11772920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge Exp2Opt(bool UnsafeFPShrink) : UnsafeFPLibCallOptimization(UnsafeFPShrink) {} 11782920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 11792920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge Value *Ret = NULL; 11802920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge if (UnsafeFPShrink && Callee->getName() == "exp2" && 11812920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge TLI->has(LibFunc::exp2)) { 11822920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge UnaryDoubleFPOpt UnsafeUnaryDoubleFP(true); 11832920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge Ret = UnsafeUnaryDoubleFP.callOptimizer(Callee, CI, B); 11842920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge } 11852920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge 11862920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge FunctionType *FT = Callee->getFunctionType(); 11872920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge // Just make sure this has 1 argument of FP type, which matches the 11882920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge // result type. 11892920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) || 11902920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge !FT->getParamType(0)->isFloatingPointTy()) 11912920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge return Ret; 11922920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge 11932920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge Value *Op = CI->getArgOperand(0); 11942920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge // Turn exp2(sitofp(x)) -> ldexp(1.0, sext(x)) if sizeof(x) <= 32 11952920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge // Turn exp2(uitofp(x)) -> ldexp(1.0, zext(x)) if sizeof(x) < 32 11962920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge Value *LdExpArg = 0; 11972920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge if (SIToFPInst *OpC = dyn_cast<SIToFPInst>(Op)) { 11982920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge if (OpC->getOperand(0)->getType()->getPrimitiveSizeInBits() <= 32) 11992920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge LdExpArg = B.CreateSExt(OpC->getOperand(0), B.getInt32Ty()); 12002920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge } else if (UIToFPInst *OpC = dyn_cast<UIToFPInst>(Op)) { 12012920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge if (OpC->getOperand(0)->getType()->getPrimitiveSizeInBits() < 32) 12022920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge LdExpArg = B.CreateZExt(OpC->getOperand(0), B.getInt32Ty()); 12032920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge } 12042920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge 12052920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge if (LdExpArg) { 12062920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge const char *Name; 12072920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge if (Op->getType()->isFloatTy()) 12082920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge Name = "ldexpf"; 12092920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge else if (Op->getType()->isDoubleTy()) 12102920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge Name = "ldexp"; 12112920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge else 12122920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge Name = "ldexpl"; 12132920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge 12142920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge Constant *One = ConstantFP::get(*Context, APFloat(1.0f)); 12152920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge if (!Op->getType()->isFloatTy()) 12162920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge One = ConstantExpr::getFPExtend(One, Op->getType()); 12172920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge 12182920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge Module *M = Caller->getParent(); 12192920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge Value *Callee = M->getOrInsertFunction(Name, Op->getType(), 12202920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge Op->getType(), 12212920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge B.getInt32Ty(), NULL); 12222920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge CallInst *CI = B.CreateCall2(Callee, One, LdExpArg); 12232920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts())) 12242920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge CI->setCallingConv(F->getCallingConv()); 12252920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge 12262920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge return CI; 12272920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge } 12282920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge return Ret; 12292920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge } 12302920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge}; 12312920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge 123215d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge//===----------------------------------------------------------------------===// 123315d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge// Integer Library Call Optimizations 123415d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge//===----------------------------------------------------------------------===// 123515d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge 123615d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Ingestruct FFSOpt : public LibCallOptimization { 123715d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 123815d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge FunctionType *FT = Callee->getFunctionType(); 123915d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge // Just make sure this has 2 arguments of the same FP type, which match the 124015d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge // result type. 124115d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge if (FT->getNumParams() != 1 || 124215d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge !FT->getReturnType()->isIntegerTy(32) || 124315d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge !FT->getParamType(0)->isIntegerTy()) 124415d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge return 0; 124515d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge 124615d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge Value *Op = CI->getArgOperand(0); 124715d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge 124815d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge // Constant fold. 124915d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge if (ConstantInt *CI = dyn_cast<ConstantInt>(Op)) { 125015d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge if (CI->isZero()) // ffs(0) -> 0. 125115d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge return B.getInt32(0); 125215d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge // ffs(c) -> cttz(c)+1 125315d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge return B.getInt32(CI->getValue().countTrailingZeros() + 1); 125415d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge } 125515d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge 125615d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge // ffs(x) -> x != 0 ? (i32)llvm.cttz(x)+1 : 0 125715d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge Type *ArgType = Op->getType(); 125815d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge Value *F = Intrinsic::getDeclaration(Callee->getParent(), 125915d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge Intrinsic::cttz, ArgType); 126015d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge Value *V = B.CreateCall2(F, Op, B.getFalse(), "cttz"); 126115d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge V = B.CreateAdd(V, ConstantInt::get(V->getType(), 1)); 126215d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge V = B.CreateIntCast(V, B.getInt32Ty(), false); 126315d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge 126415d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge Value *Cond = B.CreateICmpNE(Op, Constant::getNullValue(ArgType)); 126515d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge return B.CreateSelect(Cond, V, B.getInt32(0)); 126615d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge } 126715d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge}; 126815d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge 1269dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Ingestruct AbsOpt : public LibCallOptimization { 127033daeab1bb8df65273fd9ecbf1a261f96733732eChad Rosier virtual bool ignoreCallingConv() { return true; } 1271dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1272dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge FunctionType *FT = Callee->getFunctionType(); 1273dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge // We require integer(integer) where the types agree. 1274dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge if (FT->getNumParams() != 1 || !FT->getReturnType()->isIntegerTy() || 1275dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge FT->getParamType(0) != FT->getReturnType()) 1276dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge return 0; 1277dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge 1278dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge // abs(x) -> x >s -1 ? x : -x 1279dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge Value *Op = CI->getArgOperand(0); 1280dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge Value *Pos = B.CreateICmpSGT(Op, Constant::getAllOnesValue(Op->getType()), 1281dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge "ispos"); 1282dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge Value *Neg = B.CreateNeg(Op, "neg"); 1283dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge return B.CreateSelect(Pos, Op, Neg); 1284dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge } 1285dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge}; 1286dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge 1287a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Ingestruct IsDigitOpt : public LibCallOptimization { 1288a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1289a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Inge FunctionType *FT = Callee->getFunctionType(); 1290a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Inge // We require integer(i32) 1291a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Inge if (FT->getNumParams() != 1 || !FT->getReturnType()->isIntegerTy() || 1292a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Inge !FT->getParamType(0)->isIntegerTy(32)) 1293a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Inge return 0; 1294a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Inge 1295a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Inge // isdigit(c) -> (c-'0') <u 10 1296a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Inge Value *Op = CI->getArgOperand(0); 1297a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Inge Op = B.CreateSub(Op, B.getInt32('0'), "isdigittmp"); 1298a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Inge Op = B.CreateICmpULT(Op, B.getInt32(10), "isdigit"); 1299a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Inge return B.CreateZExt(Op, CI->getType()); 1300a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Inge } 1301a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Inge}; 1302a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Inge 1303017bb750ab99b2ca54771fc86a6b2fed4ad90eecMeador Ingestruct IsAsciiOpt : public LibCallOptimization { 1304017bb750ab99b2ca54771fc86a6b2fed4ad90eecMeador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1305017bb750ab99b2ca54771fc86a6b2fed4ad90eecMeador Inge FunctionType *FT = Callee->getFunctionType(); 1306017bb750ab99b2ca54771fc86a6b2fed4ad90eecMeador Inge // We require integer(i32) 1307017bb750ab99b2ca54771fc86a6b2fed4ad90eecMeador Inge if (FT->getNumParams() != 1 || !FT->getReturnType()->isIntegerTy() || 1308017bb750ab99b2ca54771fc86a6b2fed4ad90eecMeador Inge !FT->getParamType(0)->isIntegerTy(32)) 1309017bb750ab99b2ca54771fc86a6b2fed4ad90eecMeador Inge return 0; 1310017bb750ab99b2ca54771fc86a6b2fed4ad90eecMeador Inge 1311017bb750ab99b2ca54771fc86a6b2fed4ad90eecMeador Inge // isascii(c) -> c <u 128 1312017bb750ab99b2ca54771fc86a6b2fed4ad90eecMeador Inge Value *Op = CI->getArgOperand(0); 1313017bb750ab99b2ca54771fc86a6b2fed4ad90eecMeador Inge Op = B.CreateICmpULT(Op, B.getInt32(128), "isascii"); 1314017bb750ab99b2ca54771fc86a6b2fed4ad90eecMeador Inge return B.CreateZExt(Op, CI->getType()); 1315017bb750ab99b2ca54771fc86a6b2fed4ad90eecMeador Inge } 1316017bb750ab99b2ca54771fc86a6b2fed4ad90eecMeador Inge}; 1317017bb750ab99b2ca54771fc86a6b2fed4ad90eecMeador Inge 131838c4441797a9c90dee830d9b90491742ff83d42cMeador Ingestruct ToAsciiOpt : public LibCallOptimization { 131938c4441797a9c90dee830d9b90491742ff83d42cMeador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 132038c4441797a9c90dee830d9b90491742ff83d42cMeador Inge FunctionType *FT = Callee->getFunctionType(); 132138c4441797a9c90dee830d9b90491742ff83d42cMeador Inge // We require i32(i32) 132238c4441797a9c90dee830d9b90491742ff83d42cMeador Inge if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) || 132338c4441797a9c90dee830d9b90491742ff83d42cMeador Inge !FT->getParamType(0)->isIntegerTy(32)) 132438c4441797a9c90dee830d9b90491742ff83d42cMeador Inge return 0; 132538c4441797a9c90dee830d9b90491742ff83d42cMeador Inge 1326d6d685985047634e1faf5460321e21d77ec6c1bfMeador Inge // toascii(c) -> c & 0x7f 132738c4441797a9c90dee830d9b90491742ff83d42cMeador Inge return B.CreateAnd(CI->getArgOperand(0), 132838c4441797a9c90dee830d9b90491742ff83d42cMeador Inge ConstantInt::get(CI->getType(),0x7F)); 132938c4441797a9c90dee830d9b90491742ff83d42cMeador Inge } 133038c4441797a9c90dee830d9b90491742ff83d42cMeador Inge}; 133138c4441797a9c90dee830d9b90491742ff83d42cMeador Inge 1332d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge//===----------------------------------------------------------------------===// 1333d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge// Formatting and IO Library Call Optimizations 1334d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge//===----------------------------------------------------------------------===// 1335d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge 1336d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Ingestruct PrintFOpt : public LibCallOptimization { 1337d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge Value *optimizeFixedFormatString(Function *Callee, CallInst *CI, 1338d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge IRBuilder<> &B) { 1339d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge // Check for a fixed format string. 1340d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge StringRef FormatStr; 1341d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge if (!getConstantStringInfo(CI->getArgOperand(0), FormatStr)) 1342d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge return 0; 1343d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge 1344d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge // Empty format string -> noop. 1345d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge if (FormatStr.empty()) // Tolerate printf's declared void. 1346d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge return CI->use_empty() ? (Value*)CI : 1347d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge ConstantInt::get(CI->getType(), 0); 1348d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge 1349d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge // Do not do any of the following transformations if the printf return value 1350d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge // is used, in general the printf return value is not compatible with either 1351d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge // putchar() or puts(). 1352d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge if (!CI->use_empty()) 1353d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge return 0; 1354d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge 1355d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge // printf("x") -> putchar('x'), even for '%'. 1356d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge if (FormatStr.size() == 1) { 1357d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge Value *Res = EmitPutChar(B.getInt32(FormatStr[0]), B, TD, TLI); 1358d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge if (CI->use_empty() || !Res) return Res; 1359d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge return B.CreateIntCast(Res, CI->getType(), true); 1360d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge } 1361d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge 1362d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge // printf("foo\n") --> puts("foo") 1363d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge if (FormatStr[FormatStr.size()-1] == '\n' && 1364d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge FormatStr.find('%') == std::string::npos) { // no format characters. 1365d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge // Create a string literal with no \n on it. We expect the constant merge 1366d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge // pass to be run after this pass, to merge duplicate strings. 1367d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge FormatStr = FormatStr.drop_back(); 1368d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge Value *GV = B.CreateGlobalString(FormatStr, "str"); 1369d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge Value *NewCI = EmitPutS(GV, B, TD, TLI); 1370d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge return (CI->use_empty() || !NewCI) ? 1371d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge NewCI : 1372d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge ConstantInt::get(CI->getType(), FormatStr.size()+1); 1373d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge } 1374d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge 1375d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge // Optimize specific format strings. 1376d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge // printf("%c", chr) --> putchar(chr) 1377d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge if (FormatStr == "%c" && CI->getNumArgOperands() > 1 && 1378d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge CI->getArgOperand(1)->getType()->isIntegerTy()) { 1379d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge Value *Res = EmitPutChar(CI->getArgOperand(1), B, TD, TLI); 1380d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge 1381d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge if (CI->use_empty() || !Res) return Res; 1382d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge return B.CreateIntCast(Res, CI->getType(), true); 1383d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge } 1384d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge 1385d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge // printf("%s\n", str) --> puts(str) 1386d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge if (FormatStr == "%s\n" && CI->getNumArgOperands() > 1 && 1387d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge CI->getArgOperand(1)->getType()->isPointerTy()) { 1388d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge return EmitPutS(CI->getArgOperand(1), B, TD, TLI); 1389d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge } 1390d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge return 0; 1391d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge } 1392d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge 1393d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1394d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge // Require one fixed pointer argument and an integer/void result. 1395d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge FunctionType *FT = Callee->getFunctionType(); 1396d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge if (FT->getNumParams() < 1 || !FT->getParamType(0)->isPointerTy() || 1397d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge !(FT->getReturnType()->isIntegerTy() || 1398d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge FT->getReturnType()->isVoidTy())) 1399d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge return 0; 1400d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge 1401d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge if (Value *V = optimizeFixedFormatString(Callee, CI, B)) { 1402d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge return V; 1403d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge } 1404d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge 1405d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge // printf(format, ...) -> iprintf(format, ...) if no floating point 1406d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge // arguments. 1407d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge if (TLI->has(LibFunc::iprintf) && !callHasFloatingPointArgument(CI)) { 1408d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge Module *M = B.GetInsertBlock()->getParent()->getParent(); 1409d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge Constant *IPrintFFn = 1410d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge M->getOrInsertFunction("iprintf", FT, Callee->getAttributes()); 1411d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge CallInst *New = cast<CallInst>(CI->clone()); 1412d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge New->setCalledFunction(IPrintFFn); 1413d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge B.Insert(New); 1414d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge return New; 1415d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge } 1416d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge return 0; 1417d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge } 1418d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge}; 1419d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge 142069ea027e045f359b48bd436d530fc443a7cbb5c9Meador Ingestruct SPrintFOpt : public LibCallOptimization { 142169ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge Value *OptimizeFixedFormatString(Function *Callee, CallInst *CI, 142269ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge IRBuilder<> &B) { 142369ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge // Check for a fixed format string. 142469ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge StringRef FormatStr; 142569ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge if (!getConstantStringInfo(CI->getArgOperand(1), FormatStr)) 142669ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge return 0; 142769ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge 142869ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge // If we just have a format string (nothing else crazy) transform it. 142969ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge if (CI->getNumArgOperands() == 2) { 143069ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge // Make sure there's no % in the constant array. We could try to handle 143169ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge // %% -> % in the future if we cared. 143269ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge for (unsigned i = 0, e = FormatStr.size(); i != e; ++i) 143369ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge if (FormatStr[i] == '%') 143469ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge return 0; // we found a format specifier, bail out. 143569ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge 143669ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge // These optimizations require DataLayout. 143769ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge if (!TD) return 0; 143869ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge 143969ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge // sprintf(str, fmt) -> llvm.memcpy(str, fmt, strlen(fmt)+1, 1) 144069ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1), 144169ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge ConstantInt::get(TD->getIntPtrType(*Context), // Copy the 144269ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge FormatStr.size() + 1), 1); // nul byte. 144369ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge return ConstantInt::get(CI->getType(), FormatStr.size()); 144469ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge } 144569ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge 144669ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge // The remaining optimizations require the format string to be "%s" or "%c" 144769ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge // and have an extra operand. 144869ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge if (FormatStr.size() != 2 || FormatStr[0] != '%' || 144969ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge CI->getNumArgOperands() < 3) 145069ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge return 0; 145169ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge 145269ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge // Decode the second character of the format string. 145369ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge if (FormatStr[1] == 'c') { 145469ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge // sprintf(dst, "%c", chr) --> *(i8*)dst = chr; *((i8*)dst+1) = 0 145569ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge if (!CI->getArgOperand(2)->getType()->isIntegerTy()) return 0; 145669ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge Value *V = B.CreateTrunc(CI->getArgOperand(2), B.getInt8Ty(), "char"); 145769ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge Value *Ptr = CastToCStr(CI->getArgOperand(0), B); 145869ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge B.CreateStore(V, Ptr); 145969ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge Ptr = B.CreateGEP(Ptr, B.getInt32(1), "nul"); 146069ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge B.CreateStore(B.getInt8(0), Ptr); 146169ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge 146269ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge return ConstantInt::get(CI->getType(), 1); 146369ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge } 146469ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge 146569ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge if (FormatStr[1] == 's') { 146669ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge // These optimizations require DataLayout. 146769ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge if (!TD) return 0; 146869ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge 146969ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge // sprintf(dest, "%s", str) -> llvm.memcpy(dest, str, strlen(str)+1, 1) 147069ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge if (!CI->getArgOperand(2)->getType()->isPointerTy()) return 0; 147169ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge 147269ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge Value *Len = EmitStrLen(CI->getArgOperand(2), B, TD, TLI); 147369ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge if (!Len) 147469ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge return 0; 147569ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge Value *IncLen = B.CreateAdd(Len, 147669ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge ConstantInt::get(Len->getType(), 1), 147769ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge "leninc"); 147869ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(2), IncLen, 1); 147969ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge 148069ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge // The sprintf result is the unincremented number of bytes in the string. 148169ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge return B.CreateIntCast(Len, CI->getType(), false); 148269ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge } 148369ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge return 0; 148469ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge } 148569ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge 148669ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 148769ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge // Require two fixed pointer arguments and an integer result. 148869ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge FunctionType *FT = Callee->getFunctionType(); 148969ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() || 149069ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge !FT->getParamType(1)->isPointerTy() || 149169ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge !FT->getReturnType()->isIntegerTy()) 149269ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge return 0; 149369ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge 149469ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge if (Value *V = OptimizeFixedFormatString(Callee, CI, B)) { 149569ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge return V; 149669ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge } 149769ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge 149869ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge // sprintf(str, format, ...) -> siprintf(str, format, ...) if no floating 149969ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge // point arguments. 150069ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge if (TLI->has(LibFunc::siprintf) && !callHasFloatingPointArgument(CI)) { 150169ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge Module *M = B.GetInsertBlock()->getParent()->getParent(); 150269ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge Constant *SIPrintFFn = 150369ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge M->getOrInsertFunction("siprintf", FT, Callee->getAttributes()); 150469ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge CallInst *New = cast<CallInst>(CI->clone()); 150569ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge New->setCalledFunction(SIPrintFFn); 150669ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge B.Insert(New); 150769ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge return New; 150869ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge } 150969ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge return 0; 151069ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge } 151169ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge}; 151269ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge 151328d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Ingestruct FPrintFOpt : public LibCallOptimization { 151428d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge Value *optimizeFixedFormatString(Function *Callee, CallInst *CI, 151528d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge IRBuilder<> &B) { 151628d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge // All the optimizations depend on the format string. 151728d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge StringRef FormatStr; 151828d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge if (!getConstantStringInfo(CI->getArgOperand(1), FormatStr)) 151928d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge return 0; 152028d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge 1521c7ab4f99beceef00525f9a7df9ef58e63225cc7fPeter Collingbourne // Do not do any of the following transformations if the fprintf return 1522c7ab4f99beceef00525f9a7df9ef58e63225cc7fPeter Collingbourne // value is used, in general the fprintf return value is not compatible 1523c7ab4f99beceef00525f9a7df9ef58e63225cc7fPeter Collingbourne // with fwrite(), fputc() or fputs(). 1524c7ab4f99beceef00525f9a7df9ef58e63225cc7fPeter Collingbourne if (!CI->use_empty()) 1525c7ab4f99beceef00525f9a7df9ef58e63225cc7fPeter Collingbourne return 0; 1526c7ab4f99beceef00525f9a7df9ef58e63225cc7fPeter Collingbourne 152728d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge // fprintf(F, "foo") --> fwrite("foo", 3, 1, F) 152828d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge if (CI->getNumArgOperands() == 2) { 152928d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge for (unsigned i = 0, e = FormatStr.size(); i != e; ++i) 153028d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge if (FormatStr[i] == '%') // Could handle %% -> % if we cared. 153128d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge return 0; // We found a format specifier. 153228d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge 153328d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge // These optimizations require DataLayout. 153428d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge if (!TD) return 0; 153528d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge 1536c7ab4f99beceef00525f9a7df9ef58e63225cc7fPeter Collingbourne return EmitFWrite(CI->getArgOperand(1), 1537c7ab4f99beceef00525f9a7df9ef58e63225cc7fPeter Collingbourne ConstantInt::get(TD->getIntPtrType(*Context), 1538c7ab4f99beceef00525f9a7df9ef58e63225cc7fPeter Collingbourne FormatStr.size()), 1539c7ab4f99beceef00525f9a7df9ef58e63225cc7fPeter Collingbourne CI->getArgOperand(0), B, TD, TLI); 154028d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge } 154128d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge 154228d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge // The remaining optimizations require the format string to be "%s" or "%c" 154328d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge // and have an extra operand. 154428d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge if (FormatStr.size() != 2 || FormatStr[0] != '%' || 154528d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge CI->getNumArgOperands() < 3) 154628d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge return 0; 154728d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge 154828d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge // Decode the second character of the format string. 154928d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge if (FormatStr[1] == 'c') { 155028d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge // fprintf(F, "%c", chr) --> fputc(chr, F) 155128d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge if (!CI->getArgOperand(2)->getType()->isIntegerTy()) return 0; 1552c7ab4f99beceef00525f9a7df9ef58e63225cc7fPeter Collingbourne return EmitFPutC(CI->getArgOperand(2), CI->getArgOperand(0), B, TD, TLI); 155328d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge } 155428d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge 155528d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge if (FormatStr[1] == 's') { 155628d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge // fprintf(F, "%s", str) --> fputs(str, F) 1557c7ab4f99beceef00525f9a7df9ef58e63225cc7fPeter Collingbourne if (!CI->getArgOperand(2)->getType()->isPointerTy()) 155828d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge return 0; 155928d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge return EmitFPutS(CI->getArgOperand(2), CI->getArgOperand(0), B, TD, TLI); 156028d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge } 156128d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge return 0; 156228d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge } 156328d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge 156428d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 156528d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge // Require two fixed paramters as pointers and integer result. 156628d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge FunctionType *FT = Callee->getFunctionType(); 156728d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() || 156828d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge !FT->getParamType(1)->isPointerTy() || 156928d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge !FT->getReturnType()->isIntegerTy()) 157028d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge return 0; 157128d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge 157228d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge if (Value *V = optimizeFixedFormatString(Callee, CI, B)) { 157328d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge return V; 157428d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge } 157528d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge 157628d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge // fprintf(stream, format, ...) -> fiprintf(stream, format, ...) if no 157728d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge // floating point arguments. 157828d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge if (TLI->has(LibFunc::fiprintf) && !callHasFloatingPointArgument(CI)) { 157928d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge Module *M = B.GetInsertBlock()->getParent()->getParent(); 158028d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge Constant *FIPrintFFn = 158128d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge M->getOrInsertFunction("fiprintf", FT, Callee->getAttributes()); 158228d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge CallInst *New = cast<CallInst>(CI->clone()); 158328d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge New->setCalledFunction(FIPrintFFn); 158428d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge B.Insert(New); 158528d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge return New; 158628d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge } 158728d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge return 0; 158828d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge } 158928d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge}; 159028d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge 1591c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Ingestruct FWriteOpt : public LibCallOptimization { 1592c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1593c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge // Require a pointer, an integer, an integer, a pointer, returning integer. 1594c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge FunctionType *FT = Callee->getFunctionType(); 1595c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge if (FT->getNumParams() != 4 || !FT->getParamType(0)->isPointerTy() || 1596c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge !FT->getParamType(1)->isIntegerTy() || 1597c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge !FT->getParamType(2)->isIntegerTy() || 1598c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge !FT->getParamType(3)->isPointerTy() || 1599c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge !FT->getReturnType()->isIntegerTy()) 1600c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge return 0; 1601c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge 1602c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge // Get the element size and count. 1603c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge ConstantInt *SizeC = dyn_cast<ConstantInt>(CI->getArgOperand(1)); 1604c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge ConstantInt *CountC = dyn_cast<ConstantInt>(CI->getArgOperand(2)); 1605c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge if (!SizeC || !CountC) return 0; 1606c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge uint64_t Bytes = SizeC->getZExtValue()*CountC->getZExtValue(); 1607c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge 1608c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge // If this is writing zero records, remove the call (it's a noop). 1609c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge if (Bytes == 0) 1610c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge return ConstantInt::get(CI->getType(), 0); 1611c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge 1612c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge // If this is writing one byte, turn it into fputc. 1613c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge // This optimisation is only valid, if the return value is unused. 1614c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge if (Bytes == 1 && CI->use_empty()) { // fwrite(S,1,1,F) -> fputc(S[0],F) 1615c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge Value *Char = B.CreateLoad(CastToCStr(CI->getArgOperand(0), B), "char"); 1616c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge Value *NewCI = EmitFPutC(Char, CI->getArgOperand(3), B, TD, TLI); 1617c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge return NewCI ? ConstantInt::get(CI->getType(), 1) : 0; 1618c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge } 1619c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge 1620c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge return 0; 1621c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge } 1622c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge}; 1623c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge 16245c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Ingestruct FPutsOpt : public LibCallOptimization { 16255c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 16265c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge // These optimizations require DataLayout. 16275c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge if (!TD) return 0; 16285c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge 16295c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge // Require two pointers. Also, we can't optimize if return value is used. 16305c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge FunctionType *FT = Callee->getFunctionType(); 16315c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() || 16325c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge !FT->getParamType(1)->isPointerTy() || 16335c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge !CI->use_empty()) 16345c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge return 0; 16355c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge 16365c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge // fputs(s,F) --> fwrite(s,1,strlen(s),F) 16375c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge uint64_t Len = GetStringLength(CI->getArgOperand(0)); 16385c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge if (!Len) return 0; 16395c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge // Known to have no uses (see above). 16405c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge return EmitFWrite(CI->getArgOperand(0), 16415c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge ConstantInt::get(TD->getIntPtrType(*Context), Len-1), 16425c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge CI->getArgOperand(1), B, TD, TLI); 16435c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge } 16445c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge}; 16455c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge 1646aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Ingestruct PutsOpt : public LibCallOptimization { 1647aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1648aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge // Require one fixed pointer argument and an integer/void result. 1649aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge FunctionType *FT = Callee->getFunctionType(); 1650aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge if (FT->getNumParams() < 1 || !FT->getParamType(0)->isPointerTy() || 1651aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge !(FT->getReturnType()->isIntegerTy() || 1652aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge FT->getReturnType()->isVoidTy())) 1653aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge return 0; 1654aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge 1655aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge // Check for a constant string. 1656aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge StringRef Str; 1657aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge if (!getConstantStringInfo(CI->getArgOperand(0), Str)) 1658aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge return 0; 1659aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge 1660aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge if (Str.empty() && CI->use_empty()) { 1661aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge // puts("") -> putchar('\n') 1662aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge Value *Res = EmitPutChar(B.getInt32('\n'), B, TD, TLI); 1663aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge if (CI->use_empty() || !Res) return Res; 1664aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge return B.CreateIntCast(Res, CI->getType(), true); 1665aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge } 1666aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge 1667aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge return 0; 1668aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge } 1669aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge}; 1670aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge 16715e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge} // End anonymous namespace. 16725e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 16735e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingenamespace llvm { 16745e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 16755e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingeclass LibCallSimplifierImpl { 16765e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge const DataLayout *TD; 16775e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge const TargetLibraryInfo *TLI; 1678b69bf6be1b042a5f06a623fc546107fc6d9f46c4Meador Inge const LibCallSimplifier *LCS; 16792920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge bool UnsafeFPShrink; 1680bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge 16812920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge // Math library call optimizations. 168267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge CosOpt Cos; 168367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge PowOpt Pow; 168467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge Exp2Opt Exp2; 16855e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingepublic: 1686b69bf6be1b042a5f06a623fc546107fc6d9f46c4Meador Inge LibCallSimplifierImpl(const DataLayout *TD, const TargetLibraryInfo *TLI, 16872920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge const LibCallSimplifier *LCS, 16882920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge bool UnsafeFPShrink = false) 168967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge : Cos(UnsafeFPShrink), Pow(UnsafeFPShrink), Exp2(UnsafeFPShrink) { 16905e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge this->TD = TD; 16915e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge this->TLI = TLI; 1692b69bf6be1b042a5f06a623fc546107fc6d9f46c4Meador Inge this->LCS = LCS; 16932920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge this->UnsafeFPShrink = UnsafeFPShrink; 16945e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge } 16955e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 16965e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge Value *optimizeCall(CallInst *CI); 169767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge LibCallOptimization *lookupOptimization(CallInst *CI); 169867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge bool hasFloatVersion(StringRef FuncName); 16995e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge}; 17005e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 170167cb638629c69ab8c896175f58b4f472de5988d9Meador Ingebool LibCallSimplifierImpl::hasFloatVersion(StringRef FuncName) { 170267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge LibFunc::Func Func; 170367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge SmallString<20> FloatFuncName = FuncName; 170467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge FloatFuncName += 'f'; 170567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge if (TLI->getLibFunc(FloatFuncName, Func)) 170667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return TLI->has(Func); 170767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return false; 170867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge} 17092920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge 171067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge// Fortified library call optimizations. 171167cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic MemCpyChkOpt MemCpyChk; 171267cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic MemMoveChkOpt MemMoveChk; 171367cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic MemSetChkOpt MemSetChk; 171467cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrCpyChkOpt StrCpyChk; 171567cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StpCpyChkOpt StpCpyChk; 171667cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrNCpyChkOpt StrNCpyChk; 171767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge 171867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge// String library call optimizations. 171967cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrCatOpt StrCat; 172067cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrNCatOpt StrNCat; 172167cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrChrOpt StrChr; 172267cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrRChrOpt StrRChr; 172367cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrCmpOpt StrCmp; 172467cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrNCmpOpt StrNCmp; 172567cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrCpyOpt StrCpy; 172667cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StpCpyOpt StpCpy; 172767cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrNCpyOpt StrNCpy; 172867cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrLenOpt StrLen; 172967cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrPBrkOpt StrPBrk; 173067cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrToOpt StrTo; 173167cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrSpnOpt StrSpn; 173267cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrCSpnOpt StrCSpn; 173367cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrStrOpt StrStr; 173467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge 173567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge// Memory library call optimizations. 173667cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic MemCmpOpt MemCmp; 173767cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic MemCpyOpt MemCpy; 173867cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic MemMoveOpt MemMove; 173967cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic MemSetOpt MemSet; 174067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge 174167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge// Math library call optimizations. 174267cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic UnaryDoubleFPOpt UnaryDoubleFP(false); 174367cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic UnaryDoubleFPOpt UnsafeUnaryDoubleFP(true); 174467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge 174567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge // Integer library call optimizations. 174667cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic FFSOpt FFS; 174767cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic AbsOpt Abs; 174867cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic IsDigitOpt IsDigit; 174967cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic IsAsciiOpt IsAscii; 175067cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic ToAsciiOpt ToAscii; 175167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge 175267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge// Formatting and IO library call optimizations. 175367cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic PrintFOpt PrintF; 175467cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic SPrintFOpt SPrintF; 175567cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic FPrintFOpt FPrintF; 175667cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic FWriteOpt FWrite; 175767cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic FPutsOpt FPuts; 175867cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic PutsOpt Puts; 175967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge 176067cb638629c69ab8c896175f58b4f472de5988d9Meador IngeLibCallOptimization *LibCallSimplifierImpl::lookupOptimization(CallInst *CI) { 176167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge LibFunc::Func Func; 176267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge Function *Callee = CI->getCalledFunction(); 176367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge StringRef FuncName = Callee->getName(); 176467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge 176567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge // Next check for intrinsics. 176667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI)) { 176767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge switch (II->getIntrinsicID()) { 176867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case Intrinsic::pow: 176967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &Pow; 177067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case Intrinsic::exp2: 177167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &Exp2; 177267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge default: 177367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return 0; 177467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge } 17752920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge } 17762920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge 177767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge // Then check for known library functions. 177867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge if (TLI->getLibFunc(FuncName, Func) && TLI->has(Func)) { 177967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge switch (Func) { 178067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::strcat: 178167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &StrCat; 178267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::strncat: 178367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &StrNCat; 178467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::strchr: 178567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &StrChr; 178667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::strrchr: 178767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &StrRChr; 178867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::strcmp: 178967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &StrCmp; 179067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::strncmp: 179167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &StrNCmp; 179267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::strcpy: 179367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &StrCpy; 179467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::stpcpy: 179567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &StpCpy; 179667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::strncpy: 179767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &StrNCpy; 179867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::strlen: 179967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &StrLen; 180067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::strpbrk: 180167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &StrPBrk; 180267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::strtol: 180367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::strtod: 180467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::strtof: 180567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::strtoul: 180667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::strtoll: 180767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::strtold: 180867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::strtoull: 180967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &StrTo; 181067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::strspn: 181167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &StrSpn; 181267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::strcspn: 181367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &StrCSpn; 181467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::strstr: 181567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &StrStr; 181667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::memcmp: 181767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &MemCmp; 181867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::memcpy: 181967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &MemCpy; 182067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::memmove: 182167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &MemMove; 182267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::memset: 182367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &MemSet; 182467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::cosf: 182567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::cos: 182667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::cosl: 182767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &Cos; 182867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::powf: 182967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::pow: 183067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::powl: 183167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &Pow; 183267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::exp2l: 183367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::exp2: 183467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::exp2f: 183567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &Exp2; 183667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::ffs: 183767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::ffsl: 183867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::ffsll: 183967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &FFS; 184067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::abs: 184167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::labs: 184267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::llabs: 184367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &Abs; 184467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::isdigit: 184567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &IsDigit; 184667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::isascii: 184767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &IsAscii; 184867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::toascii: 184967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &ToAscii; 185067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::printf: 185167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &PrintF; 185267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::sprintf: 185367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &SPrintF; 185467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::fprintf: 185567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &FPrintF; 185667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::fwrite: 185767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &FWrite; 185867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::fputs: 185967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &FPuts; 186067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::puts: 186167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &Puts; 186267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::ceil: 186367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::fabs: 186467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::floor: 186567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::rint: 186667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::round: 186767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::nearbyint: 186867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::trunc: 186967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge if (hasFloatVersion(FuncName)) 187067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &UnaryDoubleFP; 187167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return 0; 187267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::acos: 187367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::acosh: 187467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::asin: 187567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::asinh: 187667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::atan: 187767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::atanh: 187867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::cbrt: 187967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::cosh: 188067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::exp: 188167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::exp10: 188267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::expm1: 188367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::log: 188467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::log10: 188567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::log1p: 188667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::log2: 188767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::logb: 188867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::sin: 188967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::sinh: 189067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::sqrt: 189167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::tan: 189267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::tanh: 189367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge if (UnsafeFPShrink && hasFloatVersion(FuncName)) 189467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &UnsafeUnaryDoubleFP; 189567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return 0; 189667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge case LibFunc::memcpy_chk: 189767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &MemCpyChk; 189867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge default: 189967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return 0; 190067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge } 190167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge } 190267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge 190367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge // Finally check for fortified library calls. 190467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge if (FuncName.endswith("_chk")) { 190567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge if (FuncName == "__memmove_chk") 190667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &MemMoveChk; 190767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge else if (FuncName == "__memset_chk") 190867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &MemSetChk; 190967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge else if (FuncName == "__strcpy_chk") 191067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &StrCpyChk; 191167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge else if (FuncName == "__stpcpy_chk") 191267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &StpCpyChk; 191367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge else if (FuncName == "__strncpy_chk") 191467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &StrNCpyChk; 191567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge else if (FuncName == "__stpncpy_chk") 191667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return &StrNCpyChk; 191767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge } 191867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge 191967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge return 0; 192015d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge 19215e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge} 19225e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 19235e8904576a5260cfd5b14596e338a4bb25b9817eMeador IngeValue *LibCallSimplifierImpl::optimizeCall(CallInst *CI) { 192467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge LibCallOptimization *LCO = lookupOptimization(CI); 19255e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge if (LCO) { 19265e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge IRBuilder<> Builder(CI); 1927b69bf6be1b042a5f06a623fc546107fc6d9f46c4Meador Inge return LCO->optimizeCall(CI, TD, TLI, LCS, Builder); 19285e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge } 19295e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge return 0; 19305e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge} 19315e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 19325e8904576a5260cfd5b14596e338a4bb25b9817eMeador IngeLibCallSimplifier::LibCallSimplifier(const DataLayout *TD, 19332920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge const TargetLibraryInfo *TLI, 19342920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge bool UnsafeFPShrink) { 19352920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge Impl = new LibCallSimplifierImpl(TD, TLI, this, UnsafeFPShrink); 19365e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge} 19375e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 19385e8904576a5260cfd5b14596e338a4bb25b9817eMeador IngeLibCallSimplifier::~LibCallSimplifier() { 19395e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge delete Impl; 19405e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge} 19415e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 19425e8904576a5260cfd5b14596e338a4bb25b9817eMeador IngeValue *LibCallSimplifier::optimizeCall(CallInst *CI) { 19432253a2f52f3c46ae75cd05f5885acb987bd1d6b6Michael Gottesman if (CI->isNoBuiltin()) return 0; 19445e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge return Impl->optimizeCall(CI); 19455e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge} 19465e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge 1947b69bf6be1b042a5f06a623fc546107fc6d9f46c4Meador Ingevoid LibCallSimplifier::replaceAllUsesWith(Instruction *I, Value *With) const { 1948b69bf6be1b042a5f06a623fc546107fc6d9f46c4Meador Inge I->replaceAllUsesWith(With); 1949b69bf6be1b042a5f06a623fc546107fc6d9f46c4Meador Inge I->eraseFromParent(); 1950b69bf6be1b042a5f06a623fc546107fc6d9f46c4Meador Inge} 1951b69bf6be1b042a5f06a623fc546107fc6d9f46c4Meador Inge 19525e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge} 1953be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge 1954be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// TODO: 1955be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// Additional cases that we need to add to this file: 1956be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// 1957be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// cbrt: 1958be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// * cbrt(expN(X)) -> expN(x/3) 1959be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// * cbrt(sqrt(x)) -> pow(x,1/6) 1960be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// * cbrt(sqrt(x)) -> pow(x,1/9) 1961be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// 1962be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// exp, expf, expl: 1963be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// * exp(log(x)) -> x 1964be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// 1965be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// log, logf, logl: 1966be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// * log(exp(x)) -> x 1967be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// * log(x**y) -> y*log(x) 1968be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// * log(exp(y)) -> y*log(e) 1969be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// * log(exp2(y)) -> y*log(2) 1970be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// * log(exp10(y)) -> y*log(10) 1971be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// * log(sqrt(x)) -> 0.5*log(x) 1972be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// * log(pow(x,y)) -> y*log(x) 1973be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// 1974be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// lround, lroundf, lroundl: 1975be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// * lround(cnst) -> cnst' 1976be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// 1977be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// pow, powf, powl: 1978be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// * pow(exp(x),y) -> exp(x*y) 1979be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// * pow(sqrt(x),y) -> pow(x,y*0.5) 1980be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// * pow(pow(x,y),z)-> pow(x,y*z) 1981be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// 1982be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// round, roundf, roundl: 1983be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// * round(cnst) -> cnst' 1984be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// 1985be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// signbit: 1986be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// * signbit(cnst) -> cnst' 1987be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// * signbit(nncst) -> 0 (if pstv is a non-negative constant) 1988be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// 1989be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// sqrt, sqrtf, sqrtl: 1990be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// * sqrt(expN(x)) -> expN(x*0.5) 1991be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// * sqrt(Nroot(x)) -> pow(x,1/(2*N)) 1992be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// * sqrt(pow(x,y)) -> pow(|x|,y*0.5) 1993be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// 1994be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// strchr: 1995be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// * strchr(p, 0) -> strlen(p) 1996be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// tan, tanf, tanl: 1997be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// * tan(atan(x)) -> x 1998be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// 1999be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// trunc, truncf, truncl: 2000be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// * trunc(cnst) -> cnst' 2001be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// 2002be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// 2003