//===- IntervalIterator.h - Interval Iterator Declaration -------*- 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
//
//===----------------------------------------------------------------------===//
//
// This file defines an iterator that enumerates the intervals in a control flow
// graph of some sort.  This iterator is parametric, allowing iterator over the
// following types of graphs:
//
//  1. A Function* object, composed of BasicBlock nodes.
//  2. An IntervalPartition& object, composed of Interval nodes.
//
// This iterator is defined to walk the control flow graph, returning intervals
// in depth first order.  These intervals are completely filled in except for
// the predecessor fields (the successor information is filled in however).
//
// By default, the intervals created by this iterator are deleted after they
// are no longer any use to the iterator.  This behavior can be changed by
// passing a false value into the intervals_begin() function. This causes the
// IOwnMem member to be set, and the intervals to not be deleted.
//
// It is only safe to use this if all of the intervals are deleted by the caller
// and all of the intervals are processed.  However, the user of the iterator is
// not allowed to modify or delete the intervals until after the iterator has
// been used completely.  The IntervalPartition class uses this functionality.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_ANALYSIS_INTERVALITERATOR_H
#define LLVM_ANALYSIS_INTERVALITERATOR_H

#include "llvm/ADT/GraphTraits.h"
#include "llvm/Analysis/Interval.h"
#include "llvm/Analysis/IntervalPartition.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
#include <cassert>
#include <iterator>
#include <set>
#include <utility>
#include <vector>

namespace llvm {

class BasicBlock;

// getNodeHeader - Given a source graph node and the source graph, return the
// BasicBlock that is the header node.  This is the opposite of
// getSourceGraphNode.
inline BasicBlock *getNodeHeader(BasicBlock *BB) { return BB; }
inline BasicBlock *getNodeHeader(Interval *I) { return I->getHeaderNode(); }

// getSourceGraphNode - Given a BasicBlock and the source graph, return the
// source graph node that corresponds to the BasicBlock.  This is the opposite
// of getNodeHeader.
inline BasicBlock *getSourceGraphNode(Function *, BasicBlock *BB) {
  return BB;
}
inline Interval *getSourceGraphNode(IntervalPartition *IP, BasicBlock *BB) {
  return IP->getBlockInterval(BB);
}

// addNodeToInterval - This method exists to assist the generic ProcessNode
// with the task of adding a node to the new interval, depending on the
// type of the source node.  In the case of a CFG source graph (BasicBlock
// case), the BasicBlock itself is added to the interval.
inline void addNodeToInterval(Interval *Int, BasicBlock *BB) {
  Int->Nodes.push_back(BB);
}

// addNodeToInterval - This method exists to assist the generic ProcessNode
// with the task of adding a node to the new interval, depending on the
// type of the source node.  In the case of a CFG source graph (BasicBlock
// case), the BasicBlock itself is added to the interval.  In the case of
// an IntervalPartition source graph (Interval case), all of the member
// BasicBlocks are added to the interval.
inline void addNodeToInterval(Interval *Int, Interval *I) {
  // Add all of the nodes in I as new nodes in Int.
  llvm::append_range(Int->Nodes, I->Nodes);
}

template<class NodeTy, class OrigContainer_t, class GT = GraphTraits<NodeTy *>,
         class IGT = GraphTraits<Inverse<NodeTy *>>>
class IntervalIterator {
  std::vector<std::pair<Interval *, typename Interval::succ_iterator>> IntStack;
  std::set<BasicBlock *> Visited;
  OrigContainer_t *OrigContainer;
  bool IOwnMem;     // If True, delete intervals when done with them
                    // See file header for conditions of use

public:
  using iterator_category = std::forward_iterator_tag;

  IntervalIterator() = default; // End iterator, empty stack

  IntervalIterator(Function *M, bool OwnMemory) : IOwnMem(OwnMemory) {
    OrigContainer = M;
    if (!ProcessInterval(&M->front())) {
      llvm_unreachable("ProcessInterval should never fail for first interval!");
    }
  }

  IntervalIterator(IntervalIterator &&x)
      : IntStack(std::move(x.IntStack)), Visited(std::move(x.Visited)),
        OrigContainer(x.OrigContainer), IOwnMem(x.IOwnMem) {
    x.IOwnMem = false;
  }

  IntervalIterator(IntervalPartition &IP, bool OwnMemory) : IOwnMem(OwnMemory) {
    OrigContainer = &IP;
    if (!ProcessInterval(IP.getRootInterval())) {
      llvm_unreachable("ProcessInterval should never fail for first interval!");
    }
  }

  ~IntervalIterator() {
    if (IOwnMem)
      while (!IntStack.empty()) {
        delete operator*();
        IntStack.pop_back();
      }
  }

  bool operator==(const IntervalIterator &x) const {
    return IntStack == x.IntStack;
  }
  bool operator!=(const IntervalIterator &x) const { return !(*this == x); }

