//===-- 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/Function.h"
#include "llvm/Instructions.h"
#include "llvm/Intrinsics.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/MathExtras.h"
#include <cerrno>
#include <cmath>
using namespace llvm;

//===----------------------------------------------------------------------===//
// Constant Folding internal helper functions
//===----------------------------------------------------------------------===//

/// IsConstantOffsetFromGlobal - If this constant is actually a constant offset
/// from a global, return the global and the constant.  Because of
/// constantexprs, this function is recursive.
static bool IsConstantOffsetFromGlobal(Constant *C, GlobalValue *&GV,
                                       int64_t &Offset, const TargetData &TD) {
  // Trivial case, constant is the global.
  if ((GV = dyn_cast<GlobalValue>(C))) {
    Offset = 0;
    return true;
  }
  
  // Otherwise, if this isn't a constant expr, bail out.
  ConstantExpr *CE = dyn_cast<ConstantExpr>(C);
  if (!CE) return false;
  
  // Look through ptr->int and ptr->ptr casts.
  if (CE->getOpcode() == Instruction::PtrToInt ||
      CE->getOpcode() == Instruction::BitCast)
    return IsConstantOffsetFromGlobal(CE->getOperand(0), GV, Offset, TD);
  
  // i32* getelementptr ([5 x i32]* @a, i32 0, i32 5)    
  if (CE->getOpcode() == Instruction::GetElementPtr) {
    // Cannot compute this if the element type of the pointer is missing size
    // info.
    if (!cast<PointerType>(CE->getOperand(0)->getType())->getElementType()->isSized())
      return false;
    
    // If the base isn't a global+constant, we aren't either.
    if (!IsConstantOffsetFromGlobal(CE->getOperand(0), GV, Offset, TD))
      return false;
    
    // Otherwise, add any offset that our operands provide.
    gep_type_iterator GTI = gep_type_begin(CE);
    for (unsigned i = 1, e = CE->getNumOperands(); i != e; ++i, ++GTI) {
      ConstantInt *CI = dyn_cast<ConstantInt>(CE->getOperand(i));
      if (!CI) return false;  // Index isn't a simple constant?
      if (CI->getZExtValue() == 0) continue;  // Not adding anything.
      
      if (const StructType *ST = dyn_cast<StructType>(*GTI)) {
        // N = N + Offset
        Offset += TD.getStructLayout(ST)->getElementOffset(CI->getZExtValue());
      } else {
        const SequentialType *SQT = cast<SequentialType>(*GTI);
        Offset += TD.getTypeSize(SQT->getElementType())*CI->getSExtValue();
      }
    }
    return true;
  }
  
  return false;
}


/// SymbolicallyEvaluateBinop - One of Op0/Op1 is a constant expression.
/// Attempt to symbolically evaluate the result of  a binary operator merging
/// these together.  If target data info is available, it is provided as TD, 
/// otherwise TD is null.
static Constant *SymbolicallyEvaluateBinop(unsigned Opc, Constant *Op0,
                                           Constant *Op1, const TargetData *TD){
  // SROA
  
  // Fold (and 0xffffffff00000000, (shl x, 32)) -> shl.
  // Fold (lshr (or X, Y), 32) -> (lshr [X/Y], 32) if one doesn't contribute
  // bits.
  
  
  // If the constant expr is something like &A[123] - &A[4].f, fold this into a
  // constant.  This happens frequently when iterating over a global array.
  if (Opc == Instruction::Sub && TD) {
    GlobalValue *GV1, *GV2;
    int64_t Offs1, Offs2;
    
    if (IsConstantOffsetFromGlobal(Op0, GV1, Offs1, *TD))
      if (IsConstantOffsetFromGlobal(Op1, GV2, Offs2, *TD) &&
          GV1 == GV2) {
        // (&GV+C1) - (&GV+C2) -> C1-C2, pointer arithmetic cannot overflow.
        return ConstantInt::get(Op0->getType(), Offs1-Offs2);
      }
  }
    
  // TODO: Fold icmp setne/seteq as well.
  return 0;
}

