//===- ARMLatencyMutations.cpp - ARM Latency Mutations --------------------===//
//
// 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 contains the ARM definition DAG scheduling mutations which
/// change inter-instruction latencies
//
//===----------------------------------------------------------------------===//

#include "ARMLatencyMutations.h"
#include "ARMSubtarget.h"
#include "Thumb2InstrInfo.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/ScheduleDAG.h"
#include "llvm/CodeGen/ScheduleDAGMutation.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include <algorithm>
#include <array>
#include <initializer_list>
#include <memory>

namespace llvm {

namespace {

// Precompute information about opcodes to speed up pass

class InstructionInformation {
protected:
  struct IInfo {
    bool HasBRegAddr : 1;      // B-side of addr gen is a register
    bool HasBRegAddrShift : 1; // B-side of addr gen has a shift
    bool IsDivide : 1;         // Some form of integer divide
    bool IsInlineShiftALU : 1; // Inline shift+ALU
    bool IsMultiply : 1;       // Some form of integer multiply
    bool IsMVEIntMAC : 1;      // MVE 8/16/32-bit integer MAC operation
    bool IsNonSubwordLoad : 1; // Load which is a word or larger
    bool IsShift : 1;          // Shift operation
    bool IsRev : 1;            // REV operation
    bool ProducesQP : 1;       // Produces a vector register result
    bool ProducesDP : 1;       // Produces a double-precision register result
    bool ProducesSP : 1;       // Produces a single-precision register result
    bool ConsumesQP : 1;       // Consumes a vector register result
    bool ConsumesDP : 1;       // Consumes a double-precision register result
    bool ConsumesSP : 1;       // Consumes a single-precision register result
    unsigned MVEIntMACMatched; // Matched operand type (for MVE)
    unsigned AddressOpMask;    // Mask indicating which operands go into AGU
    IInfo()
        : HasBRegAddr(false), HasBRegAddrShift(false), IsDivide(false),
          IsInlineShiftALU(false), IsMultiply(false), IsMVEIntMAC(false),
          IsNonSubwordLoad(false), IsShift(false), IsRev(false),
          ProducesQP(false), ProducesDP(false), ProducesSP(false),
          ConsumesQP(false), ConsumesDP(false), ConsumesSP(false),
          MVEIntMACMatched(0), AddressOpMask(0) {}
  };
  typedef std::array<IInfo, ARM::INSTRUCTION_LIST_END> IInfoArray;
  IInfoArray Info;

public:
  // Always available information
  unsigned getAddressOpMask(unsigned Op) { return Info[Op].AddressOpMask; }
  bool hasBRegAddr(unsigned Op) { return Info[Op].HasBRegAddr; }
  bool hasBRegAddrShift(unsigned Op) { return Info[Op].HasBRegAddrShift; }
  bool isDivide(unsigned Op) { return Info[Op].IsDivide; }
  bool isInlineShiftALU(unsigned Op) { return Info[Op].IsInlineShiftALU; }
  bool isMultiply(unsigned Op) { return Info[Op].IsMultiply; }
  bool isMVEIntMAC(unsigned Op) { return Info[Op].IsMVEIntMAC; }
  bool isNonSubwordLoad(unsigned Op) { return Info[Op].IsNonSubwordLoad; }
  bool isRev(unsigned Op) { return Info[Op].IsRev; }
  bool isShift(unsigned Op) { return Info[Op].IsShift; }

  // information available if markDPConsumers is called.
  bool producesQP(unsigned Op) { return Info[Op].ProducesQP; }
  bool producesDP(unsigned Op) { return Info[Op].ProducesDP; }
  bool producesSP(unsigned Op) { return Info[Op].ProducesSP; }
  bool consumesQP(unsigned Op) { return Info[Op].ConsumesQP; }
  bool consumesDP(unsigned Op) { return Info[Op].ConsumesDP; }
  bool consumesSP(unsigned Op) { return Info[Op].ConsumesSP; }

  bool isMVEIntMACMatched(unsigned SrcOp, unsigned DstOp) {
    return SrcOp == DstOp || Info[DstOp].MVEIntMACMatched == SrcOp;
  }

