//===- DSNode.h - Node definition for datastructure graphs ------*- 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.
//
//===----------------------------------------------------------------------===//
//
// Data structure graph nodes and some implementation of DSNodeHandle.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_ANALYSIS_DSNODE_H
#define LLVM_ANALYSIS_DSNODE_H

#include "dsa/DSSupport.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/ilist_node.h"

#include <map>
#include <set>
#include "dsa/sv/set.h"
#include "dsa/sv/super_set.h"
#include "DSGraph.h"

namespace llvm {

template<typename BaseType>
class DSNodeIterator;          // Data structure graph traversal iterator

//===----------------------------------------------------------------------===//
/// DSNode - Data structure node class
///
/// This class represents an untyped memory object of Size bytes.  It keeps
/// track of any pointers that have been stored into the object as well as the
/// different types represented in this object.
///
class DSNode : public ilist_node<DSNode> {
public:
  typedef std::map<unsigned, SuperSet<const Type*>::setPtr> TyMapTy;
  typedef std::map<unsigned, DSNodeHandle> LinkMapTy;

private:
  friend struct ilist_sentinel_traits<DSNode>;
  //Sentinel
  DSNode() : NumReferrers(0), Size(0), NodeType(0) {}
  
  /// NumReferrers - The number of DSNodeHandles pointing to this node... if
  /// this is a forwarding node, then this is the number of node handles which
  /// are still forwarding over us.
  ///
  unsigned NumReferrers;

  /// ForwardNH - This NodeHandle contain the node (and offset into the node)
  /// that this node really is.  When nodes get folded together, the node to be
  /// eliminated has these fields filled in, otherwise ForwardNH.getNode() is
  /// null.
  ///
  DSNodeHandle ForwardNH;

  /// Size - The current size of the node.  This should be equal to the size of
  /// the current type record.
  ///
  unsigned Size;

  /// ParentGraph - The graph this node is currently embedded into.
  ///
  DSGraph *ParentGraph;

  /// TyMap - Keep track of the loadable types and offsets those types are seen
  // at.
  TyMapTy TyMap;

  /// Links - Contains one entry for every byte in this memory
  /// object.  
  ///
  LinkMapTy Links;

  /// Globals - The list of global values that are merged into this node.
  ///
  sv::set<const GlobalValue*> Globals;

  void operator=(const DSNode &); // DO NOT IMPLEMENT
  DSNode(const DSNode &);         // DO NOT IMPLEMENT
public:
  enum NodeTy {
    ShadowNode      = 0,        // Nothing is known about this node...
    AllocaNode      = 1 << 0,   // This node was allocated with alloca
    HeapNode        = 1 << 1,   // This node was allocated with malloc
    GlobalNode      = 1 << 2,   // This node was allocated by a global var decl
    ExternFuncNode  = 1 << 3,   // This node contains external functions
    ExternGlobalNode = 1 << 4,  // This node contains external globals
    UnknownNode     = 1 << 5,   // This node points to unknown allocated memory
    IncompleteNode  = 1 << 6,   // This node may not be complete

    ModifiedNode    = 1 << 7,   // This node is modified in this context
    ReadNode        = 1 << 8,   // This node is read in this context

    ArrayNode       = 1 << 9,   // This node is treated like an array
    CollapsedNode   = 1 << 10,  // This node is collapsed
    ExternalNode    = 1 << 11,  // This node comes from an external source
    IntToPtrNode    = 1 << 12,   // This node comes from an int cast
    PtrToIntNode    = 1 << 13,  // This node excapes to an int cast
    VAStartNode     = 1 << 14,  // This node excapes to an int cast

    //#ifndef NDEBUG
    DeadNode        = 1 << 15,   // This node is dead and should not be pointed to
    //#endif

    Composition = AllocaNode | HeapNode | GlobalNode | UnknownNode
  };

  /// NodeType - A union of the above bits.  "Shadow" nodes do not add any flags
  /// to the nodes in the data structure graph, so it is possible to have nodes
  /// with a value of 0 for their NodeType.
  ///
private:
  unsigned short NodeType;
public:

