llvm/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp

//===- HexagonInstrInfo.cpp - Hexagon Instruction Information -------------===//
//
// 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 contains the Hexagon implementation of the TargetInstrInfo class.
//
//===----------------------------------------------------------------------===//

#include "HexagonInstrInfo.h"
#include "Hexagon.h"
#include "HexagonFrameLowering.h"
#include "HexagonHazardRecognizer.h"
#include "HexagonRegisterInfo.h"
#include "HexagonSubtarget.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/DFAPacketizer.h"
#include "llvm/CodeGen/LivePhysRegs.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineInstrBundle.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/ScheduleDAG.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetOpcodes.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/CodeGenTypes/MachineValueType.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCInstBuilder.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/MC/MCInstrItineraries.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include <cassert>
#include <cctype>
#include <cstdint>
#include <cstring>
#include <iterator>
#include <optional>
#include <string>
#include <utility>

usingnamespacellvm;

#define DEBUG_TYPE

#define GET_INSTRINFO_CTOR_DTOR
#define GET_INSTRMAP_INFO
#include "HexagonDepTimingClasses.h"
#include "HexagonGenDFAPacketizer.inc"
#include "HexagonGenInstrInfo.inc"

cl::opt<bool> ScheduleInlineAsm("hexagon-sched-inline-asm", cl::Hidden,
  cl::init(false), cl::desc("Do not consider inline-asm a scheduling/"
                            "packetization boundary."));

static cl::opt<bool> EnableBranchPrediction("hexagon-enable-branch-prediction",
  cl::Hidden, cl::init(true), cl::desc("Enable branch prediction"));

static cl::opt<bool> DisableNVSchedule(
    "disable-hexagon-nv-schedule", cl::Hidden,
    cl::desc("Disable schedule adjustment for new value stores."));

static cl::opt<bool> EnableTimingClassLatency(
  "enable-timing-class-latency", cl::Hidden, cl::init(false),
  cl::desc("Enable timing class latency"));

static cl::opt<bool> EnableALUForwarding(
  "enable-alu-forwarding", cl::Hidden, cl::init(true),
  cl::desc("Enable vec alu forwarding"));

static cl::opt<bool> EnableACCForwarding(
  "enable-acc-forwarding", cl::Hidden, cl::init(true),
  cl::desc("Enable vec acc forwarding"));

static cl::opt<bool> BranchRelaxAsmLarge("branch-relax-asm-large",
                                         cl::init(true), cl::Hidden,
                                         cl::desc("branch relax asm"));

static cl::opt<bool>
    UseDFAHazardRec("dfa-hazard-rec", cl::init(true), cl::Hidden,
                    cl::desc("Use the DFA based hazard recognizer."));

/// Constants for Hexagon instructions.
const int Hexagon_MEMW_OFFSET_MAX =;
const int Hexagon_MEMW_OFFSET_MIN =;
const int Hexagon_MEMD_OFFSET_MAX =;
const int Hexagon_MEMD_OFFSET_MIN =;
const int Hexagon_MEMH_OFFSET_MAX =;
const int Hexagon_MEMH_OFFSET_MIN =;
const int Hexagon_MEMB_OFFSET_MAX =;
const int Hexagon_MEMB_OFFSET_MIN =;
const int Hexagon_ADDI_OFFSET_MAX =;
const int Hexagon_ADDI_OFFSET_MIN =;

// Pin the vtable to this file.
void HexagonInstrInfo::anchor() {}

HexagonInstrInfo::HexagonInstrInfo(HexagonSubtarget &ST)
  :{}

namespace llvm {
namespace HexagonFUnits {
  bool isSlot0Only(unsigned units);
}
}

static bool isIntRegForSubInst(Register Reg) {}

static bool isDblRegForSubInst(Register Reg, const HexagonRegisterInfo &HRI) {}

/// Calculate number of instructions excluding the debug instructions.
static unsigned nonDbgMICount(MachineBasicBlock::const_instr_iterator MIB,
                              MachineBasicBlock::const_instr_iterator MIE) {}

// Check if the A2_tfrsi instruction is cheap or not. If the operand has
// to be constant-extendend it is not cheap since it occupies two slots
// in a packet.
bool HexagonInstrInfo::isAsCheapAsAMove(const MachineInstr &MI) const {}

