//===- SimplifyLibCalls.cpp - Optimize specific well-known library calls --===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements a module pass that applies a variety of small
// optimizations for calls to specific well-known function calls (e.g. runtime
// library functions). For example, a call to the function "exit(3)" that
// occurs within the main() function can be transformed into a simple "return 3"
// instruction. Any optimization that takes this form (replace call to library
// function with simpler code that provides the same result) belongs in this
// file.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "simplify-libcalls"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Instructions.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
#include "llvm/ADT/hash_map"
#include "llvm/ADT/Statistic.h"
#include "llvm/Config/config.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Transforms/IPO.h"
using namespace llvm;

/// This statistic keeps track of the total number of library calls that have
/// been simplified regardless of which call it is.
STATISTIC(SimplifiedLibCalls, "Number of library calls simplified");

namespace {
  // Forward declarations
  class LibCallOptimization;
  class SimplifyLibCalls;
  
/// This list is populated by the constructor for LibCallOptimization class.
/// Therefore all subclasses are registered here at static initialization time
/// and this list is what the SimplifyLibCalls pass uses to apply the individual
/// optimizations to the call sites.
/// @brief The list of optimizations deriving from LibCallOptimization
static LibCallOptimization *OptList = 0;

/// This class is the abstract base class for the set of optimizations that
/// corresponds to one library call. The SimplifyLibCalls pass will call the
/// ValidateCalledFunction method to ask the optimization if a given Function
/// is the kind that the optimization can handle. If the subclass returns true,
/// then SImplifyLibCalls will also call the OptimizeCall method to perform,
/// or attempt to perform, the optimization(s) for the library call. Otherwise,
/// OptimizeCall won't be called. Subclasses are responsible for providing the
/// name of the library call (strlen, strcpy, etc.) to the LibCallOptimization
/// constructor. This is used to efficiently select which call instructions to
/// optimize. The criteria for a "lib call" is "anything with well known
/// semantics", typically a library function that is defined by an international
/// standard. Because the semantics are well known, the optimizations can
/// generally short-circuit actually calling the function if there's a simpler
/// way (e.g. strlen(X) can be reduced to a constant if X is a constant global).
/// @brief Base class for library call optimizations
class VISIBILITY_HIDDEN LibCallOptimization {
  LibCallOptimization **Prev, *Next;
  const char *FunctionName; ///< Name of the library call we optimize
#ifndef NDEBUG
  Statistic occurrences; ///< debug statistic (-debug-only=simplify-libcalls)
#endif
public:
  /// The \p fname argument must be the name of the library function being
  /// optimized by the subclass.
  /// @brief Constructor that registers the optimization.
  LibCallOptimization(const char *FName, const char *Description)
    : FunctionName(FName) {
      
#ifndef NDEBUG
    occurrences.construct("simplify-libcalls", Description);
#endif
    // Register this optimizer in the list of optimizations.
    Next = OptList;
    OptList = this;
    Prev = &OptList;
    if (Next) Next->Prev = &Next;
  }
  
  /// getNext - All libcall optimizations are chained together into a list,
  /// return the next one in the list.
  LibCallOptimization *getNext() { return Next; }

  /// @brief Deregister from the optlist
  virtual ~LibCallOptimization() {
    *Prev = Next;
    if (Next) Next->Prev = Prev;
  }

  /// The implementation of this function in subclasses should determine if
  /// \p F is suitable for the optimization. This method is called by
  /// SimplifyLibCalls::runOnModule to short circuit visiting all the call
  /// sites of such a function if that function is not suitable in the first
  /// place.  If the called function is suitabe, this method should return true;
  /// false, otherwise. This function should also perform any lazy
  /// initialization that the LibCallOptimization needs to do, if its to return
  /// true. This avoids doing initialization until the optimizer is actually
  /// going to be called upon to do some optimization.
  /// @brief Determine if the function is suitable for optimization
  virtual bool ValidateCalledFunction(
    const Function* F,    ///< The function that is the target of call sites
    SimplifyLibCalls& SLC ///< The pass object invoking us
  ) = 0;

  /// The implementations of this function in subclasses is the heart of the
  /// SimplifyLibCalls algorithm. Sublcasses of this class implement
  /// OptimizeCall to determine if (a) the conditions are right for optimizing
  /// the call and (b) to perform the optimization. If an action is taken
  /// against ci, the subclass is responsible for returning true and ensuring
  /// that ci is erased from its parent.
  /// @brief Optimize a call, if possible.
  virtual bool OptimizeCall(
    CallInst* ci,          ///< The call instruction that should be optimized.
    SimplifyLibCalls& SLC  ///< The pass object invoking us
  ) = 0;

  /// @brief Get the name of the library call being optimized
  const char *getFunctionName() const { return FunctionName; }

  bool ReplaceCallWith(CallInst *CI, Value *V) {
    if (!CI->use_empty())
      CI->replaceAllUsesWith(V);
    CI->eraseFromParent();
    return true;
  }
  
  /// @brief Called by SimplifyLibCalls to update the occurrences statistic.
  void succeeded() {
#ifndef NDEBUG
    DEBUG(++occurrences);
#endif
  }
};

/// This class is an LLVM Pass that applies each of the LibCallOptimization
/// instances to all the call sites in a module, relatively efficiently. The
/// purpose of this pass is to provide optimizations for calls to well-known
/// functions with well-known semantics, such as those in the c library. The
/// class provides the basic infrastructure for handling runOnModule.  Whenever
/// this pass finds a function call, it asks the appropriate optimizer to
/// validate the call (ValidateLibraryCall). If it is validated, then
/// the OptimizeCall method is also called.
/// @brief A ModulePass for optimizing well-known function calls.
class VISIBILITY_HIDDEN SimplifyLibCalls : public ModulePass {
public:
  static char ID; // Pass identification, replacement for typeid
  SimplifyLibCalls() : ModulePass((intptr_t)&ID) {}

  /// We need some target data for accurate signature details that are
  /// target dependent. So we require target data in our AnalysisUsage.
  /// @brief Require TargetData from AnalysisUsage.
  virtual void getAnalysisUsage(AnalysisUsage& Info) const {
    // Ask that the TargetData analysis be performed before us so we can use
    // the target data.
    Info.addRequired<TargetData>();
  }

  /// For this pass, process all of the function calls in the module, calling
  /// ValidateLibraryCall and OptimizeCall as appropriate.
  /// @brief Run all the lib call optimizations on a Module.
  virtual bool runOnModule(Module &M) {
    reset(M);

    bool result = false;
    hash_map<std::string, LibCallOptimization*> OptznMap;
    for (LibCallOptimization *Optzn = OptList; Optzn; Optzn = Optzn->getNext())
      OptznMap[Optzn->getFunctionName()] = Optzn;

    // The call optimizations can be recursive. That is, the optimization might
    // generate a call to another function which can also be optimized. This way
    // we make the LibCallOptimization instances very specific to the case they
    // handle. It also means we need to keep running over the function calls in
    // the module until we don't get any more optimizations possible.
    bool found_optimization = false;
    do {
      found_optimization = false;
      for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI) {
        // All the "well-known" functions are external and have external linkage
        // because they live in a runtime library somewhere and were (probably)
        // not compiled by LLVM.  So, we only act on external functions that
        // have external or dllimport linkage and non-empty uses.
        if (!FI->isDeclaration() ||
            !(FI->hasExternalLinkage() || FI->hasDLLImportLinkage()) ||
            FI->use_empty())
          continue;

        // Get the optimization class that pertains to this function
        hash_map<std::string, LibCallOptimization*>::iterator OMI =
          OptznMap.find(FI->getName());
        if (OMI == OptznMap.end()) continue;
        
        LibCallOptimization *CO = OMI->second;

        // Make sure the called function is suitable for the optimization
        if (!CO->ValidateCalledFunction(FI, *this))
          continue;

        // Loop over each of the uses of the function
        for (Value::use_iterator UI = FI->use_begin(), UE = FI->use_end();
             UI != UE ; ) {
          // If the use of the function is a call instruction
          if (CallInst* CI = dyn_cast<CallInst>(*UI++)) {
            // Do the optimization on the LibCallOptimization.
            if (CO->OptimizeCall(CI, *this)) {
              ++SimplifiedLibCalls;
              found_optimization = result = true;
              CO->succeeded();
            }
          }
        }
      }
    } while (found_optimization);
    
    return result;
  }

  /// @brief Return the *current* module we're working on.
  Module* getModule() const { return M; }

  /// @brief Return the *current* target data for the module we're working on.
  TargetData* getTargetData() const { return TD; }

  /// @brief Return the size_t type -- syntactic shortcut
  const Type* getIntPtrType() const { return TD->getIntPtrType(); }

  /// @brief Return a Function* for the putchar libcall
  Constant *get_putchar() {
    if (!putchar_func)
      putchar_func = 
        M->getOrInsertFunction("putchar", Type::Int32Ty, Type::Int32Ty, NULL);
    return putchar_func;
  }

  /// @brief Return a Function* for the puts libcall
  Constant *get_puts() {
    if (!puts_func)
      puts_func = M->getOrInsertFunction("puts", Type::Int32Ty,
                                         PointerType::getUnqual(Type::Int8Ty),
                                         NULL);
    return puts_func;
  }

  /// @brief Return a Function* for the fputc libcall
  Constant *get_fputc(const Type* FILEptr_type) {
    if (!fputc_func)
      fputc_func = M->getOrInsertFunction("fputc", Type::Int32Ty, Type::Int32Ty,
                                          FILEptr_type, NULL);
    return fputc_func;
  }

  /// @brief Return a Function* for the fputs libcall
  Constant *get_fputs(const Type* FILEptr_type) {
    if (!fputs_func)
      fputs_func = M->getOrInsertFunction("fputs", Type::Int32Ty,
                                          PointerType::getUnqual(Type::Int8Ty),
                                          FILEptr_type, NULL);
    return fputs_func;
  }

  /// @brief Return a Function* for the fwrite libcall
  Constant *get_fwrite(const Type* FILEptr_type) {
    if (!fwrite_func)
      fwrite_func = M->getOrInsertFunction("fwrite", TD->getIntPtrType(),
                                           PointerType::getUnqual(Type::Int8Ty),
                                           TD->getIntPtrType(),
                                           TD->getIntPtrType(),
                                           FILEptr_type, NULL);
    return fwrite_func;
  }