/// SymbolicallyEvaluateGEP - If we can symbolically evaluate the specified GEP
/// constant expression, do so.
static Constant *SymbolicallyEvaluateGEP(Constant** Ops, unsigned NumOps,
                                         const Type *ResultTy,
                                         const TargetData *TD) {
  Constant *Ptr = Ops[0];
  if (!cast<PointerType>(Ptr->getType())->getElementType()->isSized())
    return 0;
  
  if (TD && Ptr->isNullValue()) {
    // If this is a constant expr gep that is effectively computing an
    // "offsetof", fold it into 'cast int Size to T*' instead of 'gep 0, 0, 12'
    bool isFoldableGEP = true;
    for (unsigned i = 1; i != NumOps; ++i)
      if (!isa<ConstantInt>(Ops[i])) {
        isFoldableGEP = false;
        break;
      }
    if (isFoldableGEP) {
      uint64_t Offset = TD->getIndexedOffset(Ptr->getType(),
                                             (Value**)Ops+1, NumOps-1);
      Constant *C = ConstantInt::get(TD->getIntPtrType(), Offset);
      return ConstantExpr::getIntToPtr(C, ResultTy);
    }
  }
  
  return 0;
}


//===----------------------------------------------------------------------===//
// Constant Folding public APIs
//===----------------------------------------------------------------------===//


/// ConstantFoldInstruction - Attempt to constant fold the specified
/// instruction.  If successful, the constant result is returned, if not, null
/// is returned.  Note that this function can only fail when attempting to fold
/// instructions like loads and stores, which have no constant expression form.
///
Constant *llvm::ConstantFoldInstruction(Instruction *I, const TargetData *TD) {
  if (PHINode *PN = dyn_cast<PHINode>(I)) {
    if (PN->getNumIncomingValues() == 0)
      return Constant::getNullValue(PN->getType());

    Constant *Result = dyn_cast<Constant>(PN->getIncomingValue(0));
    if (Result == 0) return 0;

    // Handle PHI nodes specially here...
    for (unsigned i = 1, e = PN->getNumIncomingValues(); i != e; ++i)
      if (PN->getIncomingValue(i) != Result && PN->getIncomingValue(i) != PN)
        return 0;   // Not all the same incoming constants...

    // If we reach here, all incoming values are the same constant.
    return Result;
  }

  // Scan the operand list, checking to see if they are all constants, if so,
  // hand off to ConstantFoldInstOperands.
  SmallVector<Constant*, 8> Ops;
  for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
    if (Constant *Op = dyn_cast<Constant>(I->getOperand(i)))
      Ops.push_back(Op);
    else
      return 0;  // All operands not constant!

  return ConstantFoldInstOperands(I, &Ops[0], Ops.size(), TD);
}

