//===-- PoolOptimize.cpp - Optimize pool allocated program ----------------===//
// 
//                     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 simple pass optimizes a program that has been through pool allocation.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "pa-opt"

#include "llvm/Pass.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Debug.h"
#include <set>
using namespace llvm;

static Type * VoidType  = 0;
static Type * Int8Type  = 0;
static Type * Int32Type = 0;

namespace {
  STATISTIC (NumBumpPtr, "Number of bump pointer pools");

  struct PoolOptimize : public ModulePass {
    static char ID;
    bool SAFECodeEnabled;

    PoolOptimize(bool SAFECode = true) : ModulePass(ID) {
      SAFECodeEnabled = SAFECode;
    }
    bool runOnModule(Module &M);
  };

  char PoolOptimize::ID = 0;
  RegisterPass<PoolOptimize>
  X("pooloptimize", "Optimize a pool allocated program");
}

static void getCallsOf(Constant *C, std::vector<CallInst*> &Calls) {
  // Get the Function out of the constant
  Function * F;
  ConstantExpr * CE;
  if (!(F=dyn_cast<Function>(C))) {
    if ((CE = dyn_cast<ConstantExpr>(C)) && (CE->isCast()))
      F = dyn_cast<Function>(CE->getOperand(0));
    else
      assert (0 && "Constant is not a Function of ConstantExpr!"); 
  }
  Calls.clear();
  for (Value::user_iterator UI = F->user_begin(), E = F->user_end(); UI != E; ++UI)
    Calls.push_back(cast<CallInst>(*UI));
}

