//===--- LoopRegionAnalysis.h -----------------------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
///
/// Purpose
/// =======
///
/// This is an analysis that is an implementation of interval analysis in order
/// to allow for dataflow to be done in a structured way on the loop tree. The
/// facilities it provides are:
///
/// 1. An abstraction called ``LoopRegion`` that abstracts over natural loops,
/// basic blocks, and the top level function. This is meant to provide a
/// function level pointer for summarizing information.
///
/// 2. For each Region, if it has subregions (i.e. is not a Block), an RPO
/// ordering of the Subregions are provided. Loops in this RPO ordering have the
/// RPO number of their header.
///
/// 3. Natural loops are defined by the loops that SILLoopInfo can find. Thus it
/// is useful to be able to know about loops that are not able to be found by
/// SILLoopInfo (i.e. irreducible loops). This information is computed by
/// finding all backedges and any backedge that is not recognized by SILLoopInfo
/// as a backedge has its head and tail region marked as unknown control flow
/// boundaries. This can be queries via the methods:
///
/// - LoopRegion::isUnknownControlFlowEdgeHead().
/// - LoopRegion::isUnknownControlFlowEdgeTail().
///
/// 4. Only loops with single back edges are supported by this analysis. If such
/// a loop is detected, we mark the head, tail of the edge as irreducible
/// control flow boundaries. To handle such loops, we rely on loop
/// canonicalization to transform the multiple backedge loops into multiple
/// loops with singular backedges or by merging the backedge blocks.
///
/// Algorithm
/// =========
///
/// The main consideration here is that we want to ensure that we only traverse
/// the CFG once and reuse the information that is already provided via the loop
/// info analysis and the post order analysis.
///
/// We begin by visiting each block in RPO order. During this RPO traversal, we:
///
/// 1. Create LoopRegions for each block and wire up each block's predecessor
/// and successor blocks as predecessors/successors of the block's region.
///
/// 2. Detect any backedges that are unknown to SILLoopInfo and mark the blocks
/// that form the head/tail of the backedge as unknown control flow boundaries.
///
/// 3. We lookup/create the region for the innermost loop that contains the
/// block and add the block's region as a subregion of that loop.
///
/// Then we perform a postorder DFS of the loop nest. The postorder provides the
/// inductive rule that all loops will be visited after all of their subloops
/// have been visited. If a Loop has no subloops (i.e. all subregions are
/// blocks), we do nothing. Otherwise, if the loop does have subloops, we visit
/// each subloop and do the following:
///
/// 1. The region data structure of the header of the subloop still is the
/// successor of its predecessor outside of the subloop in the various block
/// datastructures. Rewire those regions to consider the loop to be their
/// successor instead and make each of those regions on of the predecessors of
/// the subloop. Then clear the predecessor list of the subloop's header
/// region. The header should have no predecessor edges after this operation
/// completes.
///
/// 2. For each of the exiting regions of the subloop (that is the regions
/// inside the loop that leave the subloop):
///
///   a. Replace each predecessor edge in the exiting block's successors with an
///   edge pointing at the subloop instead of at the exiting block and
///   vis-a-versa.
///
///   b. Introduce a loop-escape edge from the exiting regions that associates
///   the specific successor number of the region with the loop successor edge
///   that we just created. By using this indirection, if the loop is an inner
///   loop and further acts as an exit from an outer loop, the region's
///   successor edge will be able to be used to traverse from the region ->
///   inner loop -> outer loop successor. (i).
///
/// After this is complete, the exiting blocks should have no successor edges
/// going outside the loop. For each of the removed edges additionally we
/// introduce an "exiting edge". The reason this is necessary is to make it
/// easier to handle exits through
///
/// 3. If the loop has multiple back edges, mark each of the backedges as
/// unknown control flow boundaries.
///
/// We complete by performing the same operation on the top level function.
///
/// After this is done, each level of the loop hierarchy should be able to be
/// treated from a dataflow perspective as its own separate function with only
/// one caller, the parent loop region (or the top level function), enabling
/// extremely aggressive operations (or even outlining).
///
/// (i).  The reason why this is important is to be able to handle exits to
/// trapping code. Trapping code will always be associated with the outer most
/// loop since it is an exit from all of the loops. Yet in ARC we need to be
/// able to find that region from For certain optimizations like ARC, we need to
/// be able to ignore these successor regions. By tracing up the loop nest
/// hierarchy by these loop exits, we can find the unreachable regions in the
/// parent and ignore them. This also allows us to be more precise about
/// hoisting retains/releases and avoid hoisting into such regions.
///
//===----------------------------------------------------------------------===//

#ifndef SWIFT_SILOPTIMIZER_ANALYSIS_LOOPNESTANALYSIS_H
#define SWIFT_SILOPTIMIZER_ANALYSIS_LOOPNESTANALYSIS_H

#include "swift/SILOptimizer/Analysis/Analysis.h"
#include "swift/Basic/BlotSetVector.h"
#include "swift/Basic/Range.h"
#include "swift/Basic/STLExtras.h"
#include "swift/SILOptimizer/Analysis/PostOrderAnalysis.h"
#include "swift/SILOptimizer/Analysis/LoopAnalysis.h"
#include "swift/SILOptimizer/PassManager/PassManager.h"
#include "swift/SIL/LoopInfo.h"
#include "swift/SIL/SILBasicBlock.h"
#include "swift/SIL/SILFunction.h"
#include "llvm/Support/raw_ostream.h"

