llvm/llvm/lib/CodeGen/MachineInstr.cpp

//===- lib/CodeGen/MachineInstr.cpp ---------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Methods common to all machine instructions.
//
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineInstrBundle.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/CodeGen/Register.h"
#include "llvm/CodeGen/StackMaps.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/CodeGenTypes/LowLevelType.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/ModuleSlotTracker.h"
#include "llvm/IR/Operator.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <cstring>
#include <utility>

usingnamespacellvm;

static const MachineFunction *getMFIfAvailable(const MachineInstr &MI) {}

// Try to crawl up to the machine function and get TRI and IntrinsicInfo from
// it.
static void tryToGetTargetInfo(const MachineInstr &MI,
                               const TargetRegisterInfo *&TRI,
                               const MachineRegisterInfo *&MRI,
                               const TargetIntrinsicInfo *&IntrinsicInfo,
                               const TargetInstrInfo *&TII) {}

void MachineInstr::addImplicitDefUseOperands(MachineFunction &MF) {}

/// MachineInstr ctor - This constructor creates a MachineInstr and adds the
/// implicit operands. It reserves space for the number of operands specified by
/// the MCInstrDesc.
MachineInstr::MachineInstr(MachineFunction &MF, const MCInstrDesc &TID,
                           DebugLoc DL, bool NoImp)
    :{}

/// MachineInstr ctor - Copies MachineInstr arg exactly.
/// Does not copy the number from debug instruction numbering, to preserve
/// uniqueness.
MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI)
    :{}

void MachineInstr::setDesc(const MCInstrDesc &TID) {}

void MachineInstr::moveBefore(MachineInstr *MovePos) {}

/// getRegInfo - If this instruction is embedded into a MachineFunction,
/// return the MachineRegisterInfo object for the current function, otherwise
/// return null.
MachineRegisterInfo *MachineInstr::getRegInfo() {}

const MachineRegisterInfo *MachineInstr::getRegInfo() const {}

void MachineInstr::removeRegOperandsFromUseLists(MachineRegisterInfo &MRI) {}

void MachineInstr::addRegOperandsToUseLists(MachineRegisterInfo &MRI) {}

void MachineInstr::addOperand(const MachineOperand &Op) {}

/// Move NumOps MachineOperands from Src to Dst, with support for overlapping
/// ranges. If MRI is non-null also update use-def chains.
static void moveOperands(MachineOperand *Dst, MachineOperand *Src,
                         unsigned NumOps, MachineRegisterInfo *MRI) {}

/// addOperand - Add the specified operand to the instruction.  If it is an
/// implicit operand, it is added to the end of the operand list.  If it is
/// an explicit operand it is added at the end of the explicit operand list
/// (before the first implicit operand).
void MachineInstr::addOperand(MachineFunction &MF, const MachineOperand &Op) {}

void MachineInstr::removeOperand(unsigned OpNo) {}

void MachineInstr::setExtraInfo(MachineFunction &MF,
                                ArrayRef<MachineMemOperand *> MMOs,
                                MCSymbol *PreInstrSymbol,
                                MCSymbol *PostInstrSymbol,
                                MDNode *HeapAllocMarker, MDNode *PCSections,
                                uint32_t CFIType, MDNode *MMRAs) {}

void MachineInstr::dropMemRefs(MachineFunction &MF) {}

void MachineInstr::setMemRefs(MachineFunction &MF,
                              ArrayRef<MachineMemOperand *> MMOs) {}

void MachineInstr::addMemOperand(MachineFunction &MF,
                                 MachineMemOperand *MO) {}

void MachineInstr::cloneMemRefs(MachineFunction &MF, const MachineInstr &MI) {}

/// Check to see if the MMOs pointed to by the two MemRefs arrays are
/// identical.
static bool hasIdenticalMMOs(ArrayRef<MachineMemOperand *> LHS,
                             ArrayRef<MachineMemOperand *> RHS) {}

