//===-- PoolAllocate.h - Pool allocation pass -------------------*- C++ -*-===//
// 
//                     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 transform changes programs so that disjoint data structures are
// allocated out of different pools of memory, increasing locality.  This header
// file exposes information about the pool allocation itself so that follow-on
// passes may extend or use the pool allocation for analysis.
//
//===----------------------------------------------------------------------===//

#ifndef POOLALLOCATE_H
#define POOLALLOCATE_H

#include "llvm/IR/Argument.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Instructions.h"
#include "llvm/Pass.h"
#include "llvm/IR/CallSite.h"
#include "llvm/ADT/EquivalenceClasses.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/CommandLine.h"

#include "dsa/DataStructure.h"
#include "dsa/DSGraph.h"
#include "dsa/CallTargets.h"
#include "poolalloc/Heuristic.h"

#include <utility>

namespace llvm {
class DSNode;
class DSGraph;
class Type;
class AllocaInst;

namespace PA {

  extern cl::opt<bool>  PA_SAFECODE;

  /// FuncInfo - Represent the pool allocation information for one function in
  /// the program.  Note that many functions must actually be cloned in order
  /// for pool allocation to add arguments to the function signature.  In this
  /// case, the Clone and NewToOldValueMap information identify how the clone
  /// maps to the original function...
  ///
  /// FIXME: This structure should implement information hiding.  There should
  ///        be some information hiding.  The design may depend on how we change
  ///        the way in which clients interface with pool allocation analysis
  ///        results.
  ///
  struct FuncInfo {
    FuncInfo(Function &f) : F(f), Clone(0), rev_pool_desc_map_computed(false) {}

    /// MarkedNodes - The set of nodes which are not locally pool allocatable in
    /// the current function.
    ///
    /// FIXME: This field has a non-descriptive name.
    ///
    DenseSet<const DSNode*> MarkedNodes;

    /// F - The function this FuncInfo corresponds to.
    ///
    Function &F;

    /// Clone - The cloned version of the function, if applicable.
    ///
    Function *Clone;

    /// ArgNodes - The list of DSNodes which have pools passed in as arguments.
    /// 
    std::vector<const DSNode*> ArgNodes;

    /// NodesToPA - The list of nodes which are to be pool allocated locally in
    /// this function.  This only includes heap nodes.
    std::vector<const DSNode*> NodesToPA;

    /// PoolDescriptors - The Value* which defines the pool descriptor for this
    /// DSNode.  Note: This does not necessarily include pool arguments that are
    /// passed in because of indirect function calls that are not used in the
    /// function.
    /// FIXME: This comment should clearly describe which pools are and are not
    ///        in this data structure.
    std::map<const DSNode*, Value*> PoolDescriptors;

    // Reverse mapping for PoolDescriptors, needed by TPPA
    // FIXME: There can be multiple DSNodes mapped to a single pool descriptor
    std::multimap<Value*, const DSNode*> ReversePoolDescriptors;

    // This is a hack -- a function should be added which maintains these in parallel
    // and all of PoolAlloc and SafeCode should be updated to use it instead of adding
    // to either map directly.
    bool rev_pool_desc_map_computed;
    void calculate_reverse_pool_descriptors()
    {
    	if(rev_pool_desc_map_computed)
    		return;
    	rev_pool_desc_map_computed = true;

    	for(std::map<const DSNode*, Value*>::iterator i = PoolDescriptors.begin(); i!=PoolDescriptors.end(); i++)
    		ReversePoolDescriptors.insert(std::pair<Value*,const DSNode*>(i->second,i->first));
    }

    /// This is a map from Old to New Values (the reverse of NewToOldValueMap).
    /// SAFECode uses this for check insertion.
    /// FIXME: Does SAFECode still use this?  Should a single class handle this map and the
    /// NewToOldValue Map?
    std::map<const Value*, Value*> ValueMap;

    /// NewToOldValueMap - When and if a function needs to be cloned, this map
    /// contains a mapping from all of the values in the new function back to
    /// the values they correspond to in the old function.
    ///
    typedef std::map<Value*, const Value*> NewToOldValueMapTy;
    NewToOldValueMapTy NewToOldValueMap;

    /// MapValueToOriginal - Given a value in the cloned version of this
    /// function, map it back to the original.  If the specified value did not
    /// exist in the original function (e.g. because it's a pool descriptor),
    /// return null.
    Value *MapValueToOriginal(Value *V) const {
      NewToOldValueMapTy::const_iterator I = NewToOldValueMap.find(V);
      return I != NewToOldValueMap.end() ? const_cast<Value*>(I->second) : 0;
    }
  };

} // end PA namespace


class PoolAllocateGroup : public ModulePass {
protected:
  DataStructures *Graphs;
  Type * VoidType;
  Type * Int8Type;
  Type * Int32Type;

public:
  static char ID;
  // FIXME: Some of these things should not be public.
  Constant *PoolRegister;

