From: John Criswell Date: Thu, 27 Oct 2005 16:00:10 +0000 (+0000) Subject: Move some constant folding functions into LLVMAnalysis since they are used X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=bd9d37026a5c17d9a51371a6a5446bf4761ee7d6;p=oota-llvm.git Move some constant folding functions into LLVMAnalysis since they are used by Analysis and Transformation passes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24038 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Analysis/ConstantFolding.h b/include/llvm/Analysis/ConstantFolding.h new file mode 100644 index 00000000000..4e996f9d089 --- /dev/null +++ b/include/llvm/Analysis/ConstantFolding.h @@ -0,0 +1,36 @@ +//===-- ConstantFolding.h - Analyze constant folding possibilities --------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This family of functions determines the possibility of performing constant +// folding. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Constants.h" +#include "llvm/Function.h" +using namespace llvm; + +namespace llvm { + +/// canConstantFoldCallTo - Return true if its even possible to fold a call to +/// the specified function. +extern +bool canConstantFoldCallTo(Function *F); + +/// ConstantFoldFP - Given a function that evaluates the constant, return an +/// LLVM Constant that represents the evaluated constant +extern Constant * +ConstantFoldFP(double (*NativeFP)(double), double V, const Type *Ty); + +/// ConstantFoldCall - Attempt to constant fold a call to the specified function +/// with the specified arguments, returning null if unsuccessful. +extern Constant * +ConstantFoldCall(Function *F, const std::vector &Operands); +} + diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h index 25183154272..da1ce25f6d8 100644 --- a/include/llvm/Transforms/Utils/Local.h +++ b/include/llvm/Transforms/Utils/Local.h @@ -16,6 +16,7 @@ #define LLVM_TRANSFORMS_UTILS_LOCAL_H #include "llvm/Function.h" +#include "llvm/Analysis/ConstantFolding.h" namespace llvm { @@ -48,14 +49,6 @@ bool ConstantFoldTerminator(BasicBlock *BB); Constant *ConstantFoldInstruction(Instruction *I); -/// canConstantFoldCallTo - Return true if its even possible to fold a call to -/// the specified function. -bool canConstantFoldCallTo(Function *F); - -/// ConstantFoldCall - Attempt to constant fold a call to the specified function -/// with the specified arguments, returning null if unsuccessful. -Constant *ConstantFoldCall(Function *F, const std::vector &Operands); - /// ConstantFoldLoadThroughGEPConstantExpr - Given a constant and a /// getelementptr constantexpr, return the constant value being addressed by the /// constant expression, or null if something is funny and we can't decide. diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp new file mode 100644 index 00000000000..4022bdda1de --- /dev/null +++ b/lib/Analysis/ConstantFolding.cpp @@ -0,0 +1,172 @@ +//===-- ConstantFolding.cpp - Analyze constant folding possibilities ------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This family of functions determines the possibility of performing constant +// folding. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Analysis/ConstantFolding.h" +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Instructions.h" +#include "llvm/Intrinsics.h" +#include "llvm/Support/GetElementPtrTypeIterator.h" +#include "llvm/Support/MathExtras.h" +#include +#include +using namespace llvm; + +//===----------------------------------------------------------------------===// +// Constant Folding ... +// + + +/// canConstantFoldCallTo - Return true if its even possible to fold a call to +/// the specified function. +bool +llvm::canConstantFoldCallTo(Function *F) { + const std::string &Name = F->getName(); + + switch (F->getIntrinsicID()) { + case Intrinsic::isunordered: + case Intrinsic::sqrt: + return true; + default: break; + } + + switch (Name[0]) + { + case 'a': + return Name == "acos" || Name == "asin" || Name == "atan" || + Name == "atan2"; + case 'c': + return Name == "ceil" || Name == "cos" || Name == "cosf" || + Name == "cosh"; + case 'e': + return Name == "exp"; + case 'f': + return Name == "fabs" || Name == "fmod" || Name == "floor"; + case 'l': + return Name == "log" || Name == "log10"; + case 'p': + return Name == "pow"; + case 's': + return Name == "sin" || Name == "sinh" || Name == "sqrt"; + case 't': + return Name == "tan" || Name == "tanh"; + default: + return false; + } +} + +Constant * +llvm::ConstantFoldFP(double (*NativeFP)(double), double V, const Type *Ty) { + errno = 0; + V = NativeFP(V); + if (errno == 0) + return ConstantFP::get(Ty, V); + return 0; +} + +/// ConstantFoldCall - Attempt to constant fold a call to the specified function +/// with the specified arguments, returning null if unsuccessful. +Constant * +llvm::ConstantFoldCall(Function *F, const std::vector &Operands) { + const std::string &Name = F->getName(); + const Type *Ty = F->getReturnType(); + + if (Operands.size() == 1) { + if (ConstantFP *Op = dyn_cast(Operands[0])) { + double V = Op->getValue(); + switch (Name[0]) + { + case 'a': + if (Name == "acos") + return ConstantFoldFP(acos, V, Ty); + else if (Name == "asin") + return ConstantFoldFP(asin, V, Ty); + else if (Name == "atan") + return ConstantFP::get(Ty, atan(V)); + break; + case 'c': + if (Name == "ceil") + return ConstantFoldFP(ceil, V, Ty); + else if (Name == "cos") + return ConstantFP::get(Ty, cos(V)); + else if (Name == "cosh") + return ConstantFP::get(Ty, cosh(V)); + break; + case 'e': + if (Name == "exp") + return ConstantFP::get(Ty, exp(V)); + break; + case 'f': + if (Name == "fabs") + return ConstantFP::get(Ty, fabs(V)); + else if (Name == "floor") + return ConstantFoldFP(floor, V, Ty); + break; + case 'l': + if (Name == "log" && V > 0) + return ConstantFP::get(Ty, log(V)); + else if (Name == "log10" && V > 0) + return ConstantFoldFP(log10, V, Ty); + else if (Name == "llvm.sqrt") { + if (V >= -0.0) + return ConstantFP::get(Ty, sqrt(V)); + else // Undefined + return ConstantFP::get(Ty, 0.0); + } + break; + case 's': + if (Name == "sin") + return ConstantFP::get(Ty, sin(V)); + else if (Name == "sinh") + return ConstantFP::get(Ty, sinh(V)); + else if (Name == "sqrt" && V >= 0) + return ConstantFP::get(Ty, sqrt(V)); + break; + case 't': + if (Name == "tan") + return ConstantFP::get(Ty, tan(V)); + else if (Name == "tanh") + return ConstantFP::get(Ty, tanh(V)); + break; + default: + break; + } + } + } else if (Operands.size() == 2) { + if (ConstantFP *Op1 = dyn_cast(Operands[0])) { + double Op1V = Op1->getValue(); + if (ConstantFP *Op2 = dyn_cast(Operands[1])) { + double Op2V = Op2->getValue(); + + if (Name == "llvm.isunordered") + return ConstantBool::get(IsNAN(Op1V) || IsNAN(Op2V)); + else + if (Name == "pow") { + errno = 0; + double V = pow(Op1V, Op2V); + if (errno == 0) + return ConstantFP::get(Ty, V); + } else if (Name == "fmod") { + errno = 0; + double V = fmod(Op1V, Op2V); + if (errno == 0) + return ConstantFP::get(Ty, V); + } else if (Name == "atan2") + return ConstantFP::get(Ty, atan2(Op1V,Op2V)); + } + } + } + return 0; +} +