// Do not sink floating point instructions that updates USR register.
// Example:
//    feclearexcept
//    F2_conv_w2sf
//    fetestexcept
// MachineSink sinks F2_conv_w2sf and we are not able to catch exceptions.
// TODO: On some of these floating point instructions, USR is marked as Use.
// In reality, these instructions also Def the USR. If USR is marked as Def,
// some of the assumptions in assembler packetization are broken.
bool HexagonInstrInfo::shouldSink(const MachineInstr &MI) const {}

/// Find the hardware loop instruction used to set-up the specified loop.
/// On Hexagon, we have two instructions used to set-up the hardware loop
/// (LOOP0, LOOP1) with corresponding endloop (ENDLOOP0, ENDLOOP1) instructions
/// to indicate the end of a loop.
MachineInstr *HexagonInstrInfo::findLoopInstr(MachineBasicBlock *BB,
      unsigned EndLoopOp, MachineBasicBlock *TargetBB,
      SmallPtrSet<MachineBasicBlock *, 8> &Visited) const {}

/// Gather register def/uses from MI.
/// This treats possible (predicated) defs as actually happening ones
/// (conservatively).
static inline void parseOperands(const MachineInstr &MI,
      SmallVectorImpl<Register> &Defs, SmallVectorImpl<Register> &Uses) {}

// Position dependent, so check twice for swap.
static bool isDuplexPairMatch(unsigned Ga, unsigned Gb) {}

/// isLoadFromStackSlot - If the specified machine instruction is a direct
/// load from a stack slot, return the virtual or physical register number of
/// the destination along with the FrameIndex of the loaded stack slot.  If
/// not, return 0.  This predicate must return 0 if the instruction has
/// any side effects other than loading from the stack slot.
Register HexagonInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
                                               int &FrameIndex) const {}

/// isStoreToStackSlot - If the specified machine instruction is a direct
/// store to a stack slot, return the virtual or physical register number of
/// the source reg along with the FrameIndex of the loaded stack slot.  If
/// not, return 0.  This predicate must return 0 if the instruction has
/// any side effects other than storing to the stack slot.
Register HexagonInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
                                              int &FrameIndex) const {}

/// This function checks if the instruction or bundle of instructions
/// has load from stack slot and returns frameindex and machine memory
/// operand of that instruction if true.
bool HexagonInstrInfo::hasLoadFromStackSlot(
    const MachineInstr &MI,
    SmallVectorImpl<const MachineMemOperand *> &Accesses) const {}

/// This function checks if the instruction or bundle of instructions
/// has store to stack slot and returns frameindex and machine memory
/// operand of that instruction if true.
bool HexagonInstrInfo::hasStoreToStackSlot(
    const MachineInstr &MI,
    SmallVectorImpl<const MachineMemOperand *> &Accesses) const {}

/// This function can analyze one/two way branching only and should (mostly) be
/// called by target independent side.
/// First entry is always the opcode of the branching instruction, except when
/// the Cond vector is supposed to be empty, e.g., when analyzeBranch fails, a
/// BB with only unconditional jump. Subsequent entries depend upon the opcode,
/// e.g. Jump_c p will have
/// Cond[0] = Jump_c
/// Cond[1] = p
/// HW-loop ENDLOOP:
/// Cond[0] = ENDLOOP
/// Cond[1] = MBB
/// New value jump:
/// Cond[0] = Hexagon::CMPEQri_f_Jumpnv_t_V4 -- specific opcode
/// Cond[1] = R
/// Cond[2] = Imm
bool HexagonInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
                                     MachineBasicBlock *&TBB,
                                     MachineBasicBlock *&FBB,
                                     SmallVectorImpl<MachineOperand> &Cond,
                                     bool AllowModify) const {}

unsigned HexagonInstrInfo::removeBranch(MachineBasicBlock &MBB,
                                        int *BytesRemoved) const {}

unsigned HexagonInstrInfo::insertBranch(MachineBasicBlock &MBB,
                                        MachineBasicBlock *TBB,
                                        MachineBasicBlock *FBB,
                                        ArrayRef<MachineOperand> Cond,
                                        const DebugLoc &DL,
                                        int *BytesAdded) const {}

namespace {
class HexagonPipelinerLoopInfo : public TargetInstrInfo::PipelinerLoopInfo {};
} // namespace

std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
HexagonInstrInfo::analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const {}

bool HexagonInstrInfo::isProfitableToIfCvt(MachineBasicBlock &MBB,
      unsigned NumCycles, unsigned ExtraPredCycles,
      BranchProbability Probability) const {}

