diff options
author | Reid Spencer <rspencer@reidspencer.com> | 2005-05-14 16:42:52 +0000 |
---|---|---|
committer | Reid Spencer <rspencer@reidspencer.com> | 2005-05-14 16:42:52 +0000 |
commit | c29b13d6486ceb2453f16d17f6cd44af55f706cc (patch) | |
tree | 8c200ad2a042abd44134874a5332cafc2ec1184b /lib | |
parent | 1ca85d567c8860a8a7cf0730107f4ee701fa4fd0 (diff) | |
download | llvm-c29b13d6486ceb2453f16d17f6cd44af55f706cc.tar.gz llvm-c29b13d6486ceb2453f16d17f6cd44af55f706cc.tar.bz2 llvm-c29b13d6486ceb2453f16d17f6cd44af55f706cc.tar.xz |
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
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Transforms/IPO/SimplifyLibCalls.cpp | 77 |
1 files changed, 74 insertions, 3 deletions
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<ConstantInt>(ci->getOperand(1))) + { + // ffs(cnst) -> bit# + // ffsl(cnst) -> bit# + uint64_t val = CI->getRawValue(); + int result = ffsll(static_cast<long long>(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) // |