//===- RaiseAllocations.cpp - Convert %malloc & %free calls to insts ------===//
//
//                     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 file defines the RaiseAllocations pass which convert malloc and free
// calls to malloc and free instructions.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "raiseallocs"
#include "llvm/Transforms/IPO.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/Instructions.h"
#include "llvm/Pass.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/Compiler.h"
#include "llvm/ADT/Statistic.h"
#include <algorithm>
using namespace llvm;

STATISTIC(NumRaised, "Number of allocations raised");

namespace {
  // RaiseAllocations - Turn %malloc and %free calls into the appropriate
  // instruction.
  //
  class VISIBILITY_HIDDEN RaiseAllocations : public ModulePass {
    Function *MallocFunc;   // Functions in the module we are processing
    Function *FreeFunc;     // Initialized by doPassInitializationVirt
  public:
    static char ID; // Pass identifcation, replacement for typeid
    RaiseAllocations() 
      : ModulePass((intptr_t)&ID), MallocFunc(0), FreeFunc(0) {}

    // doPassInitialization - For the raise allocations pass, this finds a
    // declaration for malloc and free if they exist.
    //
    void doInitialization(Module &M);

    // run - This method does the actual work of converting instructions over.
    //
    bool runOnModule(Module &M);
  };

  char RaiseAllocations::ID = 0;
  RegisterPass<RaiseAllocations>
  X("raiseallocs", "Raise allocations from calls to instructions");
}  // end anonymous namespace


// createRaiseAllocationsPass - The interface to this file...
ModulePass *llvm::createRaiseAllocationsPass() {
  return new RaiseAllocations();
}


// If the module has a symbol table, they might be referring to the malloc and
// free functions.  If this is the case, grab the method pointers that the
// module is using.
//
// Lookup %malloc and %free in the symbol table, for later use.  If they don't
// exist, or are not external, we do not worry about converting calls to that
// function into the appropriate instruction.
//
void RaiseAllocations::doInitialization(Module &M) {

  // Get Malloc and free prototypes if they exist!
  MallocFunc = M.getFunction("malloc");
  if (MallocFunc) {
    const FunctionType* TyWeHave = MallocFunc->getFunctionType();

    // Get the expected prototype for malloc
    const FunctionType *Malloc1Type = 
      FunctionType::get(PointerType::get(Type::Int8Ty),
                      std::vector<const Type*>(1, Type::Int64Ty), false);

    // Chck to see if we got the expected malloc
    if (TyWeHave != Malloc1Type) {
      // Check to see if the prototype is wrong, giving us sbyte*(uint) * malloc
      // This handles the common declaration of: 'void *malloc(unsigned);'
      const FunctionType *Malloc2Type = 
        FunctionType::get(PointerType::get(Type::Int8Ty),
                          std::vector<const Type*>(1, Type::Int32Ty), false);
      if (TyWeHave != Malloc2Type) {
        // Check to see if the prototype is missing, giving us 
        // sbyte*(...) * malloc
        // This handles the common declaration of: 'void *malloc();'
        const FunctionType *Malloc3Type = 
          FunctionType::get(PointerType::get(Type::Int8Ty),
                            std::vector<const Type*>(), true);
        if (TyWeHave != Malloc3Type)
          // Give up
          MallocFunc = 0;
      }
    }
  }

  FreeFunc = M.getFunction("free");
  if (FreeFunc) {
    const FunctionType* TyWeHave = FreeFunc->getFunctionType();
    
    // Get the expected prototype for void free(i8*)
    const FunctionType *Free1Type = FunctionType::get(Type::VoidTy,
        std::vector<const Type*>(1, PointerType::get(Type::Int8Ty)), false);

    if (TyWeHave != Free1Type) {
      // Check to see if the prototype was forgotten, giving us 
      // void (...) * free
      // This handles the common forward declaration of: 'void free();'
      const FunctionType* Free2Type = FunctionType::get(Type::VoidTy, 
        std::vector<const Type*>(),true);

      if (TyWeHave != Free2Type) {
        // One last try, check to see if we can find free as 
        // int (...)* free.  This handles the case where NOTHING was declared.
        const FunctionType* Free3Type = FunctionType::get(Type::Int32Ty, 
          std::vector<const Type*>(),true);
        
        if (TyWeHave != Free3Type) {
          // Give up.
          FreeFunc = 0;
        }
      }
    }
  }

  // Don't mess with locally defined versions of these functions...
  if (MallocFunc && !MallocFunc->isDeclaration()) MallocFunc = 0;
  if (FreeFunc && !FreeFunc->isDeclaration())     FreeFunc = 0;
}