bool HexagonInstrInfo::isProfitableToIfCvt(MachineBasicBlock &TMBB,
      unsigned NumTCycles, unsigned ExtraTCycles, MachineBasicBlock &FMBB,
      unsigned NumFCycles, unsigned ExtraFCycles, BranchProbability Probability)
      const {}

bool HexagonInstrInfo::isProfitableToDupForIfCvt(MachineBasicBlock &MBB,
      unsigned NumInstrs, BranchProbability Probability) const {}

static void getLiveInRegsAt(LivePhysRegs &Regs, const MachineInstr &MI) {}

static void getLiveOutRegsAt(LivePhysRegs &Regs, const MachineInstr &MI) {}

void HexagonInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
                                   MachineBasicBlock::iterator I,
                                   const DebugLoc &DL, MCRegister DestReg,
                                   MCRegister SrcReg, bool KillSrc,
                                   bool RenamableDest,
                                   bool RenamableSrc) const {}

void HexagonInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
                                           MachineBasicBlock::iterator I,
                                           Register SrcReg, bool isKill, int FI,
                                           const TargetRegisterClass *RC,
                                           const TargetRegisterInfo *TRI,
                                           Register VReg) const {}

void HexagonInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
                                            MachineBasicBlock::iterator I,
                                            Register DestReg, int FI,
                                            const TargetRegisterClass *RC,
                                            const TargetRegisterInfo *TRI,
                                            Register VReg) const {}

/// expandPostRAPseudo - This function is called for all pseudo instructions
/// that remain after register allocation. Many pseudo instructions are
/// created to help register allocation. This is the place to convert them
/// into real instructions. The target can edit MI in place, or it can insert
/// new instructions and erase MI. The function should return true if
/// anything was changed.
bool HexagonInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {}

MachineBasicBlock::instr_iterator
HexagonInstrInfo::expandVGatherPseudo(MachineInstr &MI) const {}

// We indicate that we want to reverse the branch by
// inserting the reversed branching opcode.
bool HexagonInstrInfo::reverseBranchCondition(
      SmallVectorImpl<MachineOperand> &Cond) const {}

void HexagonInstrInfo::insertNoop(MachineBasicBlock &MBB,
      MachineBasicBlock::iterator MI) const {}

bool HexagonInstrInfo::isPostIncrement(const MachineInstr &MI) const {}

// Returns true if an instruction is predicated irrespective of the predicate
// sense. For example, all of the following will return true.
// if (p0) R1 = add(R2, R3)
// if (!p0) R1 = add(R2, R3)
// if (p0.new) R1 = add(R2, R3)
// if (!p0.new) R1 = add(R2, R3)
// Note: New-value stores are not included here as in the current
// implementation, we don't need to check their predicate sense.
bool HexagonInstrInfo::isPredicated(const MachineInstr &MI) const {}

bool HexagonInstrInfo::PredicateInstruction(
    MachineInstr &MI, ArrayRef<MachineOperand> Cond) const {}

bool HexagonInstrInfo::SubsumesPredicate(ArrayRef<MachineOperand> Pred1,
      ArrayRef<MachineOperand> Pred2) const {}

bool HexagonInstrInfo::ClobbersPredicate(MachineInstr &MI,
                                         std::vector<MachineOperand> &Pred,
                                         bool SkipDead) const {}

bool HexagonInstrInfo::isPredicable(const MachineInstr &MI) const {}

bool HexagonInstrInfo::isSchedulingBoundary(const MachineInstr &MI,
                                            const MachineBasicBlock *MBB,
                                            const MachineFunction &MF) const {}

/// Measure the specified inline asm to determine an approximation of its
/// length.
/// Comments (which run till the next SeparatorString or newline) do not
/// count as an instruction.
/// Any other non-whitespace text is considered an instruction, with
/// multiple instructions separated by SeparatorString or newlines.
/// Variable-length instructions are not handled here; this function
/// may be overloaded in the target code to do that.
/// Hexagon counts the number of ##'s and adjust for that many
/// constant exenders.
unsigned HexagonInstrInfo::getInlineAsmLength(const char *Str,
                                              const MCAsmInfo &MAI,
                                              const TargetSubtargetInfo *STI) const {}

ScheduleHazardRecognizer*
HexagonInstrInfo::CreateTargetPostRAHazardRecognizer(
      const InstrItineraryData *II, const ScheduleDAG *DAG) const {}

