//=== llvm/Analysis/DominatorInternals.h - Dominator Calculation -*- C++ -*-==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_ANALYSIS_DOMINATOR_INTERNALS_H
#define LLVM_ANALYSIS_DOMINATOR_INTERNALS_H

#include "llvm/Analysis/Dominators.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
//===----------------------------------------------------------------------===//
//
// DominatorTree construction - This pass constructs immediate dominator
// information for a flow-graph based on the algorithm described in this
// document:
//
//   A Fast Algorithm for Finding Dominators in a Flowgraph
//   T. Lengauer & R. Tarjan, ACM TOPLAS July 1979, pgs 121-141.
//
// This implements both the O(n*ack(n)) and the O(n*log(n)) versions of EVAL and
// LINK, but it turns out that the theoretically slower O(n*log(n))
// implementation is actually faster than the "efficient" algorithm (even for
// large CFGs) because the constant overheads are substantially smaller.  The
// lower-complexity version can be enabled with the following #define:
//
#define BALANCE_IDOM_TREE 0
//
//===----------------------------------------------------------------------===//

namespace llvm {

template<class GraphT>
unsigned DFSPass(DominatorTreeBase<typename GraphT::NodeType>& DT,
                 typename GraphT::NodeType* V, unsigned N) {
  // This is more understandable as a recursive algorithm, but we can't use the
  // recursive algorithm due to stack depth issues.  Keep it here for
  // documentation purposes.
#if 0
  InfoRec &VInfo = DT.Info[DT.Roots[i]];
  VInfo.DFSNum = VInfo.Semi = ++N;
  VInfo.Label = V;

  Vertex.push_back(V);        // Vertex[n] = V;
  //Info[V].Ancestor = 0;     // Ancestor[n] = 0
  //Info[V].Child = 0;        // Child[v] = 0
  VInfo.Size = 1;             // Size[v] = 1

  for (succ_iterator SI = succ_begin(V), E = succ_end(V); SI != E; ++SI) {
    InfoRec &SuccVInfo = DT.Info[*SI];
    if (SuccVInfo.Semi == 0) {
      SuccVInfo.Parent = V;
      N = DTDFSPass(DT, *SI, N);
    }
  }
#else
  bool IsChilOfArtificialExit = (N != 0);

  std::vector<std::pair<typename GraphT::NodeType*,
                        typename GraphT::ChildIteratorType> > Worklist;
  Worklist.push_back(std::make_pair(V, GraphT::child_begin(V)));
  while (!Worklist.empty()) {
    typename GraphT::NodeType* BB = Worklist.back().first;
    typename GraphT::ChildIteratorType NextSucc = Worklist.back().second;

    typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &BBInfo =
                                                                    DT.Info[BB];

    // First time we visited this BB?
    if (NextSucc == GraphT::child_begin(BB)) {
      BBInfo.DFSNum = BBInfo.Semi = ++N;
      BBInfo.Label = BB;

      DT.Vertex.push_back(BB);       // Vertex[n] = V;
      //BBInfo[V].Ancestor = 0;   // Ancestor[n] = 0
      //BBInfo[V].Child = 0;      // Child[v] = 0
      BBInfo.Size = 1;            // Size[v] = 1

      if (IsChilOfArtificialExit)
        BBInfo.Parent = 1;

      IsChilOfArtificialExit = false;
    }

    // store the DFS number of the current BB - the reference to BBInfo might
    // get invalidated when processing the successors.
    unsigned BBDFSNum = BBInfo.DFSNum;

    // If we are done with this block, remove it from the worklist.
    if (NextSucc == GraphT::child_end(BB)) {
      Worklist.pop_back();
      continue;
    }

    // Increment the successor number for the next time we get to it.
    ++Worklist.back().second;
    
    // Visit the successor next, if it isn't already visited.
    typename GraphT::NodeType* Succ = *NextSucc;

    typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &SuccVInfo =
                                                                  DT.Info[Succ];
    if (SuccVInfo.Semi == 0) {
      SuccVInfo.Parent = BBDFSNum;
      Worklist.push_back(std::make_pair(Succ, GraphT::child_begin(Succ)));
    }
  }
#endif
    return N;
}

template<class GraphT>
void Compress(DominatorTreeBase<typename GraphT::NodeType>& DT,
              typename GraphT::NodeType *VIn) {
  std::vector<typename GraphT::NodeType*> Work;
  SmallPtrSet<typename GraphT::NodeType*, 32> Visited;
  typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VInVAInfo =
                                      DT.Info[DT.Vertex[DT.Info[VIn].Ancestor]];

  if (VInVAInfo.Ancestor != 0)
    Work.push_back(VIn);
  
  while (!Work.empty()) {
    typename GraphT::NodeType* V = Work.back();
    typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VInfo =
                                                                     DT.Info[V];
    typename GraphT::NodeType* VAncestor = DT.Vertex[VInfo.Ancestor];
    typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VAInfo =
                                                             DT.Info[VAncestor];

    // Process Ancestor first
    if (Visited.insert(VAncestor) &&
        VAInfo.Ancestor != 0) {
      Work.push_back(VAncestor);
      continue;
    } 
    Work.pop_back(); 

    // Update VInfo based on Ancestor info
    if (VAInfo.Ancestor == 0)
      continue;
    typename GraphT::NodeType* VAncestorLabel = VAInfo.Label;
    typename GraphT::NodeType* VLabel = VInfo.Label;
    if (DT.Info[VAncestorLabel].Semi < DT.Info[VLabel].Semi)
      VInfo.Label = VAncestorLabel;
    VInfo.Ancestor = VAInfo.Ancestor;
  }
}

template<class GraphT>
typename GraphT::NodeType* Eval(DominatorTreeBase<typename GraphT::NodeType>& DT,
                                typename GraphT::NodeType *V) {
  typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VInfo =
                                                                     DT.Info[V];
#if !BALANCE_IDOM_TREE
  // Higher-complexity but faster implementation
  if (VInfo.Ancestor == 0)
    return V;
  Compress<GraphT>(DT, V);
  return VInfo.Label;
#else
  // Lower-complexity but slower implementation
  if (VInfo.Ancestor == 0)
    return VInfo.Label;
  Compress<GraphT>(DT, V);
  GraphT::NodeType* VLabel = VInfo.Label;

  GraphT::NodeType* VAncestorLabel = DT.Info[VInfo.Ancestor].Label;
  if (DT.Info[VAncestorLabel].Semi >= DT.Info[VLabel].Semi)
    return VLabel;
  else
    return VAncestorLabel;
#endif
}

template<class GraphT>
void Link(DominatorTreeBase<typename GraphT::NodeType>& DT,
          unsigned DFSNumV, typename GraphT::NodeType* W,
        typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &WInfo) {
#if !BALANCE_IDOM_TREE
  // Higher-complexity but faster implementation
  WInfo.Ancestor = DFSNumV;
#else
  // Lower-complexity but slower implementation
  GraphT::NodeType* WLabel = WInfo.Label;
  unsigned WLabelSemi = DT.Info[WLabel].Semi;
  GraphT::NodeType* S = W;
  InfoRec *SInfo = &DT.Info[S];

  GraphT::NodeType* SChild = SInfo->Child;
  InfoRec *SChildInfo = &DT.Info[SChild];

  while (WLabelSemi < DT.Info[SChildInfo->Label].Semi) {
    GraphT::NodeType* SChildChild = SChildInfo->Child;
    if (SInfo->Size+DT.Info[SChildChild].Size >= 2*SChildInfo->Size) {
      SChildInfo->Ancestor = S;
      SInfo->Child = SChild = SChildChild;
      SChildInfo = &DT.Info[SChild];
    } else {
      SChildInfo->Size = SInfo->Size;
      S = SInfo->Ancestor = SChild;
      SInfo = SChildInfo;
      SChild = SChildChild;
      SChildInfo = &DT.Info[SChild];
    }
  }

  DominatorTreeBase::InfoRec &VInfo = DT.Info[V];
  SInfo->Label = WLabel;

  assert(V != W && "The optimization here will not work in this case!");
  unsigned WSize = WInfo.Size;
  unsigned VSize = (VInfo.Size += WSize);

  if (VSize < 2*WSize)
    std::swap(S, VInfo.Child);

  while (S) {
    SInfo = &DT.Info[S];
    SInfo->Ancestor = V;
    S = SInfo->Child;
  }
#endif
}

template<class FuncT, class NodeT>
void Calculate(DominatorTreeBase<typename GraphTraits<NodeT>::NodeType>& DT,
               FuncT& F) {
  typedef GraphTraits<NodeT> GraphT;

  unsigned N = 0;
  bool MultipleRoots = (DT.Roots.size() > 1);
  if (MultipleRoots) {
    typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &BBInfo =
        DT.Info[NULL];
    BBInfo.DFSNum = BBInfo.Semi = ++N;
    BBInfo.Label = NULL;

    DT.Vertex.push_back(NULL);       // Vertex[n] = V;
      //BBInfo[V].Ancestor = 0;   // Ancestor[n] = 0
      //BBInfo[V].Child = 0;      // Child[v] = 0
    BBInfo.Size = 1;            // Size[v] = 1
  }

  // Step #1: Number blocks in depth-first order and initialize variables used
  // in later stages of the algorithm.
  for (unsigned i = 0, e = static_cast<unsigned>(DT.Roots.size());
       i != e; ++i)
    N = DFSPass<GraphT>(DT, DT.Roots[i], N);

  // it might be that some blocks did not get a DFS number (e.g., blocks of 
  // infinite loops). In these cases an artificial exit node is required.
  MultipleRoots |= (DT.isPostDominator() && N != F.size());

  for (unsigned i = N; i >= 2; --i) {
    typename GraphT::NodeType* W = DT.Vertex[i];
    typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &WInfo =
                                                                     DT.Info[W];

    // Step #2: Calculate the semidominators of all vertices
    bool HasChildOutsideDFS = false;

    // initialize the semi dominator to point to the parent node
    WInfo.Semi = WInfo.Parent;
    for (typename GraphTraits<Inverse<NodeT> >::ChildIteratorType CI =
         GraphTraits<Inverse<NodeT> >::child_begin(W),
         E = GraphTraits<Inverse<NodeT> >::child_end(W); CI != E; ++CI) {
      if (DT.Info.count(*CI)) {  // Only if this predecessor is reachable!
        unsigned SemiU = DT.Info[Eval<GraphT>(DT, *CI)].Semi;
        if (SemiU < WInfo.Semi)
          WInfo.Semi = SemiU;
      }
      else {
        // if the child has no DFS number it is not post-dominated by any exit, 
        // and so is the current block.
        HasChildOutsideDFS = true;
      }
    }

    // if some child has no DFS number it is not post-dominated by any exit, 
    // and so is the current block.
    if (DT.isPostDominator() && HasChildOutsideDFS)
      WInfo.Semi = 0;

    DT.Info[DT.Vertex[WInfo.Semi]].Bucket.push_back(W);

    typename GraphT::NodeType* WParent = DT.Vertex[WInfo.Parent];
    Link<GraphT>(DT, WInfo.Parent, W, WInfo);

    // Step #3: Implicitly define the immediate dominator of vertices
    std::vector<typename GraphT::NodeType*> &WParentBucket =
                                                        DT.Info[WParent].Bucket;
    while (!WParentBucket.empty()) {
      typename GraphT::NodeType* V = WParentBucket.back();
      WParentBucket.pop_back();
      typename GraphT::NodeType* U = Eval<GraphT>(DT, V);
      DT.IDoms[V] = DT.Info[U].Semi < DT.Info[V].Semi ? U : WParent;
    }
  }

  // Step #4: Explicitly define the immediate dominator of each vertex
  for (unsigned i = 2; i <= N; ++i) {
    typename GraphT::NodeType* W = DT.Vertex[i];
    typename GraphT::NodeType*& WIDom = DT.IDoms[W];
    if (WIDom != DT.Vertex[DT.Info[W].Semi])
      WIDom = DT.IDoms[WIDom];
  }

  if (DT.Roots.empty()) return;

  // Add a node for the root.  This node might be the actual root, if there is
  // one exit block, or it may be the virtual exit (denoted by (BasicBlock *)0)
  // which postdominates all real exits if there are multiple exit blocks, or
  // an infinite loop.
  typename GraphT::NodeType* Root = !MultipleRoots ? DT.Roots[0] : 0;

  DT.DomTreeNodes[Root] = DT.RootNode =
                        new DomTreeNodeBase<typename GraphT::NodeType>(Root, 0);

  // Loop over all of the reachable blocks in the function...
  for (unsigned i = 2; i <= N; ++i) {
    typename GraphT::NodeType* W = DT.Vertex[i];

    DomTreeNodeBase<typename GraphT::NodeType> *BBNode = DT.DomTreeNodes[W];
    if (BBNode) continue;  // Haven't calculated this node yet?

    typename GraphT::NodeType* ImmDom = DT.getIDom(W);

    assert(ImmDom || DT.DomTreeNodes[NULL]);

    // Get or calculate the node for the immediate dominator
    DomTreeNodeBase<typename GraphT::NodeType> *IDomNode =
                                                     DT.getNodeForBlock(ImmDom);

    // Add a new tree node for this BasicBlock, and link it as a child of
    // IDomNode
    DomTreeNodeBase<typename GraphT::NodeType> *C =
                    new DomTreeNodeBase<typename GraphT::NodeType>(W, IDomNode);
    DT.DomTreeNodes[W] = IDomNode->addChild(C);
  }

  // Free temporary memory used to construct idom's
  DT.IDoms.clear();
  DT.Info.clear();
  std::vector<typename GraphT::NodeType*>().swap(DT.Vertex);
  
  // FIXME: This does not work on PostDomTrees.  It seems likely that this is
  // due to an error in the algorithm for post-dominators.  This really should
  // be investigated and fixed at some point.
  // DT.updateDFSNumbers();

  // Start out with the DFS numbers being invalid.  Let them be computed if
  // demanded.
  DT.DFSInfoValid = false;
}

}

#endif
