mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-08 03:30:22 +00:00
Provide this optimization as well:
ffs(x) -> (x == 0 ? 0 : 1+llvm.cttz(x)) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22068 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
fc87928ebb
commit
f74eb3fa2a
@ -27,7 +27,6 @@
|
|||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include "llvm/Target/TargetData.h"
|
#include "llvm/Target/TargetData.h"
|
||||||
#include "llvm/Transforms/IPO.h"
|
#include "llvm/Transforms/IPO.h"
|
||||||
#include "llvm/Config/config.h"
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
@ -1673,7 +1672,6 @@ public:
|
|||||||
}
|
}
|
||||||
} ToAsciiOptimizer;
|
} ToAsciiOptimizer;
|
||||||
|
|
||||||
#if defined(HAVE_FFSLL)
|
|
||||||
/// This LibCallOptimization will simplify calls to the "ffs" library
|
/// This LibCallOptimization will simplify calls to the "ffs" library
|
||||||
/// calls which find the first set bit in an int, long, or long long. The
|
/// 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
|
/// optimization is to compute the result at compile time if the argument is
|
||||||
@ -1709,13 +1707,43 @@ public:
|
|||||||
{
|
{
|
||||||
// ffs(cnst) -> bit#
|
// ffs(cnst) -> bit#
|
||||||
// ffsl(cnst) -> bit#
|
// ffsl(cnst) -> bit#
|
||||||
|
// ffsll(cnst) -> bit#
|
||||||
uint64_t val = CI->getRawValue();
|
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->replaceAllUsesWith(ConstantSInt::get(Type::IntTy, result));
|
||||||
ci->eraseFromParent();
|
ci->eraseFromParent();
|
||||||
return true;
|
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;
|
} FFSOptimizer;
|
||||||
|
|
||||||
@ -1745,7 +1773,19 @@ public:
|
|||||||
|
|
||||||
} FFSLLOptimizer;
|
} 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
|
/// 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
|
/// integers. This function can't rely on the size of the constant array
|
||||||
|
Loading…
Reference in New Issue
Block a user