  const Interval *operator*() const { return IntStack.back().first; }
  Interval *operator*() { return IntStack.back().first; }
  const Interval *operator->() const { return operator*(); }
  Interval *operator->() { return operator*(); }

  IntervalIterator &operator++() { // Preincrement
    assert(!IntStack.empty() && "Attempting to use interval iterator at end!");
    do {
      // All of the intervals on the stack have been visited.  Try visiting
      // their successors now.
      Interval::succ_iterator &SuccIt = IntStack.back().second,
                                EndIt = succ_end(IntStack.back().first);
      while (SuccIt != EndIt) {                 // Loop over all interval succs
        bool Done = ProcessInterval(getSourceGraphNode(OrigContainer, *SuccIt));
        ++SuccIt;                               // Increment iterator
        if (Done) return *this;                 // Found a new interval! Use it!
      }

      // Free interval memory... if necessary
      if (IOwnMem) delete IntStack.back().first;

      // We ran out of successors for this interval... pop off the stack
      IntStack.pop_back();
    } while (!IntStack.empty());

    return *this;
  }

  IntervalIterator operator++(int) { // Postincrement
    IntervalIterator tmp = *this;
    ++*this;
    return tmp;
  }

private:
  // ProcessInterval - This method is used during the construction of the
  // interval graph.  It walks through the source graph, recursively creating
  // an interval per invocation until the entire graph is covered.  This uses
  // the ProcessNode method to add all of the nodes to the interval.
  //
  // This method is templated because it may operate on two different source
  // graphs: a basic block graph, or a preexisting interval graph.
  bool ProcessInterval(NodeTy *Node) {
    BasicBlock *Header = getNodeHeader(Node);
    if (!Visited.insert(Header).second)
      return false;

    Interval *Int = new Interval(Header);

    // Check all of our successors to see if they are in the interval...
    for (typename GT::ChildIteratorType I = GT::child_begin(Node),
           E = GT::child_end(Node); I != E; ++I)
      ProcessNode(Int, getSourceGraphNode(OrigContainer, *I));

    IntStack.push_back(std::make_pair(Int, succ_begin(Int)));
    return true;
  }

  // ProcessNode - This method is called by ProcessInterval to add nodes to the
  // interval being constructed, and it is also called recursively as it walks
  // the source graph.  A node is added to the current interval only if all of
  // its predecessors are already in the graph.  This also takes care of keeping
  // the successor set of an interval up to date.
  //
  // This method is templated because it may operate on two different source
  // graphs: a basic block graph, or a preexisting interval graph.
  void ProcessNode(Interval *Int, NodeTy *Node) {
    assert(Int && "Null interval == bad!");
    assert(Node && "Null Node == bad!");

    BasicBlock *NodeHeader = getNodeHeader(Node);

    if (Visited.count(NodeHeader)) {     // Node already been visited?
      if (Int->contains(NodeHeader)) {   // Already in this interval...
        return;
      } else {                           // In other interval, add as successor
        if (!Int->isSuccessor(NodeHeader)) // Add only if not already in set
          Int->Successors.push_back(NodeHeader);
      }
    } else {                             // Otherwise, not in interval yet
      for (typename IGT::ChildIteratorType I = IGT::child_begin(Node),
             E = IGT::child_end(Node); I != E; ++I) {
        if (!Int->contains(*I)) {        // If pred not in interval, we can't be
          if (!Int->isSuccessor(NodeHeader)) // Add only if not already in set
            Int->Successors.push_back(NodeHeader);
          return;                        // See you later
        }
      }

      // If we get here, then all of the predecessors of BB are in the interval
      // already.  In this case, we must add BB to the interval!
      addNodeToInterval(Int, Node);
      Visited.insert(NodeHeader);     // The node has now been visited!

      if (Int->isSuccessor(NodeHeader)) {
        // If we were in the successor list from before... remove from succ list
        llvm::erase_value(Int->Successors, NodeHeader);
      }

      // Now that we have discovered that Node is in the interval, perhaps some
      // of its successors are as well?
      for (typename GT::ChildIteratorType It = GT::child_begin(Node),
             End = GT::child_end(Node); It != End; ++It)
        ProcessNode(Int, getSourceGraphNode(OrigContainer, *It));
    }
  }
};

using function_interval_iterator = IntervalIterator<BasicBlock, Function>;
using interval_part_interval_iterator =
    IntervalIterator<Interval, IntervalPartition>;

inline function_interval_iterator intervals_begin(Function *F,
                                                  bool DeleteInts = true) {
  return function_interval_iterator(F, DeleteInts);
}
inline function_interval_iterator intervals_end(Function *) {
  return function_interval_iterator();
}

inline interval_part_interval_iterator
   intervals_begin(IntervalPartition &IP, bool DeleteIntervals = true) {
  return interval_part_interval_iterator(IP, DeleteIntervals);
}

inline interval_part_interval_iterator intervals_end(IntervalPartition &IP) {
  return interval_part_interval_iterator();
}

} // end namespace llvm

#endif // LLVM_ANALYSIS_INTERVALITERATOR_H