  /// @brief Return a Function* for the sqrt libcall
  Constant *get_sqrt() {
    if (!sqrt_func)
      sqrt_func = M->getOrInsertFunction("sqrt", Type::DoubleTy, 
                                         Type::DoubleTy, NULL);
    return sqrt_func;
  }

  /// @brief Return a Function* for the strcpy libcall
  Constant *get_strcpy() {
    if (!strcpy_func)
      strcpy_func = M->getOrInsertFunction("strcpy",
                                           PointerType::getUnqual(Type::Int8Ty),
                                           PointerType::getUnqual(Type::Int8Ty),
                                           PointerType::getUnqual(Type::Int8Ty),
                                           NULL);
    return strcpy_func;
  }

  /// @brief Return a Function* for the strlen libcall
  Constant *get_strlen() {
    if (!strlen_func)
      strlen_func = M->getOrInsertFunction("strlen", TD->getIntPtrType(),
                                           PointerType::getUnqual(Type::Int8Ty),
                                           NULL);
    return strlen_func;
  }

  /// @brief Return a Function* for the memchr libcall
  Constant *get_memchr() {
    if (!memchr_func)
      memchr_func = M->getOrInsertFunction("memchr",
                                           PointerType::getUnqual(Type::Int8Ty),
                                           PointerType::getUnqual(Type::Int8Ty),
                                           Type::Int32Ty, TD->getIntPtrType(),
                                           NULL);
    return memchr_func;
  }

  /// @brief Return a Function* for the memcpy libcall
  Constant *get_memcpy() {
    if (!memcpy_func) {
      const Type *SBP = PointerType::getUnqual(Type::Int8Ty);
      const char *N = TD->getIntPtrType() == Type::Int32Ty ?
                            "llvm.memcpy.i32" : "llvm.memcpy.i64";
      memcpy_func = M->getOrInsertFunction(N, Type::VoidTy, SBP, SBP,
                                           TD->getIntPtrType(), Type::Int32Ty,
                                           NULL);
    }
    return memcpy_func;
  }

  Constant *getUnaryFloatFunction(const char *Name, Constant *&Cache) {
    if (!Cache)
      Cache = M->getOrInsertFunction(Name, Type::FloatTy, Type::FloatTy, NULL);
    return Cache;
  }
  
  Constant *get_floorf() { return getUnaryFloatFunction("floorf", floorf_func);}
  Constant *get_ceilf()  { return getUnaryFloatFunction( "ceilf",  ceilf_func);}
  Constant *get_roundf() { return getUnaryFloatFunction("roundf", roundf_func);}
  Constant *get_rintf()  { return getUnaryFloatFunction( "rintf",  rintf_func);}
  Constant *get_nearbyintf() { return getUnaryFloatFunction("nearbyintf",
                                                            nearbyintf_func); }
private:
  /// @brief Reset our cached data for a new Module
  void reset(Module& mod) {
    M = &mod;
    TD = &getAnalysis<TargetData>();
    putchar_func = 0;
    puts_func = 0;
    fputc_func = 0;
    fputs_func = 0;
    fwrite_func = 0;
    memcpy_func = 0;
    memchr_func = 0;
    sqrt_func   = 0;
    strcpy_func = 0;
    strlen_func = 0;
    floorf_func = 0;
    ceilf_func = 0;
    roundf_func = 0;
    rintf_func = 0;
    nearbyintf_func = 0;
  }

private:
  /// Caches for function pointers.
  Constant *putchar_func, *puts_func;
  Constant *fputc_func, *fputs_func, *fwrite_func;
  Constant *memcpy_func, *memchr_func;
  Constant *sqrt_func;
  Constant *strcpy_func, *strlen_func;
  Constant *floorf_func, *ceilf_func, *roundf_func;
  Constant *rintf_func, *nearbyintf_func;
  Module *M;             ///< Cached Module
  TargetData *TD;        ///< Cached TargetData
};

char SimplifyLibCalls::ID = 0;
// Register the pass
RegisterPass<SimplifyLibCalls>
X("simplify-libcalls", "Simplify well-known library calls");

} // anonymous namespace

// The only public symbol in this file which just instantiates the pass object
ModulePass *llvm::createSimplifyLibCallsPass() {
  return new SimplifyLibCalls();
}

// Classes below here, in the anonymous namespace, are all subclasses of the
// LibCallOptimization class, each implementing all optimizations possible for a
// single well-known library call. Each has a static singleton instance that
// auto registers it into the "optlist" global above.
namespace {

// Forward declare utility functions.
static bool GetConstantStringInfo(Value *V, std::string &Str);
static Value *CastToCStr(Value *V, Instruction *IP);

/// This LibCallOptimization will find instances of a call to "exit" that occurs
/// within the "main" function and change it to a simple "ret" instruction with
/// the same value passed to the exit function. When this is done, it splits the
/// basic block at the exit(3) call and deletes the call instruction.
/// @brief Replace calls to exit in main with a simple return
struct VISIBILITY_HIDDEN ExitInMainOptimization : public LibCallOptimization {
  ExitInMainOptimization() : LibCallOptimization("exit",
      "Number of 'exit' calls simplified") {}

  // Make sure the called function looks like exit (int argument, int return
  // type, external linkage, not varargs).
  virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
    return F->arg_size() >= 1 && F->arg_begin()->getType()->isInteger();
  }

  virtual bool OptimizeCall(CallInst* ci, SimplifyLibCalls& SLC) {
    // To be careful, we check that the call to exit is coming from "main", that
    // main has external linkage, and the return type of main and the argument
    // to exit have the same type.
    Function *from = ci->getParent()->getParent();
    if (from->hasExternalLinkage())
      if (from->getReturnType() == ci->getOperand(1)->getType())
        if (from->getName() == "main") {
          // Okay, time to actually do the optimization. First, get the basic
          // block of the call instruction
          BasicBlock* bb = ci->getParent();

          // Create a return instruction that we'll replace the call with.
          // Note that the argument of the return is the argument of the call
          // instruction.
          new ReturnInst(ci->getOperand(1), ci);

          // Split the block at the call instruction which places it in a new
          // basic block.
          bb->splitBasicBlock(ci);

          // The block split caused a branch instruction to be inserted into
          // the end of the original block, right after the return instruction
          // that we put there. That's not a valid block, so delete the branch
          // instruction.
          bb->getInstList().pop_back();

          // Now we can finally get rid of the call instruction which now lives
          // in the new basic block.
          ci->eraseFromParent();

          // Optimization succeeded, return true.
          return true;
        }
    // We didn't pass the criteria for this optimization so return false
    return false;
  }
} ExitInMainOptimizer;

/// This LibCallOptimization will simplify a call to the strcat library
/// function. The simplification is possible only if the string being
/// concatenated is a constant array or a constant expression that results in
/// a constant string. In this case we can replace it with strlen + llvm.memcpy
/// of the constant string. Both of these calls are further reduced, if possible
/// on subsequent passes.
/// @brief Simplify the strcat library function.
struct VISIBILITY_HIDDEN StrCatOptimization : public LibCallOptimization {
public:
  /// @brief Default constructor
  StrCatOptimization() : LibCallOptimization("strcat",
      "Number of 'strcat' calls simplified") {}

public:

  /// @brief Make sure that the "strcat" function has the right prototype
  virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
    const FunctionType *FT = F->getFunctionType();
    return FT->getNumParams() == 2 &&
           FT->getReturnType() == PointerType::getUnqual(Type::Int8Ty) &&
           FT->getParamType(0) == FT->getReturnType() &&
           FT->getParamType(1) == FT->getReturnType();
  }

  /// @brief Optimize the strcat library function
  virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
    // Extract some information from the instruction
    Value *Dst = CI->getOperand(1);
    Value *Src = CI->getOperand(2);

    // Extract the initializer (while making numerous checks) from the
    // source operand of the call to strcat.
    std::string SrcStr;
    if (!GetConstantStringInfo(Src, SrcStr))
      return false;

    // Handle the simple, do-nothing case
    if (SrcStr.empty())
      return ReplaceCallWith(CI, Dst);

    // We need to find the end of the destination string.  That's where the
    // memory is to be moved to. We just generate a call to strlen.
    CallInst *DstLen = new CallInst(SLC.get_strlen(), Dst,
                                    Dst->getName()+".len", CI);

    // Now that we have the destination's length, we must index into the
    // destination's pointer to get the actual memcpy destination (end of
    // the string .. we're concatenating).
    Dst = new GetElementPtrInst(Dst, DstLen, Dst->getName()+".indexed", CI);

    // We have enough information to now generate the memcpy call to
    // do the concatenation for us.
    Value *Vals[] = {
      Dst, Src,
      ConstantInt::get(SLC.getIntPtrType(), SrcStr.size()+1), // copy nul byte.
      ConstantInt::get(Type::Int32Ty, 1)  // alignment
    };
    new CallInst(SLC.get_memcpy(), Vals, Vals + 4, "", CI);

    return ReplaceCallWith(CI, Dst);
  }
} StrCatOptimizer;

/// This LibCallOptimization will simplify a call to the strchr library
/// function.  It optimizes out cases where the arguments are both constant
/// and the result can be determined statically.
/// @brief Simplify the strcmp library function.
struct VISIBILITY_HIDDEN StrChrOptimization : public LibCallOptimization {
public:
  StrChrOptimization() : LibCallOptimization("strchr",
      "Number of 'strchr' calls simplified") {}