/// For a comparison instruction, return the source registers in
/// \p SrcReg and \p SrcReg2 if having two register operands, and the value it
/// compares against in CmpValue. Return true if the comparison instruction
/// can be analyzed.
bool HexagonInstrInfo::analyzeCompare(const MachineInstr &MI, Register &SrcReg,
                                      Register &SrcReg2, int64_t &Mask,
                                      int64_t &Value) const {}

unsigned HexagonInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
                                           const MachineInstr &MI,
                                           unsigned *PredCost) const {}

DFAPacketizer *HexagonInstrInfo::CreateTargetScheduleState(
    const TargetSubtargetInfo &STI) const {}

// Inspired by this pair:
//  %r13 = L2_loadri_io %r29, 136; mem:LD4[FixedStack0]
//  S2_storeri_io %r29, 132, killed %r1; flags:  mem:ST4[FixedStack1]
// Currently AA considers the addresses in these instructions to be aliasing.
bool HexagonInstrInfo::areMemAccessesTriviallyDisjoint(
    const MachineInstr &MIa, const MachineInstr &MIb) const {}

/// If the instruction is an increment of a constant value, return the amount.
bool HexagonInstrInfo::getIncrementValue(const MachineInstr &MI,
      int &Value) const {}

std::pair<unsigned, unsigned>
HexagonInstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const {}

ArrayRef<std::pair<unsigned, const char*>>
HexagonInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {}

ArrayRef<std::pair<unsigned, const char*>>
HexagonInstrInfo::getSerializableBitmaskMachineOperandTargetFlags() const {}

Register HexagonInstrInfo::createVR(MachineFunction *MF, MVT VT) const {}

bool HexagonInstrInfo::isAbsoluteSet(const MachineInstr &MI) const {}

bool HexagonInstrInfo::isAccumulator(const MachineInstr &MI) const {}

bool HexagonInstrInfo::isBaseImmOffset(const MachineInstr &MI) const {}

bool HexagonInstrInfo::isComplex(const MachineInstr &MI) const {}

// Return true if the instruction is a compound branch instruction.
bool HexagonInstrInfo::isCompoundBranchInstr(const MachineInstr &MI) const {}

// TODO: In order to have isExtendable for fpimm/f32Ext, we need to handle
// isFPImm and later getFPImm as well.
bool HexagonInstrInfo::isConstExtended(const MachineInstr &MI) const {}

bool HexagonInstrInfo::isDeallocRet(const MachineInstr &MI) const {}

// Return true when ConsMI uses a register defined by ProdMI.
bool HexagonInstrInfo::isDependent(const MachineInstr &ProdMI,
      const MachineInstr &ConsMI) const {}

// Returns true if the instruction is alread a .cur.
bool HexagonInstrInfo::isDotCurInst(const MachineInstr &MI) const {}

// Returns true, if any one of the operands is a dot new
// insn, whether it is predicated dot new or register dot new.
bool HexagonInstrInfo::isDotNewInst(const MachineInstr &MI) const {}

/// Symmetrical. See if these two instructions are fit for duplex pair.
bool HexagonInstrInfo::isDuplexPair(const MachineInstr &MIa,
      const MachineInstr &MIb) const {}

bool HexagonInstrInfo::isEndLoopN(unsigned Opcode) const {}

bool HexagonInstrInfo::isExpr(unsigned OpType) const {}

bool HexagonInstrInfo::isExtendable(const MachineInstr &MI) const {}

// This returns true in two cases:
// - The OP code itself indicates that this is an extended instruction.
// - One of MOs has been marked with HMOTF_ConstExtended flag.
bool HexagonInstrInfo::isExtended(const MachineInstr &MI) const {}

bool HexagonInstrInfo::isFloat(const MachineInstr &MI) const {}

// No V60 HVX VMEM with A_INDIRECT.
bool HexagonInstrInfo::isHVXMemWithAIndirect(const MachineInstr &I,
      const MachineInstr &J) const {}

bool HexagonInstrInfo::isIndirectCall(const MachineInstr &MI) const {}

bool HexagonInstrInfo::isIndirectL4Return(const MachineInstr &MI) const {}

bool HexagonInstrInfo::isJumpR(const MachineInstr &MI) const {}

// Return true if a given MI can accommodate given offset.
// Use abs estimate as oppose to the exact number.
// TODO: This will need to be changed to use MC level
// definition of instruction extendable field size.
bool HexagonInstrInfo::isJumpWithinBranchRange(const MachineInstr &MI,
      unsigned offset) const {}