bool PoolOptimize::runOnModule(Module &M) {
  //
  // Get pointers to 8 and 32 bit LLVM integer types.
  //
  VoidType  = Type::getVoidTy(M.getContext());
  Int8Type  = IntegerType::getInt8Ty(M.getContext());
  Int32Type = IntegerType::getInt32Ty(M.getContext());

  //
  // Create LLVM types used by the pool allocation passes.
  //
  Type *VoidPtrTy = PointerType::getUnqual(Int8Type);
  Type *PoolDescPtrTy;
  if (SAFECodeEnabled)
    PoolDescPtrTy = PointerType::getUnqual(ArrayType::get(VoidPtrTy, 92));
  else
    PoolDescPtrTy = PointerType::getUnqual(ArrayType::get(VoidPtrTy, 16));

  // Get poolinit function.
  Constant *PoolInit = M.getOrInsertFunction("poolinit", VoidType,
                                             PoolDescPtrTy, Int32Type,
                                             Int32Type, NULL);

  // Get pooldestroy function.
  Constant *PoolDestroy = M.getOrInsertFunction("pooldestroy", VoidType,
                                                PoolDescPtrTy, NULL);
  
  // The poolalloc function.
  Constant *PoolAlloc = M.getOrInsertFunction("poolalloc", 
                                              VoidPtrTy, PoolDescPtrTy,
                                              Int32Type, NULL);
  
  // The poolrealloc function.
  Constant *PoolRealloc = M.getOrInsertFunction("poolrealloc",
                                                VoidPtrTy, PoolDescPtrTy,
                                                VoidPtrTy, Int32Type, NULL);
  // The poolmemalign function.
  Constant *PoolMemAlign = M.getOrInsertFunction("poolmemalign",
                                                 VoidPtrTy, PoolDescPtrTy,
                                                 Int32Type, Int32Type, 
                                                 NULL);

  // Get the poolfree function.
  Constant *PoolFree = M.getOrInsertFunction("poolfree", VoidType,
                                             PoolDescPtrTy, VoidPtrTy, NULL);  


  // Get poolinit_bp function.
  Constant *PoolInitBP = M.getOrInsertFunction("poolinit_bp", VoidType,
                                               PoolDescPtrTy, Int32Type, 
                                               NULL);
  
  // Get pooldestroy_bp function.
  Constant *PoolDestroyBP = M.getOrInsertFunction("pooldestroy_bp",VoidType,
                                                 PoolDescPtrTy, NULL);
  
  // The poolalloc_bp function.
  Constant *PoolAllocBP = M.getOrInsertFunction("poolalloc_bp", 
                                                VoidPtrTy, PoolDescPtrTy,
                                                Int32Type, NULL);

  Constant *Realloc = M.getOrInsertFunction("realloc",
                                            VoidPtrTy, VoidPtrTy, Int32Type,
                                            NULL);
  Constant *MemAlign = M.getOrInsertFunction("memalign",
                                             VoidPtrTy, Int32Type,
                                             Int32Type, NULL);


  // Optimize poolreallocs
  std::vector<CallInst*> Calls;
  getCallsOf(PoolRealloc, Calls);
  for (unsigned i = 0, e = Calls.size(); i != e; ++i) {
    CallInst *CI = Calls[i];
    // poolrealloc(PD, null, X) -> poolalloc(PD, X)
    if (isa<ConstantPointerNull>(CI->getOperand(2))) {
      Value* Opts[2] = {CI->getOperand(1), CI->getOperand(3)};
      Value *New = CallInst::Create(PoolAlloc, Opts,
                                CI->getName(), CI);
      CI->replaceAllUsesWith(New);
      CI->eraseFromParent();
    } else if (isa<Constant>(CI->getOperand(3)) && 
               cast<Constant>(CI->getOperand(3))->isNullValue()) {
      // poolrealloc(PD, X, 0) -> poolfree(PD, X)
      Value* Opts[2] = {CI->getOperand(1), CI->getOperand(2)};
      CallInst::Create(PoolFree, Opts, "", CI);
      PointerType * PT = dyn_cast<PointerType>(CI->getType());
      assert (PT && "poolrealloc call does not return a pointer!\n");
      CI->replaceAllUsesWith(ConstantPointerNull::get(PT));
      CI->eraseFromParent();
    } else if (isa<ConstantPointerNull>(CI->getOperand(1))) {
      // poolrealloc(null, X, Y) -> realloc(X, Y)
      Value* Opts[2] = {CI->getOperand(2), CI->getOperand(3)};
      Value *New = CallInst::Create(Realloc, Opts,
                                CI->getName(), CI);
      CI->replaceAllUsesWith(New);
      CI->eraseFromParent();
    }
  }

  // Optimize poolallocs
  getCallsOf(PoolAlloc, Calls);
  for (unsigned i = 0, e = Calls.size(); i != e; ++i) {
    CallInst *CI = Calls[i];
    // poolalloc(null, X) -> malloc(X)
    if (isa<Constant>(CI->getOperand(1)) && 
        cast<Constant>(CI->getOperand(1))->isNullValue()) {
//FIXME: handle malloc
      #if 0
      Value *New = new MallocInst(Int8Type, CI->getOperand(2),
                                  CI->getName(), CI);
      CI->replaceAllUsesWith(New);
      CI->eraseFromParent();
      #endif
    }
  }

  // Optimize poolmemaligns
  getCallsOf(PoolMemAlign, Calls);
  for (unsigned i = 0, e = Calls.size(); i != e; ++i) {
    CallInst *CI = Calls[i];
    // poolmemalign(null, X, Y) -> memalign(X, Y)
    if (isa<ConstantPointerNull>(CI->getOperand(1))) {
      Value* Opts[2] = {CI->getOperand(2), CI->getOperand(3)};
      Value *New = CallInst::Create(MemAlign, Opts, CI->getName(), CI);
      CI->replaceAllUsesWith(New);
      CI->eraseFromParent();
    }
  }

  // Optimize poolfrees
  getCallsOf(PoolFree, Calls);
  for (unsigned i = 0, e = Calls.size(); i != e; ++i) {
    CallInst *CI = Calls[i];
    // poolfree(PD, null) -> noop
    if (isa<ConstantPointerNull>(CI->getOperand(2)))
      CI->eraseFromParent();
    else if (isa<ConstantPointerNull>(CI->getOperand(1))) {
      // poolfree(null, Ptr) -> free(Ptr)
      //FIXME: Handle free
      //new FreeInst(CI->getOperand(2), CI);
      //CI->eraseFromParent();
    }
  }
      
  // Transform pools that only have poolinit/destroy/allocate uses into
  // bump-pointer pools.  Also, delete pools that are unused.  Find pools by
  // looking for pool inits in the program.
  getCallsOf(PoolInit, Calls);
  std::set<Value*> Pools;
  for (unsigned i = 0, e = Calls.size(); i != e; ++i)
    Pools.insert(Calls[i]->getOperand(1));

  // Loop over all of the pools processing each as we find it.
  for (std::set<Value*>::iterator PI = Pools.begin(), E = Pools.end();
       PI != E; ++PI) {
    bool HasPoolAlloc = false, HasOtherUse = false;
    Value *PoolDesc = *PI;
    for (Value::user_iterator UI = PoolDesc->user_begin(),
           E = PoolDesc->user_end(); UI != E; ++UI) {
      if (CallInst *CI = dyn_cast<CallInst>(*UI)) {
        if (CI->getCalledFunction() == PoolInit ||
            CI->getCalledFunction() == PoolDestroy) {
          // ignore
        } else if (CI->getCalledFunction() == PoolAlloc) {
          HasPoolAlloc = true;
        } else {
          HasOtherUse = true;
          break;
        }
      } else {
        HasOtherUse = true;
        break;
      }
    }

    // Can we optimize it?
    if (!HasOtherUse) {
      // Yes, if there are uses at all, nuke the pool init, destroy, and the PD.
      if (!HasPoolAlloc) {
        while (!PoolDesc->use_empty())
          cast<Instruction>(PoolDesc->user_back())->eraseFromParent();
        if (AllocaInst *AI = dyn_cast<AllocaInst>(PoolDesc))
          AI->eraseFromParent();
        else
          cast<GlobalVariable>(PoolDesc)->eraseFromParent();
      } else {
        // Convert all of the pool descriptor users to the BumpPtr flavor.
        std::vector<User*> PDUsers(PoolDesc->user_begin(), PoolDesc->user_end());
        
        while (!PDUsers.empty()) {
          CallInst *CI = cast<CallInst>(PDUsers.back());
          PDUsers.pop_back();
          std::vector<Value*> Args;
          if (CI->getCalledFunction() == PoolAlloc) {
            Args.assign(CI->op_begin()+1, CI->op_end());
            Value *New = CallInst::Create(PoolAllocBP, Args, CI->getName(), CI);
            CI->replaceAllUsesWith(New);
            CI->eraseFromParent();
          } else if (CI->getCalledFunction() == PoolInit) {
            Args.assign(CI->op_begin()+1, CI->op_end());
            Args.erase(Args.begin()+1); // Drop the size argument.
            CallInst::Create(PoolInitBP, Args, "", CI);
            CI->eraseFromParent();
          } else {
            assert(CI->getCalledFunction() == PoolDestroy);
            Args.assign(CI->op_begin()+1, CI->op_end());
            CallInst::Create(PoolDestroyBP, Args, "", CI);
            CI->eraseFromParent();
          }
        }
        ++NumBumpPtr;
      }
    }
  }
  return true;
}