  /// DSNode ctor - Create a node of the specified type, inserting it into the
  /// specified graph.
  ///
  explicit DSNode(DSGraph *G);

  /// DSNode "copy ctor" - Copy the specified node, inserting it into the
  /// specified graph.  If NullLinks is true, then null out all of the links,
  /// but keep the same number of them.  This can be used for efficiency if the
  /// links are just going to be clobbered anyway.
  ///
  DSNode(const DSNode &, DSGraph *G, bool NullLinks = false);

#if 0
  ~DSNode() {
    dropAllReferences();
    assert(hasNoReferrers() && "Referrers to dead node exist!");
  }
#else
  ~DSNode();
#endif

  // Iterator for graph interface... Defined in DSGraphTraits.h
  typedef DSNodeIterator<DSNode> iterator;
  typedef DSNodeIterator<const DSNode> const_iterator;
  inline iterator begin();
  inline iterator end();
  inline const_iterator begin() const;
  inline const_iterator end() const;

  /// type_* - Provide iterators for accessing types.  Some types may be null
  typedef TyMapTy::iterator type_iterator;
  typedef TyMapTy::const_iterator const_type_iterator;
  type_iterator type_begin() { return TyMap.begin(); }
  type_iterator type_end()   { return TyMap.end(); }
  const_type_iterator type_begin() const { return TyMap.begin(); }
  const_type_iterator type_end()   const { return TyMap.end(); }

  /// edge_* - Provide iterators for accessing outgoing edges.  Some outgoing
  /// edges may be null.
  typedef LinkMapTy::iterator edge_iterator;
  typedef LinkMapTy::const_iterator const_edge_iterator;
  edge_iterator edge_begin() { return Links.begin(); }
  edge_iterator edge_end() { return Links.end(); }
  const_edge_iterator edge_begin() const { return Links.begin(); }
  const_edge_iterator edge_end() const { return Links.end(); }

  //===--------------------------------------------------
  // Accessors

  /// getSize - Return the maximum number of bytes occupied by this object...
  ///
  unsigned getSize() const { return Size; }

  /// hasNoReferrers - Return true if nothing is pointing to this node at all.
  ///
  bool hasNoReferrers() const { return getNumReferrers() == 0; }

  /// getNumReferrers - This method returns the number of referrers to the
  /// current node.  Note that if this node is a forwarding node, this will
  /// return the number of nodes forwarding over the node!
  unsigned getNumReferrers() const { return NumReferrers; }


  DSGraph *getParentGraph() const { return ParentGraph; }
  void setParentGraph(DSGraph *G) { ParentGraph = G; }

  /// getForwardNode - This method returns the node that this node is forwarded
  /// to, if any.
  ///
  DSNode *getForwardNode() const { return ForwardNH.getNode(); }

  /// isForwarding - Return true if this node is forwarding to another.
  ///
  bool isForwarding() const { return !ForwardNH.isNull(); }

  /// stopForwarding - When the last reference to this forwarding node has been
  /// dropped, delete the node.
  ///
  void stopForwarding() {
    assert(isForwarding() &&
           "Node isn't forwarding, cannot stopForwarding()!");
    ForwardNH.setTo(0, 0);
    assert(ParentGraph == 0 &&
           "Forwarding nodes must have been removed from graph!");
    delete this;
  }

  void growSize(unsigned NSize) {
    assert(NSize > Size && "Cannot shrink");
    assert(!isCollapsedNode() && "growing a collapsed node");
    Size = NSize;
  }

  /// hasLink - Return true if this memory object has a link in slot LinkNo
  ///
  bool hasLink(unsigned Offset) const {
    assert(Offset < getSize() && "Link index is out of range!");
    return Links.find(Offset) != Links.end();
  }

  /// getLink - Return the link at the specified offset.
  ///
  DSNodeHandle &getLink(unsigned Offset) {
    assert(Offset < getSize() && "Link index is out of range!");
    assert(!isForwarding() && "Link on a forwarding node");
    return Links[Offset];
   }
  const DSNodeHandle &getLink(unsigned Offset) const {
    assert(hasLink(Offset) && "No Link");
    assert(!isForwarding() && "Link on a forwarding node");
    return Links.find(Offset)->second;
  }