bool HexagonInstrInfo::isLateSourceInstr(const MachineInstr &MI) const {}

bool HexagonInstrInfo::isLoopN(const MachineInstr &MI) const {}

bool HexagonInstrInfo::isMemOp(const MachineInstr &MI) const {}

bool HexagonInstrInfo::isNewValue(const MachineInstr &MI) const {}

bool HexagonInstrInfo::isNewValue(unsigned Opcode) const {}

bool HexagonInstrInfo::isNewValueInst(const MachineInstr &MI) const {}

bool HexagonInstrInfo::isNewValueJump(const MachineInstr &MI) const {}

bool HexagonInstrInfo::isNewValueJump(unsigned Opcode) const {}

bool HexagonInstrInfo::isNewValueStore(const MachineInstr &MI) const {}

bool HexagonInstrInfo::isNewValueStore(unsigned Opcode) const {}

// Returns true if a particular operand is extendable for an instruction.
bool HexagonInstrInfo::isOperandExtended(const MachineInstr &MI,
    unsigned OperandNum) const {}

bool HexagonInstrInfo::isPredicatedNew(const MachineInstr &MI) const {}

bool HexagonInstrInfo::isPredicatedNew(unsigned Opcode) const {}

bool HexagonInstrInfo::isPredicatedTrue(const MachineInstr &MI) const {}

bool HexagonInstrInfo::isPredicatedTrue(unsigned Opcode) const {}

bool HexagonInstrInfo::isPredicated(unsigned Opcode) const {}

bool HexagonInstrInfo::isPredicateLate(unsigned Opcode) const {}

bool HexagonInstrInfo::isPredictedTaken(unsigned Opcode) const {}

bool HexagonInstrInfo::isSaveCalleeSavedRegsCall(const MachineInstr &MI) const {}

bool HexagonInstrInfo::isSignExtendingLoad(const MachineInstr &MI) const {}

bool HexagonInstrInfo::isSolo(const MachineInstr &MI) const {}

bool HexagonInstrInfo::isSpillPredRegOp(const MachineInstr &MI) const {}

bool HexagonInstrInfo::isTailCall(const MachineInstr &MI) const {}

// Returns true when SU has a timing class TC1.
bool HexagonInstrInfo::isTC1(const MachineInstr &MI) const {}

bool HexagonInstrInfo::isTC2(const MachineInstr &MI) const {}

bool HexagonInstrInfo::isTC2Early(const MachineInstr &MI) const {}

bool HexagonInstrInfo::isTC4x(const MachineInstr &MI) const {}

// Schedule this ASAP.
bool HexagonInstrInfo::isToBeScheduledASAP(const MachineInstr &MI1,
      const MachineInstr &MI2) const {}

bool HexagonInstrInfo::isHVXVec(const MachineInstr &MI) const {}

// Check if the Offset is a valid auto-inc imm by Load/Store Type.
bool HexagonInstrInfo::isValidAutoIncImm(const EVT VT, int Offset) const {}

bool HexagonInstrInfo::isValidOffset(unsigned Opcode, int Offset,
      const TargetRegisterInfo *TRI, bool Extend) const {}

bool HexagonInstrInfo::isVecAcc(const MachineInstr &MI) const {}

bool HexagonInstrInfo::isVecALU(const MachineInstr &MI) const {}

bool HexagonInstrInfo::isVecUsableNextPacket(const MachineInstr &ProdMI,
      const MachineInstr &ConsMI) const {}

bool HexagonInstrInfo::isZeroExtendingLoad(const MachineInstr &MI) const {}

// Add latency to instruction.
bool HexagonInstrInfo::addLatencyToSchedule(const MachineInstr &MI1,
      const MachineInstr &MI2) const {}

/// Get the base register and byte offset of a load/store instr.
bool HexagonInstrInfo::getMemOperandsWithOffsetWidth(
    const MachineInstr &LdSt, SmallVectorImpl<const MachineOperand *> &BaseOps,
    int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width,
    const TargetRegisterInfo *TRI) const {}

/// Can these instructions execute at the same time in a bundle.
bool HexagonInstrInfo::canExecuteInBundle(const MachineInstr &First,
      const MachineInstr &Second) const {}

bool HexagonInstrInfo::doesNotReturn(const MachineInstr &CallMI) const {}

bool HexagonInstrInfo::hasEHLabel(const MachineBasicBlock *B) const {}

// Returns true if an instruction can be converted into a non-extended
// equivalent instruction.
bool HexagonInstrInfo::hasNonExtEquivalent(const MachineInstr &MI) const {}

