ConstantFolding.cpp revision 0b118206bf3411722707f2e5cab8fd2eedcd50d6
1bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell//===-- ConstantFolding.cpp - Analyze constant folding possibilities ------===// 2bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell// 3bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell// The LLVM Compiler Infrastructure 4bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell// 5bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell// This file was developed by the LLVM research group and is distributed under 6bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell// the University of Illinois Open Source License. See LICENSE.TXT for details. 7bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell// 8bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell//===----------------------------------------------------------------------===// 9bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell// 10bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell// This family of functions determines the possibility of performing constant 11bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell// folding. 12bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell// 13bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell//===----------------------------------------------------------------------===// 14bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell 15bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell#include "llvm/Analysis/ConstantFolding.h" 16bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell#include "llvm/Constants.h" 17bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell#include "llvm/DerivedTypes.h" 18bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell#include "llvm/Instructions.h" 19bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell#include "llvm/Intrinsics.h" 20bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell#include "llvm/Support/GetElementPtrTypeIterator.h" 21bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell#include "llvm/Support/MathExtras.h" 22bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell#include <cerrno> 23bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell#include <cmath> 24bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswellusing namespace llvm; 25bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell 26bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell//===----------------------------------------------------------------------===// 27bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell// Constant Folding ... 28bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell// 29bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell 30bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell 31bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell/// canConstantFoldCallTo - Return true if its even possible to fold a call to 32bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell/// the specified function. 33bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswellbool 34bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswellllvm::canConstantFoldCallTo(Function *F) { 35bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell const std::string &Name = F->getName(); 36bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell 37bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell switch (F->getIntrinsicID()) { 380b118206bf3411722707f2e5cab8fd2eedcd50d6Reid Spencer case Intrinsic::isunordered_f32: 390b118206bf3411722707f2e5cab8fd2eedcd50d6Reid Spencer case Intrinsic::isunordered_f64: 400b118206bf3411722707f2e5cab8fd2eedcd50d6Reid Spencer case Intrinsic::sqrt_f32: 410b118206bf3411722707f2e5cab8fd2eedcd50d6Reid Spencer case Intrinsic::sqrt_f64: 426fb3bd6a658940287789198d3207b0da04c0a4e6Nate Begeman case Intrinsic::bswap_i16: 436fb3bd6a658940287789198d3207b0da04c0a4e6Nate Begeman case Intrinsic::bswap_i32: 446fb3bd6a658940287789198d3207b0da04c0a4e6Nate Begeman case Intrinsic::bswap_i64: 456fb3bd6a658940287789198d3207b0da04c0a4e6Nate Begeman // FIXME: these should be constant folded as well 460b118206bf3411722707f2e5cab8fd2eedcd50d6Reid Spencer //case Intrinsic::ctpop_i8: 470b118206bf3411722707f2e5cab8fd2eedcd50d6Reid Spencer //case Intrinsic::ctpop_i16: 480b118206bf3411722707f2e5cab8fd2eedcd50d6Reid Spencer //case Intrinsic::ctpop_i32: 490b118206bf3411722707f2e5cab8fd2eedcd50d6Reid Spencer //case Intrinsic::ctpop_i64: 500b118206bf3411722707f2e5cab8fd2eedcd50d6Reid Spencer //case Intrinsic::ctlz_i8: 510b118206bf3411722707f2e5cab8fd2eedcd50d6Reid Spencer //case Intrinsic::ctlz_i16: 520b118206bf3411722707f2e5cab8fd2eedcd50d6Reid Spencer //case Intrinsic::ctlz_i32: 530b118206bf3411722707f2e5cab8fd2eedcd50d6Reid Spencer //case Intrinsic::ctlz_i64: 540b118206bf3411722707f2e5cab8fd2eedcd50d6Reid Spencer //case Intrinsic::cttz_i8: 550b118206bf3411722707f2e5cab8fd2eedcd50d6Reid Spencer //case Intrinsic::cttz_i16: 560b118206bf3411722707f2e5cab8fd2eedcd50d6Reid Spencer //case Intrinsic::cttz_i32: 570b118206bf3411722707f2e5cab8fd2eedcd50d6Reid Spencer //case Intrinsic::cttz_i64: 58bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return true; 59bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell default: break; 60bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell } 61bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell 62bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell switch (Name[0]) 63bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell { 64bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell case 'a': 65bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return Name == "acos" || Name == "asin" || Name == "atan" || 66bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell Name == "atan2"; 67bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell case 'c': 68bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return Name == "ceil" || Name == "cos" || Name == "cosf" || 69bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell Name == "cosh"; 70bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell case 'e': 71bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return Name == "exp"; 72bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell case 'f': 73bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return Name == "fabs" || Name == "fmod" || Name == "floor"; 74bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell case 'l': 75bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return Name == "log" || Name == "log10"; 76bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell case 'p': 77bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return Name == "pow"; 78bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell case 's': 79bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return Name == "sin" || Name == "sinh" || Name == "sqrt"; 80bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell case 't': 81bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return Name == "tan" || Name == "tanh"; 82bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell default: 83bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return false; 84bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell } 85bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell} 86bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell 87bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John CriswellConstant * 88bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswellllvm::ConstantFoldFP(double (*NativeFP)(double), double V, const Type *Ty) { 89bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell errno = 0; 90bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell V = NativeFP(V); 91bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell if (errno == 0) 92bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, V); 93bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return 0; 94bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell} 95bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell 96bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell/// ConstantFoldCall - Attempt to constant fold a call to the specified function 97bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell/// with the specified arguments, returning null if unsuccessful. 98bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John CriswellConstant * 99bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswellllvm::ConstantFoldCall(Function *F, const std::vector<Constant*> &Operands) { 100bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell const std::string &Name = F->getName(); 101bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell const Type *Ty = F->getReturnType(); 102bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell 103bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell if (Operands.size() == 1) { 104bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell if (ConstantFP *Op = dyn_cast<ConstantFP>(Operands[0])) { 105bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell double V = Op->getValue(); 106bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell switch (Name[0]) 107bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell { 108bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell case 'a': 109bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell if (Name == "acos") 110bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFoldFP(acos, V, Ty); 111bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell else if (Name == "asin") 112bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFoldFP(asin, V, Ty); 113bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell else if (Name == "atan") 114bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, atan(V)); 115bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell break; 116bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell case 'c': 117bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell if (Name == "ceil") 118bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFoldFP(ceil, V, Ty); 119bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell else if (Name == "cos") 120bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, cos(V)); 121bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell else if (Name == "cosh") 122bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, cosh(V)); 123bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell break; 124bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell case 'e': 125bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell if (Name == "exp") 126bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, exp(V)); 127bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell break; 128bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell case 'f': 129bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell if (Name == "fabs") 130bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, fabs(V)); 131bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell else if (Name == "floor") 132bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFoldFP(floor, V, Ty); 133bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell break; 134bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell case 'l': 135bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell if (Name == "log" && V > 0) 136bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, log(V)); 137bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell else if (Name == "log10" && V > 0) 138bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFoldFP(log10, V, Ty); 1390b118206bf3411722707f2e5cab8fd2eedcd50d6Reid Spencer else if (Name == "llvm.sqrt.f32" || Name == "llvm.sqrt.f64") { 140bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell if (V >= -0.0) 141bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, sqrt(V)); 142bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell else // Undefined 143bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, 0.0); 144bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell } 145bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell break; 146bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell case 's': 147bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell if (Name == "sin") 148bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, sin(V)); 149bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell else if (Name == "sinh") 150bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, sinh(V)); 151bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell else if (Name == "sqrt" && V >= 0) 152bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, sqrt(V)); 153bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell break; 154bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell case 't': 155bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell if (Name == "tan") 156bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, tan(V)); 157bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell else if (Name == "tanh") 158bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, tanh(V)); 159bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell break; 160bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell default: 161bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell break; 162bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell } 1636fb3bd6a658940287789198d3207b0da04c0a4e6Nate Begeman } else if (ConstantUInt *Op = dyn_cast<ConstantUInt>(Operands[0])) { 1646fb3bd6a658940287789198d3207b0da04c0a4e6Nate Begeman uint64_t V = Op->getValue(); 1656fb3bd6a658940287789198d3207b0da04c0a4e6Nate Begeman if (Name == "llvm.bswap.i16") 1666fb3bd6a658940287789198d3207b0da04c0a4e6Nate Begeman return ConstantUInt::get(Ty, ByteSwap_16(V)); 1676fb3bd6a658940287789198d3207b0da04c0a4e6Nate Begeman else if (Name == "llvm.bswap.i32") 1686fb3bd6a658940287789198d3207b0da04c0a4e6Nate Begeman return ConstantUInt::get(Ty, ByteSwap_32(V)); 1696fb3bd6a658940287789198d3207b0da04c0a4e6Nate Begeman else if (Name == "llvm.bswap.i64") 1706fb3bd6a658940287789198d3207b0da04c0a4e6Nate Begeman return ConstantUInt::get(Ty, ByteSwap_64(V)); 171bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell } 172bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell } else if (Operands.size() == 2) { 173bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell if (ConstantFP *Op1 = dyn_cast<ConstantFP>(Operands[0])) { 174bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell double Op1V = Op1->getValue(); 175bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell if (ConstantFP *Op2 = dyn_cast<ConstantFP>(Operands[1])) { 176bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell double Op2V = Op2->getValue(); 177bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell 1780b118206bf3411722707f2e5cab8fd2eedcd50d6Reid Spencer if (Name == "llvm.isunordered.f32" || Name == "llvm.isunordered.f64") 179bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantBool::get(IsNAN(Op1V) || IsNAN(Op2V)); 180bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell else 181bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell if (Name == "pow") { 182bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell errno = 0; 183bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell double V = pow(Op1V, Op2V); 184bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell if (errno == 0) 185bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, V); 186bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell } else if (Name == "fmod") { 187bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell errno = 0; 188bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell double V = fmod(Op1V, Op2V); 189bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell if (errno == 0) 190bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, V); 191bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell } else if (Name == "atan2") 192bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, atan2(Op1V,Op2V)); 193bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell } 194bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell } 195bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell } 196bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return 0; 197bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell} 198bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell 199