/// ConstantFoldInstOperands - Attempt to constant fold an instruction with the
/// specified opcode and operands.  If successful, the constant result is
/// returned, if not, null is returned.  Note that this function can fail when
/// attempting to fold instructions like loads and stores, which have no
/// constant expression form.
///
Constant *llvm::ConstantFoldInstOperands(const Instruction* I, 
                                         Constant** Ops, unsigned NumOps,
                                         const TargetData *TD) {
  unsigned Opc = I->getOpcode();
  const Type *DestTy = I->getType();

  // Handle easy binops first.
  if (isa<BinaryOperator>(I)) {
    if (isa<ConstantExpr>(Ops[0]) || isa<ConstantExpr>(Ops[1]))
      if (Constant *C = SymbolicallyEvaluateBinop(I->getOpcode(), Ops[0],
                                                  Ops[1], TD))
        return C;
    
    return ConstantExpr::get(Opc, Ops[0], Ops[1]);
  }
  
  switch (Opc) {
  default: return 0;
  case Instruction::Call:
    if (Function *F = dyn_cast<Function>(Ops[0]))
      if (canConstantFoldCallTo(F))
        return ConstantFoldCall(F, Ops+1, NumOps-1);
    return 0;
  case Instruction::ICmp:
  case Instruction::FCmp:
    return ConstantExpr::getCompare(cast<CmpInst>(I)->getPredicate(), Ops[0], 
                                    Ops[1]);
  case Instruction::PtrToInt:
    // If the input is a inttoptr, eliminate the pair.  This requires knowing
    // the width of a pointer, so it can't be done in ConstantExpr::getCast.
    if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ops[0])) {
      if (TD && CE->getOpcode() == Instruction::IntToPtr) {
        Constant *Input = CE->getOperand(0);
        unsigned InWidth = Input->getType()->getPrimitiveSizeInBits();
        Constant *Mask = 
          ConstantInt::get(APInt::getLowBitsSet(InWidth,
                                                TD->getPointerSizeInBits()));
        Input = ConstantExpr::getAnd(Input, Mask);
        // Do a zext or trunc to get to the dest size.
        return ConstantExpr::getIntegerCast(Input, I->getType(), false);
      }
    }
    // FALL THROUGH.
  case Instruction::IntToPtr:
  case Instruction::Trunc:
  case Instruction::ZExt:
  case Instruction::SExt:
  case Instruction::FPTrunc:
  case Instruction::FPExt:
  case Instruction::UIToFP:
  case Instruction::SIToFP:
  case Instruction::FPToUI:
  case Instruction::FPToSI:
  case Instruction::BitCast:
    return ConstantExpr::getCast(Opc, Ops[0], DestTy);
  case Instruction::Select:
    return ConstantExpr::getSelect(Ops[0], Ops[1], Ops[2]);
  case Instruction::ExtractElement:
    return ConstantExpr::getExtractElement(Ops[0], Ops[1]);
  case Instruction::InsertElement:
    return ConstantExpr::getInsertElement(Ops[0], Ops[1], Ops[2]);
  case Instruction::ShuffleVector:
    return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2]);
  case Instruction::GetElementPtr:
    if (Constant *C = SymbolicallyEvaluateGEP(Ops, NumOps, I->getType(), TD))
      return C;
    
    return ConstantExpr::getGetElementPtr(Ops[0], Ops+1, NumOps-1);
  }
}

/// ConstantFoldLoadThroughGEPConstantExpr - Given a constant and a
/// getelementptr constantexpr, return the constant value being addressed by the
/// constant expression, or null if something is funny and we can't decide.
Constant *llvm::ConstantFoldLoadThroughGEPConstantExpr(Constant *C, 
                                                       ConstantExpr *CE) {
  if (CE->getOperand(1) != Constant::getNullValue(CE->getOperand(1)->getType()))
    return 0;  // Do not allow stepping over the value!
  
  // Loop over all of the operands, tracking down which value we are
  // addressing...
  gep_type_iterator I = gep_type_begin(CE), E = gep_type_end(CE);
  for (++I; I != E; ++I)
    if (const StructType *STy = dyn_cast<StructType>(*I)) {
      ConstantInt *CU = cast<ConstantInt>(I.getOperand());
      assert(CU->getZExtValue() < STy->getNumElements() &&
             "Struct index out of range!");
      unsigned El = (unsigned)CU->getZExtValue();
      if (ConstantStruct *CS = dyn_cast<ConstantStruct>(C)) {
        C = CS->getOperand(El);
      } else if (isa<ConstantAggregateZero>(C)) {
        C = Constant::getNullValue(STy->getElementType(El));
      } else if (isa<UndefValue>(C)) {
        C = UndefValue::get(STy->getElementType(El));
      } else {
        return 0;
      }
    } else if (ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand())) {
      if (const ArrayType *ATy = dyn_cast<ArrayType>(*I)) {
        if (CI->getZExtValue() >= ATy->getNumElements())
         return 0;
        if (ConstantArray *CA = dyn_cast<ConstantArray>(C))
          C = CA->getOperand(CI->getZExtValue());
        else if (isa<ConstantAggregateZero>(C))
          C = Constant::getNullValue(ATy->getElementType());
        else if (isa<UndefValue>(C))
          C = UndefValue::get(ATy->getElementType());
        else
          return 0;
      } else if (const VectorType *PTy = dyn_cast<VectorType>(*I)) {
        if (CI->getZExtValue() >= PTy->getNumElements())
          return 0;
        if (ConstantVector *CP = dyn_cast<ConstantVector>(C))
          C = CP->getOperand(CI->getZExtValue());
        else if (isa<ConstantAggregateZero>(C))
          C = Constant::getNullValue(PTy->getElementType());
        else if (isa<UndefValue>(C))
          C = UndefValue::get(PTy->getElementType());
        else
          return 0;
      } else {
        return 0;
      }
    } else {
      return 0;
    }
  return C;
}


