[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