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