namespace swift {

/// A loop region is a data structure which represents one of a basic block,
/// loop, or function.
///
/// In the case of a loop, function, it contains an internal
/// data structure that represents the subregions of the loop/function. This
/// data is tail allocated so that the basic block case is not penalized by
/// storing this unnecessary information.
class LoopRegion {
  // FIXME: This should use llvm::TrailingObjects for its tail allocations, but
  // that requires restructuring the file a bit.

  /// This is a data structure that is an unsigned integer with a top bit flag
  /// that says whether it is an RPO ID for a BB Region or is an RPO ID of the
  /// header BB of a Loop Region that used as a placeholder to ensure that the
  /// Loop is visited in the proper RPO order. When the placeholder flag is hit,
  /// the subloop array should be searched for the pair that has that flag as a
  /// first element. The loop's flag will be the second element of the pair.
  struct SubregionID {
    static constexpr unsigned IDBitSize = (sizeof(unsigned) * CHAR_BIT) - 1;
    static constexpr unsigned MaxID = (unsigned(1) << IDBitSize) - 1;
    unsigned IsLoop : 1;
    unsigned ID : IDBitSize;

    SubregionID(unsigned id, bool isloop) {
      IsLoop = unsigned(isloop);
      ID = id;
    }
    bool operator<(const SubregionID &Other) const { return ID < Other.ID; }
  };
  /// These checks are just for performance.
  static_assert(IsTriviallyCopyable<SubregionID>::value,
                "Expected trivially copyable type");

  struct SubregionData;
  friend class LoopRegionFunctionInfo;

public:
  /// We operate in terms of FunctionTy, LoopTy, and BlockTy so that this can
  /// potentially be ported to LLVM in the future.
  using FunctionTy = SILFunction;
  using LoopTy = SILLoop;
  using BlockTy = SILBasicBlock;

  /// A tagged data structure that stores in its bottom bit whether or not the
  /// successor edge is non-local (implying it goes through the parent region).
  struct SuccessorID {
    static constexpr unsigned NumTaggedBits = 2;
    static constexpr unsigned IDBitSize =
        (sizeof(unsigned) * CHAR_BIT) - NumTaggedBits;
    static constexpr unsigned MaxID = (unsigned(1) << IDBitSize) - 1;

  private:
    unsigned IsDead : 1;

  public:
    unsigned IsNonLocal : 1;
    unsigned ID : IDBitSize;

    SuccessorID(unsigned rawValue)
        : IsDead(rawValue & 1), IsNonLocal((rawValue & 2) >> 1),
          ID(rawValue >> 2) {}
    SuccessorID(unsigned id, bool isnonlocal)
        : IsDead(unsigned(false)), IsNonLocal(unsigned(isnonlocal)), ID(id) {}

    bool operator<(const SuccessorID &Other) const { return ID < Other.ID; }
    bool operator==(const SuccessorID &Other) const {
      return ID == Other.ID && IsNonLocal == Other.IsNonLocal &&
             IsDead == Other.IsDead;
    }
    bool operator!=(const SuccessorID &Other) const {
      return !(*this == Other);
    }

    unsigned asInt() const { return *reinterpret_cast<const unsigned *>(this); }

    struct ToLiveSucc {
      Optional<SuccessorID> operator()(Optional<SuccessorID> ID) const {
        return ID;
      }
    };

    struct ToLiveLocalSucc {
      Optional<unsigned> operator()(Optional<SuccessorID> ID) const {
        if (!ID)
          return None;
        if ((*ID).IsNonLocal)
          return None;
        return (*ID).ID;
      }
    };

    struct ToLiveNonLocalSucc {
      Optional<unsigned> operator()(Optional<SuccessorID> ID) const {
        if (!ID)
          return None;
        if (!(*ID).IsNonLocal)
          return None;
        return (*ID).ID;
      }
    };
  };
  // These checks are just for performance.
  static_assert(IsTriviallyCopyable<SuccessorID>::value,
                "Expected trivially copyable type");