  // FIXME: We want to remove SAFECode specified flags.
  bool SAFECodeEnabled;

  enum LIE_TYPE {LIE_NONE, LIE_PRESERVE_DSA, LIE_PRESERVE_ALL, LIE_PRESERVE_DEFAULT};
  // FIXME: Try to minimize lying
  LIE_TYPE lie_preserve_passes;
  // FIXME: Let clients choose which DSA pass is used by scheduling it ahead of time.
  enum PASS_TYPE {PASS_EQTD, PASS_BUEQ, PASS_DEFAULT};
  PASS_TYPE dsa_pass_to_use;

                
  PoolAllocateGroup  (char * IDp = &ID) : ModulePass (*IDp) { }
  virtual ~PoolAllocateGroup () {return;}

  virtual PA::FuncInfo *getFuncInfo(const Function &F) { return 0;}
  virtual PA::FuncInfo *getFuncInfoOrClone(const Function &F) {return 0;}
  virtual Function *getOrigFunctionFromClone(const Function *F) const {return 0;}

  // FIXME: Clients should be able to specialize pool descriptor type
  virtual Type * getPoolType(LLVMContext*) {return 0;}

  virtual bool hasDSGraph (const Function & F) const {
    return Graphs->hasDSGraph (F);
  }

  virtual DSGraph*  getDSGraph (const Function & F) const {
    return Graphs->getDSGraph (F);
  }

  virtual DSGraph* getGlobalsGraph () const {
    return Graphs->getGlobalsGraph ();
  }

  // Return value is of type PoolDescPtrTy
  // FIXME: Do we need to have a getGlobalPool() for clients?
  // FIXME: Can we infer the function?  Possibly not since we want to distinguish between
  //        pools in clones and pools in original function.
  // FIXME: We want something like getPool (Value *) if possible.
  virtual Value * getPool (const DSNode * N, Function & F) {return 0;}

  virtual Value * getGlobalPool (const DSNode * Node) {return 0;}

};

/// PoolAllocate - The main pool allocation pass
///
class PoolAllocate : public PoolAllocateGroup {
  /// PassAllArguments - If set to true, we should pass pool descriptor
  /// arguments into any function that loads or stores to a pool, in addition to
  /// those functions that allocate or deallocate.  See also the
  /// PoolAllocatePassAllPools pass below.
  bool PassAllArguments;

  Module *CurModule;

  // FIXME: Where is this used?  Why isn't DSCallGraph used directly?
  // TransformFunction should potentially use this.
  dsa::CallTargetFinder<EQTDDataStructures>* CTF;
  
  // Map a cloned function to its original function
  std::map<const Function*, Function*> CloneToOrigMap;

public:

  Constant *PoolInit, *PoolDestroy, *PoolAlloc, *PoolRealloc, *PoolMemAlign, *PoolThreadWrapper;
  Constant *PoolFree;
  Constant *PoolCalloc;
  Constant *PoolStrdup;

  // Function which will initialize global pools
  Function * GlobalPoolCtor;
  
  static Type *PoolDescPtrTy;

  PA::Heuristic *CurHeuristic;

  /// GlobalNodes - For each node (with an H marker) in the globals graph, this
  /// map contains the global variable that holds the pool descriptor for the
  /// node.
  std::map<const DSNode*, Value*> GlobalNodes;

protected:
  std::map<const Function*, PA::FuncInfo> FunctionInfo;

 public:
  static char ID;

  PoolAllocate (bool passAllArguments,
                bool SAFECode = true,
                char * IDp = &ID)
    : PoolAllocateGroup (IDp),
      PassAllArguments(passAllArguments)
      {
		  SAFECodeEnabled = SAFECode |  PA::PA_SAFECODE;
		  lie_preserve_passes = SAFECodeEnabled ? LIE_PRESERVE_ALL : LIE_PRESERVE_DSA;
		  dsa_pass_to_use = SAFECodeEnabled ? PASS_EQTD : PASS_BUEQ;

      }