  InstructionInformation(const ARMBaseInstrInfo *TII);

protected:
  void markDPProducersConsumers(const ARMBaseInstrInfo *TII);
};

InstructionInformation::InstructionInformation(const ARMBaseInstrInfo *TII) {
  using namespace ARM;

  std::initializer_list<unsigned> hasBRegAddrList = {
      t2LDRs, t2LDRBs, t2LDRHs, t2STRs, t2STRBs, t2STRHs,
      tLDRr,  tLDRBr,  tLDRHr,  tSTRr,  tSTRBr,  tSTRHr,
  };
  for (auto op : hasBRegAddrList) {
    Info[op].HasBRegAddr = true;
  }

  std::initializer_list<unsigned> hasBRegAddrShiftList = {
      t2LDRs, t2LDRBs, t2LDRHs, t2STRs, t2STRBs, t2STRHs,
  };
  for (auto op : hasBRegAddrShiftList) {
    Info[op].HasBRegAddrShift = true;
  }

  Info[t2SDIV].IsDivide = Info[t2UDIV].IsDivide = true;

  std::initializer_list<unsigned> isInlineShiftALUList = {
      t2ADCrs, t2ADDSrs, t2ADDrs,  t2BICrs, t2EORrs, t2ORNrs, t2RSBSrs, t2RSBrs,
      t2SBCrs, t2SUBrs,  t2SUBSrs, t2CMPrs, t2CMNrs, t2TEQrs, t2TSTrs,
  };
  for (auto op : isInlineShiftALUList) {
    Info[op].IsInlineShiftALU = true;
  }

  Info[t2SDIV].IsDivide = Info[t2UDIV].IsDivide = true;

  std::initializer_list<unsigned> isMultiplyList = {
      t2MUL,    t2MLA,     t2MLS,     t2SMLABB, t2SMLABT,  t2SMLAD,   t2SMLADX,
      t2SMLAL,  t2SMLALBB, t2SMLALBT, t2SMLALD, t2SMLALDX, t2SMLALTB, t2SMLALTT,
      t2SMLATB, t2SMLATT,  t2SMLAWT,  t2SMLSD,  t2SMLSDX,  t2SMLSLD,  t2SMLSLDX,
      t2SMMLA,  t2SMMLAR,  t2SMMLS,   t2SMMLSR, t2SMMUL,   t2SMMULR,  t2SMUAD,
      t2SMUADX, t2SMULBB,  t2SMULBT,  t2SMULL,  t2SMULTB,  t2SMULTT,  t2SMULWT,
      t2SMUSD,  t2SMUSDX,  t2UMAAL,   t2UMLAL,  t2UMULL,   tMUL,
  };
  for (auto op : isMultiplyList) {
    Info[op].IsMultiply = true;
  }

  std::initializer_list<unsigned> isMVEIntMACList = {
      MVE_VMLAS_qr_i16,    MVE_VMLAS_qr_i32,    MVE_VMLAS_qr_i8,
      MVE_VMLA_qr_i16,     MVE_VMLA_qr_i32,     MVE_VMLA_qr_i8,
      MVE_VQDMLAH_qrs16,   MVE_VQDMLAH_qrs32,   MVE_VQDMLAH_qrs8,
      MVE_VQDMLASH_qrs16,  MVE_VQDMLASH_qrs32,  MVE_VQDMLASH_qrs8,
      MVE_VQRDMLAH_qrs16,  MVE_VQRDMLAH_qrs32,  MVE_VQRDMLAH_qrs8,
      MVE_VQRDMLASH_qrs16, MVE_VQRDMLASH_qrs32, MVE_VQRDMLASH_qrs8,
      MVE_VQDMLADHXs16,    MVE_VQDMLADHXs32,    MVE_VQDMLADHXs8,
      MVE_VQDMLADHs16,     MVE_VQDMLADHs32,     MVE_VQDMLADHs8,
      MVE_VQDMLSDHXs16,    MVE_VQDMLSDHXs32,    MVE_VQDMLSDHXs8,
      MVE_VQDMLSDHs16,     MVE_VQDMLSDHs32,     MVE_VQDMLSDHs8,
      MVE_VQRDMLADHXs16,   MVE_VQRDMLADHXs32,   MVE_VQRDMLADHXs8,
      MVE_VQRDMLADHs16,    MVE_VQRDMLADHs32,    MVE_VQRDMLADHs8,
      MVE_VQRDMLSDHXs16,   MVE_VQRDMLSDHXs32,   MVE_VQRDMLSDHXs8,
      MVE_VQRDMLSDHs16,    MVE_VQRDMLSDHs32,    MVE_VQRDMLSDHs8,
  };
  for (auto op : isMVEIntMACList) {
    Info[op].IsMVEIntMAC = true;
  }

  std::initializer_list<unsigned> isNonSubwordLoadList = {
      t2LDRi12, t2LDRi8,  t2LDR_POST,  t2LDR_PRE,  t2LDRpci,
      t2LDRs,   t2LDRDi8, t2LDRD_POST, t2LDRD_PRE, tLDRi,
      tLDRpci,  tLDRr,    tLDRspi,
  };
  for (auto op : isNonSubwordLoadList) {
    Info[op].IsNonSubwordLoad = true;
  }

  std::initializer_list<unsigned> isRevList = {
      t2REV, t2REV16, t2REVSH, t2RBIT, tREV, tREV16, tREVSH,
  };
  for (auto op : isRevList) {
    Info[op].IsRev = true;
  }

  std::initializer_list<unsigned> isShiftList = {
      t2ASRri, t2ASRrr, t2LSLri, t2LSLrr, t2LSRri, t2LSRrr, t2RORri, t2RORrr,
      tASRri,  tASRrr,  tLSLSri, tLSLri,  tLSLrr,  tLSRri,  tLSRrr,  tROR,
  };
  for (auto op : isShiftList) {
    Info[op].IsShift = true;
  }

  std::initializer_list<unsigned> Address1List = {
      t2LDRBi12,
      t2LDRBi8,
      t2LDRBpci,
      t2LDRBs,
      t2LDRHi12,
      t2LDRHi8,
      t2LDRHpci,
      t2LDRHs,
      t2LDRSBi12,
      t2LDRSBi8,
      t2LDRSBpci,
      t2LDRSBs,
      t2LDRSHi12,
      t2LDRSHi8,
      t2LDRSHpci,
      t2LDRSHs,
      t2LDRi12,
      t2LDRi8,
      t2LDRpci,
      t2LDRs,
      tLDRBi,
      tLDRBr,
      tLDRHi,
      tLDRHr,
      tLDRSB,
      tLDRSH,
      tLDRi,
      tLDRpci,
      tLDRr,
      tLDRspi,
      t2STRBi12,
      t2STRBi8,
      t2STRBs,
      t2STRHi12,
      t2STRHi8,
      t2STRHs,
      t2STRi12,
      t2STRi8,
      t2STRs,
      tSTRBi,
      tSTRBr,
      tSTRHi,
      tSTRHr,
      tSTRi,
      tSTRr,
      tSTRspi,
      VLDRD,
      VLDRH,
      VLDRS,
      VSTRD,
      VSTRH,
      VSTRS,
      MVE_VLD20_16,
      MVE_VLD20_32,
      MVE_VLD20_8,
      MVE_VLD21_16,
      MVE_VLD21_32,
      MVE_VLD21_8,
      MVE_VLD40_16,
      MVE_VLD40_32,
      MVE_VLD40_8,
      MVE_VLD41_16,
      MVE_VLD41_32,
      MVE_VLD41_8,
      MVE_VLD42_16,
      MVE_VLD42_32,
      MVE_VLD42_8,
      MVE_VLD43_16,
      MVE_VLD43_32,
      MVE_VLD43_8,
      MVE_VLDRBS16,
      MVE_VLDRBS16_rq,
      MVE_VLDRBS32,
      MVE_VLDRBS32_rq,
      MVE_VLDRBU16,
      MVE_VLDRBU16_rq,
      MVE_VLDRBU32,
      MVE_VLDRBU32_rq,
      MVE_VLDRBU8,
      MVE_VLDRBU8_rq,
      MVE_VLDRDU64_qi,
      MVE_VLDRDU64_rq,
      MVE_VLDRDU64_rq_u,
      MVE_VLDRHS32,
      MVE_VLDRHS32_rq,
      MVE_VLDRHS32_rq_u,
      MVE_VLDRHU16,
      MVE_VLDRHU16_rq,
      MVE_VLDRHU16_rq_u,
      MVE_VLDRHU32,
      MVE_VLDRHU32_rq,
      MVE_VLDRHU32_rq_u,
      MVE_VLDRWU32,
      MVE_VLDRWU32_qi,
      MVE_VLDRWU32_rq,
      MVE_VLDRWU32_rq_u,
      MVE_VST20_16,
      MVE_VST20_32,
      MVE_VST20_8,
      MVE_VST21_16,
      MVE_VST21_32,
      MVE_VST21_8,
      MVE_VST40_16,
      MVE_VST40_32,
      MVE_VST40_8,
      MVE_VST41_16,
      MVE_VST41_32,
      MVE_VST41_8,
      MVE_VST42_16,
      MVE_VST42_32,
      MVE_VST42_8,
      MVE_VST43_16,
      MVE_VST43_32,
      MVE_VST43_8,
      MVE_VSTRB16,
      MVE_VSTRB16_rq,
      MVE_VSTRB32,
      MVE_VSTRB32_rq,
      MVE_VSTRBU8,
      MVE_VSTRB8_rq,
      MVE_VSTRD64_qi,
      MVE_VSTRD64_rq,
      MVE_VSTRD64_rq_u,
      MVE_VSTRH32,
      MVE_VSTRH32_rq,
      MVE_VSTRH32_rq_u,
      MVE_VSTRHU16,
      MVE_VSTRH16_rq,
      MVE_VSTRH16_rq_u,
      MVE_VSTRWU32,
      MVE_VSTRW32_qi,
      MVE_VSTRW32_rq,
      MVE_VSTRW32_rq_u,
  };
  std::initializer_list<unsigned> Address2List = {
      t2LDRB_POST,
      t2LDRB_PRE,
      t2LDRDi8,
      t2LDRH_POST,
      t2LDRH_PRE,
      t2LDRSB_POST,
      t2LDRSB_PRE,
      t2LDRSH_POST,
      t2LDRSH_PRE,
      t2LDR_POST,
      t2LDR_PRE,
      t2STRB_POST,
      t2STRB_PRE,
      t2STRDi8,
      t2STRH_POST,
      t2STRH_PRE,
      t2STR_POST,
      t2STR_PRE,
      MVE_VLD20_16_wb,
      MVE_VLD20_32_wb,
      MVE_VLD20_8_wb,
      MVE_VLD21_16_wb,
      MVE_VLD21_32_wb,
      MVE_VLD21_8_wb,
      MVE_VLD40_16_wb,
      MVE_VLD40_32_wb,
      MVE_VLD40_8_wb,
      MVE_VLD41_16_wb,
      MVE_VLD41_32_wb,
      MVE_VLD41_8_wb,
      MVE_VLD42_16_wb,
      MVE_VLD42_32_wb,
      MVE_VLD42_8_wb,
      MVE_VLD43_16_wb,
      MVE_VLD43_32_wb,
      MVE_VLD43_8_wb,
      MVE_VLDRBS16_post,
      MVE_VLDRBS16_pre,
      MVE_VLDRBS32_post,
      MVE_VLDRBS32_pre,
      MVE_VLDRBU16_post,
      MVE_VLDRBU16_pre,
      MVE_VLDRBU32_post,
      MVE_VLDRBU32_pre,
      MVE_VLDRBU8_post,
      MVE_VLDRBU8_pre,
      MVE_VLDRDU64_qi_pre,
      MVE_VLDRHS32_post,
      MVE_VLDRHS32_pre,
      MVE_VLDRHU16_post,
      MVE_VLDRHU16_pre,
      MVE_VLDRHU32_post,
      MVE_VLDRHU32_pre,
      MVE_VLDRWU32_post,
      MVE_VLDRWU32_pre,
      MVE_VLDRWU32_qi_pre,
      MVE_VST20_16_wb,
      MVE_VST20_32_wb,
      MVE_VST20_8_wb,
      MVE_VST21_16_wb,
      MVE_VST21_32_wb,
      MVE_VST21_8_wb,
      MVE_VST40_16_wb,
      MVE_VST40_32_wb,
      MVE_VST40_8_wb,
      MVE_VST41_16_wb,
      MVE_VST41_32_wb,
      MVE_VST41_8_wb,
      MVE_VST42_16_wb,
      MVE_VST42_32_wb,
      MVE_VST42_8_wb,
      MVE_VST43_16_wb,
      MVE_VST43_32_wb,
      MVE_VST43_8_wb,
      MVE_VSTRB16_post,
      MVE_VSTRB16_pre,
      MVE_VSTRB32_post,
      MVE_VSTRB32_pre,
      MVE_VSTRBU8_post,
      MVE_VSTRBU8_pre,
      MVE_VSTRD64_qi_pre,
      MVE_VSTRH32_post,
      MVE_VSTRH32_pre,
      MVE_VSTRHU16_post,
      MVE_VSTRHU16_pre,
      MVE_VSTRWU32_post,
      MVE_VSTRWU32_pre,
      MVE_VSTRW32_qi_pre,
  };
  std::initializer_list<unsigned> Address3List = {
      t2LDRD_POST,
      t2LDRD_PRE,
      t2STRD_POST,
      t2STRD_PRE,
  };
  // Compute a mask of which operands are involved in address computation
  for (auto &op : Address1List) {
    Info[op].AddressOpMask = 0x6;
  }
  for (auto &op : Address2List) {
    Info[op].AddressOpMask = 0xc;
  }
  for (auto &op : Address3List) {
    Info[op].AddressOpMask = 0x18;
  }
  for (auto &op : hasBRegAddrShiftList) {
    Info[op].AddressOpMask |= 0x8;
  }
}

void InstructionInformation::markDPProducersConsumers(
    const ARMBaseInstrInfo *TII) {
  // Learn about all instructions which have FP source/dest registers
  for (unsigned MI = 0; MI < ARM::INSTRUCTION_LIST_END; ++MI) {
    const MCInstrDesc &MID = TII->get(MI);
    auto Operands = MID.operands();
    for (unsigned OI = 0, OIE = MID.getNumOperands(); OI != OIE; ++OI) {
      bool MarkQP = false, MarkDP = false, MarkSP = false;
      switch (Operands[OI].RegClass) {
      case ARM::MQPRRegClassID:
      case ARM::DPRRegClassID:
      case ARM::DPR_8RegClassID:
      case ARM::DPR_VFP2RegClassID:
      case ARM::DPairRegClassID:
      case ARM::DPairSpcRegClassID:
      case ARM::DQuadRegClassID:
      case ARM::DQuadSpcRegClassID:
      case ARM::DTripleRegClassID:
      case ARM::DTripleSpcRegClassID:
        MarkDP = true;
        break;
      case ARM::QPRRegClassID:
      case ARM::QPR_8RegClassID:
      case ARM::QPR_VFP2RegClassID:
      case ARM::QQPRRegClassID:
      case ARM::QQQQPRRegClassID:
        MarkQP = true;
        break;
      case ARM::SPRRegClassID:
      case ARM::SPR_8RegClassID:
      case ARM::FPWithVPRRegClassID:
        MarkSP = true;
        break;
      default:
        break;
      }
      if (MarkQP) {
        if (OI < MID.getNumDefs())
          Info[MI].ProducesQP = true;
        else
          Info[MI].ConsumesQP = true;
      }
      if (MarkDP) {
        if (OI < MID.getNumDefs())
          Info[MI].ProducesDP = true;
        else
          Info[MI].ConsumesDP = true;
      }
      if (MarkSP) {
        if (OI < MID.getNumDefs())
          Info[MI].ProducesSP = true;
        else
          Info[MI].ConsumesSP = true;
      }
    }
  }
}

} // anonymous namespace

static bool hasImplicitCPSRUse(const MachineInstr *MI) {
  return MI->getDesc().hasImplicitUseOfPhysReg(ARM::CPSR);
}

void ARMOverrideBypasses::setBidirLatencies(SUnit &SrcSU, SDep &SrcDep,
                                            unsigned latency) {
  SDep Reverse = SrcDep;
  Reverse.setSUnit(&SrcSU);
  for (SDep &PDep : SrcDep.getSUnit()->Preds) {
    if (PDep == Reverse) {
      PDep.setLatency(latency);
      SrcDep.getSUnit()->setDepthDirty();
      break;
    }
  }
  SrcDep.setLatency(latency);
  SrcSU.setHeightDirty();
}

static bool mismatchedPred(ARMCC::CondCodes a, ARMCC::CondCodes b) {
  return (a & 0xe) != (b & 0xe);
}

// Set output dependences to zero latency for processors which can
// simultaneously issue to the same register.  Returns true if a change
// was made.
bool ARMOverrideBypasses::zeroOutputDependences(SUnit &ISU, SDep &Dep) {
  if (Dep.getKind() == SDep::Output) {
    setBidirLatencies(ISU, Dep, 0);
    return true;
  }
  return false;
}

// The graph doesn't look inside of bundles to determine their
// scheduling boundaries and reports zero latency into and out of them
// (except for CPSR into the bundle, which has latency 1).
// Make some better scheduling assumptions:
// 1) CPSR uses have zero latency; other uses have incoming latency 1
// 2) CPSR defs retain a latency of zero; others have a latency of 1.
//
// Returns 1 if a use change was made; 2 if a def change was made; 0 otherwise
unsigned ARMOverrideBypasses::makeBundleAssumptions(SUnit &ISU, SDep &Dep) {

  SUnit &DepSU = *Dep.getSUnit();
  const MachineInstr *SrcMI = ISU.getInstr();
  unsigned SrcOpcode = SrcMI->getOpcode();
  const MachineInstr *DstMI = DepSU.getInstr();
  unsigned DstOpcode = DstMI->getOpcode();

  if (DstOpcode == ARM::BUNDLE && TII->isPredicated(*DstMI)) {
    setBidirLatencies(
        ISU, Dep,
        (Dep.isAssignedRegDep() && Dep.getReg() == ARM::CPSR) ? 0 : 1);
    return 1;
  }
  if (SrcOpcode == ARM::BUNDLE && TII->isPredicated(*SrcMI) &&
      Dep.isAssignedRegDep() && Dep.getReg() != ARM::CPSR) {
    setBidirLatencies(ISU, Dep, 1);
    return 2;
  }
  return 0;
}

// Determine whether there is a memory RAW hazard here and set up latency
// accordingly
bool ARMOverrideBypasses::memoryRAWHazard(SUnit &ISU, SDep &Dep,
                                          unsigned latency) {
  if (!Dep.isNormalMemory())
    return false;
  auto &SrcInst = *ISU.getInstr();
  auto &DstInst = *Dep.getSUnit()->getInstr();
  if (!SrcInst.mayStore() || !DstInst.mayLoad())
    return false;

  auto SrcMO = *SrcInst.memoperands().begin();
  auto DstMO = *DstInst.memoperands().begin();
  auto SrcVal = SrcMO->getValue();
  auto DstVal = DstMO->getValue();
  auto SrcPseudoVal = SrcMO->getPseudoValue();
  auto DstPseudoVal = DstMO->getPseudoValue();
  if (SrcVal && DstVal && AA->alias(SrcVal, DstVal) == AliasResult::MustAlias &&
      SrcMO->getOffset() == DstMO->getOffset()) {
    setBidirLatencies(ISU, Dep, latency);
    return true;
  } else if (SrcPseudoVal && DstPseudoVal &&
             SrcPseudoVal->kind() == DstPseudoVal->kind() &&
             SrcPseudoVal->kind() == PseudoSourceValue::FixedStack) {
    // Spills/fills
    auto FS0 = cast<FixedStackPseudoSourceValue>(SrcPseudoVal);
    auto FS1 = cast<FixedStackPseudoSourceValue>(DstPseudoVal);
    if (FS0 == FS1) {
      setBidirLatencies(ISU, Dep, latency);
      return true;
    }
  }
  return false;
}

namespace {

std::unique_ptr<InstructionInformation> II;

class CortexM7InstructionInformation : public InstructionInformation {
public:
  CortexM7InstructionInformation(const ARMBaseInstrInfo *TII)
      : InstructionInformation(TII) {}
};

class CortexM7Overrides : public ARMOverrideBypasses {
public:
  CortexM7Overrides(const ARMBaseInstrInfo *TII, AAResults *AA)
      : ARMOverrideBypasses(TII, AA) {
    if (!II)
      II.reset(new CortexM7InstructionInformation(TII));
  }