void MachineInstr::cloneMergedMemRefs(MachineFunction &MF,
                                      ArrayRef<const MachineInstr *> MIs) {}

void MachineInstr::setPreInstrSymbol(MachineFunction &MF, MCSymbol *Symbol) {}

void MachineInstr::setPostInstrSymbol(MachineFunction &MF, MCSymbol *Symbol) {}

void MachineInstr::setHeapAllocMarker(MachineFunction &MF, MDNode *Marker) {}

void MachineInstr::setPCSections(MachineFunction &MF, MDNode *PCSections) {}

void MachineInstr::setCFIType(MachineFunction &MF, uint32_t Type) {}

void MachineInstr::setMMRAMetadata(MachineFunction &MF, MDNode *MMRAs) {}

void MachineInstr::cloneInstrSymbols(MachineFunction &MF,
                                     const MachineInstr &MI) {}

uint32_t MachineInstr::mergeFlagsWith(const MachineInstr &Other) const {}

uint32_t MachineInstr::copyFlagsFromInstruction(const Instruction &I) {}

void MachineInstr::copyIRFlags(const Instruction &I) {}

bool MachineInstr::hasPropertyInBundle(uint64_t Mask, QueryType Type) const {}

bool MachineInstr::isIdenticalTo(const MachineInstr &Other,
                                 MICheckType Check) const {}

bool MachineInstr::isEquivalentDbgInstr(const MachineInstr &Other) const {}

const MachineFunction *MachineInstr::getMF() const {}

MachineInstr *MachineInstr::removeFromParent() {}

MachineInstr *MachineInstr::removeFromBundle() {}

void MachineInstr::eraseFromParent() {}

void MachineInstr::eraseFromBundle() {}

bool MachineInstr::isCandidateForCallSiteEntry(QueryType Type) const {}

bool MachineInstr::shouldUpdateCallSiteInfo() const {}

unsigned MachineInstr::getNumExplicitOperands() const {}

unsigned MachineInstr::getNumExplicitDefs() const {}

void MachineInstr::bundleWithPred() {}

void MachineInstr::bundleWithSucc() {}

void MachineInstr::unbundleFromPred() {}

void MachineInstr::unbundleFromSucc() {}

bool MachineInstr::isStackAligningInlineAsm() const {}

InlineAsm::AsmDialect MachineInstr::getInlineAsmDialect() const {}

int MachineInstr::findInlineAsmFlagIdx(unsigned OpIdx,
                                       unsigned *GroupNo) const {}

const DILabel *MachineInstr::getDebugLabel() const {}

const MachineOperand &MachineInstr::getDebugVariableOp() const {}

MachineOperand &MachineInstr::getDebugVariableOp() {}

const DILocalVariable *MachineInstr::getDebugVariable() const {}

const MachineOperand &MachineInstr::getDebugExpressionOp() const {}

MachineOperand &MachineInstr::getDebugExpressionOp() {}

const DIExpression *MachineInstr::getDebugExpression() const {}

bool MachineInstr::isDebugEntryValue() const {}

const TargetRegisterClass*
MachineInstr::getRegClassConstraint(unsigned OpIdx,
                                    const TargetInstrInfo *TII,
                                    const TargetRegisterInfo *TRI) const {}

const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVReg(
    Register Reg, const TargetRegisterClass *CurRC, const TargetInstrInfo *TII,
    const TargetRegisterInfo *TRI, bool ExploreBundle) const {}