  /*TODO: finish removing the SAFECode flag*/
  PoolAllocate (PASS_TYPE dsa_pass_to_use_ = PASS_DEFAULT,
				LIE_TYPE lie_preserve_passes_ = LIE_PRESERVE_DEFAULT,
				bool passAllArguments = false,
				bool SAFECode = true,
                char * IDp = &ID)
      : PoolAllocateGroup (IDp),
        PassAllArguments(passAllArguments)
        {
  		  SAFECodeEnabled = SAFECode |  PA::PA_SAFECODE;

  		  if(lie_preserve_passes_ == LIE_PRESERVE_DEFAULT)
  			  lie_preserve_passes = SAFECodeEnabled ? LIE_PRESERVE_ALL : LIE_PRESERVE_DSA;
  		  else
  			  lie_preserve_passes = lie_preserve_passes_;

  		  if(dsa_pass_to_use_ == PASS_DEFAULT)
  			  dsa_pass_to_use = SAFECodeEnabled ? PASS_EQTD : PASS_BUEQ;
  		  else
  			  dsa_pass_to_use = dsa_pass_to_use_;

        }

  virtual bool runOnModule(Module &M);
  
  virtual void getAnalysisUsage(AnalysisUsage &AU) const;
  
  // FIXME: This method is misnamed.
  DataStructures &getGraphs() const { return *Graphs; }

  /// getOrigFunctionFromClone - Given a pointer to a function that was cloned
  /// from another function, return the original function.  If the argument
  /// function is not a clone, return null.
  Function *getOrigFunctionFromClone(const Function *F) const {
    std::map<const Function*, Function*>::const_iterator I = CloneToOrigMap.find(F);
    return I != CloneToOrigMap.end() ? I->second : 0;
  }

  // FIXME: add isClone()

  /// getFuncInfo - Return the FuncInfo object for the specified function.
  ///
  PA::FuncInfo *getFuncInfo(const Function &F) {
    std::map<const Function*, PA::FuncInfo>::iterator I = FunctionInfo.find(&F);
    return I != FunctionInfo.end() ? &I->second : 0;
  }

  /// getFuncInfoOrClone - Return the function info object for for the specified
  /// function.  If this function is a clone of another function, return the
  /// function info object for the original function.
  PA::FuncInfo *getFuncInfoOrClone(const Function &F) {
    // If it is cloned or not check it out.
    if (PA::FuncInfo *FI = getFuncInfo(F))
      return FI;
    // Maybe this is a function clone?
    if (Function *FC = getOrigFunctionFromClone(&F))
      return getFuncInfo(*FC);
    return 0;
  }
  

  /// releaseMemory - When the pool allocator is no longer used, release
  /// resources used by it.
  virtual void releaseMemory() {
    FunctionInfo.clear();
    GlobalNodes.clear();
    CloneToOrigMap.clear();
  }


  Module *getCurModule() { return CurModule; }

  /// CreateGlobalPool - Create a global pool descriptor, initialize it in main,
  /// and return a pointer to the global for it.
  GlobalVariable *CreateGlobalPool(unsigned RecSize, unsigned Alignment,
                                   std::string name = "GlobalPool", Instruction *IPHint = 0);

  /// getPoolType - Return the type of a pool descriptor
  /// FIXME: These constants should be chosen by the client
  Type * getPoolType(LLVMContext* C) {
    IntegerType * IT = IntegerType::getInt8Ty(*C);
    Type * VoidPtrType = PointerType::getUnqual(IT);
    if (SAFECodeEnabled)
      return ArrayType::get(VoidPtrType, 92);
    else
      return ArrayType::get(VoidPtrType, 16);
  }

  virtual DSGraph* getDSGraph (const Function & F) const {
    return Graphs->getDSGraph (F);
  }

  virtual DSGraph* getGlobalsGraph () const {
    return Graphs->getGlobalsGraph ();
  }