  /// An iterator that knows how to iterate over the subregion indices of a
  /// region.
  class subregion_iterator :
    public std::iterator<std::bidirectional_iterator_tag, unsigned> {
    friend struct SubregionData;
    llvm::SmallVectorImpl<SubregionID>::const_iterator InnerIter;
    const llvm::SmallVectorImpl<std::pair<unsigned, unsigned>> *Subloops;

    /// A flag that says that this iterator is an invalid iterator belonging to
    /// a basic block. The iterator can only be compared against another invalid
    /// iterator. Any other use causes an unreachable being hit.
    ///
    /// The reason this is needed is because basic blocks cannot have
    /// subregions, yet many graph algorithms want to be able to iterate over
    /// the subregions of a region regardless of whether it is a basic block,
    /// loop, or function. By allowing for invalid iterators for basic blocks,
    /// we can allow for this.
    unsigned IsInvalid : 1;

    subregion_iterator(
        llvm::SmallVectorImpl<SubregionID>::const_iterator iter,
        const llvm::SmallVectorImpl<std::pair<unsigned, unsigned>> *subloops)
        : InnerIter(iter), Subloops(subloops), IsInvalid(false) {}

  public:
    using value_type = unsigned;
    using reference = unsigned;
    using pointer = void;
    using iterator_category = std::bidirectional_iterator_tag;
    using difference_type = int;

    /// Construct a subregion_iterator suitable for use with a basic block. It
    /// does not contain any data and can only be compared against another
    /// invalid iterator (for which it will return true). Any other usage
    /// results in an unreachable being hit.
    subregion_iterator() : InnerIter(), Subloops(), IsInvalid(true) {}

    /// Return the index of the current subregion index.
    unsigned operator*() const {
      if (IsInvalid)
        llvm_unreachable("Invalid Iterator?!");
      auto ID = *InnerIter;
      if (!ID.IsLoop)
        return ID.ID;
      for (auto &p : *Subloops) {
        if (p.first == ID.ID) {
          return p.second;
        }
      }
      llvm_unreachable("Out of sync subloops array?!");
    }

    subregion_iterator &operator++() {
      if (IsInvalid)
        llvm_unreachable("Invalid Iterator?!");
      InnerIter++;
      return *this;
    }
    subregion_iterator operator++(int) {
      if (IsInvalid)
        llvm_unreachable("Invalid Iterator?!");
      return subregion_iterator(InnerIter++, Subloops);
    }
    subregion_iterator &operator--() {
      if (IsInvalid)
        llvm_unreachable("Invalid Iterator?!");
      InnerIter--;
      return *this;
    }
    subregion_iterator operator--(int) {
      if (IsInvalid)
        llvm_unreachable("Invalid Iterator?!");
      return subregion_iterator(InnerIter--, Subloops);
    }
    bool operator==(subregion_iterator rhs) const {
      if (IsInvalid) {
        if (rhs.IsInvalid)
          return true;
        llvm_unreachable("Invalid Iterator?!");
      }
      return InnerIter == rhs.InnerIter;
    }
    bool operator!=(subregion_iterator rhs) const { return !(*this == rhs); }
  };
  using subregion_reverse_iterator = std::reverse_iterator<subregion_iterator>;

  /// An iterator that knows how to iterate over the backedge indices of a
  /// region.
  class backedge_iterator
      : public std::iterator<std::bidirectional_iterator_tag, unsigned> {
    friend struct SubregionData;
    using InnerIterTy = llvm::SmallVectorImpl<unsigned>::const_iterator;
    llvm::Optional<InnerIterTy> InnerIter;

    backedge_iterator(llvm::SmallVectorImpl<unsigned>::const_iterator iter)
        : InnerIter(iter) {}

  public:
    using value_type = unsigned;
    using reference = unsigned;
    using pointer = void;
    using iterator_category = std::bidirectional_iterator_tag;
    using difference_type = int;

    /// Construct a backedge_iterator suitable for use with a basic block. It
    /// does not contain any data and can only be compared against another
    /// invalid iterator (for which it will return true). Any other usage
    /// results in an unreachable being hit.
    backedge_iterator() : InnerIter() {}

    bool hasValue() const { return InnerIter.hasValue(); }

    /// Return the index of the current backedge index.
    unsigned operator*() const { return **InnerIter; }

    backedge_iterator &operator++() {
      ++(*InnerIter);
      return *this;
    }
    backedge_iterator operator++(int) {
      backedge_iterator iter = *this;
      ++iter;
      return iter;
    }
    backedge_iterator &operator--() {
      --(*InnerIter);
      return *this;
    }
    backedge_iterator operator--(int) {
      backedge_iterator iter = *this;
      --iter;
      return iter;
    }
    bool operator==(backedge_iterator rhs) const {
      if (InnerIter.hasValue() != rhs.InnerIter.hasValue())
        llvm_unreachable("Comparing uncomparable iterators");
      // Now we know that the two either both have values or both do not have
      // values.
      if (!InnerIter.hasValue())
        return true;
      return *InnerIter == *rhs.InnerIter;
    }
    bool operator!=(backedge_iterator rhs) const { return !(*this == rhs); }
  };
  using backedge_reverse_iterator = std::reverse_iterator<backedge_iterator>;

private:
  /// A pointer to one of a Loop, Basic Block, or Function represented by this
  /// region.
  llvm::PointerUnion<FunctionTy *, LoopTy *, BlockTy *> Ptr;

  /// The ID of this region.
  unsigned ID;

  /// The parent region of this ID if it exists.
  llvm::Optional<unsigned> ParentID;

  /// The IDs of the predecessor regions of this region.
  llvm::SmallVector<unsigned, 4> Preds;

  /// The IDs of the local and non-local successor regions of this region.
  ///
  /// Let R1 be this region. A local successor of R1 is a region R2 for which
  /// the inner most parent region that contains R2 is the same as the inner
  /// most parent region that contains R1. A local successor is represented by
  /// its real ID. A non-local successor is represented by the index of the
  /// non-local successor in this region's parent's successor list.
  ///
  /// Discussion: The reason that we have this separate representation is so
  /// that if the non-local exit is to a block in a grand+-ancestor region of
  /// this BB, we can represent each jump as individual non-local edges in
  /// between loops.
  ///
  /// *NOTE* This list is not sorted, but cannot have any duplicate
  /// elements. We have a check in LoopRegionFunctionInfo::verify to make sure
  /// that this stays true. The reason why this is necessary is that subregions
  /// of a loop, may have a non-local successor edge pointed at this region's
  /// successor edge. If we were to sort these edges, we would need to update
  /// those subregion edges as well which is strictly not necessary.
  SmallBlotSetVector<SuccessorID, 8> Succs;