bool HexagonInstrInfo::hasPseudoInstrPair(const MachineInstr &MI) const {}

bool HexagonInstrInfo::hasUncondBranch(const MachineBasicBlock *B)
      const {}

// Returns true, if a LD insn can be promoted to a cur load.
bool HexagonInstrInfo::mayBeCurLoad(const MachineInstr &MI) const {}

// Returns true, if a ST insn can be promoted to a new-value store.
bool HexagonInstrInfo::mayBeNewStore(const MachineInstr &MI) const {}

bool HexagonInstrInfo::producesStall(const MachineInstr &ProdMI,
      const MachineInstr &ConsMI) const {}

bool HexagonInstrInfo::producesStall(const MachineInstr &MI,
      MachineBasicBlock::const_instr_iterator BII) const {}

bool HexagonInstrInfo::predCanBeUsedAsDotNew(const MachineInstr &MI,
      Register PredReg) const {}

bool HexagonInstrInfo::PredOpcodeHasJMP_c(unsigned Opcode) const {}

bool HexagonInstrInfo::predOpcodeHasNot(ArrayRef<MachineOperand> Cond) const {}

unsigned HexagonInstrInfo::getAddrMode(const MachineInstr &MI) const {}

// Returns the base register in a memory access (load/store). The offset is
// returned in Offset and the access size is returned in AccessSize.
// If the base operand has a subregister or the offset field does not contain
// an immediate value, return nullptr.
MachineOperand *
HexagonInstrInfo::getBaseAndOffset(const MachineInstr &MI, int64_t &Offset,
                                   LocationSize &AccessSize) const {}

/// Return the position of the base and offset operands for this instruction.
bool HexagonInstrInfo::getBaseAndOffsetPosition(const MachineInstr &MI,
      unsigned &BasePos, unsigned &OffsetPos) const {}

// Inserts branching instructions in reverse order of their occurrence.
// e.g. jump_t t1 (i1)
// jump t2        (i2)
// Jumpers = {i2, i1}
SmallVector<MachineInstr*, 2> HexagonInstrInfo::getBranchingInstrs(
      MachineBasicBlock& MBB) const {}

// Returns Operand Index for the constant extended instruction.
unsigned HexagonInstrInfo::getCExtOpNum(const MachineInstr &MI) const {}

// See if instruction could potentially be a duplex candidate.
// If so, return its group. Zero otherwise.
HexagonII::CompoundGroup HexagonInstrInfo::getCompoundCandidateGroup(
      const MachineInstr &MI) const {}

// Returns -1 when there is no opcode found.
unsigned HexagonInstrInfo::getCompoundOpcode(const MachineInstr &GA,
      const MachineInstr &GB) const {}

// Returns -1 if there is no opcode found.
int HexagonInstrInfo::getDuplexOpcode(const MachineInstr &MI,
                                      bool ForBigCore) const {}

int HexagonInstrInfo::getCondOpcode(int Opc, bool invertPredicate) const {}

// Return the cur value instruction for a given store.
int HexagonInstrInfo::getDotCurOp(const MachineInstr &MI) const {}

// Return the regular version of the .cur instruction.
int HexagonInstrInfo::getNonDotCurOp(const MachineInstr &MI) const {}