  /// @brief Make sure that the "strchr" function has the right prototype
  virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
    const FunctionType *FT = F->getFunctionType();
    return FT->getNumParams() == 2 &&
           FT->getReturnType() == PointerType::getUnqual(Type::Int8Ty) &&
           FT->getParamType(0) == FT->getReturnType() &&
           isa<IntegerType>(FT->getParamType(1));
  }

  /// @brief Perform the strchr optimizations
  virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
    // Check that the first argument to strchr is a constant array of sbyte.
    std::string Str;
    if (!GetConstantStringInfo(CI->getOperand(1), Str))
      return false;

    // If the second operand is not constant, just lower this to memchr since we
    // know the length of the input string.
    ConstantInt *CSI = dyn_cast<ConstantInt>(CI->getOperand(2));
    if (!CSI) {
      Value *Args[3] = {
        CI->getOperand(1),
        CI->getOperand(2),
        ConstantInt::get(SLC.getIntPtrType(), Str.size()+1)
      };
      return ReplaceCallWith(CI, new CallInst(SLC.get_memchr(), Args, Args + 3,
                                              CI->getName(), CI));
    }

    // strchr can find the nul character.
    Str += '\0';
    
    // Get the character we're looking for
    char CharValue = CSI->getSExtValue();

    // Compute the offset
    uint64_t i = 0;
    while (1) {
      if (i == Str.size())    // Didn't find the char.  strchr returns null.
        return ReplaceCallWith(CI, Constant::getNullValue(CI->getType()));
      // Did we find our match?
      if (Str[i] == CharValue)
        break;
      ++i;
    }

    // strchr(s+n,c)  -> gep(s+n+i,c)
    //    (if c is a constant integer and s is a constant string)
    Value *Idx = ConstantInt::get(Type::Int64Ty, i);
    Value *GEP = new GetElementPtrInst(CI->getOperand(1), Idx, 
                                       CI->getOperand(1)->getName() +
                                       ".strchr", CI);
    return ReplaceCallWith(CI, GEP);
  }
} StrChrOptimizer;

/// This LibCallOptimization will simplify a call to the strcmp library
/// function.  It optimizes out cases where one or both arguments are constant
/// and the result can be determined statically.
/// @brief Simplify the strcmp library function.
struct VISIBILITY_HIDDEN StrCmpOptimization : public LibCallOptimization {
public:
  StrCmpOptimization() : LibCallOptimization("strcmp",
      "Number of 'strcmp' calls simplified") {}

  /// @brief Make sure that the "strcmp" function has the right prototype
  virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
    const FunctionType *FT = F->getFunctionType();
    return FT->getReturnType() == Type::Int32Ty && FT->getNumParams() == 2 &&
           FT->getParamType(0) == FT->getParamType(1) &&
           FT->getParamType(0) == PointerType::getUnqual(Type::Int8Ty);
  }

  /// @brief Perform the strcmp optimization
  virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
    // First, check to see if src and destination are the same. If they are,
    // then the optimization is to replace the CallInst with a constant 0
    // because the call is a no-op.
    Value *Str1P = CI->getOperand(1);
    Value *Str2P = CI->getOperand(2);
    if (Str1P == Str2P)      // strcmp(x,x)  -> 0
      return ReplaceCallWith(CI, ConstantInt::get(CI->getType(), 0));

    std::string Str1;
    if (!GetConstantStringInfo(Str1P, Str1))
      return false;
    if (Str1.empty()) {
      // strcmp("", x) -> *x
      Value *V = new LoadInst(Str2P, CI->getName()+".load", CI);
      V = new ZExtInst(V, CI->getType(), CI->getName()+".int", CI);
      return ReplaceCallWith(CI, V);
    }

    std::string Str2;
    if (!GetConstantStringInfo(Str2P, Str2))
      return false;
    if (Str2.empty()) {
      // strcmp(x,"") -> *x
      Value *V = new LoadInst(Str1P, CI->getName()+".load", CI);
      V = new ZExtInst(V, CI->getType(), CI->getName()+".int", CI);
      return ReplaceCallWith(CI, V);
    }

    // strcmp(x, y)  -> cnst  (if both x and y are constant strings)
    int R = strcmp(Str1.c_str(), Str2.c_str());
    return ReplaceCallWith(CI, ConstantInt::get(CI->getType(), R));
  }
} StrCmpOptimizer;

/// This LibCallOptimization will simplify a call to the strncmp library
/// function.  It optimizes out cases where one or both arguments are constant
/// and the result can be determined statically.
/// @brief Simplify the strncmp library function.
struct VISIBILITY_HIDDEN StrNCmpOptimization : public LibCallOptimization {
public:
  StrNCmpOptimization() : LibCallOptimization("strncmp",
      "Number of 'strncmp' calls simplified") {}

  /// @brief Make sure that the "strncmp" function has the right prototype
  virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
    const FunctionType *FT = F->getFunctionType();
    return FT->getReturnType() == Type::Int32Ty && FT->getNumParams() == 3 &&
           FT->getParamType(0) == FT->getParamType(1) &&
           FT->getParamType(0) == PointerType::getUnqual(Type::Int8Ty) &&
           isa<IntegerType>(FT->getParamType(2));
    return false;
  }

  /// @brief Perform the strncmp optimization
  virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
    // First, check to see if src and destination are the same. If they are,
    // then the optimization is to replace the CallInst with a constant 0
    // because the call is a no-op.
    Value *Str1P = CI->getOperand(1);
    Value *Str2P = CI->getOperand(2);
    if (Str1P == Str2P)  // strncmp(x,x, n)  -> 0
      return ReplaceCallWith(CI, ConstantInt::get(CI->getType(), 0));
    
    // Check the length argument, if it is Constant zero then the strings are
    // considered equal.
    uint64_t Length;
    if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(CI->getOperand(3)))
      Length = LengthArg->getZExtValue();
    else
      return false;
    
    if (Length == 0) // strncmp(x,y,0)   -> 0
      return ReplaceCallWith(CI, ConstantInt::get(CI->getType(), 0));
    
    std::string Str1;
    if (!GetConstantStringInfo(Str1P, Str1))
      return false;
    if (Str1.empty()) {
      // strncmp("", x, n) -> *x
      Value *V = new LoadInst(Str2P, CI->getName()+".load", CI);
      V = new ZExtInst(V, CI->getType(), CI->getName()+".int", CI);
      return ReplaceCallWith(CI, V);
    }
    
    std::string Str2;
    if (!GetConstantStringInfo(Str2P, Str2))
      return false;
    if (Str2.empty()) {
      // strncmp(x, "", n) -> *x
      Value *V = new LoadInst(Str1P, CI->getName()+".load", CI);
      V = new ZExtInst(V, CI->getType(), CI->getName()+".int", CI);
      return ReplaceCallWith(CI, V);
    }
    
    // strncmp(x, y, n)  -> cnst  (if both x and y are constant strings)
    int R = strncmp(Str1.c_str(), Str2.c_str(), Length);
    return ReplaceCallWith(CI, ConstantInt::get(CI->getType(), R));
  }
} StrNCmpOptimizer;

/// This LibCallOptimization will simplify a call to the strcpy library
/// function.  Two optimizations are possible:
/// (1) If src and dest are the same and not volatile, just return dest
/// (2) If the src is a constant then we can convert to llvm.memmove
/// @brief Simplify the strcpy library function.
struct VISIBILITY_HIDDEN StrCpyOptimization : public LibCallOptimization {
public:
  StrCpyOptimization() : LibCallOptimization("strcpy",
      "Number of 'strcpy' calls simplified") {}

  /// @brief Make sure that the "strcpy" function has the right prototype
  virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
    const FunctionType *FT = F->getFunctionType();
    return FT->getNumParams() == 2 &&
           FT->getParamType(0) == FT->getParamType(1) &&
           FT->getReturnType() == FT->getParamType(0) &&
           FT->getParamType(0) == PointerType::getUnqual(Type::Int8Ty);
  }

  /// @brief Perform the strcpy optimization
  virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
    // First, check to see if src and destination are the same. If they are,
    // then the optimization is to replace the CallInst with the destination
    // because the call is a no-op. Note that this corresponds to the
    // degenerate strcpy(X,X) case which should have "undefined" results
    // according to the C specification. However, it occurs sometimes and
    // we optimize it as a no-op.
    Value *Dst = CI->getOperand(1);
    Value *Src = CI->getOperand(2);
    if (Dst == Src) {
      // strcpy(x, x) -> x
      return ReplaceCallWith(CI, Dst);
    }
    
    // Get the length of the constant string referenced by the Src operand.
    std::string SrcStr;
    if (!GetConstantStringInfo(Src, SrcStr))
      return false;
    
    // If the constant string's length is zero we can optimize this by just
    // doing a store of 0 at the first byte of the destination
    if (SrcStr.size() == 0) {
      new StoreInst(ConstantInt::get(Type::Int8Ty, 0), Dst, CI);
      return ReplaceCallWith(CI, Dst);
    }

    // We have enough information to now generate the memcpy call to
    // do the concatenation for us.
    Value *MemcpyOps[] = {
      Dst, Src, // Pass length including nul byte.
      ConstantInt::get(SLC.getIntPtrType(), SrcStr.size()+1),
      ConstantInt::get(Type::Int32Ty, 1) // alignment
    };
    new CallInst(SLC.get_memcpy(), MemcpyOps, MemcpyOps + 4, "", CI);

    return ReplaceCallWith(CI, Dst);
  }
} StrCpyOptimizer;

/// This LibCallOptimization will simplify a call to the strlen library
/// function by replacing it with a constant value if the string provided to
/// it is a constant array.
/// @brief Simplify the strlen library function.
struct VISIBILITY_HIDDEN StrLenOptimization : public LibCallOptimization {
  StrLenOptimization() : LibCallOptimization("strlen",
      "Number of 'strlen' calls simplified") {}

  /// @brief Make sure that the "strlen" function has the right prototype
  virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
    const FunctionType *FT = F->getFunctionType();
    return FT->getNumParams() == 1 &&
           FT->getParamType(0) == PointerType::getUnqual(Type::Int8Ty) &&
           isa<IntegerType>(FT->getReturnType());
  }

  /// @brief Perform the strlen optimization
  virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
    // Make sure we're dealing with an sbyte* here.
    Value *Src = CI->getOperand(1);

    // Does the call to strlen have exactly one use?
    if (CI->hasOneUse()) {
      // Is that single use a icmp operator?
      if (ICmpInst *Cmp = dyn_cast<ICmpInst>(CI->use_back()))
        // Is it compared against a constant integer?
        if (ConstantInt *Cst = dyn_cast<ConstantInt>(Cmp->getOperand(1))) {
          // If its compared against length 0 with == or !=
          if (Cst->getZExtValue() == 0 && Cmp->isEquality()) {
            // strlen(x) != 0 -> *x != 0
            // strlen(x) == 0 -> *x == 0
            Value *V = new LoadInst(Src, Src->getName()+".first", CI);
            V = new ICmpInst(Cmp->getPredicate(), V, 
                             ConstantInt::get(Type::Int8Ty, 0),
                             Cmp->getName()+".strlen", CI);
            Cmp->replaceAllUsesWith(V);
            Cmp->eraseFromParent();
            return ReplaceCallWith(CI, 0);  // no uses.
          }
        }
    }

    // Get the length of the constant string operand
    std::string Str;
    if (!GetConstantStringInfo(Src, Str))
      return false;
      
    // strlen("xyz") -> 3 (for example)
    return ReplaceCallWith(CI, ConstantInt::get(CI->getType(), Str.size()));
  }
} StrLenOptimizer;