  /// True if this region the head of an edge that results from control flow
  /// that we do not handle.
  ///
  /// Currently this includes irreducible control flow and loops with multiple
  /// backedges. We rely on loop canonicalization to handle the multiple
  /// backedge case.
  bool IsUnknownControlFlowEdgeHead;

  /// True if this region the tail of an edge that results from control flow
  /// that we do not handle.
  ///
  /// Currently this includes irreducible control flow and loops with multiple
  /// backedges. We rely on loop canonicalization to handle the multiple
  /// backedge case.
  bool IsUnknownControlFlowEdgeTail;

  /// A tail allocated LoopSubregionData structure that is used to store state
  /// about subregions of a loop.
  ///
  /// We tail allocate this onto LoopRegions for loops/functions so that in the
  /// case of having a Block, we do not have any memory size overhead of these
  /// SmallVectors, but at the same time have reasonable memory performance. In
  /// the case of loops this overhead is acceptable since we shouldn't have many
  /// loops (compared to Blocks).
  struct SubregionData {
    /// The RPO number of the header block of this loop or function. This is
    /// used as the RPO number for the whole region.
    unsigned RPONumOfHeaderBlock;

    /// The RPO number of the back edge blocks of this loop. We use a
    /// SmallVector of size 1 since after loop canonicalization we will always
    /// have exactly one back edge block. But we want to be correct even in a
    /// non-canonicalized case implying that we need to be able to support
    /// multiple backedge blocks.
    llvm::SmallVector<unsigned, 1> BackedgeRegions;

    /// A list of subregion IDs of this region sorted in RPO order.
    ///
    /// This takes advantage of the fact that the ID of a basic block is the
    /// block's RPO number.
    ///
    /// This contains IDs that represent both basic blocks and loops that are
    /// subregions of this region. What is key to notice is that a loop is
    /// represented by the RPO number of its header. We use an auxiliary map to
    /// map the preheader's RPO number to the loop's ID.
    llvm::SmallVector<SubregionID, 16> Subregions;

    /// A map from RPO number of a subregion loop's preheader to a subloop
    /// regions id. This is necessary since we represent a loop in the
    /// Subregions array by the RPO number of its header.
    llvm::SmallVector<std::pair<unsigned, unsigned>, 2> Subloops;

    /// A list of subregions with non-local successors. This is the actual ID
    /// of the subregion since we do not care about any ordering.
    llvm::SmallVector<unsigned, 2> ExitingSubregions;

    subregion_iterator begin() const {
      return subregion_iterator(Subregions.begin(), &Subloops);
    }
    subregion_iterator end() const {
      return subregion_iterator(Subregions.end(), &Subloops);
    }
    subregion_reverse_iterator rbegin() const {
      return subregion_reverse_iterator(end());
    }
    subregion_reverse_iterator rend() const {
      return subregion_reverse_iterator(begin());
    }

    unsigned size() const { return Subregions.size(); }
    bool empty() const { return Subregions.empty(); }

    void addBlockSubregion(LoopRegion *R) {
      assert(R->ID <= SubregionID::MaxID && "Unrepresentable ID");
      Subregions.push_back(SubregionID(R->ID, false));
    }

    void addLoopSubregion(LoopRegion *L, LoopRegion *Header) {
      assert(Header->ID <= SubregionID::MaxID && "Unrepresentable ID");
      Subregions.push_back(SubregionID(Header->ID, true));
      Subloops.push_back({Header->ID, L->ID});
    }

    void addBackedgeSubregion(unsigned ID) {
      if (count(BackedgeRegions, ID))
        return;
      BackedgeRegions.push_back(ID);
    }

    backedge_iterator backedge_begin() const {
      return backedge_iterator(BackedgeRegions.begin());
    }
    backedge_iterator backedge_end() const {
      return backedge_iterator(BackedgeRegions.end());
    }
    backedge_reverse_iterator backedge_rbegin() const {
      return backedge_reverse_iterator(backedge_begin());
    }
    backedge_reverse_iterator backedge_rend() const {
      return backedge_reverse_iterator(backedge_end());
    }
    bool backedge_empty() const { return BackedgeRegions.empty(); }
    unsigned backedge_size() const { return BackedgeRegions.size(); }

    ArrayRef<unsigned> getBackedgeRegions() const { return BackedgeRegions; }

    /// Once we finish processing a loop, we sort its subregions so that they
    /// are guaranteed to be in RPO order. This works because each BB's ID is
    /// its RPO number and we represent loops by the RPO number of their
    /// preheader (with a flag in the first bit to say to look in the subloop
    /// array for the *real* ID of the loop).
    ///
    /// TODO: Is this necessary? We visit BBs in RPO order. This means that we
    /// should always add BBs in RPO order to subregion lists, no? For now I am
    /// going to sort just to be careful while bringing this up.
    void sortSubregions() { std::sort(Subregions.begin(), Subregions.end()); }
  };
public:
  ~LoopRegion();