const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVRegImpl(
    unsigned OpIdx, Register Reg, const TargetRegisterClass *CurRC,
    const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const {}

const TargetRegisterClass *MachineInstr::getRegClassConstraintEffect(
    unsigned OpIdx, const TargetRegisterClass *CurRC,
    const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const {}

/// Return the number of instructions inside the MI bundle, not counting the
/// header instruction.
unsigned MachineInstr::getBundleSize() const {}

/// Returns true if the MachineInstr has an implicit-use operand of exactly
/// the given register (not considering sub/super-registers).
bool MachineInstr::hasRegisterImplicitUseOperand(Register Reg) const {}

/// findRegisterUseOperandIdx() - Returns the MachineOperand that is a use of
/// the specific register or -1 if it is not found. It further tightens
/// the search criteria to a use that kills the register if isKill is true.
int MachineInstr::findRegisterUseOperandIdx(Register Reg,
                                            const TargetRegisterInfo *TRI,
                                            bool isKill) const {}

/// readsWritesVirtualRegister - Return a pair of bools (reads, writes)
/// indicating if this instruction reads or writes Reg. This also considers
/// partial defines.
std::pair<bool,bool>
MachineInstr::readsWritesVirtualRegister(Register Reg,
                                         SmallVectorImpl<unsigned> *Ops) const {}

/// findRegisterDefOperandIdx() - Returns the operand index that is a def of
/// the specified register or -1 if it is not found. If isDead is true, defs
/// that are not dead are skipped. If TargetRegisterInfo is non-null, then it
/// also checks if there is a def of a super-register.
int MachineInstr::findRegisterDefOperandIdx(Register Reg,
                                            const TargetRegisterInfo *TRI,
                                            bool isDead, bool Overlap) const {}

/// findFirstPredOperandIdx() - Find the index of the first operand in the
/// operand list that is used to represent the predicate. It returns -1 if
/// none is found.
int MachineInstr::findFirstPredOperandIdx() const {}

// MachineOperand::TiedTo is 4 bits wide.
const unsigned TiedMax =;

/// tieOperands - Mark operands at DefIdx and UseIdx as tied to each other.
///
/// Use and def operands can be tied together, indicated by a non-zero TiedTo
/// field. TiedTo can have these values:
///
/// 0:              Operand is not tied to anything.
/// 1 to TiedMax-1: Tied to getOperand(TiedTo-1).
/// TiedMax:        Tied to an operand >= TiedMax-1.
///
/// The tied def must be one of the first TiedMax operands on a normal
/// instruction. INLINEASM instructions allow more tied defs.
///
void MachineInstr::tieOperands(unsigned DefIdx, unsigned UseIdx) {}

/// Given the index of a tied register operand, find the operand it is tied to.
/// Defs are tied to uses and vice versa. Returns the index of the tied operand
/// which must exist.
unsigned MachineInstr::findTiedOperandIdx(unsigned OpIdx) const {}

/// clearKillInfo - Clears kill flags on all operands.
///
void MachineInstr::clearKillInfo() {}

void MachineInstr::substituteRegister(Register FromReg, Register ToReg,
                                      unsigned SubIdx,
                                      const TargetRegisterInfo &RegInfo) {}

/// isSafeToMove - Return true if it is safe to move this instruction. If
/// SawStore is set to true, it means that there is a store (or call) between
/// the instruction's location and its intended destination.
bool MachineInstr::isSafeToMove(bool &SawStore) const {}

bool MachineInstr::wouldBeTriviallyDead() const {}

static bool MemOperandsHaveAlias(const MachineFrameInfo &MFI, AAResults *AA,
                                 bool UseTBAA, const MachineMemOperand *MMOa,
                                 const MachineMemOperand *MMOb) {}

bool MachineInstr::mayAlias(AAResults *AA, const MachineInstr &Other,
                            bool UseTBAA) const {}

/// hasOrderedMemoryRef - Return true if this instruction may have an ordered
/// or volatile memory reference, or if the information describing the memory
/// reference is not available. Return false if it is known to have no ordered
/// memory references.
bool MachineInstr::hasOrderedMemoryRef() const {}

/// isDereferenceableInvariantLoad - Return true if this instruction will never
/// trap and is loading from a location whose value is invariant across a run of
/// this function.
bool MachineInstr::isDereferenceableInvariantLoad() const {}

/// isConstantValuePHI - If the specified instruction is a PHI that always
/// merges together the same virtual register, return the register, otherwise
/// return 0.
unsigned MachineInstr::isConstantValuePHI() const {}

bool MachineInstr::hasUnmodeledSideEffects() const {}

bool MachineInstr::isLoadFoldBarrier() const {}

/// allDefsAreDead - Return true if all the defs of this instruction are dead.
///
bool MachineInstr::allDefsAreDead() const {}

bool MachineInstr::allImplicitDefsAreDead() const {}

/// copyImplicitOps - Copy implicit register operands from specified
/// instruction to this instruction.
void MachineInstr::copyImplicitOps(MachineFunction &MF,
                                   const MachineInstr &MI) {}

bool MachineInstr::hasComplexRegisterTies() const {}

LLT MachineInstr::getTypeToPrint(unsigned OpIdx, SmallBitVector &PrintedTypes,
                                 const MachineRegisterInfo &MRI) const {}

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void MachineInstr::dump() const {
  dbgs() << "  ";
  print(dbgs());
}

LLVM_DUMP_METHOD void MachineInstr::dumprImpl(
    const MachineRegisterInfo &MRI, unsigned Depth, unsigned MaxDepth,
    SmallPtrSetImpl<const MachineInstr *> &AlreadySeenInstrs) const {
  if (Depth >= MaxDepth)
    return;
  if (!AlreadySeenInstrs.insert(this).second)
    return;
  // PadToColumn always inserts at least one space.
  // Don't mess up the alignment if we don't want any space.
  if (Depth)
    fdbgs().PadToColumn(Depth * 2);
  print(fdbgs());
  for (const MachineOperand &MO : operands()) {
    if (!MO.isReg() || MO.isDef())
      continue;
    Register Reg = MO.getReg();
    if (Reg.isPhysical())
      continue;
    const MachineInstr *NewMI = MRI.getUniqueVRegDef(Reg);
    if (NewMI == nullptr)
      continue;
    NewMI->dumprImpl(MRI, Depth + 1, MaxDepth, AlreadySeenInstrs);
  }
}

LLVM_DUMP_METHOD void MachineInstr::dumpr(const MachineRegisterInfo &MRI,
                                          unsigned MaxDepth) const {
  SmallPtrSet<const MachineInstr *, 16> AlreadySeenInstrs;
  dumprImpl(MRI, 0, MaxDepth, AlreadySeenInstrs);
}
#endif

void MachineInstr::print(raw_ostream &OS, bool IsStandalone, bool SkipOpers,
                         bool SkipDebugLoc, bool AddNewLine,
                         const TargetInstrInfo *TII) const {}

void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,
                         bool IsStandalone, bool SkipOpers, bool SkipDebugLoc,
                         bool AddNewLine, const TargetInstrInfo *TII) const {}

bool MachineInstr::addRegisterKilled(Register IncomingReg,
                                     const TargetRegisterInfo *RegInfo,
                                     bool AddIfNotFound) {}

void MachineInstr::clearRegisterKills(Register Reg,
                                      const TargetRegisterInfo *RegInfo) {}

bool MachineInstr::addRegisterDead(Register Reg,
                                   const TargetRegisterInfo *RegInfo,
                                   bool AddIfNotFound) {}

void MachineInstr::clearRegisterDeads(Register Reg) {}

void MachineInstr::setRegisterDefReadUndef(Register Reg, bool IsUndef) {}

void MachineInstr::addRegisterDefined(Register Reg,
                                      const TargetRegisterInfo *RegInfo) {}

void MachineInstr::setPhysRegsDeadExcept(ArrayRef<Register> UsedRegs,
                                         const TargetRegisterInfo &TRI) {}

unsigned
MachineInstrExpressionTrait::getHashValue(const MachineInstr* const &MI) {}

void MachineInstr::emitError(StringRef Msg) const {}

MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL,
                                  const MCInstrDesc &MCID, bool IsIndirect,
                                  Register Reg, const MDNode *Variable,
                                  const MDNode *Expr) {}

MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL,
                                  const MCInstrDesc &MCID, bool IsIndirect,
                                  ArrayRef<MachineOperand> DebugOps,
                                  const MDNode *Variable, const MDNode *Expr) {}

MachineInstrBuilder llvm::BuildMI(MachineBasicBlock &BB,
                                  MachineBasicBlock::iterator I,
                                  const DebugLoc &DL, const MCInstrDesc &MCID,
                                  bool IsIndirect, Register Reg,
                                  const MDNode *Variable, const MDNode *Expr) {}

MachineInstrBuilder llvm::BuildMI(MachineBasicBlock &BB,
                                  MachineBasicBlock::iterator I,
                                  const DebugLoc &DL, const MCInstrDesc &MCID,
                                  bool IsIndirect,
                                  ArrayRef<MachineOperand> DebugOps,
                                  const MDNode *Variable, const MDNode *Expr) {}

/// Compute the new DIExpression to use with a DBG_VALUE for a spill slot.
/// This prepends DW_OP_deref when spilling an indirect DBG_VALUE.
static const DIExpression *computeExprForSpill(
    const MachineInstr &MI,
    const SmallVectorImpl<const MachineOperand *> &SpilledOperands) {}
static const DIExpression *computeExprForSpill(const MachineInstr &MI,
                                               Register SpillReg) {}