/// IsOnlyUsedInEqualsComparison - Return true if it only matters that the value
/// is equal or not-equal to zero. 
static bool IsOnlyUsedInEqualsZeroComparison(Instruction *I) {
  for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
       UI != E; ++UI) {
    if (ICmpInst *IC = dyn_cast<ICmpInst>(*UI))
      if (IC->isEquality())
        if (Constant *C = dyn_cast<Constant>(IC->getOperand(1)))
          if (C->isNullValue())
            continue;
    // Unknown instruction.
    return false;
  }
  return true;
}

/// This memcmpOptimization will simplify a call to the memcmp library
/// function.
struct VISIBILITY_HIDDEN memcmpOptimization : public LibCallOptimization {
  /// @brief Default Constructor
  memcmpOptimization()
    : LibCallOptimization("memcmp", "Number of 'memcmp' calls simplified") {}
  
  /// @brief Make sure that the "memcmp" function has the right prototype
  virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &TD) {
    Function::const_arg_iterator AI = F->arg_begin();
    if (F->arg_size() != 3 || !isa<PointerType>(AI->getType())) return false;
    if (!isa<PointerType>((++AI)->getType())) return false;
    if (!(++AI)->getType()->isInteger()) return false;
    if (!F->getReturnType()->isInteger()) return false;
    return true;
  }
  
  /// Because of alignment and instruction information that we don't have, we
  /// leave the bulk of this to the code generators.
  ///
  /// Note that we could do much more if we could force alignment on otherwise
  /// small aligned allocas, or if we could indicate that loads have a small
  /// alignment.
  virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &TD) {
    Value *LHS = CI->getOperand(1), *RHS = CI->getOperand(2);

    // If the two operands are the same, return zero.
    if (LHS == RHS) {
      // memcmp(s,s,x) -> 0
      return ReplaceCallWith(CI, Constant::getNullValue(CI->getType()));
    }
    
    // Make sure we have a constant length.
    ConstantInt *LenC = dyn_cast<ConstantInt>(CI->getOperand(3));
    if (!LenC) return false;
    uint64_t Len = LenC->getZExtValue();
      
    // If the length is zero, this returns 0.
    switch (Len) {
    case 0:
      // memcmp(s1,s2,0) -> 0
      return ReplaceCallWith(CI, Constant::getNullValue(CI->getType()));
    case 1: {
      // memcmp(S1,S2,1) -> *(ubyte*)S1 - *(ubyte*)S2
      const Type *UCharPtr = PointerType::getUnqual(Type::Int8Ty);
      CastInst *Op1Cast = CastInst::create(
          Instruction::BitCast, LHS, UCharPtr, LHS->getName(), CI);
      CastInst *Op2Cast = CastInst::create(
          Instruction::BitCast, RHS, UCharPtr, RHS->getName(), CI);
      Value *S1V = new LoadInst(Op1Cast, LHS->getName()+".val", CI);
      Value *S2V = new LoadInst(Op2Cast, RHS->getName()+".val", CI);
      Value *RV = BinaryOperator::createSub(S1V, S2V, CI->getName()+".diff",CI);
      if (RV->getType() != CI->getType())
        RV = CastInst::createIntegerCast(RV, CI->getType(), false, 
                                         RV->getName(), CI);
      return ReplaceCallWith(CI, RV);
    }
    case 2:
      if (IsOnlyUsedInEqualsZeroComparison(CI)) {
        // TODO: IF both are aligned, use a short load/compare.
      
        // memcmp(S1,S2,2) -> S1[0]-S2[0] | S1[1]-S2[1] iff only ==/!= 0 matters
        const Type *UCharPtr = PointerType::getUnqual(Type::Int8Ty);
        CastInst *Op1Cast = CastInst::create(
            Instruction::BitCast, LHS, UCharPtr, LHS->getName(), CI);
        CastInst *Op2Cast = CastInst::create(
            Instruction::BitCast, RHS, UCharPtr, RHS->getName(), CI);
        Value *S1V1 = new LoadInst(Op1Cast, LHS->getName()+".val1", CI);
        Value *S2V1 = new LoadInst(Op2Cast, RHS->getName()+".val1", CI);
        Value *D1 = BinaryOperator::createSub(S1V1, S2V1,
                                              CI->getName()+".d1", CI);
        Constant *One = ConstantInt::get(Type::Int32Ty, 1);
        Value *G1 = new GetElementPtrInst(Op1Cast, One, "next1v", CI);
        Value *G2 = new GetElementPtrInst(Op2Cast, One, "next2v", CI);
        Value *S1V2 = new LoadInst(G1, LHS->getName()+".val2", CI);
        Value *S2V2 = new LoadInst(G2, RHS->getName()+".val2", CI);
        Value *D2 = BinaryOperator::createSub(S1V2, S2V2,
                                              CI->getName()+".d1", CI);
        Value *Or = BinaryOperator::createOr(D1, D2, CI->getName()+".res", CI);
        if (Or->getType() != CI->getType())
          Or = CastInst::createIntegerCast(Or, CI->getType(), false /*ZExt*/, 
                                           Or->getName(), CI);
        return ReplaceCallWith(CI, Or);
      }
      break;
    default:
      break;
    }
    
    return false;
  }
} memcmpOptimizer;


/// This LibCallOptimization will simplify a call to the memcpy library
/// function by expanding it out to a single store of size 0, 1, 2, 4, or 8
/// bytes depending on the length of the string and the alignment. Additional
/// optimizations are possible in code generation (sequence of immediate store)
/// @brief Simplify the memcpy library function.
struct VISIBILITY_HIDDEN LLVMMemCpyMoveOptzn : public LibCallOptimization {
  LLVMMemCpyMoveOptzn(const char* fname, const char* desc)
  : LibCallOptimization(fname, desc) {}

  /// @brief Make sure that the "memcpy" function has the right prototype
  virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& TD) {
    // Just make sure this has 4 arguments per LLVM spec.
    return (f->arg_size() == 4);
  }

  /// Because of alignment and instruction information that we don't have, we
  /// leave the bulk of this to the code generators. The optimization here just
  /// deals with a few degenerate cases where the length of the string and the
  /// alignment match the sizes of our intrinsic types so we can do a load and
  /// store instead of the memcpy call.
  /// @brief Perform the memcpy optimization.
  virtual bool OptimizeCall(CallInst* ci, SimplifyLibCalls& TD) {
    // Make sure we have constant int values to work with
    ConstantInt* LEN = dyn_cast<ConstantInt>(ci->getOperand(3));
    if (!LEN)
      return false;
    ConstantInt* ALIGN = dyn_cast<ConstantInt>(ci->getOperand(4));
    if (!ALIGN)
      return false;

    // If the length is larger than the alignment, we can't optimize
    uint64_t len = LEN->getZExtValue();
    uint64_t alignment = ALIGN->getZExtValue();
    if (alignment == 0)
      alignment = 1; // Alignment 0 is identity for alignment 1
    if (len > alignment)
      return false;

    // Get the type we will cast to, based on size of the string
    Value* dest = ci->getOperand(1);
    Value* src = ci->getOperand(2);
    const Type* castType = 0;
    switch (len) {
      case 0:
        // memcpy(d,s,0,a) -> d
        return ReplaceCallWith(ci, 0);
      case 1: castType = Type::Int8Ty; break;
      case 2: castType = Type::Int16Ty; break;
      case 4: castType = Type::Int32Ty; break;
      case 8: castType = Type::Int64Ty; break;
      default:
        return false;
    }

    // Cast source and dest to the right sized primitive and then load/store
    CastInst* SrcCast = CastInst::create(Instruction::BitCast,
        src, PointerType::getUnqual(castType), src->getName()+".cast", ci);
    CastInst* DestCast = CastInst::create(Instruction::BitCast,
        dest, PointerType::getUnqual(castType),dest->getName()+".cast", ci);
    LoadInst* LI = new LoadInst(SrcCast,SrcCast->getName()+".val",ci);
    new StoreInst(LI, DestCast, ci);
    return ReplaceCallWith(ci, 0);
  }
};

/// This LibCallOptimization will simplify a call to the memcpy/memmove library
/// functions.
LLVMMemCpyMoveOptzn LLVMMemCpyOptimizer32("llvm.memcpy.i32",
                                    "Number of 'llvm.memcpy' calls simplified");
LLVMMemCpyMoveOptzn LLVMMemCpyOptimizer64("llvm.memcpy.i64",
                                   "Number of 'llvm.memcpy' calls simplified");
LLVMMemCpyMoveOptzn LLVMMemMoveOptimizer32("llvm.memmove.i32",
                                   "Number of 'llvm.memmove' calls simplified");
LLVMMemCpyMoveOptzn LLVMMemMoveOptimizer64("llvm.memmove.i64",
                                   "Number of 'llvm.memmove' calls simplified");

/// This LibCallOptimization will simplify a call to the memset library
/// function by expanding it out to a single store of size 0, 1, 2, 4, or 8
/// bytes depending on the length argument.
struct VISIBILITY_HIDDEN LLVMMemSetOptimization : public LibCallOptimization {
  /// @brief Default Constructor
  LLVMMemSetOptimization(const char *Name) : LibCallOptimization(Name,
      "Number of 'llvm.memset' calls simplified") {}

