From c29b13d6486ceb2453f16d17f6cd44af55f706cc Mon Sep 17 00:00:00 2001 From: Reid Spencer Date: Sat, 14 May 2005 16:42:52 +0000 Subject: 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 --- lib/Transforms/IPO/SimplifyLibCalls.cpp | 77 +++++++++++++++++++++++++++++++-- 1 file changed, 74 insertions(+), 3 deletions(-) (limited to 'lib/Transforms') diff --git a/lib/Transforms/IPO/SimplifyLibCalls.cpp b/lib/Transforms/IPO/SimplifyLibCalls.cpp index 24bcf4ed63..951516a184 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) // -- cgit v1.2.3-18-g5258