  //unsigned getNumLinks() const {
//     assert(!isForwarding() && "Link on a forwarding node");
//    return Links.size();
//  }

  /// mergeTypeInfo - This method merges the specified type into the current
  /// node at the specified offset.  This may update the current node's type
  /// record if this gives more information to the node, it may do nothing to
  /// the node if this information is already known, or it may merge the node
  /// completely (and return true) if the information is incompatible with what
  /// is already known.
  ///
  /// FIXME: description
  void mergeTypeInfo(const Type *Ty, unsigned Offset);
  void mergeTypeInfo(const TyMapTy::mapped_type TyIt, unsigned Offset);
  void mergeTypeInfo(const DSNode* D, unsigned Offset);

  // Types records might exist without types in them
  bool hasNoType() {
    type_iterator ii = type_begin(), ee = type_end();
    while (ii != ee) {
      if (ii->second) return false;
      ++ii;
    }
    return true;
  }

  /// foldNodeCompletely - If we determine that this node has some funny
  /// behavior happening to it that we cannot represent, we fold it down to a
  /// single, completely pessimistic, node.  This node is represented as a
  /// single byte with a single TypeEntry of "void" with isArray = true.
  ///
  void foldNodeCompletely();

  /// isNodeCompletelyFolded - Return true if this node has been completely
  /// folded down to something that can never be expanded, effectively losing
  /// all of the field sensitivity that may be present in the node.
  ///
  bool isNodeCompletelyFolded() const;

  /// setLink - Set the link at the specified offset to the specified
  /// NodeHandle, replacing what was there.  It is uncommon to use this method,
  /// instead one of the higher level methods should be used, below.
  ///
  void setLink(unsigned Offset, const DSNodeHandle &NH) {
    assert(Offset < getSize() && "Link index is out of range!");
    Links[Offset] = NH;
  }

  /// addEdgeTo - Add an edge from the current node to the specified node.  This
  /// can cause merging of nodes in the graph.
  ///
  void addEdgeTo(unsigned Offset, const DSNodeHandle &NH);

  /// mergeWith - Merge this node and the specified node, moving all links to
  /// and from the argument node into the current node, deleting the node
  /// argument.  Offset indicates what offset the specified node is to be merged
  /// into the current node.
  ///
  /// The specified node may be a null pointer (in which case, nothing happens).
  ///
  void mergeWith(const DSNodeHandle &NH, unsigned Offset);

  /// addGlobal - Add an entry for a global value to the Globals list.  This
  /// also marks the node with the 'G' flag if it does not already have it.
  ///
  void addGlobal(const GlobalValue *GV);

  void addFunction(const Function* F);

  /// removeGlobal - Remove the specified global that is explicitly in the
  /// globals list.
  void removeGlobal(const GlobalValue *GV);

  void mergeGlobals(const DSNode& RHS);
  void clearGlobals() { Globals.clear(); }

  bool isEmptyGlobals() const { return Globals.empty(); }
  unsigned numGlobals() const { return Globals.size(); }

  /// addFullGlobalsList - Compute the full set of global values that are
  /// represented by this node.  Unlike getGlobalsList(), this requires fair
  /// amount of work to compute, so don't treat this method call as free.
  void addFullGlobalsList(std::vector<const GlobalValue*> &List) const;

  /// addFullFunctionList - Identical to addFullGlobalsList, but only return the
  /// functions in the full list.
  void addFullFunctionList(std::vector<const Function*> &List) const;

  /// globals_iterator/begin/end - Provide iteration methods over the global
  /// value leaders set that is merged into this node.  Like the getGlobalsList
  /// method, these iterators do not return globals that are part of the
  /// equivalence classes for globals in this node, but aren't leaders.
  typedef sv::set<const GlobalValue*>::const_iterator globals_iterator;
  globals_iterator globals_begin() const { return Globals.begin(); }
  globals_iterator globals_end() const { return Globals.end(); }


