//===- LowerAllocations.cpp - Reduce malloc & free insts to calls ---------===//
//
//                     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.
//
//===----------------------------------------------------------------------===//
//
// The LowerAllocations transformation is a target-dependent tranformation
// because it depends on the size of data types and alignment constraints.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "lowerallocs"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h"
#include "llvm/Module.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Instructions.h"
#include "llvm/Constants.h"
#include "llvm/Pass.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Support/Compiler.h"
using namespace llvm;

STATISTIC(NumLowered, "Number of allocations lowered");

namespace {
  /// LowerAllocations - Turn malloc and free instructions into %malloc and
  /// %free calls.
  ///
  class VISIBILITY_HIDDEN LowerAllocations : public BasicBlockPass {
    Constant *MallocFunc;   // Functions in the module we are processing
    Constant *FreeFunc;     // Initialized by doInitialization
    bool LowerMallocArgToInteger;
  public:
    static char ID; // Pass ID, replacement for typeid
    LowerAllocations(bool LowerToInt = false)
      : BasicBlockPass((intptr_t)&ID), MallocFunc(0), FreeFunc(0), 
        LowerMallocArgToInteger(LowerToInt) {}

    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.addRequired<TargetData>();
      AU.setPreservesCFG();

      // This is a cluster of orthogonal Transforms:
      AU.addPreserved<UnifyFunctionExitNodes>();
      AU.addPreservedID(PromoteMemoryToRegisterID);
      AU.addPreservedID(LowerSelectID);
      AU.addPreservedID(LowerSwitchID);
      AU.addPreservedID(LowerInvokePassID);
    }

    /// doPassInitialization - For the lower allocations pass, this ensures that
    /// a module contains a declaration for a malloc and a free function.
    ///
    bool doInitialization(Module &M);

    virtual bool doInitialization(Function &F) {
      return BasicBlockPass::doInitialization(F);
    }

    /// runOnBasicBlock - This method does the actual work of converting
    /// instructions over, assuming that the pass has already been initialized.
    ///
    bool runOnBasicBlock(BasicBlock &BB);
  };

  char LowerAllocations::ID = 0;
  RegisterPass<LowerAllocations>
  X("lowerallocs", "Lower allocations from instructions to calls");
}

// Publically exposed interface to pass...
const PassInfo *llvm::LowerAllocationsID = X.getPassInfo();
// createLowerAllocationsPass - Interface to this file...
Pass *llvm::createLowerAllocationsPass(bool LowerMallocArgToInteger) {
  return new LowerAllocations(LowerMallocArgToInteger);
}


// doInitialization - For the lower allocations pass, this ensures that a
// module contains a declaration for a malloc and a free function.
//
// This function is always successful.
//
bool LowerAllocations::doInitialization(Module &M) {
  const Type *BPTy = PointerType::get(Type::Int8Ty);
  // Prototype malloc as "char* malloc(...)", because we don't know in
  // doInitialization whether size_t is int or long.
  FunctionType *FT = FunctionType::get(BPTy, std::vector<const Type*>(), true);
  MallocFunc = M.getOrInsertFunction("malloc", FT);
  FreeFunc = M.getOrInsertFunction("free"  , Type::VoidTy, BPTy, (Type *)0);
  return true;
}

// runOnBasicBlock - This method does the actual work of converting
// instructions over, assuming that the pass has already been initialized.
//
bool LowerAllocations::runOnBasicBlock(BasicBlock &BB) {
  bool Changed = false;
  assert(MallocFunc && FreeFunc && "Pass not initialized!");

  BasicBlock::InstListType &BBIL = BB.getInstList();

  const TargetData &TD = getAnalysis<TargetData>();
  const Type *IntPtrTy = TD.getIntPtrType();

  // Loop over all of the instructions, looking for malloc or free instructions
  for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I) {
    if (MallocInst *MI = dyn_cast<MallocInst>(I)) {
      const Type *AllocTy = MI->getType()->getElementType();

      // malloc(type) becomes sbyte *malloc(size)
      Value *MallocArg;
      if (LowerMallocArgToInteger)
        MallocArg = ConstantInt::get(Type::Int64Ty, TD.getTypeSize(AllocTy));
      else
        MallocArg = ConstantExpr::getSizeOf(AllocTy);
      MallocArg = ConstantExpr::getTruncOrBitCast(cast<Constant>(MallocArg), 
                                                  IntPtrTy);

      if (MI->isArrayAllocation()) {
        if (isa<ConstantInt>(MallocArg) &&
            cast<ConstantInt>(MallocArg)->isOne()) {
          MallocArg = MI->getOperand(0);         // Operand * 1 = Operand
        } else if (Constant *CO = dyn_cast<Constant>(MI->getOperand(0))) {
          CO = ConstantExpr::getIntegerCast(CO, IntPtrTy, false /*ZExt*/);
          MallocArg = ConstantExpr::getMul(CO, cast<Constant>(MallocArg));
        } else {
          Value *Scale = MI->getOperand(0);
          if (Scale->getType() != IntPtrTy)
            Scale = CastInst::createIntegerCast(Scale, IntPtrTy, false /*ZExt*/,
                                                "", I);

          // Multiply it by the array size if necessary...
          MallocArg = BinaryOperator::create(Instruction::Mul, Scale,
                                             MallocArg, "", I);
        }
      }

      // Create the call to Malloc.
      CallInst *MCall = new CallInst(MallocFunc, MallocArg, "", I);
      MCall->setTailCall();

      // Create a cast instruction to convert to the right type...
      Value *MCast;
      if (MCall->getType() != Type::VoidTy)
        MCast = new BitCastInst(MCall, MI->getType(), "", I);
      else
        MCast = Constant::getNullValue(MI->getType());

      // Replace all uses of the old malloc inst with the cast inst
      MI->replaceAllUsesWith(MCast);
      I = --BBIL.erase(I);         // remove and delete the malloc instr...
      Changed = true;
      ++NumLowered;
    } else if (FreeInst *FI = dyn_cast<FreeInst>(I)) {
      Value *PtrCast = new BitCastInst(FI->getOperand(0),
                                       PointerType::get(Type::Int8Ty), "", I);

      // Insert a call to the free function...
      (new CallInst(FreeFunc, PtrCast, "", I))->setTailCall();

      // Delete the old free instruction
      I = --BBIL.erase(I);
      Changed = true;
      ++NumLowered;
    }
  }

  return Changed;
}

