summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorReid Spencer <rspencer@reidspencer.com>2005-05-14 16:42:52 +0000
committerReid Spencer <rspencer@reidspencer.com>2005-05-14 16:42:52 +0000
commitc29b13d6486ceb2453f16d17f6cd44af55f706cc (patch)
tree8c200ad2a042abd44134874a5332cafc2ec1184b /lib
parent1ca85d567c8860a8a7cf0730107f4ee701fa4fd0 (diff)
downloadllvm-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.cpp77
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)
//