  //
  // Method: getPool()
  //
  // Description:
  //  Returns the pool handle associated with the DSNode in the given function.
  //
  // Inputs:
  //  N - The DSNode of the value for which the caller wants a pool handle.
  //  F - The function in which the value for which we want a pool handle
  //      exists.
  //
  // Notes:
  //  o) The DSNode N may *not* be in the current function.  The caller may
  //     have mapped a value in the cloned function back to the original
  //     function.
  //
  virtual Value * getPool (const DSNode * N, Function & F) {
    //
    // Grab the structure containing information about the function and its
    // clones.
    //
    PA::FuncInfo * FI = getFuncInfoOrClone (F);
    assert (FI && "Function has no FuncInfoOrClone!\n");

    //
    // Look for a mapping from the DSNode to the pool handle.
    //
    std::map<const DSNode*, Value*>::iterator I = FI->PoolDescriptors.find(N);
    if (I != FI->PoolDescriptors.end()) {
      Value * Pool = I->second;

      //
      // Now the fun part:
      //  The specified function could either be a clone or the original
      //  function.  This means that the pool descriptor that is matched with
      //  the DSNode is:
      //    o) A constant accessible from both the original function and its
      //       clones.
      //    o) A global variable accessible from both the original function and
      //       its clones.
      //    o) An allocation accessible only to the function.
      //    o) A function parameter accessible only to the local function.
      //
      //  In short, we need to filter out the case where we find a pool handle,
      //  but it's only accessible from a clone and not the original function.
      //
      //FIXME: handle allocators
      assert ((isa<GlobalVariable>(Pool) ||
               isa<AllocaInst>(Pool) ||
               isa<Argument>(Pool) ||
               isa<Constant>(Pool)) &&
               "Pool of unknown type!\n");
      if ((isa<GlobalVariable>(Pool)) || (isa<Constant>(Pool))) {
          return Pool;
      } else if (AllocaInst * AI = dyn_cast<AllocaInst>(Pool)) {
        if (AI->getParent()->getParent() == &F)
          return Pool;
      } else if (Argument * Arg = dyn_cast<Argument>(Pool)) {
        if (Arg->getParent() == &F)
          return Pool;
      }
    }

    //
    // Perhaps this is a global pool.  If it isn't, then return a NULL
    // pointer.
    //
    return getGlobalPool (N);
  }

  virtual Value * getGlobalPool (const DSNode * Node) {
    std::map<const DSNode *, Value *>::iterator I = GlobalNodes.find (Node);
    if (I == GlobalNodes.end())
      return 0;
    else
      return I->second;
  }

  /// getNumInitialPoolArguments - If the passed function name is recognized
  /// as a runtime check, return the number of initial pool arguments for
  /// the runtime check. Otherwise return 0.
  static unsigned getNumInitialPoolArguments(StringRef Name);

protected:
  
  /// AddPoolPrototypes - Add prototypes for the pool functions to the
  /// specified module and update the Pool* instance variables to point to
  /// them.
  ///
  void AddPoolPrototypes(Module*);

  /// createGlobalPoolCtor - Create an empty function and insert it into the
  /// constructor list. The created function can be used for poolinit calls.
  Function *createGlobalPoolCtor(Module &M);

 private:

  /// MicroOptimizePoolCalls - Apply any microoptimizations to calls to pool
  /// allocation function calls that we can.
  void MicroOptimizePoolCalls();
  
  /// BuildIndirectFunctionSets - Iterate over the module looking for indirect
  /// calls to functions
  void BuildIndirectFunctionSets(Module &M);   

  /// SetupGlobalPools - Create global pools for all DSNodes in the globals
  /// graph which contain heap objects.  If a global variable points to a piece
  /// of memory allocated from the heap, this pool gets a global lifetime.
  ///
  /// This method returns true if correct pool allocation of the module cannot
  /// be performed because there is no main function for the module and there
  /// are global pools.
  bool SetupGlobalPools(Module &M);

  /// FindPoolArgs - Make a pass over the module and find the arguments of each
  /// function that need to have their pools passed in.  This will build a
  /// FunctionInfo for each function.
  void FindPoolArgs (Module & M);

  /// FindFunctionPoolArgs - In the first pass over the program, we decide which
  /// arguments will have to be added for each function, build the FunctionInfo
  /// map and recording this info in the ArgNodes set.
  void FindFunctionPoolArgs (const std::vector<const Function *> & Funcs);   
  
  /// MakeFunctionClone - If the specified function needs to be modified for
  /// pool allocation support, make a clone of it, adding additional arguments
  /// as neccesary, and return it.  If not, just return null.
  ///
  Function *MakeFunctionClone(Function &F);
  
  /// ProcessFunctionBody - Rewrite the body of a transformed function to use
  /// pool allocation where appropriate.
  ///
  void ProcessFunctionBody(Function &Old, Function &New);
  
  /// CreatePools - This inserts alloca instruction in the function for all
  /// pools specified in the NodesToPA list.  This adds an entry to the
  /// PoolDescriptors map for each DSNode.
  ///
  void CreatePools(Function &F, DSGraph* G, 
                   const std::vector<const DSNode*> &NodesToPA,
                   std::map<const DSNode*, Value*> &PoolDescriptors);
  
  void TransformBody(DSGraph* g, PA::FuncInfo &fi,
                     std::multimap<AllocaInst*, Instruction*> &poolUses,
                     std::multimap<AllocaInst*, CallInst*> &poolFrees,
                     Function &F);

  /// InitializeAndDestroyPools - This inserts calls to poolinit and pooldestroy
  /// into the function to initialize and destroy the pools in the NodesToPA
  /// list.
  void InitializeAndDestroyPools(Function &F,
                                 const std::vector<const DSNode*> &NodesToPA,
                      std::map<const DSNode*, Value*> &PoolDescriptors,
                      std::multimap<AllocaInst*, Instruction*> &PoolUses,
                      std::multimap<AllocaInst*, CallInst*> &PoolFrees);