MachineInstr *llvm::buildDbgValueForSpill(MachineBasicBlock &BB,
                                          MachineBasicBlock::iterator I,
                                          const MachineInstr &Orig,
                                          int FrameIndex, Register SpillReg) {}
MachineInstr *llvm::buildDbgValueForSpill(
    MachineBasicBlock &BB, MachineBasicBlock::iterator I,
    const MachineInstr &Orig, int FrameIndex,
    const SmallVectorImpl<const MachineOperand *> &SpilledOperands) {}

void llvm::updateDbgValueForSpill(MachineInstr &Orig, int FrameIndex,
                                  Register Reg) {}

void MachineInstr::collectDebugValues(
                                SmallVectorImpl<MachineInstr *> &DbgValues) {}

void MachineInstr::changeDebugValuesDefReg(Register Reg) {}

MMOList;

static LocationSize getSpillSlotSize(const MMOList &Accesses,
                                     const MachineFrameInfo &MFI) {}

std::optional<LocationSize>
MachineInstr::getSpillSize(const TargetInstrInfo *TII) const {}

std::optional<LocationSize>
MachineInstr::getFoldedSpillSize(const TargetInstrInfo *TII) const {}

std::optional<LocationSize>
MachineInstr::getRestoreSize(const TargetInstrInfo *TII) const {}

std::optional<LocationSize>
MachineInstr::getFoldedRestoreSize(const TargetInstrInfo *TII) const {}

unsigned MachineInstr::getDebugInstrNum() {}

unsigned MachineInstr::getDebugInstrNum(MachineFunction &MF) {}

std::tuple<LLT, LLT> MachineInstr::getFirst2LLTs() const {}

std::tuple<LLT, LLT, LLT> MachineInstr::getFirst3LLTs() const {}

std::tuple<LLT, LLT, LLT, LLT> MachineInstr::getFirst4LLTs() const {}

std::tuple<LLT, LLT, LLT, LLT, LLT> MachineInstr::getFirst5LLTs() const {}

std::tuple<Register, LLT, Register, LLT>
MachineInstr::getFirst2RegLLTs() const {}

std::tuple<Register, LLT, Register, LLT, Register, LLT>
MachineInstr::getFirst3RegLLTs() const {}

std::tuple<Register, LLT, Register, LLT, Register, LLT, Register, LLT>
MachineInstr::getFirst4RegLLTs() const {}

std::tuple<Register, LLT, Register, LLT, Register, LLT, Register, LLT, Register,
           LLT>
MachineInstr::getFirst5RegLLTs() const {}

void MachineInstr::insert(mop_iterator InsertBefore,
                          ArrayRef<MachineOperand> Ops) {}

bool MachineInstr::mayFoldInlineAsmRegOp(unsigned OpId) const {}