  void modifyBypasses(SUnit &) override;
};

void CortexM7Overrides::modifyBypasses(SUnit &ISU) {
  const MachineInstr *SrcMI = ISU.getInstr();
  unsigned SrcOpcode = SrcMI->getOpcode();
  bool isNSWload = II->isNonSubwordLoad(SrcOpcode);

  // Walk the successors looking for latency overrides that are needed
  for (SDep &Dep : ISU.Succs) {

    // Output dependences should have 0 latency, as M7 is able to
    // schedule writers to the same register for simultaneous issue.
    if (zeroOutputDependences(ISU, Dep))
      continue;

    if (memoryRAWHazard(ISU, Dep, 4))
      continue;

    // Ignore dependencies other than data
    if (Dep.getKind() != SDep::Data)
      continue;

    SUnit &DepSU = *Dep.getSUnit();
    if (DepSU.isBoundaryNode())
      continue;

    if (makeBundleAssumptions(ISU, Dep) == 1)
      continue;

    const MachineInstr *DstMI = DepSU.getInstr();
    unsigned DstOpcode = DstMI->getOpcode();

    // Word loads into any multiply or divide instruction are considered
    // cannot bypass their scheduling stage. Didn't do this in the .td file
    // because we cannot easily create a read advance that is 0 from certain
    // writer classes and 1 from all the rest.
    // (The other way around would have been easy.)
    if (isNSWload && (II->isMultiply(DstOpcode) || II->isDivide(DstOpcode)))
      setBidirLatencies(ISU, Dep, Dep.getLatency() + 1);

    // Word loads into B operand of a load/store are considered cannot bypass
    // their scheduling stage. Cannot do in the .td file because
    // need to decide between -1 and -2 for ReadAdvance
    if (isNSWload && II->hasBRegAddr(DstOpcode) &&
        DstMI->getOperand(2).getReg() == Dep.getReg())
      setBidirLatencies(ISU, Dep, Dep.getLatency() + 1);

    // Multiplies into any address generation cannot bypass from EX3.  Cannot do
    // in the .td file because need to decide between -1 and -2 for ReadAdvance
    if (II->isMultiply(SrcOpcode)) {
      unsigned OpMask = II->getAddressOpMask(DstOpcode) >> 1;
      for (unsigned i = 1; OpMask; ++i, OpMask >>= 1) {
        if ((OpMask & 1) && DstMI->getOperand(i).isReg() &&
            DstMI->getOperand(i).getReg() == Dep.getReg()) {
          setBidirLatencies(ISU, Dep, 4); // first legal bypass is EX4->EX1
          break;
        }
      }
    }

    // Mismatched conditional producers take longer on M7; they end up looking
    // like they were produced at EX3 and read at IS.
    if (TII->isPredicated(*SrcMI) && Dep.isAssignedRegDep() &&
        (SrcOpcode == ARM::BUNDLE ||
         mismatchedPred(TII->getPredicate(*SrcMI),
                        TII->getPredicate(*DstMI)))) {
      unsigned Lat = 1;
      // Operand A of shift+ALU is treated as an EX1 read instead of EX2.
      if (II->isInlineShiftALU(DstOpcode) && DstMI->getOperand(3).getImm() &&
          DstMI->getOperand(1).getReg() == Dep.getReg())
        Lat = 2;
      Lat = std::min(3u, Dep.getLatency() + Lat);
      setBidirLatencies(ISU, Dep, std::max(Dep.getLatency(), Lat));
    }

    // CC setter into conditional producer shouldn't have a latency of more
    // than 1 unless it's due to an implicit read. (All the "true" readers
    // of the condition code use an implicit read, and predicates use an
    // explicit.)
    if (Dep.isAssignedRegDep() && Dep.getReg() == ARM::CPSR &&
        TII->isPredicated(*DstMI) && !hasImplicitCPSRUse(DstMI))
      setBidirLatencies(ISU, Dep, 1);

    // REV instructions cannot bypass directly into the EX1 shifter.  The
    // code is slightly inexact as it doesn't attempt to ensure that the bypass
    // is to the shifter operands.
    if (II->isRev(SrcOpcode)) {
      if (II->isInlineShiftALU(DstOpcode))
        setBidirLatencies(ISU, Dep, 2);
      else if (II->isShift(DstOpcode))
        setBidirLatencies(ISU, Dep, 1);
    }
  }
}

class M85InstructionInformation : public InstructionInformation {
public:
  M85InstructionInformation(const ARMBaseInstrInfo *t)
      : InstructionInformation(t) {
    markDPProducersConsumers(t);
  }
};

class M85Overrides : public ARMOverrideBypasses {
public:
  M85Overrides(const ARMBaseInstrInfo *t, AAResults *a)
      : ARMOverrideBypasses(t, a) {
    if (!II)
      II.reset(new M85InstructionInformation(t));
  }