// The diagram below shows the steps involved in the conversion of a predicated
// store instruction to its .new predicated new-value form.
//
// Note: It doesn't include conditional new-value stores as they can't be
// converted to .new predicate.
//
//               p.new NV store [ if(p0.new)memw(R0+#0)=R2.new ]
//                ^           ^
//               /             \ (not OK. it will cause new-value store to be
//              /               X conditional on p0.new while R2 producer is
//             /                 \ on p0)
//            /                   \.
//     p.new store                 p.old NV store
// [if(p0.new)memw(R0+#0)=R2]    [if(p0)memw(R0+#0)=R2.new]
//            ^                  ^
//             \                /
//              \              /
//               \            /
//                 p.old store
//             [if (p0)memw(R0+#0)=R2]
//
// The following set of instructions further explains the scenario where
// conditional new-value store becomes invalid when promoted to .new predicate
// form.
//
// { 1) if (p0) r0 = add(r1, r2)
//   2) p0 = cmp.eq(r3, #0) }
//
//   3) if (p0) memb(r1+#0) = r0  --> this instruction can't be grouped with
// the first two instructions because in instr 1, r0 is conditional on old value
// of p0 but its use in instr 3 is conditional on p0 modified by instr 2 which
// is not valid for new-value stores.
// Predicated new value stores (i.e. if (p0) memw(..)=r0.new) are excluded
// from the "Conditional Store" list. Because a predicated new value store
// would NOT be promoted to a double dot new store. See diagram below:
// This function returns yes for those stores that are predicated but not
// yet promoted to predicate dot new instructions.
//
//                          +---------------------+
//                    /-----| if (p0) memw(..)=r0 |---------\~
//                   ||     +---------------------+         ||
//          promote  ||       /\       /\                   ||  promote
//                   ||      /||\     /||\                  ||
//                  \||/    demote     ||                  \||/
//                   \/       ||       ||                   \/
//       +-------------------------+   ||   +-------------------------+
//       | if (p0.new) memw(..)=r0 |   ||   | if (p0) memw(..)=r0.new |
//       +-------------------------+   ||   +-------------------------+
//                        ||           ||         ||
//                        ||         demote      \||/
//                      promote        ||         \/ NOT possible
//                        ||           ||         /\~
//                       \||/          ||        /||\~
//                        \/           ||         ||
//                      +-----------------------------+
//                      | if (p0.new) memw(..)=r0.new |
//                      +-----------------------------+
//                           Double Dot New Store
//
// Returns the most basic instruction for the .new predicated instructions and
// new-value stores.
// For example, all of the following instructions will be converted back to the
// same instruction:
// 1) if (p0.new) memw(R0+#0) = R1.new  --->
// 2) if (p0) memw(R0+#0)= R1.new      -------> if (p0) memw(R0+#0) = R1
// 3) if (p0.new) memw(R0+#0) = R1      --->
//
// To understand the translation of instruction 1 to its original form, consider
// a packet with 3 instructions.
// { p0 = cmp.eq(R0,R1)
//   if (p0.new) R2 = add(R3, R4)
//   R5 = add (R3, R1)
// }
// if (p0) memw(R5+#0) = R2 <--- trying to include it in the previous packet
//
// This instruction can be part of the previous packet only if both p0 and R2
// are promoted to .new values. This promotion happens in steps, first
// predicate register is promoted to .new and in the next iteration R2 is
// promoted. Therefore, in case of dependence check failure (due to R5) during
// next iteration, it should be converted back to its most basic form.

// Return the new value instruction for a given store.
int HexagonInstrInfo::getDotNewOp(const MachineInstr &MI) const {}

// Returns the opcode to use when converting MI, which is a conditional jump,
// into a conditional instruction which uses the .new value of the predicate.
// We also use branch probabilities to add a hint to the jump.
// If MBPI is null, all edges will be treated as equally likely for the
// purposes of establishing a predication hint.
int HexagonInstrInfo::getDotNewPredJumpOp(const MachineInstr &MI,
      const MachineBranchProbabilityInfo *MBPI) const {}

// Return .new predicate version for an instruction.
int HexagonInstrInfo::getDotNewPredOp(const MachineInstr &MI,
      const MachineBranchProbabilityInfo *MBPI) const {}

int HexagonInstrInfo::getDotOldOp(const MachineInstr &MI) const {}

// See if instruction could potentially be a duplex candidate.
// If so, return its group. Zero otherwise.
HexagonII::SubInstructionGroup HexagonInstrInfo::getDuplexCandidateGroup(
      const MachineInstr &MI) const {}

short HexagonInstrInfo::getEquivalentHWInstr(const MachineInstr &MI) const {}

unsigned HexagonInstrInfo::getInstrTimingClassLatency(
      const InstrItineraryData *ItinData, const MachineInstr &MI) const {}

/// getOperandLatency - Compute and return the use operand latency of a given
/// pair of def and use.
/// In most cases, the static scheduling itinerary was enough to determine the
/// operand latency. But it may not be possible for instructions with variable
/// number of defs / uses.
///
/// This is a raw interface to the itinerary that may be directly overriden by
/// a target. Use computeOperandLatency to get the best estimate of latency.
std::optional<unsigned> HexagonInstrInfo::getOperandLatency(
    const InstrItineraryData *ItinData, const MachineInstr &DefMI,
    unsigned DefIdx, const MachineInstr &UseMI, unsigned UseIdx) const {}

// inverts the predication logic.
// p -> NotP
// NotP -> P
bool HexagonInstrInfo::getInvertedPredSense(
      SmallVectorImpl<MachineOperand> &Cond) const {}