  /// @brief Make sure that the "memset" function has the right prototype
  virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &TD) {
    // Just make sure this has 3 arguments per LLVM spec.
    return F->arg_size() == 4;
  }

  /// Because of alignment and instruction information that we don't have, we
  /// leave the bulk of this to the code generators. The optimization here just
  /// deals with a few degenerate cases where the length parameter is constant
  /// and the alignment matches the sizes of our intrinsic types so we can do
  /// store instead of the memcpy call. Other calls are transformed into the
  /// llvm.memset intrinsic.
  /// @brief Perform the memset optimization.
  virtual bool OptimizeCall(CallInst *ci, SimplifyLibCalls &TD) {
    // Make sure we have constant int values to work with
    ConstantInt* LEN = dyn_cast<ConstantInt>(ci->getOperand(3));
    if (!LEN)
      return false;
    ConstantInt* ALIGN = dyn_cast<ConstantInt>(ci->getOperand(4));
    if (!ALIGN)
      return false;

    // Extract the length and alignment
    uint64_t len = LEN->getZExtValue();
    uint64_t alignment = ALIGN->getZExtValue();

    // Alignment 0 is identity for alignment 1
    if (alignment == 0)
      alignment = 1;

    // If the length is zero, this is a no-op
    if (len == 0) {
      // memset(d,c,0,a) -> noop
      return ReplaceCallWith(ci, 0);
    }

    // If the length is larger than the alignment, we can't optimize
    if (len > alignment)
      return false;

    // Make sure we have a constant ubyte to work with so we can extract
    // the value to be filled.
    ConstantInt* FILL = dyn_cast<ConstantInt>(ci->getOperand(2));
    if (!FILL)
      return false;
    if (FILL->getType() != Type::Int8Ty)
      return false;

    // memset(s,c,n) -> store s, c (for n=1,2,4,8)

    // Extract the fill character
    uint64_t fill_char = FILL->getZExtValue();
    uint64_t fill_value = fill_char;

    // Get the type we will cast to, based on size of memory area to fill, and
    // and the value we will store there.
    Value* dest = ci->getOperand(1);
    const Type* castType = 0;
    switch (len) {
      case 1:
        castType = Type::Int8Ty;
        break;
      case 2:
        castType = Type::Int16Ty;
        fill_value |= fill_char << 8;
        break;
      case 4:
        castType = Type::Int32Ty;
        fill_value |= fill_char << 8 | fill_char << 16 | fill_char << 24;
        break;
      case 8:
        castType = Type::Int64Ty;
        fill_value |= fill_char << 8 | fill_char << 16 | fill_char << 24;
        fill_value |= fill_char << 32 | fill_char << 40 | fill_char << 48;
        fill_value |= fill_char << 56;
        break;
      default:
        return false;
    }

    // Cast dest to the right sized primitive and then load/store
    CastInst* DestCast = new BitCastInst(dest, PointerType::getUnqual(castType), 
                                         dest->getName()+".cast", ci);
    new StoreInst(ConstantInt::get(castType,fill_value),DestCast, ci);
    return ReplaceCallWith(ci, 0);
  }
};

LLVMMemSetOptimization MemSet32Optimizer("llvm.memset.i32");
LLVMMemSetOptimization MemSet64Optimizer("llvm.memset.i64");


/// This LibCallOptimization will simplify calls to the "pow" library
/// function. It looks for cases where the result of pow is well known and
/// substitutes the appropriate value.
/// @brief Simplify the pow library function.
struct VISIBILITY_HIDDEN PowOptimization : public LibCallOptimization {
public:
  /// @brief Default Constructor
  PowOptimization() : LibCallOptimization("pow",
      "Number of 'pow' calls simplified") {}

  /// @brief Make sure that the "pow" function has the right prototype
  virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC){
    // Just make sure this has 2 arguments
    return (f->arg_size() == 2);
  }

  /// @brief Perform the pow optimization.
  virtual bool OptimizeCall(CallInst *ci, SimplifyLibCalls &SLC) {
    const Type *Ty = cast<Function>(ci->getOperand(0))->getReturnType();
    if (Ty!=Type::FloatTy && Ty!=Type::DoubleTy)
      return false;   // FIXME long double not yet supported
    Value* base = ci->getOperand(1);
    Value* expn = ci->getOperand(2);
    if (ConstantFP *Op1 = dyn_cast<ConstantFP>(base)) {
      if (Op1->isExactlyValue(1.0)) // pow(1.0,x) -> 1.0
        return ReplaceCallWith(ci, ConstantFP::get(Ty, 
          Ty==Type::FloatTy ? APFloat(1.0f) : APFloat(1.0)));
    }  else if (ConstantFP* Op2 = dyn_cast<ConstantFP>(expn)) {
      if (Op2->getValueAPF().isZero()) {
        // pow(x,0.0) -> 1.0
        return ReplaceCallWith(ci, ConstantFP::get(Ty,
            Ty==Type::FloatTy ? APFloat(1.0f) : APFloat(1.0)));
      } else if (Op2->isExactlyValue(0.5)) {
        // pow(x,0.5) -> sqrt(x)
        CallInst* sqrt_inst = new CallInst(SLC.get_sqrt(), base,
            ci->getName()+".pow",ci);
        return ReplaceCallWith(ci, sqrt_inst);
      } else if (Op2->isExactlyValue(1.0)) {
        // pow(x,1.0) -> x
        return ReplaceCallWith(ci, base);
      } else if (Op2->isExactlyValue(-1.0)) {
        // pow(x,-1.0)    -> 1.0/x
        Value *div_inst = 
          BinaryOperator::createFDiv(ConstantFP::get(Ty,
            Ty==Type::FloatTy ? APFloat(1.0f) : APFloat(1.0)), 
            base, ci->getName()+".pow", ci);
        return ReplaceCallWith(ci, div_inst);
      }
    }
    return false; // opt failed
  }
} PowOptimizer;

/// This LibCallOptimization will simplify calls to the "printf" library
/// function. It looks for cases where the result of printf is not used and the
/// operation can be reduced to something simpler.
/// @brief Simplify the printf library function.
struct VISIBILITY_HIDDEN PrintfOptimization : public LibCallOptimization {
public:
  /// @brief Default Constructor
  PrintfOptimization() : LibCallOptimization("printf",
      "Number of 'printf' calls simplified") {}

  /// @brief Make sure that the "printf" function has the right prototype
  virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
    // Just make sure this has at least 1 argument and returns an integer or
    // void type.
    const FunctionType *FT = F->getFunctionType();
    return FT->getNumParams() >= 1 &&
          (isa<IntegerType>(FT->getReturnType()) ||
           FT->getReturnType() == Type::VoidTy);
  }

  /// @brief Perform the printf optimization.
  virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
    // All the optimizations depend on the length of the first argument and the
    // fact that it is a constant string array. Check that now
    std::string FormatStr;
    if (!GetConstantStringInfo(CI->getOperand(1), FormatStr))
      return false;
    
    // If this is a simple constant string with no format specifiers that ends
    // with a \n, turn it into a puts call.
    if (FormatStr.empty()) {
      // Tolerate printf's declared void.
      if (CI->use_empty()) return ReplaceCallWith(CI, 0);
      return ReplaceCallWith(CI, ConstantInt::get(CI->getType(), 0));
    }
    
    if (FormatStr.size() == 1) {
      // Turn this into a putchar call, even if it is a %.
      Value *V = ConstantInt::get(Type::Int32Ty, FormatStr[0]);
      new CallInst(SLC.get_putchar(), V, "", CI);
      if (CI->use_empty()) return ReplaceCallWith(CI, 0);
      return ReplaceCallWith(CI, ConstantInt::get(CI->getType(), 1));
    }

    // Check to see if the format str is something like "foo\n", in which case
    // we convert it to a puts call.  We don't allow it to contain any format
    // characters.
    if (FormatStr[FormatStr.size()-1] == '\n' &&
        FormatStr.find('%') == std::string::npos) {
      // Create a string literal with no \n on it.  We expect the constant merge
      // pass to be run after this pass, to merge duplicate strings.
      FormatStr.erase(FormatStr.end()-1);
      Constant *Init = ConstantArray::get(FormatStr, true);
      Constant *GV = new GlobalVariable(Init->getType(), true,
                                        GlobalVariable::InternalLinkage,
                                        Init, "str",
                                     CI->getParent()->getParent()->getParent());
      // Cast GV to be a pointer to char.
      GV = ConstantExpr::getBitCast(GV, PointerType::getUnqual(Type::Int8Ty));
      new CallInst(SLC.get_puts(), GV, "", CI);

      if (CI->use_empty()) return ReplaceCallWith(CI, 0);
      // The return value from printf includes the \n we just removed, so +1.
      return ReplaceCallWith(CI,
                             ConstantInt::get(CI->getType(), 
                                              FormatStr.size()+1));
    }
    
    
    // Only support %c or "%s\n" for now.
    if (FormatStr.size() < 2 || FormatStr[0] != '%')
      return false;

    // Get the second character and switch on its value
    switch (FormatStr[1]) {
    default:  return false;
    case 's':
      if (FormatStr != "%s\n" || CI->getNumOperands() < 3 ||
          // TODO: could insert strlen call to compute string length.
          !CI->use_empty())
        return false;

      // printf("%s\n",str) -> puts(str)
      new CallInst(SLC.get_puts(), CastToCStr(CI->getOperand(2), CI),
                   CI->getName(), CI);
      return ReplaceCallWith(CI, 0);
    case 'c': {
      // printf("%c",c) -> putchar(c)
      if (FormatStr.size() != 2 || CI->getNumOperands() < 3)
        return false;
      
      Value *V = CI->getOperand(2);
      if (!isa<IntegerType>(V->getType()) ||
          cast<IntegerType>(V->getType())->getBitWidth() > 32)
        return false;

      V = CastInst::createZExtOrBitCast(V, Type::Int32Ty, CI->getName()+".int",
                                        CI);
      new CallInst(SLC.get_putchar(), V, "", CI);
      return ReplaceCallWith(CI, ConstantInt::get(CI->getType(), 1));
    }
    }
  }
} PrintfOptimizer;

/// This LibCallOptimization will simplify calls to the "fprintf" library
/// function. It looks for cases where the result of fprintf is not used and the
/// operation can be reduced to something simpler.
/// @brief Simplify the fprintf library function.
struct VISIBILITY_HIDDEN FPrintFOptimization : public LibCallOptimization {
public:
  /// @brief Default Constructor
  FPrintFOptimization() : LibCallOptimization("fprintf",
      "Number of 'fprintf' calls simplified") {}

