//===- IteratedDominanceFrontier.h - Calculate IDF --------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
/// Compute iterated dominance frontiers using a linear time algorithm.
///
/// The algorithm used here is based on:
///
///   Sreedhar and Gao. A linear time algorithm for placing phi-nodes.
///   In Proceedings of the 22nd ACM SIGPLAN-SIGACT Symposium on Principles of
///   Programming Languages
///   POPL '95. ACM, New York, NY, 62-73.
///
/// It has been modified to not explicitly use the DJ graph data structure and
/// to directly compute pruned SSA using per-variable liveness information.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_SUPPORT_GENERICITERATEDDOMINANCEFRONTIER_H
#define LLVM_SUPPORT_GENERICITERATEDDOMINANCEFRONTIER_H

#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/GenericDomTree.h"
#include <queue>

namespace llvm {

namespace IDFCalculatorDetail {

/// Generic utility class used for getting the children of a basic block.
/// May be specialized if, for example, one wouldn't like to return nullpointer
/// successors.
template <class NodeTy, bool IsPostDom> struct ChildrenGetterTy {
  using NodeRef = typename GraphTraits<NodeTy *>::NodeRef;
  using ChildrenTy = SmallVector<NodeRef, 8>;

  ChildrenTy get(const NodeRef &N);
};

} // end of namespace IDFCalculatorDetail

/// Determine the iterated dominance frontier, given a set of defining
/// blocks, and optionally, a set of live-in blocks.
///
/// In turn, the results can be used to place phi nodes.
///
/// This algorithm is a linear time computation of Iterated Dominance Frontiers,
/// pruned using the live-in set.
/// By default, liveness is not used to prune the IDF computation.
/// The template parameters should be of a CFG block type.
template <class NodeTy, bool IsPostDom> class IDFCalculatorBase {
public:
  using OrderedNodeTy =
      std::conditional_t<IsPostDom, Inverse<NodeTy *>, NodeTy *>;
  using ChildrenGetterTy =
      IDFCalculatorDetail::ChildrenGetterTy<NodeTy, IsPostDom>;

  IDFCalculatorBase(DominatorTreeBase<NodeTy, IsPostDom> &DT) : DT(DT) {}

  IDFCalculatorBase(DominatorTreeBase<NodeTy, IsPostDom> &DT,
                    const ChildrenGetterTy &C)
      : DT(DT), ChildrenGetter(C) {}

  /// Give the IDF calculator the set of blocks in which the value is
  /// defined.  This is equivalent to the set of starting blocks it should be
  /// calculating the IDF for (though later gets pruned based on liveness).
  ///
  /// Note: This set *must* live for the entire lifetime of the IDF calculator.
  void setDefiningBlocks(const SmallPtrSetImpl<NodeTy *> &Blocks) {
    DefBlocks = &Blocks;
  }

  /// Give the IDF calculator the set of blocks in which the value is
  /// live on entry to the block.   This is used to prune the IDF calculation to
  /// not include blocks where any phi insertion would be dead.
  ///
  /// Note: This set *must* live for the entire lifetime of the IDF calculator.
  void setLiveInBlocks(const SmallPtrSetImpl<NodeTy *> &Blocks) {
    LiveInBlocks = &Blocks;
    useLiveIn = true;
  }

  /// Reset the live-in block set to be empty, and tell the IDF
  /// calculator to not use liveness anymore.
  void resetLiveInBlocks() {
    LiveInBlocks = nullptr;
    useLiveIn = false;
  }

  /// Calculate iterated dominance frontiers
  ///
  /// This uses the linear-time phi algorithm based on DJ-graphs mentioned in
  /// the file-level comment.  It performs DF->IDF pruning using the live-in
  /// set, to avoid computing the IDF for blocks where an inserted PHI node
  /// would be dead.
  void calculate(SmallVectorImpl<NodeTy *> &IDFBlocks);

private:
  DominatorTreeBase<NodeTy, IsPostDom> &DT;
  ChildrenGetterTy ChildrenGetter;
  bool useLiveIn = false;
  const SmallPtrSetImpl<NodeTy *> *LiveInBlocks;
  const SmallPtrSetImpl<NodeTy *> *DefBlocks;
};

//===----------------------------------------------------------------------===//
// Implementation.
//===----------------------------------------------------------------------===//

namespace IDFCalculatorDetail {

template <class NodeTy, bool IsPostDom>
typename ChildrenGetterTy<NodeTy, IsPostDom>::ChildrenTy
ChildrenGetterTy<NodeTy, IsPostDom>::get(const NodeRef &N) {
  using OrderedNodeTy =
      typename IDFCalculatorBase<NodeTy, IsPostDom>::OrderedNodeTy;

  auto Children = children<OrderedNodeTy>(N);
  return {Children.begin(), Children.end()};
}

} // end of namespace IDFCalculatorDetail

template <class NodeTy, bool IsPostDom>
void IDFCalculatorBase<NodeTy, IsPostDom>::calculate(
    SmallVectorImpl<NodeTy *> &IDFBlocks) {
  // Use a priority queue keyed on dominator tree level so that inserted nodes
  // are handled from the bottom of the dominator tree upwards. We also augment
  // the level with a DFS number to ensure that the blocks are ordered in a
  // deterministic way.
  using DomTreeNodePair =
      std::pair<DomTreeNodeBase<NodeTy> *, std::pair<unsigned, unsigned>>;
  using IDFPriorityQueue =
      std::priority_queue<DomTreeNodePair, SmallVector<DomTreeNodePair, 32>,
                          less_second>;

  IDFPriorityQueue PQ;

  DT.updateDFSNumbers();

  SmallVector<DomTreeNodeBase<NodeTy> *, 32> Worklist;
  SmallPtrSet<DomTreeNodeBase<NodeTy> *, 32> VisitedPQ;
  SmallPtrSet<DomTreeNodeBase<NodeTy> *, 32> VisitedWorklist;

  for (NodeTy *BB : *DefBlocks)
    if (DomTreeNodeBase<NodeTy> *Node = DT.getNode(BB)) {
      PQ.push({Node, std::make_pair(Node->getLevel(), Node->getDFSNumIn())});
      VisitedWorklist.insert(Node);
    }

  while (!PQ.empty()) {
    DomTreeNodePair RootPair = PQ.top();
    PQ.pop();
    DomTreeNodeBase<NodeTy> *Root = RootPair.first;
    unsigned RootLevel = RootPair.second.first;

    // Walk all dominator tree children of Root, inspecting their CFG edges with
    // targets elsewhere on the dominator tree. Only targets whose level is at
    // most Root's level are added to the iterated dominance frontier of the
    // definition set.

    assert(Worklist.empty());
    Worklist.push_back(Root);

    while (!Worklist.empty()) {
      DomTreeNodeBase<NodeTy> *Node = Worklist.pop_back_val();
      NodeTy *BB = Node->getBlock();
      // Succ is the successor in the direction we are calculating IDF, so it is
      // successor for IDF, and predecessor for Reverse IDF.
      auto DoWork = [&](NodeTy *Succ) {
        DomTreeNodeBase<NodeTy> *SuccNode = DT.getNode(Succ);

        const unsigned SuccLevel = SuccNode->getLevel();
        if (SuccLevel > RootLevel)
          return;

        if (!VisitedPQ.insert(SuccNode).second)
          return;

        NodeTy *SuccBB = SuccNode->getBlock();
        if (useLiveIn && !LiveInBlocks->count(SuccBB))
          return;

        IDFBlocks.emplace_back(SuccBB);
        if (!DefBlocks->count(SuccBB))
          PQ.push(std::make_pair(
              SuccNode, std::make_pair(SuccLevel, SuccNode->getDFSNumIn())));
      };

      for (auto Succ : ChildrenGetter.get(BB))
        DoWork(Succ);

      for (auto DomChild : *Node) {
        if (VisitedWorklist.insert(DomChild).second)
          Worklist.push_back(DomChild);
      }
    }
  }
}

} // end of namespace llvm

#endif