  /// These will assert if this is not a loop region. If this is a loop region,
  /// the forward iterators will give the IDs of the subregions in RPO order.
  /// The backward iterators will give the IDs of the subregions in PO order.
  ///
  /// The reason why all of this work is being done for subregions is because we
  /// are working around the following contradiction:
  ///
  /// 1. There are not that many loops in a function so it makes sense to take
  /// advantage of this to store more data that makes performing analysis easy
  /// (such as the IDs of subregions of the loop in RPO order).
  /// 2. There are a lot of BBs in a function so it makes sense to try to
  /// minimize the amount of state stored for each BB.
  /// 3. This is a data structure that attempts to generalize over both of them
  /// without using dynamic dispatch.
  ///
  /// We use tail allocation of the extra data for loops so we do not incur the
  /// memory cost of large SmallVectors for BBs.
  subregion_iterator subregion_begin() const {
    if (isBlock())
      return subregion_iterator();
    return getSubregionData().begin();
  }

  /// This is the end equivalent of subregion_begin(). Please see comment on
  /// subregion_begin().
  subregion_iterator subregion_end() const {
    if (isBlock())
      return subregion_iterator();
    return getSubregionData().end();
  }

  bool subregions_empty() const {
    if (isBlock())
      return true;
    return getSubregionData().empty();
  }

  unsigned subregions_size() const {
    if (isBlock())
      return 0;
    return getSubregionData().size();
  }

  subregion_reverse_iterator subregion_rbegin() const {
    if (isBlock())
      return subregion_reverse_iterator();
    return getSubregionData().rbegin();
  }

  subregion_reverse_iterator subregion_rend() const {
    if (isBlock())
      return subregion_reverse_iterator();
    return getSubregionData().rend();
  }

  iterator_range<subregion_iterator> getSubregions() const {
    return {subregion_begin(), subregion_end()};
  }

  iterator_range<subregion_reverse_iterator>
  getReverseSubregions() const {
    return {subregion_rbegin(), subregion_rend()};
  }

  /// Returns true if \p R is an immediate subregion of this region.
  bool containsSubregion(LoopRegion *R) {
    auto End = subregion_end();
    return std::find(subregion_begin(), End, R->getID()) != End;
  }

  /// Returns an ArrayRef containing IDs of the exiting subregions of this
  /// region. The exit regions associated with the exiting subregions are the
  /// end points of the non-local edges. This asserts if this is a region
  /// representing a block.
  ArrayRef<unsigned> getExitingSubregions() const {
    return getSubregionData().ExitingSubregions;
  }

  bool isBackedgeRegion(unsigned ID) const {
    if (isBlock())
      return false;
    return count(getSubregionData().getBackedgeRegions(), ID);
  }

  ArrayRef<unsigned> getBackedgeRegions() const {
    if (isBlock())
      return ArrayRef<unsigned>();
    return getSubregionData().getBackedgeRegions();
  }

  Optional<unsigned> getBackedgeRegion() const {
    if (isBlock())
      return None;
    auto bedge_begin = getSubregionData().backedge_begin();
    auto bedge_end = getSubregionData().backedge_end();
    if (bedge_begin == bedge_end)
      return None;
    return *bedge_begin;
  }

  using backedge_iterator = backedge_iterator;
  backedge_iterator backedge_begin() const {
    if (isBlock())
      return backedge_iterator();
    return getSubregionData().backedge_begin();
  }
  backedge_iterator backedge_end() const {
    if (isBlock())
      return backedge_iterator();
    return getSubregionData().backedge_end();
  }
  bool backedge_empty() const {
    if (isBlock())
      return true;
    return getSubregionData().backedge_empty();
  }
  unsigned backedge_size() const {
    if (isBlock())
      return 0;
    return getSubregionData().backedge_size();
  }

  using pred_const_iterator = decltype(Preds)::const_iterator;
  pred_const_iterator pred_begin() const { return Preds.begin(); }
  pred_const_iterator pred_end() const { return Preds.end(); }
  bool pred_empty() const { return Preds.empty(); }
  unsigned pred_size() const { return Preds.size(); }
  iterator_range<pred_const_iterator> getPreds() const {
    return {pred_begin(), pred_end()};
  }

  using const_succ_iterator = decltype(Succs)::const_iterator;
  const_succ_iterator succ_begin() const { return Succs.begin(); }
  const_succ_iterator succ_end() const { return Succs.end(); }
  bool succ_empty() const { return Succs.empty(); }
  unsigned succ_size() const { return Succs.size(); }

private:
  using InnerSuccRange = iterator_range<decltype(Succs)::const_iterator>;

public:
  using SuccRange =
      OptionalTransformRange<InnerSuccRange, SuccessorID::ToLiveSucc>;
  using LocalSuccRange =
      OptionalTransformRange<InnerSuccRange, SuccessorID::ToLiveLocalSucc>;
  using NonLocalSuccRange =
      OptionalTransformRange<InnerSuccRange, SuccessorID::ToLiveNonLocalSucc>;
  SuccRange getSuccs() const;
  LocalSuccRange getLocalSuccs() const;
  NonLocalSuccRange getNonLocalSuccs() const;

  BlockTy *getBlock() const;
  LoopTy *getLoop() const;
  FunctionTy *getFunction() const;

  bool isBlock() const { return Ptr.is<BlockTy *>(); }
  bool isLoop() const { return Ptr.is<LoopTy *>(); }
  bool isFunction() const { return Ptr.is<FunctionTy *>(); }