  /// @brief Make sure that the "fprintf" function has the right prototype
  virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
    const FunctionType *FT = F->getFunctionType();
    return FT->getNumParams() == 2 &&  // two fixed arguments.
           FT->getParamType(1) == PointerType::getUnqual(Type::Int8Ty) &&
           isa<PointerType>(FT->getParamType(0)) &&
           isa<IntegerType>(FT->getReturnType());
  }

  /// @brief Perform the fprintf optimization.
  virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
    // If the call has more than 3 operands, we can't optimize it
    if (CI->getNumOperands() != 3 && CI->getNumOperands() != 4)
      return false;

    // All the optimizations depend on the format string.
    std::string FormatStr;
    if (!GetConstantStringInfo(CI->getOperand(2), FormatStr))
      return false;

    // If this is just a format string, turn it into fwrite.
    if (CI->getNumOperands() == 3) {
      for (unsigned i = 0, e = FormatStr.size(); i != e; ++i)
        if (FormatStr[i] == '%')
          return false; // we found a format specifier

      // fprintf(file,fmt) -> fwrite(fmt,strlen(fmt),file)
      const Type *FILEty = CI->getOperand(1)->getType();

      Value *FWriteArgs[] = {
        CI->getOperand(2),
        ConstantInt::get(SLC.getIntPtrType(), FormatStr.size()),
        ConstantInt::get(SLC.getIntPtrType(), 1),
        CI->getOperand(1)
      };
      new CallInst(SLC.get_fwrite(FILEty), FWriteArgs, FWriteArgs + 4, CI->getName(), CI);
      return ReplaceCallWith(CI, ConstantInt::get(CI->getType(), 
                                                  FormatStr.size()));
    }
    
    // The remaining optimizations require the format string to be length 2:
    // "%s" or "%c".
    if (FormatStr.size() != 2 || FormatStr[0] != '%')
      return false;

    // Get the second character and switch on its value
    switch (FormatStr[1]) {
    case 'c': {
      // fprintf(file,"%c",c) -> fputc(c,file)
      const Type *FILETy = CI->getOperand(1)->getType();
      Value *C = CastInst::createZExtOrBitCast(CI->getOperand(3), Type::Int32Ty,
                                               CI->getName()+".int", CI);
      SmallVector<Value *, 2> Args;
      Args.push_back(C);
      Args.push_back(CI->getOperand(1));
      new CallInst(SLC.get_fputc(FILETy), Args.begin(), Args.end(), "", CI);
      return ReplaceCallWith(CI, ConstantInt::get(CI->getType(), 1));
    }
    case 's': {
      const Type *FILETy = CI->getOperand(1)->getType();
      
      // If the result of the fprintf call is used, we can't do this.
      // TODO: we should insert a strlen call.
      if (!CI->use_empty())
        return false;
      
      // fprintf(file,"%s",str) -> fputs(str,file)
      SmallVector<Value *, 2> Args;
      Args.push_back(CastToCStr(CI->getOperand(3), CI));
      Args.push_back(CI->getOperand(1));
      new CallInst(SLC.get_fputs(FILETy), Args.begin(),
                   Args.end(), CI->getName(), CI);
      return ReplaceCallWith(CI, 0);
    }
    default:
      return false;
    }
  }
} FPrintFOptimizer;

/// This LibCallOptimization will simplify calls to the "sprintf" library
/// function. It looks for cases where the result of sprintf is not used and the
/// operation can be reduced to something simpler.
/// @brief Simplify the sprintf library function.
struct VISIBILITY_HIDDEN SPrintFOptimization : public LibCallOptimization {
public:
  /// @brief Default Constructor
  SPrintFOptimization() : LibCallOptimization("sprintf",
      "Number of 'sprintf' calls simplified") {}

  /// @brief Make sure that the "sprintf" function has the right prototype
  virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
    const FunctionType *FT = F->getFunctionType();
    return FT->getNumParams() == 2 &&  // two fixed arguments.
           FT->getParamType(1) == PointerType::getUnqual(Type::Int8Ty) &&
           FT->getParamType(0) == FT->getParamType(1) &&
           isa<IntegerType>(FT->getReturnType());
  }

  /// @brief Perform the sprintf optimization.
  virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
    // If the call has more than 3 operands, we can't optimize it
    if (CI->getNumOperands() != 3 && CI->getNumOperands() != 4)
      return false;

    std::string FormatStr;
    if (!GetConstantStringInfo(CI->getOperand(2), FormatStr))
      return false;
    
    if (CI->getNumOperands() == 3) {
      // Make sure there's no % in the constant array
      for (unsigned i = 0, e = FormatStr.size(); i != e; ++i)
        if (FormatStr[i] == '%')
          return false; // we found a format specifier
      
      // sprintf(str,fmt) -> llvm.memcpy(str,fmt,strlen(fmt),1)
      Value *MemCpyArgs[] = {
        CI->getOperand(1), CI->getOperand(2),
        ConstantInt::get(SLC.getIntPtrType(), 
                         FormatStr.size()+1), // Copy the nul byte.
        ConstantInt::get(Type::Int32Ty, 1)
      };
      new CallInst(SLC.get_memcpy(), MemCpyArgs, MemCpyArgs + 4, "", CI);
      return ReplaceCallWith(CI, ConstantInt::get(CI->getType(), 
                                                  FormatStr.size()));
    }

    // The remaining optimizations require the format string to be "%s" or "%c".
    if (FormatStr.size() != 2 || FormatStr[0] != '%')
      return false;

    // Get the second character and switch on its value
    switch (FormatStr[1]) {
    case 'c': {
      // sprintf(dest,"%c",chr) -> store chr, dest
      Value *V = CastInst::createTruncOrBitCast(CI->getOperand(3),
                                                Type::Int8Ty, "char", CI);
      new StoreInst(V, CI->getOperand(1), CI);
      Value *Ptr = new GetElementPtrInst(CI->getOperand(1),
                                         ConstantInt::get(Type::Int32Ty, 1),
                                         CI->getOperand(1)->getName()+".end",
                                         CI);
      new StoreInst(ConstantInt::get(Type::Int8Ty,0), Ptr, CI);
      return ReplaceCallWith(CI, ConstantInt::get(Type::Int32Ty, 1));
    }
    case 's': {
      // sprintf(dest,"%s",str) -> llvm.memcpy(dest, str, strlen(str)+1, 1)
      Value *Len = new CallInst(SLC.get_strlen(),
                                CastToCStr(CI->getOperand(3), CI),
                                CI->getOperand(3)->getName()+".len", CI);
      Value *UnincLen = Len;
      Len = BinaryOperator::createAdd(Len, ConstantInt::get(Len->getType(), 1),
                                      Len->getName()+"1", CI);
      Value *MemcpyArgs[4] = {
        CI->getOperand(1),
        CastToCStr(CI->getOperand(3), CI),
        Len,
        ConstantInt::get(Type::Int32Ty, 1)
      };
      new CallInst(SLC.get_memcpy(), MemcpyArgs, MemcpyArgs + 4, "", CI);
      
      // The strlen result is the unincremented number of bytes in the string.
      if (!CI->use_empty()) {
        if (UnincLen->getType() != CI->getType())
          UnincLen = CastInst::createIntegerCast(UnincLen, CI->getType(), false, 
                                                 Len->getName(), CI);
        CI->replaceAllUsesWith(UnincLen);
      }
      return ReplaceCallWith(CI, 0);
    }
    }
    return false;
  }
} SPrintFOptimizer;

/// This LibCallOptimization will simplify calls to the "fputs" library
/// function. It looks for cases where the result of fputs is not used and the
/// operation can be reduced to something simpler.
/// @brief Simplify the fputs library function.
struct VISIBILITY_HIDDEN FPutsOptimization : public LibCallOptimization {
public:
  /// @brief Default Constructor
  FPutsOptimization() : LibCallOptimization("fputs",
      "Number of 'fputs' calls simplified") {}

  /// @brief Make sure that the "fputs" function has the right prototype
  virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
    // Just make sure this has 2 arguments
    return F->arg_size() == 2;
  }

  /// @brief Perform the fputs optimization.
  virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
    // If the result is used, none of these optimizations work.
    if (!CI->use_empty())
      return false;

    // All the optimizations depend on the length of the first argument and the
    // fact that it is a constant string array. Check that now
    std::string Str;
    if (!GetConstantStringInfo(CI->getOperand(1), Str))
      return false;

    const Type *FILETy = CI->getOperand(2)->getType();
    // fputs(s,F)  -> fwrite(s,1,len,F) (if s is constant and strlen(s) > 1)
    Value *FWriteParms[4] = {
      CI->getOperand(1),
      ConstantInt::get(SLC.getIntPtrType(), Str.size()),
      ConstantInt::get(SLC.getIntPtrType(), 1),
      CI->getOperand(2)
    };
    new CallInst(SLC.get_fwrite(FILETy), FWriteParms, FWriteParms + 4, "", CI);
    return ReplaceCallWith(CI, 0);  // Known to have no uses (see above).
  }
} FPutsOptimizer;

/// This LibCallOptimization will simplify calls to the "fwrite" function.
struct VISIBILITY_HIDDEN FWriteOptimization : public LibCallOptimization {
public:
  /// @brief Default Constructor
  FWriteOptimization() : LibCallOptimization("fwrite",
                                       "Number of 'fwrite' calls simplified") {}
  
  /// @brief Make sure that the "fputs" function has the right prototype
  virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
    const FunctionType *FT = F->getFunctionType();
    return FT->getNumParams() == 4 && 
           FT->getParamType(0) == PointerType::getUnqual(Type::Int8Ty) &&
           FT->getParamType(1) == FT->getParamType(2) &&
           isa<IntegerType>(FT->getParamType(1)) &&
           isa<PointerType>(FT->getParamType(3)) &&
           isa<IntegerType>(FT->getReturnType());
  }
  
  virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
    // Get the element size and count.
    uint64_t EltSize, EltCount;
    if (ConstantInt *C = dyn_cast<ConstantInt>(CI->getOperand(2)))
      EltSize = C->getZExtValue();
    else
      return false;
    if (ConstantInt *C = dyn_cast<ConstantInt>(CI->getOperand(3)))
      EltCount = C->getZExtValue();
    else
      return false;
    
    // If this is writing zero records, remove the call (it's a noop).
    if (EltSize * EltCount == 0)
      return ReplaceCallWith(CI, ConstantInt::get(CI->getType(), 0));
    
    // If this is writing one byte, turn it into fputc.
    if (EltSize == 1 && EltCount == 1) {
      SmallVector<Value *, 2> Args;
      // fwrite(s,1,1,F) -> fputc(s[0],F)
      Value *Ptr = CI->getOperand(1);
      Value *Val = new LoadInst(Ptr, Ptr->getName()+".byte", CI);
      Args.push_back(new ZExtInst(Val, Type::Int32Ty, Val->getName()+".int", CI));
      Args.push_back(CI->getOperand(4));
      const Type *FILETy = CI->getOperand(4)->getType();
      new CallInst(SLC.get_fputc(FILETy), Args.begin(), Args.end(), "", CI);
      return ReplaceCallWith(CI, ConstantInt::get(CI->getType(), 1));
    }
    return false;
  }
} FWriteOptimizer;

