[llvm-commits] CVS: llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp
Reid Spencer
reid at x10sys.com
Sun May 15 14:19:56 PDT 2005
Changes in directory llvm/lib/Transforms/IPO:
SimplifyLibCalls.cpp updated: 1.35 -> 1.36
---
Log message:
Provide this optimization as well:
ffs(x) -> (x == 0 ? 0 : 1+llvm.cttz(x))
---
Diffs of the changes: (+45 -5)
SimplifyLibCalls.cpp | 50 +++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 45 insertions(+), 5 deletions(-)
Index: llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp
diff -u llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.35 llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.36
--- llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.35 Sun May 15 12:20:47 2005
+++ llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp Sun May 15 16:19:45 2005
@@ -27,7 +27,6 @@
#include "llvm/Support/Debug.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Transforms/IPO.h"
-#include "llvm/Config/config.h"
#include <iostream>
using namespace llvm;
@@ -1673,7 +1672,6 @@
}
} 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
@@ -1709,13 +1707,43 @@
{
// ffs(cnst) -> bit#
// ffsl(cnst) -> bit#
+ // ffsll(cnst) -> bit#
uint64_t val = CI->getRawValue();
- int result = ffsll(static_cast<long long>(val));
+ int result = 0;
+ while (val != 0) {
+ result +=1;
+ if (val&1)
+ break;
+ val >>= 1;
+ }
ci->replaceAllUsesWith(ConstantSInt::get(Type::IntTy, result));
ci->eraseFromParent();
return true;
}
- return false;
+
+ // ffs(x) -> ( x == 0 ? 0 : llvm.cttz(x)+1)
+ // ffsl(x) -> ( x == 0 ? 0 : llvm.cttz(x)+1)
+ // ffsll(x) -> ( x == 0 ? 0 : llvm.cttz(x)+1)
+ const Type* arg_type = ci->getOperand(1)->getType();
+ std::vector<const Type*> args;
+ args.push_back(arg_type);
+ FunctionType* llvm_cttz_type = FunctionType::get(arg_type,args,false);
+ Function* F =
+ SLC.getModule()->getOrInsertFunction("llvm.cttz",llvm_cttz_type);
+ std::string inst_name(ci->getName()+".ffs");
+ Instruction* call =
+ new CallInst(F, ci->getOperand(1), inst_name, ci);
+ if (arg_type != Type::IntTy)
+ call = new CastInst(call, Type::IntTy, inst_name, ci);
+ BinaryOperator* add = BinaryOperator::create(Instruction::Add, call,
+ ConstantSInt::get(Type::IntTy,1), inst_name, ci);
+ SetCondInst* eq = new SetCondInst(Instruction::SetEQ,ci->getOperand(1),
+ ConstantSInt::get(ci->getOperand(1)->getType(),0),inst_name,ci);
+ SelectInst* select = new SelectInst(eq,ConstantSInt::get(Type::IntTy,0),add,
+ inst_name,ci);
+ ci->replaceAllUsesWith(select);
+ ci->eraseFromParent();
+ return true;
}
} FFSOptimizer;
@@ -1745,7 +1773,19 @@
} FFSLLOptimizer;
-#endif
+/// This LibCallOptimization will simplify calls to the "__builtin_ffs"
+/// function which is generated by the CFE (its GCC specific).
+/// It simply uses FFSOptimization for which the transformation is
+/// identical.
+/// @brief Simplify the ffsl library function.
+struct BuiltinFFSOptimization : public FFSOptimization
+{
+public:
+ /// @brief Default Constructor
+ BuiltinFFSOptimization() : FFSOptimization("__builtin_ffs",
+ "Number of '__builtin_ffs' calls simplified") {}
+
+} BuiltinFFSOptimization;
/// 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
More information about the llvm-commits
mailing list