aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms/IPO
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-08-24 17:22:17 +0000
committerChris Lattner <sabre@nondot.org>2005-08-24 17:22:17 +0000
commit53249865ec4bca31481f29b8f35e3695c90437f7 (patch)
treee0e4d653dbefa557b1894e42bef282a9bcc93c23 /lib/Transforms/IPO
parent890226dd34abbbd03fa2b026f7d920a8ebccecc4 (diff)
downloadexternal_llvm-53249865ec4bca31481f29b8f35e3695c90437f7.zip
external_llvm-53249865ec4bca31481f29b8f35e3695c90437f7.tar.gz
external_llvm-53249865ec4bca31481f29b8f35e3695c90437f7.tar.bz2
Transform floor((double)FLT) -> (double)floorf(FLT), implementing
Regression/Transforms/SimplifyLibCalls/floor.ll. This triggers 19 times in 177.mesa. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23017 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/IPO')
-rw-r--r--lib/Transforms/IPO/SimplifyLibCalls.cpp72
1 files changed, 55 insertions, 17 deletions
diff --git a/lib/Transforms/IPO/SimplifyLibCalls.cpp b/lib/Transforms/IPO/SimplifyLibCalls.cpp
index b8337d6..19e2f6c 100644
--- a/lib/Transforms/IPO/SimplifyLibCalls.cpp
+++ b/lib/Transforms/IPO/SimplifyLibCalls.cpp
@@ -129,7 +129,8 @@ private:
/// instances to all the call sites in a module, relatively efficiently. The
/// purpose of this pass is to provide optimizations for calls to well-known
/// functions with well-known semantics, such as those in the c library. The
-/// class provides the basic infrastructure for handling runOnModule. Whenever /// this pass finds a function call, it asks the appropriate optimizer to
+/// class provides the basic infrastructure for handling runOnModule. Whenever
+/// this pass finds a function call, it asks the appropriate optimizer to
/// validate the call (ValidateLibraryCall). If it is validated, then
/// the OptimizeCall method is also called.
/// @brief A ModulePass for optimizing well-known function calls.
@@ -306,22 +307,22 @@ public:
}
/// @brief Return a Function* for the memcpy libcall
- Function* get_memcpy()
- {
- if (!memcpy_func)
- {
- // Note: this is for llvm.memcpy intrinsic
- std::vector<const Type*> args;
- args.push_back(PointerType::get(Type::SByteTy));
- args.push_back(PointerType::get(Type::SByteTy));
- args.push_back(Type::UIntTy);
- args.push_back(Type::UIntTy);
- FunctionType* memcpy_type = FunctionType::get(Type::VoidTy, args, false);
- memcpy_func = M->getOrInsertFunction("llvm.memcpy",memcpy_type);
+ Function* get_memcpy() {
+ if (!memcpy_func) {
+ const Type *SBP = PointerType::get(Type::SByteTy);
+ memcpy_func = M->getOrInsertFunction("llvm.memcpy", Type::VoidTy,SBP, SBP,
+ Type::UIntTy, Type::UIntTy, 0);
}
return memcpy_func;
}
+ Function* get_floorf() {
+ if (!floorf_func)
+ floorf_func = M->getOrInsertFunction("floorf", Type::FloatTy,
+ Type::FloatTy, 0);
+ return floorf_func;
+ }
+
private:
/// @brief Reset our cached data for a new Module
void reset(Module& mod)
@@ -335,6 +336,7 @@ private:
sqrt_func = 0;
strcpy_func = 0;
strlen_func = 0;
+ floorf_func = 0;
}
private:
@@ -345,6 +347,7 @@ private:
Function* sqrt_func; ///< Cached sqrt function
Function* strcpy_func; ///< Cached strcpy function
Function* strlen_func; ///< Cached strlen function
+ Function* floorf_func; ///< Cached floorf function
Module* M; ///< Cached Module
TargetData* TD; ///< Cached TargetData
};
@@ -1238,7 +1241,7 @@ public:
else if (Op2V == -1.0)
{
// pow(x,-1.0) -> 1.0/x
- BinaryOperator* div_inst= BinaryOperator::create(Instruction::Div,
+ BinaryOperator* div_inst= BinaryOperator::createDiv(
ConstantFP::get(Ty,1.0), base, ci->getName()+".pow", ci);
ci->replaceAllUsesWith(div_inst);
ci->eraseFromParent();
@@ -1641,7 +1644,7 @@ public:
CastInst* cast =
new CastInst(ci->getOperand(1),Type::UIntTy,
ci->getOperand(1)->getName()+".uint",ci);
- BinaryOperator* sub_inst = BinaryOperator::create(Instruction::Sub,cast,
+ BinaryOperator* sub_inst = BinaryOperator::createSub(cast,
ConstantUInt::get(Type::UIntTy,0x30),
ci->getOperand(1)->getName()+".sub",ci);
SetCondInst* setcond_inst = new SetCondInst(Instruction::SetLE,sub_inst,
@@ -1682,7 +1685,7 @@ public:
{
// toascii(c) -> (c & 0x7f)
Value* chr = ci->getOperand(1);
- BinaryOperator* and_inst = BinaryOperator::create(Instruction::And,chr,
+ BinaryOperator* and_inst = BinaryOperator::createAnd(chr,
ConstantInt::get(chr->getType(),0x7F),ci->getName()+".toascii",ci);
ci->replaceAllUsesWith(and_inst);
ci->eraseFromParent();
@@ -1753,7 +1756,7 @@ public:
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,
+ 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);
@@ -1791,6 +1794,41 @@ public:
} FFSLLOptimizer;
+
+/// This LibCallOptimization will simplify calls to the "floor" library
+/// function.
+/// @brief Simplify the floor library function.
+struct FloorOptimization : public LibCallOptimization {
+ FloorOptimization()
+ : LibCallOptimization("floor", "Number of 'floor' calls simplified") {}
+
+ /// @brief Make sure that the "floor" function has the right prototype
+ virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
+ return F->arg_size() == 1 && F->arg_begin()->getType() == Type::DoubleTy &&
+ F->getReturnType() == Type::DoubleTy;
+ }
+
+ virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
+ // If this is a float argument passed in, convert to floorf.
+ // e.g. floor((double)FLT) -> (double)floorf(FLT). There can be no loss of
+ // precision due to this.
+ if (CastInst *Cast = dyn_cast<CastInst>(CI->getOperand(1)))
+ if (Cast->getOperand(0)->getType() == Type::FloatTy) {
+ Value *New = new CallInst(SLC.get_floorf(), Cast->getOperand(0),
+ CI->getName(), CI);
+ New = new CastInst(New, Type::DoubleTy, CI->getName(), CI);
+ CI->replaceAllUsesWith(New);
+ CI->eraseFromParent();
+ if (Cast->use_empty())
+ Cast->eraseFromParent();
+ return true;
+ }
+ return false; // opt failed
+ }
+} FloorOptimizer;
+
+
+
/// 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.