//===- subzero/src/IceLiveness.h - Liveness analysis ------------*- C++ -*-===//
//
//                        The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Declares the Liveness and LivenessNode classes, which are used for
/// liveness analysis.
///
/// The node-specific information tracked for each Variable includes whether it
/// is live on entry, whether it is live on exit, the instruction number that
/// starts its live range, and the instruction number that ends its live range.
/// At the Cfg level, the actual live intervals are recorded.
///
//===----------------------------------------------------------------------===//

#ifndef SUBZERO_SRC_ICELIVENESS_H
#define SUBZERO_SRC_ICELIVENESS_H

#include "IceDefs.h"
#include "IceBitVector.h"
#include "IceCfgNode.h"
#include "IceTLS.h"
#include "IceTypes.h"

#include <memory>
#include <utility>

namespace Ice {

class Liveness {
  Liveness() = delete;
  Liveness(const Liveness &) = delete;
  Liveness &operator=(const Liveness &) = delete;

  class LivenessNode {
    LivenessNode &operator=(const LivenessNode &) = delete;

  public:
    LivenessNode() = default;
    LivenessNode(const LivenessNode &) = default;
    /// NumLocals is the number of Variables local to this block.
    SizeT NumLocals = 0;
    /// NumNonDeadPhis tracks the number of Phi instructions that
    /// Inst::liveness() identified as tentatively live. If NumNonDeadPhis
    /// changes from the last liveness pass, then liveness has not yet
    /// converged.
    SizeT NumNonDeadPhis = 0;
    // LiveToVarMap maps a liveness bitvector index to a Variable. This is
    // generally just for printing/dumping. The index should be less than
    // NumLocals + Liveness::NumGlobals.
    LivenessVector<Variable *> LiveToVarMap;
    // LiveIn and LiveOut track the in- and out-liveness of the global
    // variables. The size of each vector is LivenessNode::NumGlobals.
    LivenessBV LiveIn, LiveOut;
    // LiveBegin and LiveEnd track the instruction numbers of the start and end
    // of each variable's live range within this block. The index/key of each
    // element is less than NumLocals + Liveness::NumGlobals.
    LiveBeginEndMap LiveBegin, LiveEnd;
  };

public:
  void init();
  void initPhiEdgeSplits(NodeList::const_iterator FirstNode,
                         VarList::const_iterator FirstVar);
  Cfg *getFunc() const { return Func; }
  LivenessMode getMode() const { return Mode; }
  Variable *getVariable(SizeT LiveIndex, const CfgNode *Node) const;
  SizeT getLiveIndex(SizeT VarIndex) const {
    const SizeT LiveIndex = VarToLiveMap[VarIndex];
    assert(LiveIndex != InvalidLiveIndex);
    return LiveIndex;
  }
  SizeT getNumGlobalVars() const { return NumGlobals; }
  SizeT getNumVarsInNode(const CfgNode *Node) const {
    return NumGlobals + Nodes[Node->getIndex()].NumLocals;
  }
  SizeT &getNumNonDeadPhis(const CfgNode *Node) {
    return Nodes[Node->getIndex()].NumNonDeadPhis;
  }
  LivenessBV &getLiveIn(const CfgNode *Node) {
    SizeT Index = Node->getIndex();
    resize(Index);
    return Nodes[Index].LiveIn;
  }
  LivenessBV &getLiveOut(const CfgNode *Node) {
    SizeT Index = Node->getIndex();
    resize(Index);
    return Nodes[Index].LiveOut;
  }
  LivenessBV &getScratchBV() { return ScratchBV; }
  LiveBeginEndMap *getLiveBegin(const CfgNode *Node) {
    SizeT Index = Node->getIndex();
    resize(Index);
    return &Nodes[Index].LiveBegin;
  }
  LiveBeginEndMap *getLiveEnd(const CfgNode *Node) {
    SizeT Index = Node->getIndex();
    resize(Index);
    return &Nodes[Index].LiveEnd;
  }
  bool getRangeMask(SizeT Index) const { return RangeMask[Index]; }

  ArenaAllocator *getAllocator() const { return Alloc.get(); }

  static std::unique_ptr<Liveness> create(Cfg *Func, LivenessMode Mode) {
    return std::unique_ptr<Liveness>(new Liveness(Func, Mode));
  }

  static void TlsInit() { LivenessAllocatorTraits::init(); }

  std::string dumpStr() const {
    return "MaxLocals(" + std::to_string(MaxLocals) + "), "
                                                      "NumGlobals(" +
           std::to_string(NumGlobals) + ")";
  }

private:
  Liveness(Cfg *Func, LivenessMode Mode)
      : Alloc(new ArenaAllocator()), AllocScope(this), Func(Func), Mode(Mode) {}

  void initInternal(NodeList::const_iterator FirstNode,
                    VarList::const_iterator FirstVar, bool IsFullInit);
  /// Resize Nodes so that Nodes[Index] is valid.
  void resize(SizeT Index) {
    if (Index >= Nodes.size()) {
      assert(false && "The Nodes array is not expected to be resized.");
      Nodes.resize(Index + 1);
    }
  }
  std::unique_ptr<ArenaAllocator> Alloc;
  LivenessAllocatorScope AllocScope; // Must be declared after Alloc.
  static constexpr SizeT InvalidLiveIndex = -1;
  Cfg *Func;
  LivenessMode Mode;
  /// Size of Nodes is Cfg::Nodes.size().
  LivenessVector<LivenessNode> Nodes;
  /// VarToLiveMap maps a Variable's Variable::Number to its live index within
  /// its basic block.
  LivenessVector<SizeT> VarToLiveMap;
  /// LiveToVarMap is analogous to LivenessNode::LiveToVarMap, but for non-local
  /// variables.
  LivenessVector<Variable *> LiveToVarMap;
  /// RangeMask[Variable::Number] indicates whether we want to track that
  /// Variable's live range.
  LivenessBV RangeMask;
  /// ScratchBV is a bitvector that can be reused across CfgNode passes, to
  /// avoid having to allocate/deallocate memory so frequently.
  LivenessBV ScratchBV;
  /// MaxLocals indicates what is the maximum number of local variables in a
  /// single basic block, across all blocks in a function.
  SizeT MaxLocals = 0;
  /// NumGlobals indicates how many global variables (i.e., Multi Block) exist
  /// for a function.
  SizeT NumGlobals = 0;
};

} // end of namespace Ice

#endif // SUBZERO_SRC_ICELIVENESS_H
