From c29b13d6486ceb2453f16d17f6cd44af55f706cc Mon Sep 17 00:00:00 2001 From: Reid Spencer Date: Sat, 14 May 2005 16:42:52 +0000 Subject: [PATCH] Changes for ffs lib call simplification: * Check for availability of ffsll call in configure script * Support ffs, ffsl, and ffsll conversion to constant value if the argument is constant. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22027 91177308-0d34-0410-b5e6-96231b3b80d8 --- autoconf/configure.ac | 4 +- configure | 5 +- lib/Transforms/IPO/SimplifyLibCalls.cpp | 77 ++++++++++++++++++++++++- 3 files changed, 79 insertions(+), 7 deletions(-) diff --git a/autoconf/configure.ac b/autoconf/configure.ac index 093d9f1f47d..becdb14b32c 100644 --- a/autoconf/configure.ac +++ b/autoconf/configure.ac @@ -484,8 +484,8 @@ dnl=== SECTION 8: Check for specific functions needed dnl=== dnl===-----------------------------------------------------------------------=== -AC_CHECK_FUNCS([backtrace getcwd getpagesize getrusage gettimeofday isatty ]) -AC_CHECK_FUNCS([mkdtemp mkstemp mktemp ]) +AC_CHECK_FUNCS([backtrace ffsll getcwd getpagesize getrusage gettimeofday ]) +AC_CHECK_FUNCS([isatty mkdtemp mkstemp mktemp ]) AC_CHECK_FUNCS([realpath sbrk setrlimit strdup strerror strerror_r ]) AC_CHECK_FUNCS([strtoll strtoq sysconf]) AC_C_PRINTF_A diff --git a/configure b/configure index 948517019d2..4948bc61c54 100755 --- a/configure +++ b/configure @@ -27227,7 +27227,7 @@ fi -for ac_func in backtrace getcwd getpagesize getrusage gettimeofday isatty +for ac_func in backtrace ffsll getcwd getpagesize getrusage gettimeofday do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 @@ -27331,7 +27331,8 @@ done -for ac_func in mkdtemp mkstemp mktemp + +for ac_func in isatty mkdtemp mkstemp mktemp do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 diff --git a/lib/Transforms/IPO/SimplifyLibCalls.cpp b/lib/Transforms/IPO/SimplifyLibCalls.cpp index 24bcf4ed630..951516a1842 100644 --- a/lib/Transforms/IPO/SimplifyLibCalls.cpp +++ b/lib/Transforms/IPO/SimplifyLibCalls.cpp @@ -1672,6 +1672,80 @@ public: } } ToAsciiOptimizer; +#if defined(HAVE_FFSLL) +/// This LibCallOptimization will simplify calls to the "ffs" library +/// calls which find the first set bit in an int, long, or long long. The +/// optimization is to compute the result at compile time if the argument is +/// a constant. +/// @brief Simplify the ffs library function. +struct FFSOptimization : public LibCallOptimization +{ +protected: + /// @brief Subclass Constructor + FFSOptimization(const char* funcName, const char* description) + : LibCallOptimization(funcName, description) + {} + +public: + /// @brief Default Constructor + FFSOptimization() : LibCallOptimization("ffs", + "Number of 'ffs' calls simplified") {} + + /// @brief Destructor + virtual ~FFSOptimization() {} + + /// @brief Make sure that the "fputs" function has the right prototype + virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC) + { + // Just make sure this has 2 arguments + return (f->arg_size() == 1 && f->getReturnType() == Type::IntTy); + } + + /// @brief Perform the ffs optimization. + virtual bool OptimizeCall(CallInst* ci, SimplifyLibCalls& SLC) + { + if (ConstantInt* CI = dyn_cast(ci->getOperand(1))) + { + // ffs(cnst) -> bit# + // ffsl(cnst) -> bit# + uint64_t val = CI->getRawValue(); + int result = ffsll(static_cast(val)); + ci->replaceAllUsesWith(ConstantSInt::get(Type::IntTy, result)); + ci->eraseFromParent(); + return true; + } + return false; + } +} FFSOptimizer; + +/// This LibCallOptimization will simplify calls to the "ffsl" library +/// calls. It simply uses FFSOptimization for which the transformation is +/// identical. +/// @brief Simplify the ffsl library function. +struct FFSLOptimization : public FFSOptimization +{ +public: + /// @brief Default Constructor + FFSLOptimization() : FFSOptimization("ffsl", + "Number of 'ffsl' calls simplified") {} + +} FFSLOptimizer; + +/// This LibCallOptimization will simplify calls to the "ffsll" library +/// calls. It simply uses FFSOptimization for which the transformation is +/// identical. +/// @brief Simplify the ffsl library function. +struct FFSLLOptimization : public FFSOptimization +{ +public: + /// @brief Default Constructor + FFSLLOptimization() : FFSOptimization("ffsll", + "Number of 'ffsll' calls simplified") {} + +} FFSLLOptimizer; + +#endif + /// A function to compute the length of a null-terminated constant array of /// integers. This function can't rely on the size of the constant array /// because there could be a null terminator in the middle of the array. @@ -1788,9 +1862,6 @@ bool getConstantStringLength(Value* V, uint64_t& len, ConstantArray** CA ) // exp, expf, expl: // * exp(log(x)) -> x // -// ffs, ffsl, ffsll: -// * ffs(cnst) -> cnst' -// // isascii: // * isascii(c) -> ((c & ~0x7f) == 0) //