//===- MipsRegisterBankInfo.h -----------------------------------*- 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
/// This file declares the targeting of the RegisterBankInfo class for Mips.
/// \todo This should be generated by TableGen.
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_MIPS_MIPSREGISTERBANKINFO_H
#define LLVM_LIB_TARGET_MIPS_MIPSREGISTERBANKINFO_H

#include "llvm/CodeGen/RegisterBankInfo.h"

#define GET_REGBANK_DECLARATIONS
#include "MipsGenRegisterBank.inc"

namespace llvm {

class TargetRegisterInfo;

class MipsGenRegisterBankInfo : public RegisterBankInfo {
#define GET_TARGET_REGBANK_CLASS
#include "MipsGenRegisterBank.inc"
};

/// This class provides the information for the target register banks.
class MipsRegisterBankInfo final : public MipsGenRegisterBankInfo {
public:
  MipsRegisterBankInfo(const TargetRegisterInfo &TRI);

  const RegisterBank &getRegBankFromRegClass(const TargetRegisterClass &RC,
                                             LLT) const override;

  const InstructionMapping &
  getInstrMapping(const MachineInstr &MI) const override;

  /// Here we have to narrowScalar s64 operands to s32, combine away G_MERGE or
  /// G_UNMERGE and erase instructions that became dead in the process. We
  /// manually assign bank to def operand of all new instructions that were
  /// created in the process since they will not end up in RegBankSelect loop.
  void applyMappingImpl(const OperandsMapper &OpdMapper) const override;

  /// RegBankSelect determined that s64 operand is better to be split into two
  /// s32 operands in gprb. Here we manually set register banks of def operands
  /// of newly created instructions since they will not get regbankselected.
  void setRegBank(MachineInstr &MI, MachineRegisterInfo &MRI) const;

private:
  /// Some instructions are used with both floating point and integer operands.
  /// We assign InstType to such instructions as it helps us to avoid cross bank
  /// copies. InstType deppends on context.
  enum InstType {
    /// Temporary type, when visit(..., nullptr) finishes will convert to one of
    /// the remaining types: Integer, FloatingPoint or Ambiguous.
    NotDetermined,
    /// Connected with instruction that interprets 'bags of bits' as integers.
    /// Select gprb to avoid cross bank copies.
    Integer,
    /// Connected with instruction that interprets 'bags of bits' as floating
    /// point numbers. Select fprb to avoid cross bank copies.
    FloatingPoint,
    /// Represents moving 'bags of bits' around. Select same bank for entire
    /// chain to avoid cross bank copies. Currently we select fprb for s64 and
    /// gprb for s32 Ambiguous operands.
    Ambiguous,
    /// Only used for s64. Unlike Ambiguous s64, AmbiguousWithMergeOrUnmerge s64
    /// is mapped to gprb (legalized using narrow scalar to s32).
    AmbiguousWithMergeOrUnmerge
  };

  bool isAmbiguous_64(InstType InstTy, unsigned OpSize) const {
    if (InstTy == InstType::Ambiguous && OpSize == 64)
      return true;
    return false;
  }

  bool isAmbiguous_32(InstType InstTy, unsigned OpSize) const {
    if (InstTy == InstType::Ambiguous && OpSize == 32)
      return true;
    return false;
  }

  bool isAmbiguous_32or64(InstType InstTy, unsigned OpSize) const {
    if (InstTy == InstType::Ambiguous && (OpSize == 32 || OpSize == 64))
      return true;
    return false;
  }

  bool isAmbiguousWithMergeOrUnmerge_64(InstType InstTy,
                                        unsigned OpSize) const {
    if (InstTy == InstType::AmbiguousWithMergeOrUnmerge && OpSize == 64)
      return true;
    return false;
  }

  bool isFloatingPoint_32or64(InstType InstTy, unsigned OpSize) const {
    if (InstTy == InstType::FloatingPoint && (OpSize == 32 || OpSize == 64))
      return true;
    return false;
  }

  bool isFloatingPoint_64(InstType InstTy, unsigned OpSize) const {
    if (InstTy == InstType::FloatingPoint && OpSize == 64)
      return true;
    return false;
  }

  bool isInteger_32(InstType InstTy, unsigned OpSize) const {
    if (InstTy == InstType::Integer && OpSize == 32)
      return true;
    return false;
  }

  /// Some generic instructions have operands that can be mapped to either fprb
  /// or gprb e.g. for G_LOAD we consider only operand 0 as ambiguous, operand 1
  /// is always gprb since it is a pointer.
  /// This class provides containers for MI's ambiguous:
  /// DefUses : MachineInstrs that use one of MI's ambiguous def operands.
  /// UseDefs : MachineInstrs that define MI's ambiguous use operands.
  class AmbiguousRegDefUseContainer {
    SmallVector<MachineInstr *, 2> DefUses;
    SmallVector<MachineInstr *, 2> UseDefs;

