//===- subzero/src/IceLiveness.cpp - Liveness analysis implementation -----===//
//
//                        The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file provides some of the support for the Liveness class. In
/// particular, it handles the sparsity representation of the mapping between
/// Variables and CfgNodes. The idea is that since most variables are used only
/// within a single basic block, we can partition the variables into "local" and
/// "global" sets. Instead of sizing and indexing vectors according to
/// Variable::Number, we create a mapping such that global variables are mapped
/// to low indexes that are common across nodes, and local variables are mapped
/// to a higher index space that is shared across nodes.
///
//===----------------------------------------------------------------------===//

#include "IceLiveness.h"

#include "IceCfg.h"
#include "IceCfgNode.h"
#include "IceDefs.h"
#include "IceInst.h"
#include "IceOperand.h"

namespace Ice {

// Initializes the basic liveness-related data structures for full liveness
// analysis (IsFullInit=true), or for incremental update after phi lowering
// (IsFullInit=false). In the latter case, FirstNode points to the first node
// added since starting phi lowering, and FirstVar points to the first Variable
// added since starting phi lowering.
void Liveness::initInternal(NodeList::const_iterator FirstNode,
                            VarList::const_iterator FirstVar, bool IsFullInit) {
  // Initialize most of the container sizes.
  SizeT NumVars = Func->getVariables().size();
  SizeT NumNodes = Func->getNumNodes();
  VariablesMetadata *VMetadata = Func->getVMetadata();
  Nodes.resize(NumNodes);
  VarToLiveMap.resize(NumVars);

  // Count the number of globals, and the number of locals for each block.
  SizeT TmpNumGlobals = 0;
  for (auto I = FirstVar, E = Func->getVariables().end(); I != E; ++I) {
    Variable *Var = *I;
    if (VMetadata->isMultiBlock(Var)) {
      ++TmpNumGlobals;
    } else {
      SizeT Index = VMetadata->getLocalUseNode(Var)->getIndex();
      ++Nodes[Index].NumLocals;
    }
  }
  if (IsFullInit)
    NumGlobals = TmpNumGlobals;
  else
    assert(TmpNumGlobals == 0);

  // Resize each LivenessNode::LiveToVarMap, and the global LiveToVarMap. Reset
  // the counts to 0.
  for (auto I = FirstNode, E = Func->getNodes().end(); I != E; ++I) {
    LivenessNode &N = Nodes[(*I)->getIndex()];
    N.LiveToVarMap.assign(N.NumLocals, nullptr);
    N.NumLocals = 0;
    N.NumNonDeadPhis = 0;
  }
  if (IsFullInit)
    LiveToVarMap.assign(NumGlobals, nullptr);

  // Initialize the bitmask of which variables to track.
  RangeMask.resize(NumVars);
  RangeMask.set(0, NumVars); // Track all variables by default.

  // Sort each variable into the appropriate LiveToVarMap. Set VarToLiveMap.
  // Set RangeMask correctly for each variable.
  TmpNumGlobals = 0;
  for (auto I = FirstVar, E = Func->getVariables().end(); I != E; ++I) {
    Variable *Var = *I;
    SizeT VarIndex = Var->getIndex();
    SizeT LiveIndex;
    if (VMetadata->isMultiBlock(Var)) {
      LiveIndex = TmpNumGlobals++;
      LiveToVarMap[LiveIndex] = Var;
    } else {
      SizeT NodeIndex = VMetadata->getLocalUseNode(Var)->getIndex();
      LiveIndex = Nodes[NodeIndex].NumLocals++;
      Nodes[NodeIndex].LiveToVarMap[LiveIndex] = Var;
      LiveIndex += NumGlobals;
    }
    VarToLiveMap[VarIndex] = LiveIndex;
    if (Var->getIgnoreLiveness())
      RangeMask[VarIndex] = false;
  }
  assert(TmpNumGlobals == (IsFullInit ? NumGlobals : 0));

  // Fix up RangeMask for variables before FirstVar.
  for (auto I = Func->getVariables().begin(); I != FirstVar; ++I) {
    Variable *Var = *I;
    SizeT VarIndex = Var->getIndex();
    if (Var->getIgnoreLiveness() ||
        (!IsFullInit && !Var->hasReg() && !Var->mustHaveReg()))
      RangeMask[VarIndex] = false;
  }

  // Process each node.
  for (auto I = FirstNode, E = Func->getNodes().end(); I != E; ++I) {
    LivenessNode &Node = Nodes[(*I)->getIndex()];
    // NumLocals, LiveToVarMap already initialized
    Node.LiveIn.resize(NumGlobals);
    Node.LiveOut.resize(NumGlobals);
    // LiveBegin and LiveEnd are reinitialized before each pass over the block.
  }
}

void Liveness::init() {
  constexpr bool IsFullInit = true;
  NodeList::const_iterator FirstNode = Func->getNodes().begin();
  VarList::const_iterator FirstVar = Func->getVariables().begin();
  initInternal(FirstNode, FirstVar, IsFullInit);
}

void Liveness::initPhiEdgeSplits(NodeList::const_iterator FirstNode,
                                 VarList::const_iterator FirstVar) {
  constexpr bool IsFullInit = false;
  initInternal(FirstNode, FirstVar, IsFullInit);
}

Variable *Liveness::getVariable(SizeT LiveIndex, const CfgNode *Node) const {
  if (LiveIndex < NumGlobals)
    return LiveToVarMap[LiveIndex];
  SizeT NodeIndex = Node->getIndex();
  return Nodes[NodeIndex].LiveToVarMap[LiveIndex - NumGlobals];
}

} // end of namespace Ice
