Changes in directory llvm/lib/Analysis:
ConstantFolding.cpp added (r1.1.4.2) Expressions.cpp (r1.45) removed InstCount.cpp updated: 1.12 -> 1.12.4.1 ScalarEvolution.cpp updated: 1.43.2.1 -> 1.43.2.2 ScalarEvolutionExpander.cpp updated: 1.1 -> 1.1.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+202 -2) ConstantFolding.cpp | 172 ++++++++++++++++++++++++++++++++++++++++++++ InstCount.cpp | 3 ScalarEvolution.cpp | 2 ScalarEvolutionExpander.cpp | 27 ++++++ 4 files changed, 202 insertions(+), 2 deletions(-) Index: llvm/lib/Analysis/ConstantFolding.cpp diff -c /dev/null llvm/lib/Analysis/ConstantFolding.cpp:1.1.4.2 *** /dev/null Wed Nov 16 12:32:13 2005 --- llvm/lib/Analysis/ConstantFolding.cpp Wed Nov 16 12:32:03 2005 *************** *** 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 <cerrno> + #include <cmath> + 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<Constant*> &Operands) { + const std::string &Name = F->getName(); + const Type *Ty = F->getReturnType(); + + if (Operands.size() == 1) { + if (ConstantFP *Op = dyn_cast<ConstantFP>(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<ConstantFP>(Operands[0])) { + double Op1V = Op1->getValue(); + if (ConstantFP *Op2 = dyn_cast<ConstantFP>(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; + } + Index: llvm/lib/Analysis/InstCount.cpp diff -u llvm/lib/Analysis/InstCount.cpp:1.12 llvm/lib/Analysis/InstCount.cpp:1.12.4.1 --- llvm/lib/Analysis/InstCount.cpp:1.12 Thu Apr 21 16:04:58 2005 +++ llvm/lib/Analysis/InstCount.cpp Wed Nov 16 12:32:03 2005 @@ -11,6 +11,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Analysis/Passes.h" #include "llvm/Pass.h" #include "llvm/Function.h" #include "llvm/Support/InstVisitor.h" @@ -57,6 +58,8 @@ "Counts the various types of Instructions"); } +FunctionPass *llvm::createInstCountPass() { return new InstCount(); } + // InstCount::run - This is the main Analysis entry point for a // function. // Index: llvm/lib/Analysis/ScalarEvolution.cpp diff -u llvm/lib/Analysis/ScalarEvolution.cpp:1.43.2.1 llvm/lib/Analysis/ScalarEvolution.cpp:1.43.2.2 --- llvm/lib/Analysis/ScalarEvolution.cpp:1.43.2.1 Tue Oct 18 14:21:56 2005 +++ llvm/lib/Analysis/ScalarEvolution.cpp Wed Nov 16 12:32:03 2005 @@ -64,10 +64,10 @@ #include "llvm/DerivedTypes.h" #include "llvm/GlobalVariable.h" #include "llvm/Instructions.h" +#include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Assembly/Writer.h" #include "llvm/Transforms/Scalar.h" -#include "llvm/Transforms/Utils/Local.h" #include "llvm/Support/CFG.h" #include "llvm/Support/ConstantRange.h" #include "llvm/Support/InstIterator.h" Index: llvm/lib/Analysis/ScalarEvolutionExpander.cpp diff -u llvm/lib/Analysis/ScalarEvolutionExpander.cpp:1.1 llvm/lib/Analysis/ScalarEvolutionExpander.cpp:1.1.2.1 --- llvm/lib/Analysis/ScalarEvolutionExpander.cpp:1.1 Fri Jul 29 19:12:19 2005 +++ llvm/lib/Analysis/ScalarEvolutionExpander.cpp Wed Nov 16 12:32:03 2005 @@ -87,9 +87,34 @@ // Get the canonical induction variable I for this loop. Value *I = getOrInsertCanonicalInductionVariable(L, Ty); + // If this is a simple linear addrec, emit it now as a special case. if (S->getNumOperands() == 2) { // {0,+,F} --> i*F Value *F = expandInTy(S->getOperand(1), Ty); - return BinaryOperator::createMul(I, F, "tmp.", InsertPt); + + // IF the step is by one, just return the inserted IV. + if (ConstantIntegral *CI = dyn_cast<ConstantIntegral>(F)) + if (CI->getRawValue() == 1) + return I; + + // If the insert point is directly inside of the loop, emit the multiply at + // the insert point. Otherwise, L is a loop that is a parent of the insert + // point loop. If we can, move the multiply to the outer most loop that it + // is safe to be in. + Instruction *MulInsertPt = InsertPt; + Loop *InsertPtLoop = LI.getLoopFor(MulInsertPt->getParent()); + if (InsertPtLoop != L && InsertPtLoop && + L->contains(InsertPtLoop->getHeader())) { + while (InsertPtLoop != L) { + // If we cannot hoist the multiply out of this loop, don't. + if (!InsertPtLoop->isLoopInvariant(F)) break; + + // Otherwise, move the insert point to the preheader of the loop. + MulInsertPt = InsertPtLoop->getLoopPreheader()->getTerminator(); + InsertPtLoop = InsertPtLoop->getParentLoop(); + } + } + + return BinaryOperator::createMul(I, F, "tmp.", MulInsertPt); } // If this is a chain of recurrences, turn it into a closed form, using the _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits