// Copyright (c) 2021 Google LLC.
//
// 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_CONTROL_DEPENDENCE_H_
#define SOURCE_OPT_CONTROL_DEPENDENCE_H_

#include <algorithm>
#include <cstdint>
#include <functional>
#include <ostream>
#include <unordered_map>
#include <vector>

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

namespace spvtools {
namespace opt {

class ControlDependence {
 public:
  // The label of the source of this dependence, i.e. the block on which the
  // target is dependent on.
  // A |source_bb_id| of 0 represents an "entry" dependence, meaning that the
  // execution of |target_bb_id| is only dependent on entry to the function.
  uint32_t source_bb_id() const { return source_bb_id_; }
  // The label of the target of this dependence, i.e. the block which is
  // dependent on the source.
  uint32_t target_bb_id() const { return target_bb_id_; }
  // The label of the target of the *branch* for this dependence.
  // Equal to the ID of the entry block for entry dependences.
  //
  // For example, for the partial CFG pictured below:
  // 1 ---> 2 ---> 4 ---> 6
  //  \      \            ^
  //   \-> 3  \-> 5 -----/
  // Block 6 is control dependent on block 1, but this dependence comes from the
  // branch 1 -> 2, so in this case the branch target ID would be 2.
  uint32_t branch_target_bb_id() const { return branch_target_bb_id_; }

  // Create a direct control dependence from BB ID |source| to |target|.
  ControlDependence(uint32_t source, uint32_t target)
      : source_bb_id_(source),
        target_bb_id_(target),
        branch_target_bb_id_(target) {}
  // Create a control dependence from BB ID |source| to |target| through the
  // branch from |source| to |branch_target|.
  ControlDependence(uint32_t source, uint32_t target, uint32_t branch_target)
      : source_bb_id_(source),
        target_bb_id_(target),
        branch_target_bb_id_(branch_target) {}

  // Gets the ID of the conditional value for the branch corresponding to this
  // control dependence. This is the first input operand for both
  // OpConditionalBranch and OpSwitch.
  // Returns 0 for entry dependences.
  uint32_t GetConditionID(const CFG& cfg) const;

  bool operator==(const ControlDependence& other) const;
  bool operator!=(const ControlDependence& other) const {
    return !(*this == other);
  }

  // Comparison operators, ordered lexicographically. Total ordering.
  bool operator<(const ControlDependence& other) const;
  bool operator>(const ControlDependence& other) const { return other < *this; }
  bool operator<=(const ControlDependence& other) const {
    return !(*this > other);
  }
  bool operator>=(const ControlDependence& other) const {
    return !(*this < other);
  }

 private:
  uint32_t source_bb_id_;
  uint32_t target_bb_id_;
  uint32_t branch_target_bb_id_;
};

// Prints |dep| to |os| in a human-readable way. For example,
//   1->2           (target_bb_id = branch_target_bb_id = 2)
//   3->4 through 5 (target_bb_id = 4, branch_target_bb_id = 5)
std::ostream& operator<<(std::ostream& os, const ControlDependence& dep);

// Represents the control dependence graph. A basic block is control dependent
// on another if the result of that block (e.g. the condition of a conditional
// branch) influences whether it is executed or not. More formally, a block A is
// control dependent on B iff:
// 1. there exists a path from A to the exit node that does *not* go through B
//    (i.e., A does not postdominate B), and
// 2. there exists a path B -> b_1 -> ... -> b_n -> A such that A post-dominates
//    all nodes b_i.
class ControlDependenceAnalysis {
 public:
  // Map basic block labels to control dependencies/dependents.
  // Not guaranteed to be in any particular order.
  using ControlDependenceList = std::vector<ControlDependence>;
  using ControlDependenceListMap =
      std::unordered_map<uint32_t, ControlDependenceList>;

  // 0, the label number for the pseudo entry block.
  // All control dependences on the pseudo entry block are of type kEntry, and
  // vice versa.
  static constexpr uint32_t kPseudoEntryBlock = 0;

  // Build the control dependence graph for the given control flow graph |cfg|
  // and corresponding post-dominator analysis |pdom|.
  void ComputeControlDependenceGraph(const CFG& cfg,
                                     const PostDominatorAnalysis& pdom);

  // Get the list of the nodes that depend on a block.
  // Return value is not guaranteed to be in any particular order.
  const ControlDependenceList& GetDependenceTargets(uint32_t block) const {
    return forward_nodes_.at(block);
  }

  // Get the list of the nodes on which a block depends on.
  // Return value is not guaranteed to be in any particular order.
  const ControlDependenceList& GetDependenceSources(uint32_t block) const {
    return reverse_nodes_.at(block);
  }

  // Runs the function |f| on each block label in the CDG. If any iteration
  // returns false, immediately stops iteration and returns false. Otherwise
  // returns true. Nodes are iterated in some undefined order, including the
  // pseudo-entry block.
  bool WhileEachBlockLabel(std::function<bool(uint32_t)> f) const {
    for (const auto& entry : forward_nodes_) {
      if (!f(entry.first)) {
        return false;
      }
    }
    return true;
  }

  // Runs the function |f| on each block label in the CDG. Nodes are iterated in
  // some undefined order, including the pseudo-entry block.
  void ForEachBlockLabel(std::function<void(uint32_t)> f) const {
    WhileEachBlockLabel([&f](uint32_t label) {
      f(label);
      return true;
    });
  }

  // Returns true if the block |id| exists in the control dependence graph.
  // This can be false even if the block exists in the function when it is part
  // of an infinite loop, since it is not part of the post-dominator tree.
  bool DoesBlockExist(uint32_t id) const {
    return forward_nodes_.count(id) > 0;
  }

  // Returns true if block |a| is dependent on block |b|.
  bool IsDependent(uint32_t a, uint32_t b) const {
    if (!DoesBlockExist(a)) return false;
    // BBs tend to have more dependents (targets) than they are dependent on
    // (sources), so search sources.
    const ControlDependenceList& a_sources = GetDependenceSources(a);
    return std::find_if(a_sources.begin(), a_sources.end(),
                        [b](const ControlDependence& dep) {
                          return dep.source_bb_id() == b;
                        }) != a_sources.end();
  }

 private:
  // Computes the post-dominance frontiers (i.e. the reverse CDG) for each node
  // in the post-dominator tree. Only modifies reverse_nodes_; forward_nodes_ is
  // not modified.
  void ComputePostDominanceFrontiers(const CFG& cfg,
                                     const PostDominatorAnalysis& pdom);
  // Computes the post-dominance frontier for a specific node |pdom_node| in the
  // post-dominator tree. Result is placed in reverse_nodes_[pdom_node.id()].
  void ComputePostDominanceFrontierForNode(const CFG& cfg,
                                           const PostDominatorAnalysis& pdom,
                                           uint32_t function_entry,
                                           const DominatorTreeNode& pdom_node);

  // Computes the forward graph (forward_nodes_) from the reverse graph
  // (reverse_nodes_).
  void ComputeForwardGraphFromReverse();

  ControlDependenceListMap forward_nodes_;
  ControlDependenceListMap reverse_nodes_;
};

}  // namespace opt
}  // namespace spvtools

#endif  // SOURCE_OPT_CONTROL_DEPENDENCE_H_