  /// Is this the head of an edge that causes unknown control flow.
  ///
  /// This means that dataflow that enters the region must not propagate any
  /// information into this region from predecessors.
  bool isUnknownControlFlowEdgeHead() const {
    return IsUnknownControlFlowEdgeHead;
  }

  /// Is this the head of an edge that causes unknown control flow.
  ///
  /// This means that dataflow state must not be propagated out of this region.
  bool isUnknownControlFlowEdgeTail() const {
    return IsUnknownControlFlowEdgeTail;
  }

  /// Returns the ID of this region in the region array.
  ///
  /// For basic blocks this is the RPO number of the basic block. This is done
  /// just as a convenient way to compress our region data structures.
  unsigned getID() const { return ID; }

  /// Return the ID of the parent region of this BB. Asserts if this is a
  /// function region.
  Optional<unsigned> getParentID() const { return ParentID; }

  unsigned getRPONumber() const {
    if (isBlock())
      return getID();
    return getSubregionData().RPONumOfHeaderBlock;
  }

  void dump() const;
  void print(llvm::raw_ostream &os, bool insertSpaces = false) const;
  void dumpName() const;
  void printName(llvm::raw_ostream &os) const;

private:
  LoopRegion(LoopTy *L, unsigned Idx)
      : Ptr(L), ID(Idx), ParentID(), Preds(), Succs(),
        IsUnknownControlFlowEdgeHead(false),
        IsUnknownControlFlowEdgeTail(false) {}

  LoopRegion(BlockTy *BB, unsigned Idx)
      : Ptr(BB), ID(Idx), ParentID(), Preds(), Succs(),
        IsUnknownControlFlowEdgeHead(false),
        IsUnknownControlFlowEdgeTail(false) {}

  LoopRegion(FunctionTy *F, unsigned Idx)
      : Ptr(F), ID(Idx), ParentID(), Preds(), Succs(),
        IsUnknownControlFlowEdgeHead(false),
        IsUnknownControlFlowEdgeTail(false) {}

  void setParent(LoopRegion *PR) {
    assert(!isFunction() && "Functions cannot be subregions");
    assert(!PR->isBlock() && "BB regions cannot be parents of a region");
    ParentID = PR->getID();
  }

  void addPred(LoopRegion *LNR) {
    assert(!isFunction() && "Functions cannot have predecessors");
    if (count(getPreds(), LNR->getID()))
      return;
    Preds.push_back(LNR->ID);
  }

  unsigned addSucc(LoopRegion *Successor) {
    assert(!isFunction() && "Functions cannot have successors");
    return Succs.insert(SuccessorID(Successor->getID(), false)).first;
  }

  void replacePred(unsigned OldPredID, unsigned NewPredID) {
    // Check if we already have NewPred in our list. If so, we just delete
    // OldPredID.
    if (count(Preds, NewPredID)) {
      // If this becomes a performance issue due to copying/moving/etc (which it
      // most likely will not), just use the marked dead model like successor
      // does.
      auto Iter = std::remove(Preds.begin(), Preds.end(), OldPredID);
      Preds.erase(Iter);
      return;
    }
    std::replace(Preds.begin(), Preds.end(), OldPredID, NewPredID);
  }

  /// Replace OldSuccID by NewSuccID, just deleting OldSuccID if what NewSuccID
  /// is already in the list.
  void replaceSucc(SuccessorID OldSucc, SuccessorID NewSucc);

  /// Set the IsDead flag on all successors of this region that have an id \p
  /// ID.
  ///
  /// Due to the creation of up-edges during loop region construction, we can
  /// never actually remove successors. Instead we mark successors as being dead
  /// and ignore such values when iterating.
  void removeLocalSucc(unsigned ID) { Succs.erase(SuccessorID(ID, false)); }

  void addBlockSubregion(LoopRegion *R) {
    assert(!isBlock() && "Blocks cannot have subregions");
    assert(R->isBlock() && "Assumed R was a basic block");
    R->setParent(this);
    getSubregionData().addBlockSubregion(R);
  }

  void addLoopSubregion(LoopRegion *L, LoopRegion *Header) {
    assert(!isBlock() && "Blocks cannot have subregions");
    assert(L->isLoop() && "Assumed L was a loop");
    assert(Header->isBlock() && "Assumed Header was a loop");
    L->setParent(this);
    getSubregionData().addLoopSubregion(L, Header);
  }


  SubregionData &getSubregionData() {
    assert(!isBlock() && "BBs do not have subregion data");
    return reinterpret_cast<SubregionData &>(*(this + 1));
  }

  const SubregionData &getSubregionData() const {
    assert(!isBlock() && "BBs do not have subregion data");
    return reinterpret_cast<const SubregionData &>(*(this + 1));
  }
};

} // end swift namespace

