//===- SpillPlacement.h - Optimal Spill Code Placement ---------*- 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 analysis computes the optimal spill code placement between basic blocks.
//
// The runOnMachineFunction() method only precomputes some profiling information
// about the CFG. The real work is done by prepare(), addConstraints(), and
// finish() which are called by the register allocator.
//
// Given a variable that is live across multiple basic blocks, and given
// constraints on the basic blocks where the variable is live, determine which
// edge bundles should have the variable in a register and which edge bundles
// should have the variable in a stack slot.
//
// The returned bit vector can be used to place optimal spill code at basic
// block entries and exits. Spill code placement inside a basic block is not
// considered.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_CODEGEN_SPILLPLACEMENT_H
#define LLVM_LIB_CODEGEN_SPILLPLACEMENT_H

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SparseSet.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/Support/BlockFrequency.h"

namespace llvm {

class BitVector;
class EdgeBundles;
class MachineBlockFrequencyInfo;
class MachineFunction;
class MachineLoopInfo;

class SpillPlacement : public MachineFunctionPass {
  struct Node;
  const MachineFunction *MF = nullptr;
  const EdgeBundles *bundles = nullptr;
  const MachineLoopInfo *loops = nullptr;
  const MachineBlockFrequencyInfo *MBFI = nullptr;
  Node *nodes = nullptr;

  // Nodes that are active in the current computation. Owned by the prepare()
  // caller.
  BitVector *ActiveNodes = nullptr;

  // Nodes with active links. Populated by scanActiveBundles.
  SmallVector<unsigned, 8> Linked;

  // Nodes that went positive during the last call to scanActiveBundles or
  // iterate.
  SmallVector<unsigned, 8> RecentPositive;

  // Block frequencies are computed once. Indexed by block number.
  SmallVector<BlockFrequency, 8> BlockFrequencies;

  /// Decision threshold. A node gets the output value 0 if the weighted sum of
  /// its inputs falls in the open interval (-Threshold;Threshold).
  BlockFrequency Threshold;

  /// List of nodes that need to be updated in ::iterate.
  SparseSet<unsigned> TodoList;

public:
  static char ID; // Pass identification, replacement for typeid.

  SpillPlacement() : MachineFunctionPass(ID) {}
  ~SpillPlacement() override { releaseMemory(); }

  /// BorderConstraint - A basic block has separate constraints for entry and
  /// exit.
  enum BorderConstraint {
    DontCare,  ///< Block doesn't care / variable not live.
    PrefReg,   ///< Block entry/exit prefers a register.
    PrefSpill, ///< Block entry/exit prefers a stack slot.
    PrefBoth,  ///< Block entry prefers both register and stack.
    MustSpill  ///< A register is impossible, variable must be spilled.
  };

  /// BlockConstraint - Entry and exit constraints for a basic block.
  struct BlockConstraint {
    unsigned Number;            ///< Basic block number (from MBB::getNumber()).
    BorderConstraint Entry : 8; ///< Constraint on block entry.
    BorderConstraint Exit : 8;  ///< Constraint on block exit.

    /// True when this block changes the value of the live range. This means
    /// the block has a non-PHI def.  When this is false, a live-in value on
    /// the stack can be live-out on the stack without inserting a spill.
    bool ChangesValue;

    void print(raw_ostream &OS) const;
    void dump() const;
  };

  /// prepare - Reset state and prepare for a new spill placement computation.
  /// @param RegBundles Bit vector to receive the edge bundles where the
  ///                   variable should be kept in a register. Each bit
  ///                   corresponds to an edge bundle, a set bit means the
  ///                   variable should be kept in a register through the
  ///                   bundle. A clear bit means the variable should be
  ///                   spilled. This vector is retained.
  void prepare(BitVector &RegBundles);

  /// addConstraints - Add constraints and biases. This method may be called
  /// more than once to accumulate constraints.
  /// @param LiveBlocks Constraints for blocks that have the variable live in or
  ///                   live out.
  void addConstraints(ArrayRef<BlockConstraint> LiveBlocks);

  /// addPrefSpill - Add PrefSpill constraints to all blocks listed.  This is
  /// equivalent to calling addConstraint with identical BlockConstraints with
  /// Entry = Exit = PrefSpill, and ChangesValue = false.
  ///
  /// @param Blocks Array of block numbers that prefer to spill in and out.
  /// @param Strong When true, double the negative bias for these blocks.
  void addPrefSpill(ArrayRef<unsigned> Blocks, bool Strong);

  /// addLinks - Add transparent blocks with the given numbers.
  void addLinks(ArrayRef<unsigned> Links);

  /// scanActiveBundles - Perform an initial scan of all bundles activated by
  /// addConstraints and addLinks, updating their state. Add all the bundles
  /// that now prefer a register to RecentPositive.
  /// Prepare internal data structures for iterate.
  /// Return true is there are any positive nodes.
  bool scanActiveBundles();

  /// iterate - Update the network iteratively until convergence, or new bundles
  /// are found.
  void iterate();

  /// getRecentPositive - Return an array of bundles that became positive during
  /// the previous call to scanActiveBundles or iterate.
  ArrayRef<unsigned> getRecentPositive() { return RecentPositive; }

  /// finish - Compute the optimal spill code placement given the
  /// constraints. No MustSpill constraints will be violated, and the smallest
  /// possible number of PrefX constraints will be violated, weighted by
  /// expected execution frequencies.
  /// The selected bundles are returned in the bitvector passed to prepare().
  /// @return True if a perfect solution was found, allowing the variable to be
  ///         in a register through all relevant bundles.
  bool finish();

  /// getBlockFrequency - Return the estimated block execution frequency per
  /// function invocation.
  BlockFrequency getBlockFrequency(unsigned Number) const {
    return BlockFrequencies[Number];
  }

private:
  bool runOnMachineFunction(MachineFunction &mf) override;
  void getAnalysisUsage(AnalysisUsage &AU) const override;
  void releaseMemory() override;

  void activate(unsigned n);
  void setThreshold(const BlockFrequency &Entry);

  bool update(unsigned n);
};

} // end namespace llvm

#endif // LLVM_LIB_CODEGEN_SPILLPLACEMENT_H
