// Copyright (c) 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef SOURCE_OPT_DOMINATOR_TREE_H_
#define SOURCE_OPT_DOMINATOR_TREE_H_

#include <algorithm>
#include <cstdint>
#include <map>
#include <utility>
#include <vector>

#include "source/opt/cfg.h"
#include "source/opt/tree_iterator.h"

namespace spvtools {
namespace opt {
// This helper struct forms the nodes in the tree, with each node containing its
// children. It also contains two values, for the pre and post indexes in the
// tree which are used to compare two nodes.
struct DominatorTreeNode {
  explicit DominatorTreeNode(BasicBlock* bb)
      : bb_(bb),
        parent_(nullptr),
        children_({}),
        dfs_num_pre_(-1),
        dfs_num_post_(-1) {}

  using iterator = std::vector<DominatorTreeNode*>::iterator;
  using const_iterator = std::vector<DominatorTreeNode*>::const_iterator;

  // depth first preorder iterator.
  using df_iterator = TreeDFIterator<DominatorTreeNode>;
  using const_df_iterator = TreeDFIterator<const DominatorTreeNode>;
  // depth first postorder iterator.
  using post_iterator = PostOrderTreeDFIterator<DominatorTreeNode>;
  using const_post_iterator = PostOrderTreeDFIterator<const DominatorTreeNode>;

  iterator begin() { return children_.begin(); }
  iterator end() { return children_.end(); }
  const_iterator begin() const { return cbegin(); }
  const_iterator end() const { return cend(); }
  const_iterator cbegin() const { return children_.begin(); }
  const_iterator cend() const { return children_.end(); }

  // Depth first preorder iterator using this node as root.
  df_iterator df_begin() { return df_iterator(this); }
  df_iterator df_end() { return df_iterator(); }
  const_df_iterator df_begin() const { return df_cbegin(); }
  const_df_iterator df_end() const { return df_cend(); }
  const_df_iterator df_cbegin() const { return const_df_iterator(this); }
  const_df_iterator df_cend() const { return const_df_iterator(); }

  // Depth first postorder iterator using this node as root.
  post_iterator post_begin() { return post_iterator::begin(this); }
  post_iterator post_end() { return post_iterator::end(nullptr); }
  const_post_iterator post_begin() const { return post_cbegin(); }
  const_post_iterator post_end() const { return post_cend(); }
  const_post_iterator post_cbegin() const {
    return const_post_iterator::begin(this);
  }
  const_post_iterator post_cend() const {
    return const_post_iterator::end(nullptr);
  }

  inline uint32_t id() const { return bb_->id(); }

  BasicBlock* bb_;
  DominatorTreeNode* parent_;
  std::vector<DominatorTreeNode*> children_;

  // These indexes are used to compare two given nodes. A node is a child or
  // grandchild of another node if its preorder index is greater than the
  // first nodes preorder index AND if its postorder index is less than the
  // first nodes postorder index.
  int dfs_num_pre_;
  int dfs_num_post_;
};

// A class representing a tree of BasicBlocks in a given function, where each
// node is dominated by its parent.
class DominatorTree {
 public:
  // Map OpLabel ids to dominator tree nodes
  using DominatorTreeNodeMap = std::map<uint32_t, DominatorTreeNode>;
  using iterator = TreeDFIterator<DominatorTreeNode>;
  using const_iterator = TreeDFIterator<const DominatorTreeNode>;
  using post_iterator = PostOrderTreeDFIterator<DominatorTreeNode>;
  using const_post_iterator = PostOrderTreeDFIterator<const DominatorTreeNode>;

  // List of DominatorTreeNode to define the list of roots
  using DominatorTreeNodeList = std::vector<DominatorTreeNode*>;
  using roots_iterator = DominatorTreeNodeList::iterator;
  using roots_const_iterator = DominatorTreeNodeList::const_iterator;