  /// maskNodeTypes - Apply a mask to the node types bitfield.
  ///
  void maskNodeTypes(unsigned Mask) {
    NodeType &= Mask;
  }

  void mergeNodeFlags(unsigned RHS) {
    NodeType |= RHS;
  }

  /// getNodeFlags - Return all of the flags set on the node.  If the DEAD flag
  /// is set, hide it from the caller.
  ///
  unsigned getNodeFlags() const { return NodeType & ~DeadNode; }

  /// clearNodeFlags - Useful for completely resetting a node, 
  /// used in external recognizers
  DSNode* clearNodeFlags() { NodeType = 0; return this; }

  bool isAllocaNode()     const { return NodeType & AllocaNode;    }
  bool isHeapNode()       const { return NodeType & HeapNode;      }
  bool isGlobalNode()     const { return NodeType & GlobalNode;    }
  bool isExternFuncNode() const { return NodeType & ExternFuncNode; }
  bool isUnknownNode()    const { return NodeType & UnknownNode;   }
  bool isModifiedNode()   const { return NodeType & ModifiedNode;  }
  bool isReadNode()       const { return NodeType & ReadNode;      }
  bool isArrayNode()      const { return NodeType & ArrayNode;     }
  bool isCollapsedNode()  const { return NodeType & CollapsedNode; }
  bool isIncompleteNode() const { return NodeType & IncompleteNode;}
  bool isCompleteNode()   const { return !isIncompleteNode();      }
  bool isDeadNode()       const { return NodeType & DeadNode;      }
  bool isExternalNode()   const { return NodeType & ExternalNode;  }
  bool isIntToPtrNode()   const { return NodeType & IntToPtrNode;  }
  bool isPtrToIntNode()   const { return NodeType & PtrToIntNode;  }
  bool isVAStartNode()    const { return NodeType & VAStartNode;   }

  DSNode* setAllocaMarker()     { NodeType |= AllocaNode;     return this; }
  DSNode* setHeapMarker()       { NodeType |= HeapNode;       return this; }
  DSNode* setGlobalMarker()     { NodeType |= GlobalNode;     return this; }
  DSNode* setExternFuncMarker() { NodeType |= ExternFuncNode; return this; }
  DSNode* setExternGlobalMarker() { NodeType |= ExternGlobalNode; return this; }
  DSNode* setUnknownMarker()    { NodeType |= UnknownNode;    return this; }
  DSNode* setModifiedMarker()   { NodeType |= ModifiedNode;   return this; }
  DSNode* setReadMarker()       { NodeType |= ReadNode;       return this; }
  DSNode* setArrayMarker()      { NodeType |= ArrayNode;      return this; }
  DSNode* setCollapsedMarker()  { NodeType |= CollapsedNode;  return this; }
  DSNode* setIncompleteMarker() { NodeType |= IncompleteNode; return this; }
  DSNode* setExternalMarker()   { NodeType |= ExternalNode;   return this; }
  DSNode* setIntToPtrMarker()   { NodeType |= IntToPtrNode;   return this; }
  DSNode* setPtrToIntMarker()   { NodeType |= PtrToIntNode;   return this; }
  DSNode* setVAStartMarker()    { NodeType |= VAStartNode;    return this; }

  void makeNodeDead() {
    Globals.clear();
    assert(hasNoReferrers() && "Dead node shouldn't have refs!");
    NodeType = DeadNode;
  }

  /// forwardNode - Mark this node as being obsolete, and all references to it
  /// should be forwarded to the specified node and offset.
  ///
  void forwardNode(DSNode *To, unsigned Offset);

  void cleanEdges();

  void print(llvm::raw_ostream &O, const DSGraph *G) const;
  void dump() const;

  void assertOK() const;

  void dropAllReferences() {
    Links.clear();
    TyMap.clear();
    if (isForwarding())
      ForwardNH.setTo(0, 0);
  }

  /// remapLinks - Change all of the Links in the current node according to the
  /// specified mapping.
  ///
  void remapLinks(std::map<const DSNode*, DSNodeHandle> &OldNodeMap);