  void InitializeAndDestroyPool(Function &F, const DSNode *Pool,
                            std::map<const DSNode*, Value*> &PoolDescriptors,
                            std::multimap<AllocaInst*, Instruction*> &PoolUses,
                            std::multimap<AllocaInst*, CallInst*> &PoolFrees);

  void CalculateLivePoolFreeBlocks(std::set<BasicBlock*> &LiveBlocks,Value *PD);
};


/// PoolAllocatePassAllPools - This class is the same as the pool allocator,
/// except that it passes pool descriptors into functions that do not do
/// allocations or deallocations.  This is needed by the pointer compression
/// pass, which requires a pool descriptor to be available for a pool if any
/// load or store to that pool is performed.
struct PoolAllocatePassAllPools : public PoolAllocate {
  static char ID;
  PoolAllocatePassAllPools() : PoolAllocate(PASS_DEFAULT, LIE_PRESERVE_DEFAULT, true, false, &ID) {}
};

/// PoolAllocateSimple - This class modifies the heap allocations so that they
/// use the pool allocator run-time.  However, unlike PoolAllocatePassAllPools,
/// it doesn't involve all of complex machinery of the original pool allocation
/// implementation.
class PoolAllocateSimple : public PoolAllocate {
  Value * TheGlobalPool;
  DSGraph * CombinedDSGraph;
  EquivalenceClasses<const GlobalValue*> GlobalECs;
  bool CompleteDSA;
public:
  static char ID;
  PoolAllocateSimple(bool passAllArgs=false, bool SAFECode = true, bool CompleteDSA = true)
    : PoolAllocate (PASS_DEFAULT, LIE_PRESERVE_DEFAULT, passAllArgs, SAFECode, &ID), CompleteDSA(CompleteDSA) {}
  ~PoolAllocateSimple() {return;}
  void getAnalysisUsage(AnalysisUsage &AU) const;
  bool runOnModule(Module &M);
  GlobalVariable *CreateGlobalPool(unsigned RecSize, unsigned Align,
                                   Module& M);
  void ProcessFunctionBodySimple(Function& F, const DataLayout & TD);


  virtual DSGraph* getDSGraph (const Function & F) const {
    return CombinedDSGraph;
  }

  virtual DSGraph* getGlobalsGraph () const {
    return CombinedDSGraph->getGlobalsGraph();
  }

  virtual Value * getGlobalPool (const DSNode * Node) {
    return TheGlobalPool;
  }

  virtual Value * getPool (const DSNode * N, Function & F) {
    return TheGlobalPool;
  }
};

/// PoolAllocateMultipleGlobalPool
/// Context-insensitive pool allocation. It pool allocates objects into multiple
/// global pools. It does not need to rewrite the functions declarations, which
/// simplifies the implementation a lot. Technically, PoolAllocateSimple, which
/// pool allocates everything into a single global pool, is a
/// special case of PoolAllocateMultipleGlobalPool.
///
/// It requires some work on code clean up to make these two pass integrate
/// nicely.

// FIXME: Is this used?  Should it be removed?
class PoolAllocateMultipleGlobalPool : public PoolAllocate {
  void ProcessFunctionBodySimple(Function& F, const DataLayout & TD);
  /// Mapping between DSNodes and Pool descriptors. For this pass, it is a
  /// one-to-one relationship.
  typedef DenseMap<const DSNode *, GlobalVariable *> PoolMapTy;
  PoolMapTy PoolMap;
  void generatePool(unsigned RecSize, unsigned Align,
                    Module& M, BasicBlock * InsertAtEnd, const DSNode * Node);
  Module * currentModule;
public:
  static char ID;
  PoolAllocateMultipleGlobalPool(bool passAllArgs=false, bool SAFECode = true)
    : PoolAllocate (PASS_DEFAULT, LIE_PRESERVE_DEFAULT, passAllArgs, SAFECode, &ID) {}
  ~PoolAllocateMultipleGlobalPool();
  virtual void getAnalysisUsage(AnalysisUsage &AU) const;
  virtual bool runOnModule(Module &M);
  void CreateGlobalPool(unsigned RecSize, unsigned Align,
                                   Module& M);

  virtual Value * getGlobalPool (const DSNode * Node);
  virtual Value * getPool (const DSNode * N, Function & F);
  virtual void print(llvm::raw_ostream &OS, const Module * M) const;
  virtual void dump() const;
};

}
#endif