    void addDefUses(Register Reg, const MachineRegisterInfo &MRI);
    void addUseDef(Register Reg, const MachineRegisterInfo &MRI);

    /// Skip copy instructions until we get to a non-copy instruction or to a
    /// copy with phys register as def. Used during search for DefUses.
    /// MI :  %5 = COPY %4
    ///       %6 = COPY %5
    ///       $v0 = COPY %6 <- we want this one.
    MachineInstr *skipCopiesOutgoing(MachineInstr *MI) const;

    /// Skip copy instructions until we get to a non-copy instruction or to a
    /// copy with phys register as use. Used during search for UseDefs.
    ///       %1 = COPY $a1 <- we want this one.
    ///       %2 = COPY %1
    /// MI =  %3 = COPY %2
    MachineInstr *skipCopiesIncoming(MachineInstr *MI) const;

  public:
    AmbiguousRegDefUseContainer(const MachineInstr *MI);
    SmallVectorImpl<MachineInstr *> &getDefUses() { return DefUses; }
    SmallVectorImpl<MachineInstr *> &getUseDefs() { return UseDefs; }
  };

  class TypeInfoForMF {
    /// MachineFunction name is used to recognise when MF changes.
    std::string MFName;
    /// <key, value> : value is vector of all MachineInstrs that are waiting for
    /// key to figure out type of some of its ambiguous operands.
    DenseMap<const MachineInstr *, SmallVector<const MachineInstr *, 2>>
        WaitingQueues;
    /// Recorded InstTypes for visited instructions.
    DenseMap<const MachineInstr *, InstType> Types;

    /// Recursively visit MI's adjacent instructions and find MI's InstType.
    bool visit(const MachineInstr *MI, const MachineInstr *WaitingForTypeOfMI,
               InstType &AmbiguousTy);

    /// Visit MI's adjacent UseDefs or DefUses.
    bool visitAdjacentInstrs(const MachineInstr *MI,
                             SmallVectorImpl<MachineInstr *> &AdjacentInstrs,
                             bool isDefUse, InstType &AmbiguousTy);

    /// Set type for MI, and recursively for all instructions that are
    /// waiting for MI's type.
    void setTypes(const MachineInstr *MI, InstType ITy);

    /// InstType for MI is determined, set it to InstType that corresponds to
    /// physical regisiter that is operand number Op in CopyInst.
    void setTypesAccordingToPhysicalRegister(const MachineInstr *MI,
                                             const MachineInstr *CopyInst,
                                             unsigned Op);

    /// Set default values for MI in order to start visit.
    void startVisit(const MachineInstr *MI) {
      Types.try_emplace(MI, InstType::NotDetermined);
      WaitingQueues.try_emplace(MI);
    }

    /// Returns true if instruction was already visited. Type might not be
    /// determined at this point but will be when visit(..., nullptr) finishes.
    bool wasVisited(const MachineInstr *MI) const { return Types.count(MI); };

    /// Returns recorded type for instruction.
    const InstType &getRecordedTypeForInstr(const MachineInstr *MI) const {
      assert(wasVisited(MI) && "Instruction was not visited!");
      return Types.find(MI)->getSecond();
    };

    /// Change recorded type for instruction.
    void changeRecordedTypeForInstr(const MachineInstr *MI, InstType InstTy) {
      assert(wasVisited(MI) && "Instruction was not visited!");
      Types.find(MI)->getSecond() = InstTy;
    };

    /// Returns WaitingQueue for instruction.
    const SmallVectorImpl<const MachineInstr *> &
    getWaitingQueueFor(const MachineInstr *MI) const {
      assert(WaitingQueues.count(MI) && "Instruction was not visited!");
      return WaitingQueues.find(MI)->getSecond();
    };

    /// Add WaitingForMI to MI's WaitingQueue.
    void addToWaitingQueue(const MachineInstr *MI,
                           const MachineInstr *WaitingForMI) {
      assert(WaitingQueues.count(MI) && "Instruction was not visited!");
      WaitingQueues.find(MI)->getSecond().push_back(WaitingForMI);
    };

  public:
    InstType determineInstType(const MachineInstr *MI);

    void cleanupIfNewFunction(llvm::StringRef FunctionName);

    /// MI is about to get destroyed (using narrow scalar). Internal data is
    /// saved based on MI's address, clear it since it is no longer valid.
    void clearTypeInfoData(const MachineInstr *MI) {
      Types.erase(MI);
      WaitingQueues.erase(MI);
    };
  };
};
} // end namespace llvm
#endif