  void modifyBypasses(SUnit &) override;

private:
  unsigned computeBypassStage(const MCSchedClassDesc *SCD);
  signed modifyMixedWidthFP(const MachineInstr *SrcMI,
                            const MachineInstr *DstMI, unsigned RegID,
                            const MCSchedClassDesc *SCD);
};

unsigned M85Overrides::computeBypassStage(const MCSchedClassDesc *SCDesc) {
  auto SM = DAG->getSchedModel();
  unsigned DefIdx = 0; // just look for the first output's timing
  if (DefIdx < SCDesc->NumWriteLatencyEntries) {
    // Lookup the definition's write latency in SubtargetInfo.
    const MCWriteLatencyEntry *WLEntry =
        SM->getSubtargetInfo()->getWriteLatencyEntry(SCDesc, DefIdx);
    unsigned Latency = WLEntry->Cycles >= 0 ? WLEntry->Cycles : 1000;
    if (Latency == 4)
      return 2;
    else if (Latency == 5)
      return 3;
    else if (Latency > 3)
      return 3;
    else
      return Latency;
  }
  return 2;
}

// Latency changes for bypassing between FP registers of different sizes:
//
// Note that mixed DP/SP are unlikely because of the semantics
// of C.  Mixed MVE/SP are quite common when MVE intrinsics are used.
signed M85Overrides::modifyMixedWidthFP(const MachineInstr *SrcMI,
                                        const MachineInstr *DstMI,
                                        unsigned RegID,
                                        const MCSchedClassDesc *SCD) {

  if (!II->producesSP(SrcMI->getOpcode()) &&
      !II->producesDP(SrcMI->getOpcode()) &&
      !II->producesQP(SrcMI->getOpcode()))
    return 0;

  if (Register::isVirtualRegister(RegID)) {
    if (II->producesSP(SrcMI->getOpcode()) &&
        II->consumesDP(DstMI->getOpcode())) {
      for (auto &OP : SrcMI->operands())
        if (OP.isReg() && OP.isDef() && OP.getReg() == RegID &&
            OP.getSubReg() == ARM::ssub_1)
          return 5 - computeBypassStage(SCD);
    } else if (II->producesSP(SrcMI->getOpcode()) &&
               II->consumesQP(DstMI->getOpcode())) {
      for (auto &OP : SrcMI->operands())
        if (OP.isReg() && OP.isDef() && OP.getReg() == RegID &&
            (OP.getSubReg() == ARM::ssub_1 || OP.getSubReg() == ARM::ssub_3))
          return 5 - computeBypassStage(SCD) -
                 ((OP.getSubReg() == ARM::ssub_2 ||
                   OP.getSubReg() == ARM::ssub_3)
                      ? 1
                      : 0);
    } else if (II->producesDP(SrcMI->getOpcode()) &&
               II->consumesQP(DstMI->getOpcode())) {
      for (auto &OP : SrcMI->operands())
        if (OP.isReg() && OP.isDef() && OP.getReg() == RegID &&
            OP.getSubReg() == ARM::ssub_1)
          return -1;
    } else if (II->producesDP(SrcMI->getOpcode()) &&
               II->consumesSP(DstMI->getOpcode())) {
      for (auto &OP : DstMI->operands())
        if (OP.isReg() && OP.isUse() && OP.getReg() == RegID &&
            OP.getSubReg() == ARM::ssub_1)
          return 5 - computeBypassStage(SCD);
    } else if (II->producesQP(SrcMI->getOpcode()) &&
               II->consumesSP(DstMI->getOpcode())) {
      for (auto &OP : DstMI->operands())
        if (OP.isReg() && OP.isUse() && OP.getReg() == RegID &&
            (OP.getSubReg() == ARM::ssub_1 || OP.getSubReg() == ARM::ssub_3))
          return 5 - computeBypassStage(SCD) +
                 ((OP.getSubReg() == ARM::ssub_2 ||
                   OP.getSubReg() == ARM::ssub_3)
                      ? 1
                      : 0);
    } else if (II->producesQP(SrcMI->getOpcode()) &&
               II->consumesDP(DstMI->getOpcode())) {
      for (auto &OP : DstMI->operands())
        if (OP.isReg() && OP.isUse() && OP.getReg() == RegID &&
            OP.getSubReg() == ARM::ssub_1)
          return 1;
    }
  } else if (Register::isPhysicalRegister(RegID)) {
    // Note that when the producer is narrower, not all of the producers
    // may be present in the scheduling graph; somewhere earlier in the
    // compiler, an implicit def/use of the aliased full register gets
    // added to the producer, and so only that producer is seen as *the*
    // single producer.  This behavior also has the unfortunate effect of
    // serializing the producers in the compiler's view of things.
    if (II->producesSP(SrcMI->getOpcode()) &&
        II->consumesDP(DstMI->getOpcode())) {
      for (auto &OP : SrcMI->operands())
        if (OP.isReg() && OP.isDef() && OP.getReg() >= ARM::S1 &&
            OP.getReg() <= ARM::S31 && (OP.getReg() - ARM::S0) % 2 &&
            (OP.getReg() == RegID ||
             (OP.getReg() - ARM::S0) / 2 + ARM::D0 == RegID ||
             (OP.getReg() - ARM::S0) / 4 + ARM::Q0 == RegID))
          return 5 - computeBypassStage(SCD);
    } else if (II->producesSP(SrcMI->getOpcode()) &&
               II->consumesQP(DstMI->getOpcode())) {
      for (auto &OP : SrcMI->operands())
        if (OP.isReg() && OP.isDef() && OP.getReg() >= ARM::S1 &&
            OP.getReg() <= ARM::S31 && (OP.getReg() - ARM::S0) % 2 &&
            (OP.getReg() == RegID ||
             (OP.getReg() - ARM::S0) / 2 + ARM::D0 == RegID ||
             (OP.getReg() - ARM::S0) / 4 + ARM::Q0 == RegID))
          return 5 - computeBypassStage(SCD) -
                 (((OP.getReg() - ARM::S0) / 2) % 2 ? 1 : 0);
    } else if (II->producesDP(SrcMI->getOpcode()) &&
               II->consumesQP(DstMI->getOpcode())) {
      for (auto &OP : SrcMI->operands())
        if (OP.isReg() && OP.isDef() && OP.getReg() >= ARM::D0 &&
            OP.getReg() <= ARM::D15 && (OP.getReg() - ARM::D0) % 2 &&
            (OP.getReg() == RegID ||
             (OP.getReg() - ARM::D0) / 2 + ARM::Q0 == RegID))
          return -1;
    } else if (II->producesDP(SrcMI->getOpcode()) &&
               II->consumesSP(DstMI->getOpcode())) {
      if (RegID >= ARM::S1 && RegID <= ARM::S31 && (RegID - ARM::S0) % 2)
        return 5 - computeBypassStage(SCD);
    } else if (II->producesQP(SrcMI->getOpcode()) &&
               II->consumesSP(DstMI->getOpcode())) {
      if (RegID >= ARM::S1 && RegID <= ARM::S31 && (RegID - ARM::S0) % 2)
        return 5 - computeBypassStage(SCD) +
               (((RegID - ARM::S0) / 2) % 2 ? 1 : 0);
    } else if (II->producesQP(SrcMI->getOpcode()) &&
               II->consumesDP(DstMI->getOpcode())) {
      if (RegID >= ARM::D1 && RegID <= ARM::D15 && (RegID - ARM::D0) % 2)
        return 1;
    }
  }
  return 0;
}

void M85Overrides::modifyBypasses(SUnit &ISU) {
  const MachineInstr *SrcMI = ISU.getInstr();
  unsigned SrcOpcode = SrcMI->getOpcode();
  bool isNSWload = II->isNonSubwordLoad(SrcOpcode);

  // Walk the successors looking for latency overrides that are needed
  for (SDep &Dep : ISU.Succs) {

    // Output dependences should have 0 latency, as CortexM85 is able to
    // schedule writers to the same register for simultaneous issue.
    if (zeroOutputDependences(ISU, Dep))
      continue;

    if (memoryRAWHazard(ISU, Dep, 3))
      continue;

    // Ignore dependencies other than data or strong ordering.
    if (Dep.getKind() != SDep::Data)
      continue;

    SUnit &DepSU = *Dep.getSUnit();
    if (DepSU.isBoundaryNode())
      continue;

    if (makeBundleAssumptions(ISU, Dep) == 1)
      continue;

    const MachineInstr *DstMI = DepSU.getInstr();
    unsigned DstOpcode = DstMI->getOpcode();

    // Word loads into B operand of a load/store with cannot bypass their
    // scheduling stage. Cannot do in the .td file because need to decide
    // between -1 and -2 for ReadAdvance

    if (isNSWload && II->hasBRegAddrShift(DstOpcode) &&
        DstMI->getOperand(3).getImm() != 0 && // shift operand
        DstMI->getOperand(2).getReg() == Dep.getReg())
      setBidirLatencies(ISU, Dep, Dep.getLatency() + 1);

    if (isNSWload && isMVEVectorInstruction(DstMI)) {
      setBidirLatencies(ISU, Dep, Dep.getLatency() + 1);
    }

    if (II->isMVEIntMAC(DstOpcode) &&
        II->isMVEIntMACMatched(SrcOpcode, DstOpcode) &&
        DstMI->getOperand(0).isReg() &&
        DstMI->getOperand(0).getReg() == Dep.getReg())
      setBidirLatencies(ISU, Dep, Dep.getLatency() - 1);

    // CC setter into conditional producer shouldn't have a latency of more
    // than 0 unless it's due to an implicit read.
    if (Dep.isAssignedRegDep() && Dep.getReg() == ARM::CPSR &&
        TII->isPredicated(*DstMI) && !hasImplicitCPSRUse(DstMI))
      setBidirLatencies(ISU, Dep, 0);

    if (signed ALat = modifyMixedWidthFP(SrcMI, DstMI, Dep.getReg(),
                                         DAG->getSchedClass(&ISU)))
      setBidirLatencies(ISU, Dep, std::max(0, signed(Dep.getLatency()) + ALat));

    if (II->isRev(SrcOpcode)) {
      if (II->isInlineShiftALU(DstOpcode))
        setBidirLatencies(ISU, Dep, 1);
      else if (II->isShift(DstOpcode))
        setBidirLatencies(ISU, Dep, 1);
    }
  }
}

// Add M55 specific overrides for latencies between instructions. Currently it:
//  - Adds an extra cycle latency between MVE VMLAV and scalar instructions.
class CortexM55Overrides : public ARMOverrideBypasses {
public:
  CortexM55Overrides(const ARMBaseInstrInfo *TII, AAResults *AA)
      : ARMOverrideBypasses(TII, AA) {}

