ConstantFolding.cpp revision 72d88ae5447a3929c97e88f4c806213847b5d988
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> 2397af751deb9b26fd42fbcee082da9ccc4ded5b45Jeff Cohen#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::sqrt_f32: 390b118206bf3411722707f2e5cab8fd2eedcd50d6Reid Spencer case Intrinsic::sqrt_f64: 406fb3bd6a658940287789198d3207b0da04c0a4e6Nate Begeman case Intrinsic::bswap_i16: 416fb3bd6a658940287789198d3207b0da04c0a4e6Nate Begeman case Intrinsic::bswap_i32: 426fb3bd6a658940287789198d3207b0da04c0a4e6Nate Begeman case Intrinsic::bswap_i64: 43b5282dcf4745be59046f440980a1c0f0a50c9c09Chris Lattner case Intrinsic::powi_f32: 44b5282dcf4745be59046f440980a1c0f0a50c9c09Chris Lattner case Intrinsic::powi_f64: 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': 795cff2677a68bf7748bbc2d680b59248448a7fc89Chris Lattner return Name == "sin" || Name == "sinh" || 805cff2677a68bf7748bbc2d680b59248448a7fc89Chris Lattner Name == "sqrt" || Name == "sqrtf"; 81bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell case 't': 82bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return Name == "tan" || Name == "tanh"; 83bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell default: 84bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return false; 85bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell } 86bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell} 87bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell 8872d88ae5447a3929c97e88f4c806213847b5d988Chris Lattnerstatic Constant *ConstantFoldFP(double (*NativeFP)(double), double V, 8972d88ae5447a3929c97e88f4c806213847b5d988Chris Lattner const Type *Ty) { 90bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell errno = 0; 91bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell V = NativeFP(V); 92bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell if (errno == 0) 93bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, V); 9472d88ae5447a3929c97e88f4c806213847b5d988Chris Lattner errno = 0; 95bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return 0; 96bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell} 97bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell 98bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell/// ConstantFoldCall - Attempt to constant fold a call to the specified function 99bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell/// with the specified arguments, returning null if unsuccessful. 100bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John CriswellConstant * 10172d88ae5447a3929c97e88f4c806213847b5d988Chris Lattnerllvm::ConstantFoldCall(Function *F, Constant** Operands, unsigned NumOperands) { 102bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell const std::string &Name = F->getName(); 103bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell const Type *Ty = F->getReturnType(); 104bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell 10572d88ae5447a3929c97e88f4c806213847b5d988Chris Lattner if (NumOperands == 1) { 106bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell if (ConstantFP *Op = dyn_cast<ConstantFP>(Operands[0])) { 107bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell double V = Op->getValue(); 108bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell switch (Name[0]) 109bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell { 110bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell case 'a': 111bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell if (Name == "acos") 112bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFoldFP(acos, V, Ty); 113bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell else if (Name == "asin") 114bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFoldFP(asin, V, Ty); 115bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell else if (Name == "atan") 116bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, atan(V)); 117bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell break; 118bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell case 'c': 119bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell if (Name == "ceil") 120bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFoldFP(ceil, V, Ty); 121bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell else if (Name == "cos") 122bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, cos(V)); 123bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell else if (Name == "cosh") 124bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, cosh(V)); 125bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell break; 126bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell case 'e': 127bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell if (Name == "exp") 128bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, exp(V)); 129bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell break; 130bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell case 'f': 131bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell if (Name == "fabs") 132bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, fabs(V)); 133bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell else if (Name == "floor") 134bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFoldFP(floor, V, Ty); 135bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell break; 136bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell case 'l': 137bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell if (Name == "log" && V > 0) 138bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, log(V)); 139bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell else if (Name == "log10" && V > 0) 140bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFoldFP(log10, V, Ty); 1410b118206bf3411722707f2e5cab8fd2eedcd50d6Reid Spencer else if (Name == "llvm.sqrt.f32" || Name == "llvm.sqrt.f64") { 142bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell if (V >= -0.0) 143bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, sqrt(V)); 144bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell else // Undefined 145bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, 0.0); 146bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell } 147bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell break; 148bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell case 's': 149bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell if (Name == "sin") 150bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, sin(V)); 151bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell else if (Name == "sinh") 152bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, sinh(V)); 153bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell else if (Name == "sqrt" && V >= 0) 154bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, sqrt(V)); 1555cff2677a68bf7748bbc2d680b59248448a7fc89Chris Lattner else if (Name == "sqrtf" && V >= 0) 1565cff2677a68bf7748bbc2d680b59248448a7fc89Chris Lattner return ConstantFP::get(Ty, sqrt((float)V)); 157bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell break; 158bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell case 't': 159bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell if (Name == "tan") 160bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, tan(V)); 161bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell else if (Name == "tanh") 162bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, tanh(V)); 163bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell break; 164bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell default: 165bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell break; 166bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell } 167b83eb6447ba155342598f0fabe1f08f5baa9164aReid Spencer } else if (ConstantInt *Op = dyn_cast<ConstantInt>(Operands[0])) { 168b83eb6447ba155342598f0fabe1f08f5baa9164aReid Spencer uint64_t V = Op->getZExtValue(); 1696fb3bd6a658940287789198d3207b0da04c0a4e6Nate Begeman if (Name == "llvm.bswap.i16") 170b83eb6447ba155342598f0fabe1f08f5baa9164aReid Spencer return ConstantInt::get(Ty, ByteSwap_16(V)); 1716fb3bd6a658940287789198d3207b0da04c0a4e6Nate Begeman else if (Name == "llvm.bswap.i32") 172b83eb6447ba155342598f0fabe1f08f5baa9164aReid Spencer return ConstantInt::get(Ty, ByteSwap_32(V)); 1736fb3bd6a658940287789198d3207b0da04c0a4e6Nate Begeman else if (Name == "llvm.bswap.i64") 174b83eb6447ba155342598f0fabe1f08f5baa9164aReid Spencer return ConstantInt::get(Ty, ByteSwap_64(V)); 175bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell } 17672d88ae5447a3929c97e88f4c806213847b5d988Chris Lattner } else if (NumOperands == 2) { 177bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell if (ConstantFP *Op1 = dyn_cast<ConstantFP>(Operands[0])) { 178bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell double Op1V = Op1->getValue(); 179bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell if (ConstantFP *Op2 = dyn_cast<ConstantFP>(Operands[1])) { 180bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell double Op2V = Op2->getValue(); 181bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell 182bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell if (Name == "pow") { 183bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell errno = 0; 184bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell double V = pow(Op1V, Op2V); 185bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell if (errno == 0) 186bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, V); 187bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell } else if (Name == "fmod") { 188bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell errno = 0; 189bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell double V = fmod(Op1V, Op2V); 190bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell if (errno == 0) 191bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, V); 192b5282dcf4745be59046f440980a1c0f0a50c9c09Chris Lattner } else if (Name == "atan2") { 193bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return ConstantFP::get(Ty, atan2(Op1V,Op2V)); 194b5282dcf4745be59046f440980a1c0f0a50c9c09Chris Lattner } 195b5282dcf4745be59046f440980a1c0f0a50c9c09Chris Lattner } else if (ConstantInt *Op2C = dyn_cast<ConstantInt>(Operands[1])) { 196b5282dcf4745be59046f440980a1c0f0a50c9c09Chris Lattner if (Name == "llvm.powi.f32") { 197b5282dcf4745be59046f440980a1c0f0a50c9c09Chris Lattner return ConstantFP::get(Ty, std::pow((float)Op1V, 198b5282dcf4745be59046f440980a1c0f0a50c9c09Chris Lattner (int)Op2C->getZExtValue())); 199b5282dcf4745be59046f440980a1c0f0a50c9c09Chris Lattner } else if (Name == "llvm.powi.f64") { 200b5282dcf4745be59046f440980a1c0f0a50c9c09Chris Lattner return ConstantFP::get(Ty, std::pow((double)Op1V, 201b5282dcf4745be59046f440980a1c0f0a50c9c09Chris Lattner (int)Op2C->getZExtValue())); 202b5282dcf4745be59046f440980a1c0f0a50c9c09Chris Lattner } 203bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell } 204bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell } 205bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell } 206bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell return 0; 207bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell} 208bd9d37026a5c17d9a51371a6a5446bf4761ee7d6John Criswell 209