namespace llvm {

raw_ostream &operator<<(raw_ostream &os, swift::LoopRegion &LR);
raw_ostream &operator<<(raw_ostream &os, swift::LoopRegion::SuccessorID &S);

template <> struct DenseMapInfo<swift::LoopRegion::SuccessorID> {
  using Type = swift::LoopRegion::SuccessorID;

  static_assert(sizeof(Type) == sizeof(unsigned),
                "Expected SuccessorID to be the size of an unsigned!");
  static inline Type getEmptyKey() {
    return Type(DenseMapInfo<unsigned>::getEmptyKey());
  }
  static inline Type getTombstoneKey() {
    return Type(DenseMapInfo<unsigned>::getTombstoneKey());
  }
  static unsigned getHashValue(const swift::LoopRegion::SuccessorID Val) {
    return DenseMapInfo<unsigned>::getHashValue(Val.asInt());
  }
  static bool isEqual(const swift::LoopRegion::SuccessorID LHS,
                      const swift::LoopRegion::SuccessorID RHS) {
    return LHS == RHS;
  }
};

} // end llvm namespace

namespace swift {

class LoopRegionFunctionInfo {
  using RegionTy = LoopRegion;
  using BlockTy = SILBasicBlock;
  using LoopInfoTy = SILLoopInfo;
  using LoopTy = SILLoop;
  using FunctionTy = SILFunction;

  /// The function that this data structure contains loop regions for.
  FunctionTy *F;

  /// A bump ptr allocator that we allocate regions from.
  llvm::BumpPtrAllocator Allocator;

  /// The ID in the IDToRegionMap of the Region associated with \p F.
  llvm::Optional<unsigned> FunctionRegionID;

  /// A map from a BB to the ID in the IDToRegionMap of the Region associated
  /// with the BB.
  ///
  /// *NOTE* This ID is *also* the function level RPO number of the BB.
  llvm::DenseMap<BlockTy *, unsigned> BBToIDMap;

  /// A map from a Loop to the ID in the IDToRegionMap of the Region associated
  /// with the loop.
  llvm::DenseMap<LoopTy *, unsigned> LoopToIDMap;

  /// A map from an unsigned integer ID to a region.
  ///
  /// *WARNING* Before modifying the initialization of this field of the data
  /// structure please read the comment below:
  ///
  /// We assign IDs to BBs, Loops, and the top level Function, so that we can
  /// abstract above the underlying type of any specific region. A key thing to
  /// notice is that we always allocate regions associated with BBs before
  /// regions associated with Loops or the top level function (1). The reason
  /// that we do this is to ensure that each BBs ID is the RPO number of the BB
  /// at the function level. This is done so we do not have to represent the RPO
  /// numbers in a separate array. This means that when initializing this data
  /// structure, we need to be careful about how we initialize regions in order
  /// to preserve said property.
  ///
  /// In order to avoid having to initialize loop/function regions after BB
  /// regions (which would cause us to have to visit BBs twice), we instead
  /// allocate the memory for all of the BBs up front and set the pointer entry
  /// to be nullptr.
  ///
  /// Then when we initialize BBRegions, we just assign the resulting Region's
  /// pointer into the array using its RPO index rather than performing a
  /// push_back. For regions associated with Loops, Functions we still perform a
  /// push_back. This enables us to initialize regions for all types at the same
  /// time while preserving said property.
  ///
  /// (1) Currently there is no work done to ensure that the creation of the
  /// function level region will have any ordering with respect to the creation
  /// of any of the loop regions.
  std::vector<RegionTy *> IDToRegionMap;

  /// True if all BB regions have been created. Only in Debug Builds. Used to
  /// fire asserts to make sure that:
  ///
  ///   RegionTy *createRegion(SILBasicBlock *, unsigned)
  ///
  /// is only called in initializeBBRegions and everywhere else:
  ///
  ///   RegionTy *getRegion(SILBasicBlock *)
  ///
  /// is called.
#ifndef NDEBUG
  unsigned AllBBRegionsCreated : 1;
#endif

public:
  LoopRegionFunctionInfo(FunctionTy *F, PostOrderFunctionInfo *POI,
                         LoopInfoTy *LI);
  ~LoopRegionFunctionInfo();

  RegionTy *getRegion(unsigned RegionID) const {
    return IDToRegionMap[RegionID];
  }

  RegionTy *getRegionForNonLocalSuccessor(const RegionTy *Child,
                                          unsigned SuccID) const;

  Optional<unsigned> getGrandparentID(const RegionTy *GrandChild) {
    if (auto ParentID = GrandChild->getParentID()) {
      return getRegion(*ParentID)->getParentID();
    }
    return None;
  }

  /// Look up the region associated with this block and return it. Asserts if
  /// the block does not have a region associated with it.
  ///
  /// Regions associated with blocks are only created by the function
  /// createRegion(). FunctionTy and LoopTy have their RegionTys created via
  /// getRegion() lazily. For more information read the documentation for
  /// IDToRegionMap.
  RegionTy *getRegion(BlockTy *BB) const;

  /// Return the RegionTy associated with \p F. Creates the region if it does
  /// not exist yet.
  RegionTy *getRegion(FunctionTy *F) const;

  /// Return the RegionTy associated with \p Loop. Creates the region if it does
  /// not exist yet.
  RegionTy *getRegion(LoopTy *Loop) const;

  using iterator = decltype(IDToRegionMap)::iterator;
  using const_iterator = decltype(IDToRegionMap)::const_iterator;
  iterator begin() { return IDToRegionMap.begin(); }
  iterator end() { return IDToRegionMap.end(); }
  const_iterator begin() const { return IDToRegionMap.begin(); }
  const_iterator end() const { return IDToRegionMap.end(); }
  unsigned size() const { return IDToRegionMap.size(); }
  bool empty() const { return IDToRegionMap.empty(); }
  iterator_range<const_iterator> getRegions() const {
    return {begin(), end()};
  }

