//===-- RunTimeAssociate.h - Runtime Ptr Association Pass -----------------===//
//
//                     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 pointers have an associated handle
// corrosponding to DSA results.  This is a generalization of the Poolalloc
// pass
//
//===----------------------------------------------------------------------===//

#ifndef _RUNTIMEASSOCIATE_H
#define	_RUNTIMEASSOCIATE_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/Support/CommandLine.h"

#include "dsa/DataStructure.h"

#include <set>
#include <map>
#include <vector>
#include <utility>

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

namespace rPA {

/// 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...
///

class FuncInfo {
public:
  FuncInfo(const Function* f, DSGraph* g) : F(f), G(g), Clone(0) { }

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

  DSGraph* G;

  /// 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;

  /// 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.
  std::map<const DSNode*, Value*> PoolDescriptors;

  /// 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<const Value*, Value*> ValueMapTy;
  ValueMapTy 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 {
    ValueMapTy::const_iterator I = NewToOldValueMap.find(V);
    return I != NewToOldValueMap.end() ? const_cast<Value*> (I->second) : 0;
  }

  Value* getOldValueIfAvailable(Value* V) {
    if (!NewToOldValueMap.empty()) {
      // If the NewToOldValueMap is in effect, use it.
      ValueMapTy::iterator I = NewToOldValueMap.find(V);
      if (I != NewToOldValueMap.end())
        V = I->second;
    }
    return V;
  }

  void UpdateNewToOldValueMap(Value *OldVal, Value *NewV1, Value *NewV2 = 0) {
    ValueMapTy::iterator I = NewToOldValueMap.find(OldVal);
    assert(I != NewToOldValueMap.end() && "OldVal not found in clone?");
    NewToOldValueMap.insert(std::make_pair(NewV1, I->second));
    if (NewV2)
      NewToOldValueMap.insert(std::make_pair(NewV2, I->second));
    NewToOldValueMap.erase(I);
  }

  DSNodeHandle& getDSNodeHFor(Value* V) {
    return G->getScalarMap()[getOldValueIfAvailable(V)];
  }

};

class PoolInfo {
  Value* PrimDesc;
  
public:

  void addPrimaryDescriptor(Value* P) {
    PrimDesc = P;
  }

  void mergeNodeInfo(const DSNode* N) { }

};

} // end rPA namespace


/// RTAssociate - Associate handles with pointers
///

class RTAssociate : public ModulePass {

  // Type used to represent the pool, will be opaque in this pass
  Type *PoolDescPtrTy, *PoolDescType;

  /// Special Values - Values created by this pass which should be ignored
  std::set<const Value*> SpecialValues;

  /// ValueMap - associate pools with values
  std::map<const Value*, rPA::PoolInfo*> ValueMap;
  
  /// NodePoolMap - Find a pool from a DSNode
  std::map<const DSNode*, rPA::PoolInfo*> NodePoolMap;
  std::map<const Function*, rPA::FuncInfo> FunctionInfo;

  //////////////////////////////////////////////////////////////////////////////

  GlobalVariable* CreateGlobalPool(const DSNode*, Module*);
  AllocaInst*     CreateLocalPool(const DSNode*, Function&);
  Argument*       CreateArgPool(const DSNode*, Argument*);

  /// SetupGlobalPools - Create a global for each global dsnode and associate
  /// a pool with it
  void SetupGlobalPools(Module*, DSGraph*);

  /// setPoolForNode - associate a pool with a dsnode
  void setupPoolForNode(const DSNode*, Value*);

  /// getPoolForNode - return a poolinfo for a dsnode
  rPA::PoolInfo* getPoolForNode(const DSNode* D) {
    return NodePoolMap[D];
  }

  rPA::FuncInfo* getFuncInfo(const Function*);

  rPA::FuncInfo& makeFuncInfo(const Function* F, DSGraph* G);

  Function* MakeFunctionClone(Function& F, rPA::FuncInfo& FI, DSGraph* G);

  /// ProcessCloneBody - Rewrite the body of a transformed function to use
  /// pool allocation where appropriate.
  ///
  void ProcessFunctionBody(Function &Old, Function &New, DSGraph* G,
                           DataStructures* DS);

  void TransformBody(Function& F, rPA::FuncInfo& FI, DataStructures* DS);

  void replaceCall(CallSite CS, rPA::FuncInfo& FI, DataStructures* DS);
  
  //////////////////////////////////////////////////////////////////////////////

public:
  static char ID;

  RTAssociate();
  bool runOnModule(Module &M);
  void getAnalysisUsage(AnalysisUsage &AU) const;

  
};
/*
private:


  /// 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;
  std::map<const Function*, Function*> CloneToOrigMap;

public:

  /// 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*, rPA::FuncInfo> FunctionInfo;
  DataStructures* Graphs;
  
public:

  //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;
  }

  /// getFuncInfo - Return the FuncInfo object for the specified function.
  ///

  rPA::FuncInfo *getFuncInfo(const Function &F) {
    std::map<const Function*, rPA::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.

  rPA::FuncInfo *getFuncInfoOrClone(const Function &F) {
    // If it is cloned or not check it out.
    if (rPA::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();
  }

  //
  // 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 containg information about the function and its
    // clones.
    //
    rPA::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.
      //
      assert((isa<GlobalVariable > (Pool) ||
             isa<AllocationInst > (Pool) ||
             isa<Argument > (Pool) ||
             isa<Constant > (Pool)) &&
             "Pool of unknown type!\n");
      if ((isa<GlobalVariable > (Pool)) || (isa<Constant > (Pool))) {
        return Pool;
      } else if (AllocationInst * AI = dyn_cast<AllocationInst > (Pool)) {
        if (AI->getParent()->getParent() == &F)
          return Pool;
      } else if (Argument * Arg = dyn_cast<Argument > (Pool)) {
        if (Arg->getParent() == &F)
          return Pool;
      }
    }

    //
    // We either do not have a pool, or the pool is not accessible from the
    // specified function.  Return NULL.
    //
    return 0;
  }

  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;
  }

protected:

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

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);

  /// 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(Function &F);

  /// 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, rPA::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);
};
*/

}

#endif	/* _RUNTIMEASSOCIATE_H */