  void modifyBypasses(SUnit &SU) override {
    MachineInstr *SrcMI = SU.getInstr();
    if (!(SrcMI->getDesc().TSFlags & ARMII::HorizontalReduction))
      return;

    for (SDep &Dep : SU.Succs) {
      if (Dep.getKind() != SDep::Data)
        continue;
      SUnit &DepSU = *Dep.getSUnit();
      if (DepSU.isBoundaryNode())
        continue;
      MachineInstr *DstMI = DepSU.getInstr();

      if (!isMVEVectorInstruction(DstMI) && !DstMI->mayStore())
        setBidirLatencies(SU, Dep, 3);
    }
  }
};

} // end anonymous namespace

void ARMOverrideBypasses::apply(ScheduleDAGInstrs *DAGInstrs) {
  DAG = DAGInstrs;
  for (SUnit &ISU : DAGInstrs->SUnits) {
    if (ISU.isBoundaryNode())
      continue;
    modifyBypasses(ISU);
  }
  if (DAGInstrs->ExitSU.getInstr())
    modifyBypasses(DAGInstrs->ExitSU);
}

std::unique_ptr<ScheduleDAGMutation>
createARMLatencyMutations(const ARMSubtarget &ST, AAResults *AA) {
  if (ST.isCortexM85())
    return std::make_unique<M85Overrides>(ST.getInstrInfo(), AA);
  else if (ST.isCortexM7())
    return std::make_unique<CortexM7Overrides>(ST.getInstrInfo(), AA);
  else if (ST.isCortexM55())
    return std::make_unique<CortexM55Overrides>(ST.getInstrInfo(), AA);

  return nullptr;
}

} // end namespace llvm