  DominatorTree() : postdominator_(false) {}
  explicit DominatorTree(bool post) : postdominator_(post) {}

  // Depth first iterators.
  // Traverse the dominator tree in a depth first pre-order.
  // The pseudo-block is ignored.
  iterator begin() { return ++iterator(GetRoot()); }
  iterator end() { return iterator(); }
  const_iterator begin() const { return cbegin(); }
  const_iterator end() const { return cend(); }
  const_iterator cbegin() const { return ++const_iterator(GetRoot()); }
  const_iterator cend() const { return const_iterator(); }

  // Traverse the dominator tree in a depth first post-order.
  // The pseudo-block is ignored.
  post_iterator post_begin() { return post_iterator::begin(GetRoot()); }
  post_iterator post_end() { return post_iterator::end(GetRoot()); }
  const_post_iterator post_begin() const { return post_cbegin(); }
  const_post_iterator post_end() const { return post_cend(); }
  const_post_iterator post_cbegin() const {
    return const_post_iterator::begin(GetRoot());
  }
  const_post_iterator post_cend() const {
    return const_post_iterator::end(GetRoot());
  }

  roots_iterator roots_begin() { return roots_.begin(); }
  roots_iterator roots_end() { return roots_.end(); }
  roots_const_iterator roots_begin() const { return roots_cbegin(); }
  roots_const_iterator roots_end() const { return roots_cend(); }
  roots_const_iterator roots_cbegin() const { return roots_.begin(); }
  roots_const_iterator roots_cend() const { return roots_.end(); }

  // Get the unique root of the tree.
  // It is guaranteed to work on a dominator tree.
  // post-dominator might have a list.
  DominatorTreeNode* GetRoot() {
    assert(roots_.size() == 1);
    return *roots_.begin();
  }

  const DominatorTreeNode* GetRoot() const {
    assert(roots_.size() == 1);
    return *roots_.begin();
  }

  const DominatorTreeNodeList& Roots() const { return roots_; }

  // Dumps the tree in the graphvis dot format into the |out_stream|.
  void DumpTreeAsDot(std::ostream& out_stream) const;

  // Build the (post-)dominator tree for the given control flow graph
  // |cfg| and the function |f|. |f| must exist in the |cfg|. Any
  // existing data in the dominator tree will be overwritten
  void InitializeTree(const CFG& cfg, const Function* f);

  // Check if the basic block |a| dominates the basic block |b|.
  bool Dominates(const BasicBlock* a, const BasicBlock* b) const;

  // Check if the basic block id |a| dominates the basic block id |b|.
  bool Dominates(uint32_t a, uint32_t b) const;

  // Check if the dominator tree node |a| dominates the dominator tree node |b|.
  bool Dominates(const DominatorTreeNode* a, const DominatorTreeNode* b) const;

  // Check if the basic block |a| strictly dominates the basic block |b|.
  bool StrictlyDominates(const BasicBlock* a, const BasicBlock* b) const;

  // Check if the basic block id |a| strictly dominates the basic block id |b|.
  bool StrictlyDominates(uint32_t a, uint32_t b) const;

  // Check if the dominator tree node |a| strictly dominates the dominator tree
  // node |b|.
  bool StrictlyDominates(const DominatorTreeNode* a,
                         const DominatorTreeNode* b) const;

  // Returns the immediate dominator of basic block |a|.
  BasicBlock* ImmediateDominator(const BasicBlock* A) const;

  // Returns the immediate dominator of basic block id |a|.
  BasicBlock* ImmediateDominator(uint32_t a) const;

  // Returns true if the basic block |a| is reachable by this tree. A node would
  // be unreachable if it cannot be reached by traversal from the start node or
  // for a postdominator tree, cannot be reached from the exit nodes.
  inline bool ReachableFromRoots(const BasicBlock* a) const {
    if (!a) return false;
    return ReachableFromRoots(a->id());
  }