//===----------------------------------------------------------------------===//
//  Constant Folding for Calls
//

/// canConstantFoldCallTo - Return true if its even possible to fold a call to
/// the specified function.
bool
llvm::canConstantFoldCallTo(Function *F) {
  switch (F->getIntrinsicID()) {
  case Intrinsic::sqrt_f32:
  case Intrinsic::sqrt_f64:
  case Intrinsic::powi_f32:
  case Intrinsic::powi_f64:
  case Intrinsic::bswap:
  case Intrinsic::ctpop:
  case Intrinsic::ctlz:
  case Intrinsic::cttz:
    return true;
  default: break;
  }

  const ValueName *NameVal = F->getValueName();
  if (NameVal == 0) return false;
  const char *Str = NameVal->getKeyData();
  unsigned Len = NameVal->getKeyLength();
  
  // In these cases, the check of the length is required.  We don't want to
  // return true for a name like "cos\0blah" which strcmp would return equal to
  // "cos", but has length 8.
  switch (Str[0]) {
  default: return false;
  case 'a':
    if (Len == 4)
      return !strcmp(Str, "acos") || !strcmp(Str, "asin") ||
             !strcmp(Str, "atan");
    else if (Len == 5)
      return !strcmp(Str, "atan2");
    return false;
  case 'c':
    if (Len == 3)
      return !strcmp(Str, "cos");
    else if (Len == 4)
      return !strcmp(Str, "ceil") || !strcmp(Str, "cosf") ||
             !strcmp(Str, "cosh");
    return false;
  case 'e':
    if (Len == 3)
      return !strcmp(Str, "exp");
    return false;
  case 'f':
    if (Len == 4)
      return !strcmp(Str, "fabs") || !strcmp(Str, "fmod");
    else if (Len == 5)
      return !strcmp(Str, "floor");
    return false;
    break;
  case 'l':
    if (Len == 3 && !strcmp(Str, "log"))
      return true;
    if (Len == 5 && !strcmp(Str, "log10"))
      return true;
    return false;
  case 'p':
    if (Len == 3 && !strcmp(Str, "pow"))
      return true;
    return false;
  case 's':
    if (Len == 3)
      return !strcmp(Str, "sin");
    if (Len == 4)
      return !strcmp(Str, "sinh") || !strcmp(Str, "sqrt");
    if (Len == 5)
      return !strcmp(Str, "sqrtf");
    return false;
  case 't':
    if (Len == 3 && !strcmp(Str, "tan"))
      return true;
    else if (Len == 4 && !strcmp(Str, "tanh"))
      return true;
    return false;
  }
}

static Constant *ConstantFoldFP(double (*NativeFP)(double), double V, 
                                const Type *Ty) {
  errno = 0;
  V = NativeFP(V);
  if (errno == 0)
    return ConstantFP::get(Ty, V);
  errno = 0;
  return 0;
}

