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