// run - Transform calls into instructions...
//
bool RaiseAllocations::runOnModule(Module &M) {
  // Find the malloc/free prototypes...
  doInitialization(M);

  bool Changed = false;

  // First, process all of the malloc calls...
  if (MallocFunc) {
    std::vector<User*> Users(MallocFunc->use_begin(), MallocFunc->use_end());
    std::vector<Value*> EqPointers;   // Values equal to MallocFunc
    while (!Users.empty()) {
      User *U = Users.back();
      Users.pop_back();

      if (Instruction *I = dyn_cast<Instruction>(U)) {
        CallSite CS = CallSite::get(I);
        if (CS.getInstruction() && CS.arg_begin() != CS.arg_end() &&
            (CS.getCalledFunction() == MallocFunc ||
             std::find(EqPointers.begin(), EqPointers.end(),
                       CS.getCalledValue()) != EqPointers.end())) {

          Value *Source = *CS.arg_begin();

          // If no prototype was provided for malloc, we may need to cast the
          // source size.
          if (Source->getType() != Type::Int32Ty)
            Source = 
              CastInst::createIntegerCast(Source, Type::Int32Ty, false/*ZExt*/,
                                          "MallocAmtCast", I);

          MallocInst *MI = new MallocInst(Type::Int8Ty, Source, "", I);
          MI->takeName(I);
          I->replaceAllUsesWith(MI);

          // If the old instruction was an invoke, add an unconditional branch
          // before the invoke, which will become the new terminator.
          if (InvokeInst *II = dyn_cast<InvokeInst>(I))
            new BranchInst(II->getNormalDest(), I);

          // Delete the old call site
          MI->getParent()->getInstList().erase(I);
          Changed = true;
          ++NumRaised;
        }
      } else if (GlobalValue *GV = dyn_cast<GlobalValue>(U)) {
        Users.insert(Users.end(), GV->use_begin(), GV->use_end());
        EqPointers.push_back(GV);
      } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U)) {
        if (CE->isCast()) {
          Users.insert(Users.end(), CE->use_begin(), CE->use_end());
          EqPointers.push_back(CE);
        }
      }
    }
  }

  // Next, process all free calls...
  if (FreeFunc) {
    std::vector<User*> Users(FreeFunc->use_begin(), FreeFunc->use_end());
    std::vector<Value*> EqPointers;   // Values equal to FreeFunc

    while (!Users.empty()) {
      User *U = Users.back();
      Users.pop_back();

      if (Instruction *I = dyn_cast<Instruction>(U)) {
        CallSite CS = CallSite::get(I);
        if (CS.getInstruction() && CS.arg_begin() != CS.arg_end() &&
            (CS.getCalledFunction() == FreeFunc ||
             std::find(EqPointers.begin(), EqPointers.end(),
                       CS.getCalledValue()) != EqPointers.end())) {

          // If no prototype was provided for free, we may need to cast the
          // source pointer.  This should be really uncommon, but it's necessary
          // just in case we are dealing with weird code like this:
          //   free((long)ptr);
          //
          Value *Source = *CS.arg_begin();
          if (!isa<PointerType>(Source->getType()))
            Source = new IntToPtrInst(Source, PointerType::get(Type::Int8Ty), 
                                      "FreePtrCast", I);
          new FreeInst(Source, I);

          // If the old instruction was an invoke, add an unconditional branch
          // before the invoke, which will become the new terminator.
          if (InvokeInst *II = dyn_cast<InvokeInst>(I))
            new BranchInst(II->getNormalDest(), I);

          // Delete the old call site
          if (I->getType() != Type::VoidTy)
            I->replaceAllUsesWith(UndefValue::get(I->getType()));
          I->eraseFromParent();
          Changed = true;
          ++NumRaised;
        }
      } else if (GlobalValue *GV = dyn_cast<GlobalValue>(U)) {
        Users.insert(Users.end(), GV->use_begin(), GV->use_end());
        EqPointers.push_back(GV);
      } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U)) {
        if (CE->isCast()) {
          Users.insert(Users.end(), CE->use_begin(), CE->use_end());
          EqPointers.push_back(CE);
        }
      }
    }
  }

  return Changed;
}