static Constant *ConstantFoldBinaryFP(double (*NativeFP)(double, double),
                                      double V, double W,
                                      const Type *Ty) {
  errno = 0;
  V = NativeFP(V, W);
  if (errno == 0)
    return ConstantFP::get(Ty, V);
  errno = 0;
  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, Constant** Operands, unsigned NumOperands) {
  const ValueName *NameVal = F->getValueName();
  if (NameVal == 0) return 0;
  const char *Str = NameVal->getKeyData();
  unsigned Len = NameVal->getKeyLength();
  
  const Type *Ty = F->getReturnType();
  if (NumOperands == 1) {
    if (ConstantFP *Op = dyn_cast<ConstantFP>(Operands[0])) {
      double V = Op->getValue();
      switch (Str[0]) {
      case 'a':
        if (Len == 4 && !strcmp(Str, "acos"))
          return ConstantFoldFP(acos, V, Ty);
        else if (Len == 4 && !strcmp(Str, "asin"))
          return ConstantFoldFP(asin, V, Ty);
        else if (Len == 4 && !strcmp(Str, "atan"))
          return ConstantFoldFP(atan, V, Ty);
        break;
      case 'c':
        if (Len == 4 && !strcmp(Str, "ceil"))
          return ConstantFoldFP(ceil, V, Ty);
        else if (Len == 3 && !strcmp(Str, "cos"))
          return ConstantFoldFP(cos, V, Ty);
        else if (Len == 4 && !strcmp(Str, "cosh"))
          return ConstantFoldFP(cosh, V, Ty);
        break;
      case 'e':
        if (Len == 3 && !strcmp(Str, "exp"))
          return ConstantFoldFP(exp, V, Ty);
        break;
      case 'f':
        if (Len == 4 && !strcmp(Str, "fabs"))
          return ConstantFP::get(Ty, fabs(V));
        else if (Len == 5 && !strcmp(Str, "floor"))
          return ConstantFoldFP(floor, V, Ty);
        break;
      case 'l':
        if (Len == 3 && !strcmp(Str, "log") && V > 0)
          return ConstantFoldFP(log, V, Ty);
        else if (Len == 5 && !strcmp(Str, "log10") && V > 0)
          return ConstantFoldFP(log10, V, Ty);
        else if (!strcmp(Str, "llvm.sqrt.f32") ||
                 !strcmp(Str, "llvm.sqrt.f64")) {
          if (V >= -0.0)
            return ConstantFP::get(Ty, sqrt(V));
          else // Undefined
            return ConstantFP::get(Ty, 0.0);
        }
        break;
      case 's':
        if (Len == 3 && !strcmp(Str, "sin"))
          return ConstantFoldFP(sin, V, Ty);
        else if (Len == 4 && !strcmp(Str, "sinh"))
          return ConstantFoldFP(sinh, V, Ty);
        else if (Len == 4 && !strcmp(Str, "sqrt") && V >= 0)
          return ConstantFoldFP(sqrt, V, Ty);
        else if (Len == 5 && !strcmp(Str, "sqrtf") && V >= 0)
          return ConstantFoldFP(sqrt, V, Ty);
        break;
      case 't':
        if (Len == 3 && !strcmp(Str, "tan"))
          return ConstantFoldFP(tan, V, Ty);
        else if (Len == 4 && !strcmp(Str, "tanh"))
          return ConstantFoldFP(tanh, V, Ty);
        break;
      default:
        break;
      }
    } else if (ConstantInt *Op = dyn_cast<ConstantInt>(Operands[0])) {
      if (Len > 11 && !memcmp(Str, "llvm.bswap", 10)) {
        return ConstantInt::get(Op->getValue().byteSwap());
      } else if (Len > 11 && !memcmp(Str, "llvm.ctpop", 10)) {
        uint64_t ctpop = Op->getValue().countPopulation();
        return ConstantInt::get(Ty, ctpop);
      } else if (Len > 10 && !memcmp(Str, "llvm.cttz", 9)) {
        uint64_t cttz = Op->getValue().countTrailingZeros();
        return ConstantInt::get(Ty, cttz);
      } else if (Len > 10 && !memcmp(Str, "llvm.ctlz", 9)) {
        uint64_t ctlz = Op->getValue().countLeadingZeros();
        return ConstantInt::get(Ty, ctlz);
      }
    }
  } else if (NumOperands == 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 (Len == 3 && !strcmp(Str, "pow")) {
          return ConstantFoldBinaryFP(pow, Op1V, Op2V, Ty);
        } else if (Len == 4 && !strcmp(Str, "fmod")) {
          return ConstantFoldBinaryFP(fmod, Op1V, Op2V, Ty);
        } else if (Len == 5 && !strcmp(Str, "atan2")) {
          return ConstantFoldBinaryFP(atan2, Op1V, Op2V, Ty);
        }
      } else if (ConstantInt *Op2C = dyn_cast<ConstantInt>(Operands[1])) {
        if (!strcmp(Str, "llvm.powi.f32")) {
          return ConstantFP::get(Ty, std::pow((float)Op1V,
                                              (int)Op2C->getZExtValue()));
        } else if (!strcmp(Str, "llvm.powi.f64")) {
          return ConstantFP::get(Ty, std::pow((double)Op1V,
                                              (int)Op2C->getZExtValue()));
        }
      }
    }
  }
  return 0;
}

