// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_COMPILER_BACKEND_SPILL_PLACER_H_
#define V8_COMPILER_BACKEND_SPILL_PLACER_H_

#include "src/compiler/backend/instruction.h"

namespace v8 {
namespace internal {

namespace compiler {

class LiveRangeFinder;
class TopLevelLiveRange;
class TopTierRegisterAllocationData;

// SpillPlacer is an implementation of an algorithm to find optimal spill
// insertion positions, where optimal is defined as:
//
// 1. Spills needed by deferred code don't affect non-deferred code.
// 2. No control-flow path spills the same value more than once in non-deferred
//    blocks.
// 3. Where possible based on #2, control-flow paths through non-deferred code
//    that don't need the value to be on the stack don't execute any spills.
// 4. The fewest number of spill instructions is written to meet these rules.
// 5. Spill instructions are placed as early as possible.
//
// These rules are an attempt to make code paths that don't need to spill faster
// while not increasing code size too much.
//
// Considering just one value at a time for now, the steps are:
//
// 1. If the value is defined in a deferred block, or needs its value to be on
//    the stack during the definition block, emit a move right after the
//    definition and exit.
// 2. Build an array representing the state at each block, where the state can
//    be any of the following:
//    - unmarked (default/initial state)
//    - definition
//    - spill required
//    - spill required in non-deferred successor
//    - spill required in deferred successor
// 3. Mark the block containing the definition.
// 4. Mark as "spill required" all blocks that contain any part of a spilled
//    LiveRange, or any use that requires the value to be on the stack.
// 5. Walk the block list backward, setting the "spill required in successor"
//    values where appropriate. If both deferred and non-deferred successors
//    require a spill, then the result should be "spill required in non-deferred
//    successor".
// 6. Walk the block list forward, updating marked blocks to "spill required" if
//    all of their predecessors agree that a spill is required. Furthermore, if
//    a block is marked as "spill required in non-deferred successor" and any
//    non-deferred predecessor is marked as "spill required", then the current
//    block is updated to "spill required". We must mark these merge points as
//    "spill required" to obey rule #2 above: if we didn't, then there would
//    exist a control-flow path through two different spilled regions.
// 7. Walk the block list backward again, updating blocks to "spill required" if
//    all of their successors agree that a spill is required, or if the current
//    block is deferred and any of its successors require spills. If only some
//    successors of a non-deferred block require spills, then insert spill moves
//    at the beginning of those successors. If we manage to smear the "spill
//    required" value all the way to the definition block, then insert a spill
//    move at the definition instead. (Spilling at the definition implies that
//    we didn't emit any other spill moves, and there is a DCHECK mechanism to
//    ensure that invariant.)
//
// Loop back-edges can be safely ignored in every step. Anything that the loop
// header needs on-stack will be spilled either in the loop header itself or
// sometime before entering the loop, so its back-edge predecessors don't need
// to contain any data about the loop header.
//
// The operations described in those steps are simple Boolean logic, so we can
// easily process a batch of values at the same time as an optimization.
class SpillPlacer {
 public:
  SpillPlacer(LiveRangeFinder* finder, TopTierRegisterAllocationData* data,
              Zone* zone);

  ~SpillPlacer();

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

  // Adds the given TopLevelLiveRange to the SpillPlacer's state. Will
  // eventually commit spill moves for that range and mark the range to indicate
  // whether its value is spilled at the definition or some later point, so that
  // subsequent phases can know whether to assume the value is always on-stack.
  // However, those steps may happen during a later call to Add or during the
  // destructor.
  void Add(TopLevelLiveRange* range);

 private:
  TopTierRegisterAllocationData* data() const { return data_; }

  // While initializing data for a range, returns the index within each Entry
  // where data about that range should be stored. May cause data about previous
  // ranges to be committed to make room if the table is full.
  int GetOrCreateIndexForLatestVreg(int vreg);

  bool IsLatestVreg(int vreg) const {
    return assigned_indices_ > 0 &&
           vreg_numbers_[assigned_indices_ - 1] == vreg;
  }

  // Processes all of the ranges which have been added, inserts spill moves for
  // them to the instruction sequence, and marks the ranges with whether they
  // are spilled at the definition or later.
  void CommitSpills();

  void ClearData();

  // Updates the iteration bounds first_block_ and last_block_ so that they
  // include the new value.
  void ExpandBoundsToInclude(RpoNumber block);

  void SetSpillRequired(InstructionBlock* block, int vreg,
                        RpoNumber top_start_block);

  void SetDefinition(RpoNumber block, int vreg);

  // The first backward pass is responsible for marking blocks which do not
  // themselves need the value to be on the stack, but which do have successors
  // requiring the value to be on the stack.
  void FirstBackwardPass();

  // The forward pass is responsible for selecting merge points that should
  // require the value to be on the stack.
  void ForwardPass();

  // The second backward pass is responsible for propagating the spill
  // requirements to the earliest block where all successors can agree a spill
  // is required. It also emits the actual spill instructions.
  void SecondBackwardPass();

  void CommitSpill(int vreg, InstructionBlock* predecessor,
                   InstructionBlock* successor);

  // Each Entry represents the state for 64 values at a block, so that we can
  // compute a batch of values in parallel.
  class Entry;
  static constexpr int kValueIndicesPerEntry = 64;

  // Objects provided to the constructor, which all outlive this SpillPlacer.
  LiveRangeFinder* finder_;
  TopTierRegisterAllocationData* data_;
  Zone* zone_;

  // An array of one Entry per block, where blocks are in reverse post-order.
  Entry* entries_ = nullptr;

  // An array representing which TopLevelLiveRange is in each bit.
  int* vreg_numbers_ = nullptr;

  // The number of vreg_numbers_ that have been assigned.
  int assigned_indices_ = 0;

  // The first and last block that have any definitions or uses in the current
  // batch of values. In large functions, tracking these bounds can help prevent
  // additional work.
  RpoNumber first_block_ = RpoNumber::Invalid();
  RpoNumber last_block_ = RpoNumber::Invalid();
};

}  // namespace compiler
}  // namespace internal
}  // namespace v8

#endif  // V8_COMPILER_BACKEND_SPILL_PLACER_H_