unsigned HexagonInstrInfo::getInvertedPredicatedOpcode(const int Opc) const {}

// Returns the max value that doesn't need to be extended.
int HexagonInstrInfo::getMaxValue(const MachineInstr &MI) const {}


bool HexagonInstrInfo::isAddrModeWithOffset(const MachineInstr &MI) const {}

bool HexagonInstrInfo::isPureSlot0(const MachineInstr &MI) const {}

bool HexagonInstrInfo::isRestrictNoSlot1Store(const MachineInstr &MI) const {}

void HexagonInstrInfo::changeDuplexOpcode(MachineBasicBlock::instr_iterator MII,
                                          bool ToBigInstrs) const {}

// This function is used to translate instructions to facilitate generating
// Duplexes on TinyCore.
void HexagonInstrInfo::translateInstrsForDup(MachineFunction &MF,
                                             bool ToBigInstrs) const {}

// This is a specialized form of above function.
void HexagonInstrInfo::translateInstrsForDup(
    MachineBasicBlock::instr_iterator MII, bool ToBigInstrs) const {}

unsigned HexagonInstrInfo::getMemAccessSize(const MachineInstr &MI) const {}

// Returns the min value that doesn't need to be extended.
int HexagonInstrInfo::getMinValue(const MachineInstr &MI) const {}

// Returns opcode of the non-extended equivalent instruction.
short HexagonInstrInfo::getNonExtOpcode(const MachineInstr &MI) const {}

bool HexagonInstrInfo::getPredReg(ArrayRef<MachineOperand> Cond,
      Register &PredReg, unsigned &PredRegPos, unsigned &PredRegFlags) const {}

short HexagonInstrInfo::getPseudoInstrPair(const MachineInstr &MI) const {}

short HexagonInstrInfo::getRegForm(const MachineInstr &MI) const {}

// Return the number of bytes required to encode the instruction.
// Hexagon instructions are fixed length, 4 bytes, unless they
// use a constant extender, which requires another 4 bytes.
// For debug instructions and prolog labels, return 0.
unsigned HexagonInstrInfo::getSize(const MachineInstr &MI) const {}

uint64_t HexagonInstrInfo::getType(const MachineInstr &MI) const {}

InstrStage::FuncUnits HexagonInstrInfo::getUnits(const MachineInstr &MI) const {}

// Calculate size of the basic block without debug instructions.
unsigned HexagonInstrInfo::nonDbgBBSize(const MachineBasicBlock *BB) const {}

unsigned HexagonInstrInfo::nonDbgBundleSize(
      MachineBasicBlock::const_iterator BundleHead) const {}

/// immediateExtend - Changes the instruction in place to one using an immediate
/// extender.
void HexagonInstrInfo::immediateExtend(MachineInstr &MI) const {}

bool HexagonInstrInfo::invertAndChangeJumpTarget(
      MachineInstr &MI, MachineBasicBlock *NewTarget) const {}

void HexagonInstrInfo::genAllInsnTimingClasses(MachineFunction &MF) const {}

// inverts the predication logic.
// p -> NotP
// NotP -> P
bool HexagonInstrInfo::reversePredSense(MachineInstr &MI) const {}

// Reverse the branch prediction.
unsigned HexagonInstrInfo::reversePrediction(unsigned Opcode) const {}

// TODO: Add more rigorous validation.
bool HexagonInstrInfo::validateBranchCond(const ArrayRef<MachineOperand> &Cond)
      const {}

void HexagonInstrInfo::
setBundleNoShuf(MachineBasicBlock::instr_iterator MIB) const {}

bool HexagonInstrInfo::getBundleNoShuf(const MachineInstr &MIB) const {}

// Addressing mode relations.
short HexagonInstrInfo::changeAddrMode_abs_io(short Opc) const {}

short HexagonInstrInfo::changeAddrMode_io_abs(short Opc) const {}

short HexagonInstrInfo::changeAddrMode_io_pi(short Opc) const {}

short HexagonInstrInfo::changeAddrMode_io_rr(short Opc) const {}

short HexagonInstrInfo::changeAddrMode_pi_io(short Opc) const {}

short HexagonInstrInfo::changeAddrMode_rr_io(short Opc) const {}

short HexagonInstrInfo::changeAddrMode_rr_ur(short Opc) const {}

short HexagonInstrInfo::changeAddrMode_ur_rr(short Opc) const {}

MCInst HexagonInstrInfo::getNop() const {}