/// This LibCallOptimization will simplify calls to the "isdigit" library
/// function. It simply does range checks the parameter explicitly.
/// @brief Simplify the isdigit library function.
struct VISIBILITY_HIDDEN isdigitOptimization : public LibCallOptimization {
public:
  isdigitOptimization() : LibCallOptimization("isdigit",
      "Number of 'isdigit' calls simplified") {}

  /// @brief Make sure that the "isdigit" function has the right prototype
  virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC){
    // Just make sure this has 1 argument
    return (f->arg_size() == 1);
  }

  /// @brief Perform the toascii optimization.
  virtual bool OptimizeCall(CallInst *ci, SimplifyLibCalls &SLC) {
    if (ConstantInt* CI = dyn_cast<ConstantInt>(ci->getOperand(1))) {
      // isdigit(c)   -> 0 or 1, if 'c' is constant
      uint64_t val = CI->getZExtValue();
      if (val >= '0' && val <= '9')
        return ReplaceCallWith(ci, ConstantInt::get(Type::Int32Ty, 1));
      else
        return ReplaceCallWith(ci, ConstantInt::get(Type::Int32Ty, 0));
    }

    // isdigit(c)   -> (unsigned)c - '0' <= 9
    CastInst* cast = CastInst::createIntegerCast(ci->getOperand(1),
        Type::Int32Ty, false/*ZExt*/, ci->getOperand(1)->getName()+".uint", ci);
    BinaryOperator* sub_inst = BinaryOperator::createSub(cast,
        ConstantInt::get(Type::Int32Ty,0x30),
        ci->getOperand(1)->getName()+".sub",ci);
    ICmpInst* setcond_inst = new ICmpInst(ICmpInst::ICMP_ULE,sub_inst,
        ConstantInt::get(Type::Int32Ty,9),
        ci->getOperand(1)->getName()+".cmp",ci);
    CastInst* c2 = new ZExtInst(setcond_inst, Type::Int32Ty, 
        ci->getOperand(1)->getName()+".isdigit", ci);
    return ReplaceCallWith(ci, c2);
  }
} isdigitOptimizer;

struct VISIBILITY_HIDDEN isasciiOptimization : public LibCallOptimization {
public:
  isasciiOptimization()
    : LibCallOptimization("isascii", "Number of 'isascii' calls simplified") {}
  
  virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
    return F->arg_size() == 1 && F->arg_begin()->getType()->isInteger() && 
           F->getReturnType()->isInteger();
  }
  
  /// @brief Perform the isascii optimization.
  virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
    // isascii(c)   -> (unsigned)c < 128
    Value *V = CI->getOperand(1);
    Value *Cmp = new ICmpInst(ICmpInst::ICMP_ULT, V, 
                              ConstantInt::get(V->getType(), 128), 
                              V->getName()+".isascii", CI);
    if (Cmp->getType() != CI->getType())
      Cmp = new ZExtInst(Cmp, CI->getType(), Cmp->getName(), CI);
    return ReplaceCallWith(CI, Cmp);
  }
} isasciiOptimizer;


/// This LibCallOptimization will simplify calls to the "toascii" library
/// function. It simply does the corresponding and operation to restrict the
/// range of values to the ASCII character set (0-127).
/// @brief Simplify the toascii library function.
struct VISIBILITY_HIDDEN ToAsciiOptimization : public LibCallOptimization {
public:
  /// @brief Default Constructor
  ToAsciiOptimization() : LibCallOptimization("toascii",
      "Number of 'toascii' calls simplified") {}

  /// @brief Make sure that the "fputs" function has the right prototype
  virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC){
    // Just make sure this has 2 arguments
    return (f->arg_size() == 1);
  }

  /// @brief Perform the toascii optimization.
  virtual bool OptimizeCall(CallInst *ci, SimplifyLibCalls &SLC) {
    // toascii(c)   -> (c & 0x7f)
    Value *chr = ci->getOperand(1);
    Value *and_inst = BinaryOperator::createAnd(chr,
        ConstantInt::get(chr->getType(),0x7F),ci->getName()+".toascii",ci);
    return ReplaceCallWith(ci, and_inst);
  }
} ToAsciiOptimizer;

/// This LibCallOptimization will simplify calls to the "ffs" library
/// calls which find the first set bit in an int, long, or long long. The
/// optimization is to compute the result at compile time if the argument is
/// a constant.
/// @brief Simplify the ffs library function.
struct VISIBILITY_HIDDEN FFSOptimization : public LibCallOptimization {
protected:
  /// @brief Subclass Constructor
  FFSOptimization(const char* funcName, const char* description)
    : LibCallOptimization(funcName, description) {}

public:
  /// @brief Default Constructor
  FFSOptimization() : LibCallOptimization("ffs",
      "Number of 'ffs' calls simplified") {}

  /// @brief Make sure that the "ffs" function has the right prototype
  virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
    // Just make sure this has 2 arguments
    return F->arg_size() == 1 && F->getReturnType() == Type::Int32Ty;
  }

  /// @brief Perform the ffs optimization.
  virtual bool OptimizeCall(CallInst *TheCall, SimplifyLibCalls &SLC) {
    if (ConstantInt *CI = dyn_cast<ConstantInt>(TheCall->getOperand(1))) {
      // ffs(cnst)  -> bit#
      // ffsl(cnst) -> bit#
      // ffsll(cnst) -> bit#
      uint64_t val = CI->getZExtValue();
      int result = 0;
      if (val) {
        ++result;
        while ((val & 1) == 0) {
          ++result;
          val >>= 1;
        }
      }
      return ReplaceCallWith(TheCall, ConstantInt::get(Type::Int32Ty, result));
    }

    // ffs(x)   -> x == 0 ? 0 : llvm.cttz(x)+1
    // ffsl(x)  -> x == 0 ? 0 : llvm.cttz(x)+1
    // ffsll(x) -> x == 0 ? 0 : llvm.cttz(x)+1
    const Type *ArgType = TheCall->getOperand(1)->getType();
    const char *CTTZName;
    assert(ArgType->getTypeID() == Type::IntegerTyID &&
           "llvm.cttz argument is not an integer?");
    unsigned BitWidth = cast<IntegerType>(ArgType)->getBitWidth();
    if (BitWidth == 8)
      CTTZName = "llvm.cttz.i8";
    else if (BitWidth == 16)
      CTTZName = "llvm.cttz.i16"; 
    else if (BitWidth == 32)
      CTTZName = "llvm.cttz.i32";
    else {
      assert(BitWidth == 64 && "Unknown bitwidth");
      CTTZName = "llvm.cttz.i64";
    }
    
    Constant *F = SLC.getModule()->getOrInsertFunction(CTTZName, ArgType,
                                                       ArgType, NULL);
    Value *V = CastInst::createIntegerCast(TheCall->getOperand(1), ArgType, 
                                           false/*ZExt*/, "tmp", TheCall);
    Value *V2 = new CallInst(F, V, "tmp", TheCall);
    V2 = CastInst::createIntegerCast(V2, Type::Int32Ty, false/*ZExt*/, 
                                     "tmp", TheCall);
    V2 = BinaryOperator::createAdd(V2, ConstantInt::get(Type::Int32Ty, 1),
                                   "tmp", TheCall);
    Value *Cond = new ICmpInst(ICmpInst::ICMP_EQ, V, 
                               Constant::getNullValue(V->getType()), "tmp", 
                               TheCall);
    V2 = new SelectInst(Cond, ConstantInt::get(Type::Int32Ty, 0), V2,
                        TheCall->getName(), TheCall);
    return ReplaceCallWith(TheCall, V2);
  }
} FFSOptimizer;

/// This LibCallOptimization will simplify calls to the "ffsl" library
/// calls. It simply uses FFSOptimization for which the transformation is
/// identical.
/// @brief Simplify the ffsl library function.
struct VISIBILITY_HIDDEN FFSLOptimization : public FFSOptimization {
public:
  /// @brief Default Constructor
  FFSLOptimization() : FFSOptimization("ffsl",
      "Number of 'ffsl' calls simplified") {}

} FFSLOptimizer;

/// This LibCallOptimization will simplify calls to the "ffsll" library
/// calls. It simply uses FFSOptimization for which the transformation is
/// identical.
/// @brief Simplify the ffsl library function.
struct VISIBILITY_HIDDEN FFSLLOptimization : public FFSOptimization {
public:
  /// @brief Default Constructor
  FFSLLOptimization() : FFSOptimization("ffsll",
      "Number of 'ffsll' calls simplified") {}

} FFSLLOptimizer;

/// This optimizes unary functions that take and return doubles.
struct UnaryDoubleFPOptimizer : public LibCallOptimization {
  UnaryDoubleFPOptimizer(const char *Fn, const char *Desc)
  : LibCallOptimization(Fn, Desc) {}
  
  // Make sure that this function has the right prototype
  virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
    return F->arg_size() == 1 && F->arg_begin()->getType() == Type::DoubleTy &&
           F->getReturnType() == Type::DoubleTy;
  }

  /// ShrinkFunctionToFloatVersion - If the input to this function is really a
  /// float, strength reduce this to a float version of the function,
  /// e.g. floor((double)FLT) -> (double)floorf(FLT).  This can only be called
  /// when the target supports the destination function and where there can be
  /// no precision loss.
  static bool ShrinkFunctionToFloatVersion(CallInst *CI, SimplifyLibCalls &SLC,
                                           Constant *(SimplifyLibCalls::*FP)()){
    if (FPExtInst *Cast = dyn_cast<FPExtInst>(CI->getOperand(1)))
      if (Cast->getOperand(0)->getType() == Type::FloatTy) {
        Value *New = new CallInst((SLC.*FP)(), Cast->getOperand(0),
                                  CI->getName(), CI);
        New = new FPExtInst(New, Type::DoubleTy, CI->getName(), CI);
        CI->replaceAllUsesWith(New);
        CI->eraseFromParent();
        if (Cast->use_empty())
          Cast->eraseFromParent();
        return true;
      }
    return false;
  }
};


