//===- 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 identification, 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;
}