  RegionTy *getTopLevelRegion() const { return getRegion(F); }
  FunctionTy *getFunction() const { return F; }

  void dump() const;
  void print(llvm::raw_ostream &os) const;
  void viewLoopRegions() const;
  void verify();

private:
  RegionTy *createRegion(BlockTy *BB, unsigned RPONum);

  /// Initialize regions for all basic blocks.
  ///
  /// This initializes all BBs to have their regular predecessors, successors in
  /// the CFG ignoring BBs that are unreachable from the entry. During
  /// initialization of loops, we modify these edges in the region graph by
  /// removing and or substituting edges to loops for basic block edges. See
  /// large comment at the top of the file.
  void initializeBlockRegions(PostOrderFunctionInfo *PI, LoopInfoTy *LI);

  /// Initialize regions for all loops.
  ///
  /// This traverses the loop nest bottom up:
  ///
  /// 1. Removing backedges of loops.
  /// 2. Changing header predecessors to be loop predecessors.
  /// 3. Changing exiting block successors to be loop successors.
  ///
  /// For more information see large comment at the top of LoopRegionAnalysis.h.
  void initializeLoopRegions(LoopInfoTy *LI);

  /// Initialize the subregions of a function, treating the function as a top
  /// level loop.
  void
  initializeFunctionRegion(iterator_range<LoopInfoTy::iterator> TopLevelLoops);

  /// This is a refactored routine that handles common initialization of loops
  /// and functions.
  void
  initializeLoopFunctionRegion(RegionTy *ParentRegion,
                               iterator_range<LoopInfoTy::iterator> SubLoops);

  /// This helper routine rewrites all predecessors of the header of \p Loop to
  /// be predecessors of \p Loop and vis-a-versa. Returns the region for the
  /// SubLoopHeaderRegion
  RegionTy *
  rewriteLoopHeaderPredecessors(LoopTy *Loop, RegionTy *LoopRegion);

  /// This helper routine rewrites all successors of loop region exiting blocks
  /// to be successors of the loop. It also removes backedges and ignores
  /// non-backedge edges in the loop.
  void
  rewriteLoopExitingBlockSuccessors(LoopTy *Loop, RegionTy *LoopRegion);

  /// This helper routine for a given block, creates successor edges in between
  /// the block's region and all of the regions associated with the block's
  /// successor blocks.
  void initializeBlockRegionSuccessors(BlockTy *BB, RegionTy *BBRegion,
                                       PostOrderFunctionInfo *PI);

  /// This helper method goes through the predecessors of the basic block \p
  /// NonHeaderBB and determines if any of them are back edges. Since we know
  /// that \p NonHeaderBB is a basic block that has not been identified by loop
  /// info as a loop header, we know that these backedges are not known to us
  /// via loop info. We treat them as irreducible control flow edges to be
  /// conservative. In truth some of them may not be due to deficiencies in loop
  /// info.
  ///
  /// TODO: This needs a better name.
  void
  markIrreducibleLoopPredecessorsOfNonLoopHeader(BlockTy *NonHeaderBB,
                                                 RegionTy *NonHeaderBBRegion,
                                                 PostOrderFunctionInfo *PI);

  /// This helper method takes in a loop that has multiple loop latches and
  /// marks each of those loop latches as being unknown control flow tails. We
  /// do not support loops with multiple loop latches and instead rely on loops
  /// to be canonicalized to have one back edge. But we still need to be
  /// conservatively correct.
  ///
  /// TODO: This needs a better name.
  void
  markMultipleLoopLatchLoopBackEdges(RegionTy *LoopHeaderRegion,
                                     LoopTy *L,
                                     PostOrderFunctionInfo *PI);

  /// Recursively visit all the descendants of Parent. If there is a non-local
  /// successor edge path that points to a dead edge in Parent, mark the
  /// descendant non-local successor edge as dead.
  void propagateLivenessDownNonLocalSuccessorEdges(LoopRegion *Parent);
};

class LoopRegionAnalysis : public FunctionAnalysisBase<LoopRegionFunctionInfo> {
  SILLoopAnalysis *SLA;
  PostOrderAnalysis *POA;

public:
  LoopRegionAnalysis(SILModule *M)
      : FunctionAnalysisBase<LoopRegionFunctionInfo>(
            SILAnalysisKind::LoopRegion) {}

  LoopRegionAnalysis(const LoopRegionAnalysis &) = delete;
  LoopRegionAnalysis &operator=(const LoopRegionAnalysis &) = delete;

  virtual ~LoopRegionAnalysis() {}

  virtual void initialize(SILPassManager *PM) override;

  static bool classof(const SILAnalysis *S) {
    return S->getKind() == SILAnalysisKind::LoopRegion;
  }

  virtual std::unique_ptr<LoopRegionFunctionInfo>
  newFunctionAnalysis(SILFunction *F) override {
    return llvm::make_unique<LoopRegionFunctionInfo>(F, POA->get(F),
                                                     SLA->get(F));
  }

  virtual bool shouldInvalidate(SILAnalysis::InvalidationKind K) override {
    return K & InvalidationKind::Branches;
  }
};

} // end namespace swift

#endif
