[llvm-commits] CVS: llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp
Chris Lattner
lattner at cs.uiuc.edu
Tue Jan 17 10:27:28 PST 2006
Changes in directory llvm/lib/Transforms/IPO:
SimplifyLibCalls.cpp updated: 1.55 -> 1.56
---
Log message:
Clean up the FFS optimization code, and make it correctly create the appropriate
unsigned llvm.cttz.* intrinsic, fixing the 2005-05-11-Popcount-ffs-fls regression
last night.
---
Diffs of the changes: (+43 -41)
SimplifyLibCalls.cpp | 84 ++++++++++++++++++++++++++-------------------------
1 files changed, 43 insertions(+), 41 deletions(-)
Index: llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp
diff -u llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.55 llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.56
--- llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.55 Sat Oct 22 23:37:20 2005
+++ llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp Tue Jan 17 12:27:17 2006
@@ -1810,69 +1810,71 @@
/// 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
-{
+struct FFSOptimization : public LibCallOptimization {
protected:
/// @brief Subclass Constructor
FFSOptimization(const char* funcName, const char* description)
- : LibCallOptimization(funcName, description)
- {}
+ : LibCallOptimization(funcName, description) {}
public:
/// @brief Default Constructor
FFSOptimization() : LibCallOptimization("ffs",
"Number of 'ffs' calls simplified") {}
- /// @brief Make sure that the "fputs" function has the right prototype
- virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC)
- {
+ /// @brief Make sure that the "ffs" 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);
+ 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)))
- {
+ virtual bool OptimizeCall(CallInst *TheCall, SimplifyLibCalls &SLC) {
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(TheCall->getOperand(1))) {
// ffs(cnst) -> bit#
// ffsl(cnst) -> bit#
// ffsll(cnst) -> bit#
uint64_t val = CI->getRawValue();
int result = 0;
- while (val != 0) {
- result +=1;
- if (val&1)
- break;
- val >>= 1;
+ if (val) {
+ ++result;
+ while ((val & 1) == 0) {
+ ++result;
+ val >>= 1;
+ }
}
- ci->replaceAllUsesWith(ConstantSInt::get(Type::IntTy, result));
- ci->eraseFromParent();
+ TheCall->replaceAllUsesWith(ConstantSInt::get(Type::IntTy, result));
+ TheCall->eraseFromParent();
return true;
}
- // 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::createAdd(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();
+ // 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 *ArgType = TheCall->getOperand(1)->getType();
+ ArgType = ArgType->getUnsignedVersion();
+ const char *CTTZName;
+ switch (ArgType->getTypeID()) {
+ default: assert(0 && "Unknown unsigned type!");
+ case Type::UByteTyID : CTTZName = "llvm.cttz.i8" ; break;
+ case Type::UShortTyID: CTTZName = "llvm.cttz.i16"; break;
+ case Type::UIntTyID : CTTZName = "llvm.cttz.i32"; break;
+ case Type::ULongTyID : CTTZName = "llvm.cttz.i64"; break;
+ }
+
+ Function *F = SLC.getModule()->getOrInsertFunction(CTTZName, ArgType,
+ ArgType, NULL);
+ Value *V = new CastInst(TheCall->getOperand(1), ArgType, "tmp", TheCall);
+ Value *V2 = new CallInst(F, V, "tmp", TheCall);
+ V2 = new CastInst(V2, Type::IntTy, "tmp", TheCall);
+ V2 = BinaryOperator::createAdd(V2, ConstantSInt::get(Type::IntTy, 1),
+ "tmp", TheCall);
+ Value *Cond =
+ BinaryOperator::createSetEQ(V, Constant::getNullValue(V->getType()),
+ "tmp", TheCall);
+ V2 = new SelectInst(Cond, ConstantInt::get(Type::IntTy, 0), V2,
+ TheCall->getName(), TheCall);
+ TheCall->replaceAllUsesWith(V2);
+ TheCall->eraseFromParent();
return true;
}
} FFSOptimizer;
More information about the llvm-commits
mailing list