  /// markReachableNodes - This method recursively traverses the specified
  /// DSNodes, marking any nodes which are reachable.  All reachable nodes it
  /// adds to the set, which allows it to only traverse visited nodes once.
  ///
  void markReachableNodes(llvm::DenseSet<const DSNode*> &ReachableNodes) const;

private:
  friend class DSNodeHandle;

  // static mergeNodes - Helper for mergeWith()
  static void MergeNodes(DSNodeHandle& CurNodeH, DSNodeHandle& NH);
};

//===----------------------------------------------------------------------===//
// Define inline DSNodeHandle functions that depend on the definition of DSNode
//
inline DSNode *DSNodeHandle::getNode() const {
  // Disabling this assertion because it is failing on a "magic" struct
  // in named (from bind).  The fourth field is an array of length 0,
  // presumably used to create struct instances of different sizes.
  // In a variable length struct, Offset could exceed Size when getNode()
  // is called before such a node is folded. In this case, the DS Analysis now 
  // correctly folds this node after calling getNode.
  /*  assert((!N ||
          N->isNodeCompletelyFolded() ||
          (N->Size == 0 && Offset == 0) ||
          (int(Offset) >= 0 && Offset < N->Size) ||
          (int(Offset) < 0 && -int(Offset) < int(N->Size)) ||
          N->isForwarding()) && "Node handle offset out of range!");
  */
  if (N == 0 || !N->isForwarding())
    return N;

  return HandleForwarding();
}

inline void DSNodeHandle::setTo(DSNode *n, unsigned NewOffset) const {
  assert((!n || !n->isForwarding()) && "Cannot set node to a forwarded node!");
  if (N) getNode()->NumReferrers--;
  N = n;
  Offset = NewOffset;
  if (N) {
    N->NumReferrers++;
    if (Offset >= N->Size) {
      assert((Offset == 0 || N->Size == 1) &&
             "Pointer to non-collapsed node with invalid offset!");
      Offset = 0;
    }
  }
  assert(!N || ((N->NodeType & DSNode::DeadNode) == 0));
  assert((!N || Offset < N->Size || (N->Size == 0 && Offset == 0) ||
          N->isForwarding()) && "Node handle offset out of range!");
}

inline bool DSNodeHandle::hasLink(unsigned Num) const {
  assert(N && "DSNodeHandle does not point to a node yet!");
  return getNode()->hasLink(Num+Offset);
}


/// getLink - Treat this current node pointer as a pointer to a structure of
/// some sort.  This method will return the pointer a mem[this+Num]
///
inline const DSNodeHandle &DSNodeHandle::getLink(unsigned Off) const {
  assert(N && "DSNodeHandle does not point to a node yet!");
  return getNode()->getLink(Offset+Off);
}
inline DSNodeHandle &DSNodeHandle::getLink(unsigned Off) {
  assert(N && "DSNodeHandle does not point to a node yet!");
  return getNode()->getLink(Off+Offset);
}

inline void DSNodeHandle::setLink(unsigned Off, const DSNodeHandle &NH) {
  assert(N && "DSNodeHandle does not point to a node yet!");
  getNode()->setLink(Off+Offset, NH);
}

/// addEdgeTo - Add an edge from the current node to the specified node.  This
/// can cause merging of nodes in the graph.
///
inline void DSNodeHandle::addEdgeTo(unsigned Off, const DSNodeHandle &Node) {
  assert(N && "DSNodeHandle does not point to a node yet!");
  getNode()->addEdgeTo(Off+Offset, Node);
}

/// mergeWith - Merge the logical node pointed to by 'this' with the node
/// pointed to by 'N'.
///
inline void DSNodeHandle::mergeWith(const DSNodeHandle &Node) const {
  if (!isNull())
    getNode()->mergeWith(Node, Offset);
  else {   // No node to merge with, so just point to Node
    Offset = 0;
    DSNode *NN = Node.getNode();
    setTo(NN, Node.getOffset());
  }
}

} // End llvm namespace

#endif