struct VISIBILITY_HIDDEN FloorOptimization : public UnaryDoubleFPOptimizer {
  FloorOptimization()
    : UnaryDoubleFPOptimizer("floor", "Number of 'floor' calls simplified") {}
  
  virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
#ifdef HAVE_FLOORF
    // If this is a float argument passed in, convert to floorf.
    if (ShrinkFunctionToFloatVersion(CI, SLC, &SimplifyLibCalls::get_floorf))
      return true;
#endif
    return false; // opt failed
  }
} FloorOptimizer;

struct VISIBILITY_HIDDEN CeilOptimization : public UnaryDoubleFPOptimizer {
  CeilOptimization()
  : UnaryDoubleFPOptimizer("ceil", "Number of 'ceil' calls simplified") {}
  
  virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
#ifdef HAVE_CEILF
    // If this is a float argument passed in, convert to ceilf.
    if (ShrinkFunctionToFloatVersion(CI, SLC, &SimplifyLibCalls::get_ceilf))
      return true;
#endif
    return false; // opt failed
  }
} CeilOptimizer;

struct VISIBILITY_HIDDEN RoundOptimization : public UnaryDoubleFPOptimizer {
  RoundOptimization()
  : UnaryDoubleFPOptimizer("round", "Number of 'round' calls simplified") {}
  
  virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
#ifdef HAVE_ROUNDF
    // If this is a float argument passed in, convert to roundf.
    if (ShrinkFunctionToFloatVersion(CI, SLC, &SimplifyLibCalls::get_roundf))
      return true;
#endif
    return false; // opt failed
  }
} RoundOptimizer;

struct VISIBILITY_HIDDEN RintOptimization : public UnaryDoubleFPOptimizer {
  RintOptimization()
  : UnaryDoubleFPOptimizer("rint", "Number of 'rint' calls simplified") {}
  
  virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
#ifdef HAVE_RINTF
    // If this is a float argument passed in, convert to rintf.
    if (ShrinkFunctionToFloatVersion(CI, SLC, &SimplifyLibCalls::get_rintf))
      return true;
#endif
    return false; // opt failed
  }
} RintOptimizer;

struct VISIBILITY_HIDDEN NearByIntOptimization : public UnaryDoubleFPOptimizer {
  NearByIntOptimization()
  : UnaryDoubleFPOptimizer("nearbyint",
                           "Number of 'nearbyint' calls simplified") {}
  
  virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
#ifdef HAVE_NEARBYINTF
    // If this is a float argument passed in, convert to nearbyintf.
    if (ShrinkFunctionToFloatVersion(CI, SLC,&SimplifyLibCalls::get_nearbyintf))
      return true;
#endif
    return false; // opt failed
  }
} NearByIntOptimizer;

/// GetConstantStringInfo - This function computes the length of a
/// null-terminated constant array of integers.  This function can't rely on the
/// size of the constant array because there could be a null terminator in the
/// middle of the array.
///
/// We also have to bail out if we find a non-integer constant initializer
/// of one of the elements or if there is no null-terminator. The logic
/// below checks each of these conditions and will return true only if all
/// conditions are met.  If the conditions aren't met, this returns false.
///
/// If successful, the \p Array param is set to the constant array being
/// indexed, the \p Length parameter is set to the length of the null-terminated
/// string pointed to by V, the \p StartIdx value is set to the first
/// element of the Array that V points to, and true is returned.
static bool GetConstantStringInfo(Value *V, std::string &Str) {
  // Look through noop bitcast instructions.
  if (BitCastInst *BCI = dyn_cast<BitCastInst>(V)) {
    if (BCI->getType() == BCI->getOperand(0)->getType())
      return GetConstantStringInfo(BCI->getOperand(0), Str);
    return false;
  }
  
  // If the value is not a GEP instruction nor a constant expression with a
  // GEP instruction, then return false because ConstantArray can't occur
  // any other way
  User *GEP = 0;
  if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(V)) {
    GEP = GEPI;
  } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
    if (CE->getOpcode() != Instruction::GetElementPtr)
      return false;
    GEP = CE;
  } else {
    return false;
  }

  // Make sure the GEP has exactly three arguments.
  if (GEP->getNumOperands() != 3)
    return false;

  // Check to make sure that the first operand of the GEP is an integer and
  // has value 0 so that we are sure we're indexing into the initializer.
  if (ConstantInt *Idx = dyn_cast<ConstantInt>(GEP->getOperand(1))) {
    if (!Idx->isZero())
      return false;
  } else
    return false;

  // If the second index isn't a ConstantInt, then this is a variable index
  // into the array.  If this occurs, we can't say anything meaningful about
  // the string.
  uint64_t StartIdx = 0;
  if (ConstantInt *CI = dyn_cast<ConstantInt>(GEP->getOperand(2)))
    StartIdx = CI->getZExtValue();
  else
    return false;

  // The GEP instruction, constant or instruction, must reference a global
  // variable that is a constant and is initialized. The referenced constant
  // initializer is the array that we'll use for optimization.
  GlobalVariable* GV = dyn_cast<GlobalVariable>(GEP->getOperand(0));
  if (!GV || !GV->isConstant() || !GV->hasInitializer())
    return false;
  Constant *GlobalInit = GV->getInitializer();

  // Handle the ConstantAggregateZero case
  if (isa<ConstantAggregateZero>(GlobalInit)) {
    // This is a degenerate case. The initializer is constant zero so the
    // length of the string must be zero.
    Str.clear();
    return true;
  }

  // Must be a Constant Array
  ConstantArray *Array = dyn_cast<ConstantArray>(GlobalInit);
  if (!Array) return false;

  // Get the number of elements in the array
  uint64_t NumElts = Array->getType()->getNumElements();

  // Traverse the constant array from StartIdx (derived above) which is
  // the place the GEP refers to in the array.
  for (unsigned i = StartIdx; i < NumElts; ++i) {
    Constant *Elt = Array->getOperand(i);
    ConstantInt *CI = dyn_cast<ConstantInt>(Elt);
    if (!CI) // This array isn't suitable, non-int initializer.
      return false;
    if (CI->isZero())
      return true; // we found end of string, success!
    Str += (char)CI->getZExtValue();
  }
  
  return false; // The array isn't null terminated.
}

/// CastToCStr - Return V if it is an sbyte*, otherwise cast it to sbyte*,
/// inserting the cast before IP, and return the cast.
/// @brief Cast a value to a "C" string.
static Value *CastToCStr(Value *V, Instruction *IP) {
  assert(isa<PointerType>(V->getType()) && 
         "Can't cast non-pointer type to C string type");
  const Type *SBPTy = PointerType::getUnqual(Type::Int8Ty);
  if (V->getType() != SBPTy)
    return new BitCastInst(V, SBPTy, V->getName(), IP);
  return V;
}

// TODO:
//   Additional cases that we need to add to this file:
//
// cbrt:
//   * cbrt(expN(X))  -> expN(x/3)
//   * cbrt(sqrt(x))  -> pow(x,1/6)
//   * cbrt(sqrt(x))  -> pow(x,1/9)
//
// cos, cosf, cosl:
//   * cos(-x)  -> cos(x)
//
// exp, expf, expl:
//   * exp(log(x))  -> x
//
// log, logf, logl:
//   * log(exp(x))   -> x
//   * log(x**y)     -> y*log(x)
//   * log(exp(y))   -> y*log(e)
//   * log(exp2(y))  -> y*log(2)
//   * log(exp10(y)) -> y*log(10)
//   * log(sqrt(x))  -> 0.5*log(x)
//   * log(pow(x,y)) -> y*log(x)
//
// lround, lroundf, lroundl:
//   * lround(cnst) -> cnst'
//
// memcmp:
//   * memcmp(x,y,l)   -> cnst
//      (if all arguments are constant and strlen(x) <= l and strlen(y) <= l)
//
// memmove:
//   * memmove(d,s,l,a) -> memcpy(d,s,l,a)
//       (if s is a global constant array)
//
// pow, powf, powl:
//   * pow(exp(x),y)  -> exp(x*y)
//   * pow(sqrt(x),y) -> pow(x,y*0.5)
//   * pow(pow(x,y),z)-> pow(x,y*z)
//
// puts:
//   * puts("") -> putchar("\n")
//
// round, roundf, roundl:
//   * round(cnst) -> cnst'
//
// signbit:
//   * signbit(cnst) -> cnst'
//   * signbit(nncst) -> 0 (if pstv is a non-negative constant)
//
// sqrt, sqrtf, sqrtl:
//   * sqrt(expN(x))  -> expN(x*0.5)
//   * sqrt(Nroot(x)) -> pow(x,1/(2*N))
//   * sqrt(pow(x,y)) -> pow(|x|,y*0.5)
//
// stpcpy:
//   * stpcpy(str, "literal") ->
//           llvm.memcpy(str,"literal",strlen("literal")+1,1)
// strrchr:
//   * strrchr(s,c) -> reverse_offset_of_in(c,s)
//      (if c is a constant integer and s is a constant string)
//   * strrchr(s1,0) -> strchr(s1,0)
//
// strncat:
//   * strncat(x,y,0) -> x
//   * strncat(x,y,0) -> x (if strlen(y) = 0)
//   * strncat(x,y,l) -> strcat(x,y) (if y and l are constants an l > strlen(y))
//
// strncpy:
//   * strncpy(d,s,0) -> d
//   * strncpy(d,s,l) -> memcpy(d,s,l,1)
//      (if s and l are constants)
//
// strpbrk:
//   * strpbrk(s,a) -> offset_in_for(s,a)
//      (if s and a are both constant strings)
//   * strpbrk(s,"") -> 0
//   * strpbrk(s,a) -> strchr(s,a[0]) (if a is constant string of length 1)
//
// strspn, strcspn:
//   * strspn(s,a)   -> const_int (if both args are constant)
//   * strspn("",a)  -> 0
//   * strspn(s,"")  -> 0
//   * strcspn(s,a)  -> const_int (if both args are constant)
//   * strcspn("",a) -> 0
//   * strcspn(s,"") -> strlen(a)
//
// strstr:
//   * strstr(x,x)  -> x
//   * strstr(s1,s2) -> offset_of_s2_in(s1)
//       (if s1 and s2 are constant strings)
//
// tan, tanf, tanl:
//   * tan(atan(x)) -> x
//
// trunc, truncf, truncl:
//   * trunc(cnst) -> cnst'
//
//
}
