//===-- llvm/CodeGen/AllocationOrder.h - Allocation Order -*- 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 file implements an allocation order for virtual registers.
//
// The preferred allocation order for a virtual register depends on allocation
// hints and target hooks. The AllocationOrder class encapsulates all of that.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_CODEGEN_ALLOCATIONORDER_H
#define LLVM_LIB_CODEGEN_ALLOCATIONORDER_H

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/Register.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"

namespace llvm {

class RegisterClassInfo;
class VirtRegMap;
class LiveRegMatrix;

class LLVM_LIBRARY_VISIBILITY AllocationOrder {
  // Used as storage for both Hints and CustomOrder if the Order received in the
  // constructor needs to be altered. [0, NumHints) contains regular hints. If a
  // custom order is present, [NumHints, end) contains the custom order.
  const SmallVector<MCPhysReg, 16> HintsAndCustomOrder;
  const int NumHints;
  ArrayRef<MCPhysReg> Order;
  // How far into the Order we can iterate. This is 0 if the AllocationOrder is
  // constructed with HardHints = true, Order.size() otherwise. While
  // technically a size_t, it will participate in comparisons with the
  // Iterator's Pos, which must be signed, so it's typed here as signed, too, to
  // avoid warnings and under the assumption that the size of Order is
  // relatively small.
  // IterationLimit defines an invalid iterator position.
  const int IterationLimit;

  ArrayRef<MCPhysReg> hints() const {
    return ArrayRef<MCPhysReg>(HintsAndCustomOrder).take_front(NumHints);
  }

public:
  /// Forward iterator for an AllocationOrder.
  class Iterator final {
    const AllocationOrder &AO;
    int Pos = 0;

  public:
    Iterator(const AllocationOrder &AO, int Pos) : AO(AO), Pos(Pos) {}

    /// Return true if the current position is that of a preferred register.
    bool isHint() const { return Pos < 0; }

    /// Return the next physical register in the allocation order.
    MCRegister operator*() const {
      if (Pos < 0)
        return AO.HintsAndCustomOrder[AO.NumHints + Pos];
      assert(Pos < AO.IterationLimit);
      return AO.Order[Pos];
    }

    /// Advance the iterator to the next position. If that's past the Hints
    /// list, advance to the first value that's not also in the Hints list.
    Iterator &operator++() {
      if (Pos < AO.IterationLimit)
        ++Pos;
      while (Pos >= 0 && Pos < AO.IterationLimit && AO.isHint(AO.Order[Pos]))
        ++Pos;
      return *this;
    }

    bool operator==(const Iterator &Other) const {
      assert(&AO == &Other.AO);
      return Pos == Other.Pos;
    }

    bool operator!=(const Iterator &Other) const { return !(*this == Other); }
  };

  /// Create a new AllocationOrder for VirtReg.
  /// @param VirtReg      Virtual register to allocate for.
  /// @param VRM          Virtual register map for function.
  /// @param RegClassInfo Information about reserved and allocatable registers.
  static AllocationOrder create(Register VirtReg, const VirtRegMap &VRM,
                                const RegisterClassInfo &RegClassInfo,
                                const LiveRegMatrix *Matrix);

  /// Create an AllocationOrder from HintsAndCustomOrder that contains NumHints
  /// Hints optionally followed by a custom order. When that custom order is
  /// present it becomes the allocation order otherwise Order is used as-is.
  AllocationOrder(SmallVector<MCPhysReg, 16> &&HintsAndCustomOrder,
                  int NumHints, ArrayRef<MCPhysReg> Order, bool HardHints)
      : HintsAndCustomOrder(std::move(HintsAndCustomOrder)), NumHints(NumHints),
        Order(static_cast<int>(this->HintsAndCustomOrder.size()) > NumHints
                  ? ArrayRef<MCPhysReg>(this->HintsAndCustomOrder)
                        .drop_front(NumHints)
                  : Order),
        IterationLimit(HardHints ? 0 : static_cast<int>(this->Order.size())) {}

  /// Create an AllocationOrder given the Hints, Order, and HardHints values.
  /// Use the create method above - the ctor is for unittests.
  AllocationOrder(SmallVector<MCPhysReg, 16> &&Hints, ArrayRef<MCPhysReg> Order,
                  bool HardHints)
      : AllocationOrder(std::move(Hints), static_cast<int>(Hints.size()), Order,
                        HardHints) {}

  Iterator begin() const { return Iterator(*this, -NumHints); }

  Iterator end() const { return Iterator(*this, IterationLimit); }

  Iterator getOrderLimitEnd(unsigned OrderLimit) const {
    assert(OrderLimit <= Order.size());
    if (OrderLimit == 0)
      return end();
    Iterator Ret(*this,
                 std::min(static_cast<int>(OrderLimit) - 1, IterationLimit));
    return ++Ret;
  }

  /// Get the allocation order without reordered hints.
  ArrayRef<MCPhysReg> getOrder() const { return Order; }

  /// Return true if a custom order replaced the RegisterClassInfo order.
  bool hasCustomOrder() const {
    return static_cast<int>(HintsAndCustomOrder.size()) > NumHints;
  }

  /// Return true if Reg is a preferred physical register.
  bool isHint(Register Reg) const {
    assert(!Reg.isPhysical() ||
           Reg.id() <
               static_cast<uint32_t>(std::numeric_limits<MCPhysReg>::max()));
    return Reg.isPhysical() && is_contained(hints(), Reg.id());
  }
};

} // end namespace llvm

#endif
