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 | b195fcd5ef214a5c613e54ae3922a19213bf858f (patch) | |
| tree | 1ba4047606c6df28ad5f6a50fbf8328fb45bdb22 /llvm/lib/Transforms/IPO | |
| parent | e4f71d036f7ac07f99cf1e6b32be4ffe92084454 (diff) | |
| download | bcm5719-llvm-b195fcd5ef214a5c613e54ae3922a19213bf858f.tar.gz bcm5719-llvm-b195fcd5ef214a5c613e54ae3922a19213bf858f.zip | |
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.
llvm-svn: 22027
Diffstat (limited to 'llvm/lib/Transforms/IPO')
| -rw-r--r-- | llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp | 77 |
1 files changed, 74 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp b/llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp index 24bcf4ed630..951516a1842 100644 --- a/llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp +++ b/llvm/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) // |