  // Returns true if the basic block id |a| is reachable by this tree.
  bool ReachableFromRoots(uint32_t a) const {
    return GetTreeNode(a) != nullptr;
  }

  // Returns true if this tree is a post dominator tree.
  bool IsPostDominator() const { return postdominator_; }

  // Clean up the tree.
  void ClearTree() {
    nodes_.clear();
    roots_.clear();
  }

  // Applies the std::function |func| to all nodes in the dominator tree.
  // Tree nodes are visited in a depth first pre-order.
  bool Visit(std::function<bool(DominatorTreeNode*)> func) {
    for (auto n : *this) {
      if (!func(&n)) return false;
    }
    return true;
  }

  // Applies the std::function |func| to all nodes in the dominator tree.
  // Tree nodes are visited in a depth first pre-order.
  bool Visit(std::function<bool(const DominatorTreeNode*)> func) const {
    for (auto n : *this) {
      if (!func(&n)) return false;
    }
    return true;
  }

  // Applies the std::function |func| to all nodes in the dominator tree from
  // |node| downwards. The boolean return from |func| is used to determine
  // whether or not the children should also be traversed. Tree nodes are
  // visited in a depth first pre-order.
  void VisitChildrenIf(std::function<bool(DominatorTreeNode*)> func,
                       iterator node) {
    if (func(&*node)) {
      for (auto n : *node) {
        VisitChildrenIf(func, n->df_begin());
      }
    }
  }

  // Returns the DominatorTreeNode associated with the basic block |bb|.
  // If the |bb| is unknown to the dominator tree, it returns null.
  inline DominatorTreeNode* GetTreeNode(BasicBlock* bb) {
    return GetTreeNode(bb->id());
  }
  // Returns the DominatorTreeNode associated with the basic block |bb|.
  // If the |bb| is unknown to the dominator tree, it returns null.
  inline const DominatorTreeNode* GetTreeNode(BasicBlock* bb) const {
    return GetTreeNode(bb->id());
  }

  // Returns the DominatorTreeNode associated with the basic block id |id|.
  // If the id |id| is unknown to the dominator tree, it returns null.
  inline DominatorTreeNode* GetTreeNode(uint32_t id) {
    DominatorTreeNodeMap::iterator node_iter = nodes_.find(id);
    if (node_iter == nodes_.end()) {
      return nullptr;
    }
    return &node_iter->second;
  }
  // Returns the DominatorTreeNode associated with the basic block id |id|.
  // If the id |id| is unknown to the dominator tree, it returns null.
  inline const DominatorTreeNode* GetTreeNode(uint32_t id) const {
    DominatorTreeNodeMap::const_iterator node_iter = nodes_.find(id);
    if (node_iter == nodes_.end()) {
      return nullptr;
    }
    return &node_iter->second;
  }

  // Adds the basic block |bb| to the tree structure if it doesn't already
  // exist.
  DominatorTreeNode* GetOrInsertNode(BasicBlock* bb);

  // Recomputes the DF numbering of the tree.
  void ResetDFNumbering();

 private:
  // Wrapper function which gets the list of pairs of each BasicBlocks to its
  // immediately  dominating BasicBlock and stores the result in the the edges
  // parameter.
  //
  // The |edges| vector will contain the dominator tree as pairs of nodes.
  // The first node in the pair is a node in the graph. The second node in the
  // pair is its immediate dominator.
  // The root of the tree has themself as immediate dominator.
  void GetDominatorEdges(
      const Function* f, const BasicBlock* dummy_start_node,
      std::vector<std::pair<BasicBlock*, BasicBlock*>>* edges);

  // The roots of the tree.
  std::vector<DominatorTreeNode*> roots_;

  // Pairs each basic block id to the tree node containing that basic block.
  DominatorTreeNodeMap nodes_;

  // True if this is a post dominator tree.
  bool postdominator_;
};

}  // namespace opt
}  // namespace spvtools

#endif  // SOURCE_OPT_DOMINATOR_TREE_H_
