//===-- SIRegisterInfo.h - SI Register Info Interface ----------*- 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
//
//===----------------------------------------------------------------------===//
//
/// \file
/// Interface definition for SIRegisterInfo
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_AMDGPU_SIREGISTERINFO_H
#define LLVM_LIB_TARGET_AMDGPU_SIREGISTERINFO_H

#define GET_REGINFO_HEADER
#include "AMDGPUGenRegisterInfo.inc"

#include "SIDefines.h"

namespace llvm {

class GCNSubtarget;
class LiveIntervals;
class LivePhysRegs;
class RegisterBank;
struct SGPRSpillBuilder;

class SIRegisterInfo final : public AMDGPUGenRegisterInfo {
private:
  const GCNSubtarget &ST;
  bool SpillSGPRToVGPR;
  bool isWave32;
  BitVector RegPressureIgnoredUnits;

  /// Sub reg indexes for getRegSplitParts.
  /// First index represents subreg size from 1 to 16 DWORDs.
  /// The inner vector is sorted by bit offset.
  /// Provided a register can be fully split with given subregs,
  /// all elements of the inner vector combined give a full lane mask.
  static std::array<std::vector<int16_t>, 16> RegSplitParts;

  // Table representing sub reg of given width and offset.
  // First index is subreg size: 32, 64, 96, 128, 160, 192, 224, 256, 512.
  // Second index is 32 different dword offsets.
  static std::array<std::array<uint16_t, 32>, 9> SubRegFromChannelTable;

  void reserveRegisterTuples(BitVector &, MCRegister Reg) const;

public:
  SIRegisterInfo(const GCNSubtarget &ST);

  /// \returns the sub reg enum value for the given \p Channel
  /// (e.g. getSubRegFromChannel(0) -> AMDGPU::sub0)
  static unsigned getSubRegFromChannel(unsigned Channel, unsigned NumRegs = 1);

  bool spillSGPRToVGPR() const {
    return SpillSGPRToVGPR;
  }

  /// Return the end register initially reserved for the scratch buffer in case
  /// spilling is needed.
  MCRegister reservedPrivateSegmentBufferReg(const MachineFunction &MF) const;

  BitVector getReservedRegs(const MachineFunction &MF) const override;

  const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;
  const MCPhysReg *getCalleeSavedRegsViaCopy(const MachineFunction *MF) const;
  const uint32_t *getCallPreservedMask(const MachineFunction &MF,
                                       CallingConv::ID) const override;
  const uint32_t *getNoPreservedMask() const override;

  // Stack access is very expensive. CSRs are also the high registers, and we
  // want to minimize the number of used registers.
  unsigned getCSRFirstUseCost() const override {
    return 100;
  }

  const TargetRegisterClass *
  getLargestLegalSuperClass(const TargetRegisterClass *RC,
                            const MachineFunction &MF) const override;

  Register getFrameRegister(const MachineFunction &MF) const override;

  bool hasBasePointer(const MachineFunction &MF) const;
  Register getBaseRegister() const;

  bool shouldRealignStack(const MachineFunction &MF) const override;
  bool requiresRegisterScavenging(const MachineFunction &Fn) const override;

  bool requiresFrameIndexScavenging(const MachineFunction &MF) const override;
  bool requiresFrameIndexReplacementScavenging(
    const MachineFunction &MF) const override;
  bool requiresVirtualBaseRegisters(const MachineFunction &Fn) const override;

  int64_t getScratchInstrOffset(const MachineInstr *MI) const;

  int64_t getFrameIndexInstrOffset(const MachineInstr *MI,
                                   int Idx) const override;

  bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override;

  Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx,
                                        int64_t Offset) const override;

  void resolveFrameIndex(MachineInstr &MI, Register BaseReg,
                         int64_t Offset) const override;

  bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg,
                          int64_t Offset) const override;

  const TargetRegisterClass *getPointerRegClass(
    const MachineFunction &MF, unsigned Kind = 0) const override;

  /// Returns a legal register class to copy a register in the specified class
  /// to or from. If it is possible to copy the register directly without using
  /// a cross register class copy, return the specified RC. Returns NULL if it
  /// is not possible to copy between two registers of the specified class.
  const TargetRegisterClass *
  getCrossCopyRegClass(const TargetRegisterClass *RC) const override;

  void buildVGPRSpillLoadStore(SGPRSpillBuilder &SB, int Index, int Offset,
                               bool IsLoad, bool IsKill = true) const;

  /// If \p OnlyToVGPR is true, this will only succeed if this
  bool spillSGPR(MachineBasicBlock::iterator MI,
                 int FI, RegScavenger *RS,
                 LiveIntervals *LIS = nullptr,
                 bool OnlyToVGPR = false) const;

  bool restoreSGPR(MachineBasicBlock::iterator MI,
                   int FI, RegScavenger *RS,
                   LiveIntervals *LIS = nullptr,
                   bool OnlyToVGPR = false) const;

  bool spillEmergencySGPR(MachineBasicBlock::iterator MI,
                          MachineBasicBlock &RestoreMBB, Register SGPR,
                          RegScavenger *RS) const;

  void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
                           unsigned FIOperandNum,
                           RegScavenger *RS) const override;

  bool eliminateSGPRToVGPRSpillFrameIndex(MachineBasicBlock::iterator MI,
                                          int FI, RegScavenger *RS,
                                          LiveIntervals *LIS = nullptr) const;

  StringRef getRegAsmName(MCRegister Reg) const override;

  // Pseudo regs are not allowed
  unsigned getHWRegIndex(MCRegister Reg) const {
    return getEncodingValue(Reg) & 0xff;
  }

  LLVM_READONLY
  const TargetRegisterClass *getVGPRClassForBitWidth(unsigned BitWidth) const;

  LLVM_READONLY
  const TargetRegisterClass *getAGPRClassForBitWidth(unsigned BitWidth) const;

  LLVM_READONLY
  const TargetRegisterClass *
  getVectorSuperClassForBitWidth(unsigned BitWidth) const;

  LLVM_READONLY
  static const TargetRegisterClass *getSGPRClassForBitWidth(unsigned BitWidth);

  /// Return the 'base' register class for this register.
  /// e.g. SGPR0 => SReg_32, VGPR => VGPR_32 SGPR0_SGPR1 -> SReg_32, etc.
  const TargetRegisterClass *getPhysRegClass(MCRegister Reg) const;

  /// \returns true if this class contains only SGPR registers
  static bool isSGPRClass(const TargetRegisterClass *RC) {
    return !hasVGPRs(RC) && !hasAGPRs(RC);
  }

  /// \returns true if this class ID contains only SGPR registers
  bool isSGPRClassID(unsigned RCID) const {
    return isSGPRClass(getRegClass(RCID));
  }

  bool isSGPRReg(const MachineRegisterInfo &MRI, Register Reg) const;

  /// \returns true if this class contains only VGPR registers
  static bool isVGPRClass(const TargetRegisterClass *RC) {
    return hasVGPRs(RC) && !hasAGPRs(RC);
  }

  /// \returns true if this class contains only AGPR registers
  static bool isAGPRClass(const TargetRegisterClass *RC) {
    return hasAGPRs(RC) && !hasVGPRs(RC);
  }

  /// \returns true only if this class contains both VGPR and AGPR registers
  bool isVectorSuperClass(const TargetRegisterClass *RC) const {
    return hasVGPRs(RC) && hasAGPRs(RC);
  }

  /// \returns true if this class contains VGPR registers.
  static bool hasVGPRs(const TargetRegisterClass *RC) {
    return RC->TSFlags & SIRCFlags::HasVGPR;
  }

  /// \returns true if this class contains AGPR registers.
  static bool hasAGPRs(const TargetRegisterClass *RC) {
    return RC->TSFlags & SIRCFlags::HasAGPR;
  }

  /// \returns true if this class contains any vector registers.
  static bool hasVectorRegisters(const TargetRegisterClass *RC) {
    return hasVGPRs(RC) || hasAGPRs(RC);
  }

  /// \returns A VGPR reg class with the same width as \p SRC
  const TargetRegisterClass *
  getEquivalentVGPRClass(const TargetRegisterClass *SRC) const;

  /// \returns An AGPR reg class with the same width as \p SRC
  const TargetRegisterClass *
  getEquivalentAGPRClass(const TargetRegisterClass *SRC) const;

  /// \returns A SGPR reg class with the same width as \p SRC
  const TargetRegisterClass *
  getEquivalentSGPRClass(const TargetRegisterClass *VRC) const;

  /// \returns The canonical register class that is used for a sub-register of
  /// \p RC for the given \p SubIdx.  If \p SubIdx equals NoSubRegister, \p RC
  /// will be returned.
  const TargetRegisterClass *getSubRegClass(const TargetRegisterClass *RC,
                                            unsigned SubIdx) const;

  /// Returns a register class which is compatible with \p SuperRC, such that a
  /// subregister exists with class \p SubRC with subregister index \p
  /// SubIdx. If this is impossible (e.g., an unaligned subregister index within
  /// a register tuple), return null.
  const TargetRegisterClass *
  getCompatibleSubRegClass(const TargetRegisterClass *SuperRC,
                           const TargetRegisterClass *SubRC,
                           unsigned SubIdx) const;

  bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC,
                            unsigned DefSubReg,
                            const TargetRegisterClass *SrcRC,
                            unsigned SrcSubReg) const override;

  /// \returns True if operands defined with this operand type can accept
  /// a literal constant (i.e. any 32-bit immediate).
  bool opCanUseLiteralConstant(unsigned OpType) const;

  /// \returns True if operands defined with this operand type can accept
  /// an inline constant. i.e. An integer value in the range (-16, 64) or
  /// -4.0f, -2.0f, -1.0f, -0.5f, 0.0f, 0.5f, 1.0f, 2.0f, 4.0f.
  bool opCanUseInlineConstant(unsigned OpType) const;

  MCRegister findUnusedRegister(const MachineRegisterInfo &MRI,
                                const TargetRegisterClass *RC,
                                const MachineFunction &MF,
                                bool ReserveHighestVGPR = false) const;

  const TargetRegisterClass *getRegClassForReg(const MachineRegisterInfo &MRI,
                                               Register Reg) const;
  bool isVGPR(const MachineRegisterInfo &MRI, Register Reg) const;
  bool isAGPR(const MachineRegisterInfo &MRI, Register Reg) const;
  bool isVectorRegister(const MachineRegisterInfo &MRI, Register Reg) const {
    return isVGPR(MRI, Reg) || isAGPR(MRI, Reg);
  }

  bool isConstantPhysReg(MCRegister PhysReg) const override;

  bool isDivergentRegClass(const TargetRegisterClass *RC) const override {
    return !isSGPRClass(RC);
  }

  ArrayRef<int16_t> getRegSplitParts(const TargetRegisterClass *RC,
                                     unsigned EltSize) const;

  bool shouldCoalesce(MachineInstr *MI,
                      const TargetRegisterClass *SrcRC,
                      unsigned SubReg,
                      const TargetRegisterClass *DstRC,
                      unsigned DstSubReg,
                      const TargetRegisterClass *NewRC,
                      LiveIntervals &LIS) const override;

  unsigned getRegPressureLimit(const TargetRegisterClass *RC,
                               MachineFunction &MF) const override;

  unsigned getRegPressureSetLimit(const MachineFunction &MF,
                                  unsigned Idx) const override;

  const int *getRegUnitPressureSets(unsigned RegUnit) const override;

  MCRegister getReturnAddressReg(const MachineFunction &MF) const;

  const TargetRegisterClass *
  getRegClassForSizeOnBank(unsigned Size,
                           const RegisterBank &Bank,
                           const MachineRegisterInfo &MRI) const;

  const TargetRegisterClass *
  getRegClassForTypeOnBank(LLT Ty,
                           const RegisterBank &Bank,
                           const MachineRegisterInfo &MRI) const {
    return getRegClassForSizeOnBank(Ty.getSizeInBits(), Bank, MRI);
  }

  const TargetRegisterClass *
  getConstrainedRegClassForOperand(const MachineOperand &MO,
                                 const MachineRegisterInfo &MRI) const override;

  const TargetRegisterClass *getBoolRC() const {
    return isWave32 ? &AMDGPU::SReg_32RegClass
                    : &AMDGPU::SReg_64RegClass;
  }

  const TargetRegisterClass *getWaveMaskRegClass() const {
    return isWave32 ? &AMDGPU::SReg_32_XM0_XEXECRegClass
                    : &AMDGPU::SReg_64_XEXECRegClass;
  }

  // Return the appropriate register class to use for 64-bit VGPRs for the
  // subtarget.
  const TargetRegisterClass *getVGPR64Class() const;

  MCRegister getVCC() const;

  const TargetRegisterClass *getRegClass(unsigned RCID) const;

  // Find reaching register definition
  MachineInstr *findReachingDef(Register Reg, unsigned SubReg,
                                MachineInstr &Use,
                                MachineRegisterInfo &MRI,
                                LiveIntervals *LIS) const;

  const uint32_t *getAllVGPRRegMask() const;
  const uint32_t *getAllAGPRRegMask() const;
  const uint32_t *getAllVectorRegMask() const;
  const uint32_t *getAllAllocatableSRegMask() const;

  // \returns number of 32 bit registers covered by a \p LM
  static unsigned getNumCoveredRegs(LaneBitmask LM) {
    // The assumption is that every lo16 subreg is an even bit and every hi16
    // is an adjacent odd bit or vice versa.
    uint64_t Mask = LM.getAsInteger();
    uint64_t Even = Mask & 0xAAAAAAAAAAAAAAAAULL;
    Mask = (Even >> 1) | Mask;
    uint64_t Odd = Mask & 0x5555555555555555ULL;
    return countPopulation(Odd);
  }

  // \returns a DWORD offset of a \p SubReg
  unsigned getChannelFromSubReg(unsigned SubReg) const {
    return SubReg ? (getSubRegIdxOffset(SubReg) + 31) / 32 : 0;
  }

  // \returns a DWORD size of a \p SubReg
  unsigned getNumChannelsFromSubReg(unsigned SubReg) const {
    return getNumCoveredRegs(getSubRegIndexLaneMask(SubReg));
  }

  // For a given 16 bit \p Reg \returns a 32 bit register holding it.
  // \returns \p Reg otherwise.
  MCPhysReg get32BitRegister(MCPhysReg Reg) const;

  // Returns true if a given register class is properly aligned for
  // the subtarget.
  bool isProperlyAlignedRC(const TargetRegisterClass &RC) const;

  /// Return all SGPR128 which satisfy the waves per execution unit requirement
  /// of the subtarget.
  ArrayRef<MCPhysReg> getAllSGPR128(const MachineFunction &MF) const;

  /// Return all SGPR64 which satisfy the waves per execution unit requirement
  /// of the subtarget.
  ArrayRef<MCPhysReg> getAllSGPR64(const MachineFunction &MF) const;

  /// Return all SGPR32 which satisfy the waves per execution unit requirement
  /// of the subtarget.
  ArrayRef<MCPhysReg> getAllSGPR32(const MachineFunction &MF) const;

  // Insert spill or restore instructions.
  // When lowering spill pseudos, the RegScavenger should be set.
  // For creating spill instructions during frame lowering, where no scavenger
  // is available, LiveRegs can be used.
  void buildSpillLoadStore(MachineBasicBlock &MBB,
                           MachineBasicBlock::iterator MI, const DebugLoc &DL,
                           unsigned LoadStoreOp, int Index, Register ValueReg,
                           bool ValueIsKill, MCRegister ScratchOffsetReg,
                           int64_t InstrOffset, MachineMemOperand *MMO,
                           RegScavenger *RS,
                           LivePhysRegs *LiveRegs = nullptr) const;
};

} // End namespace llvm

#endif
