10b57cec5SDimitry Andric //===- lib/CodeGen/MachineOperand.cpp -------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric /// \file Methods common to all machine operands. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h" 145f757f3fSDimitry Andric #include "llvm/ADT/StableHashing.h" 150b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h" 160b57cec5SDimitry Andric #include "llvm/Analysis/Loads.h" 17480093f4SDimitry Andric #include "llvm/CodeGen/MIRFormatter.h" 180b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h" 190b57cec5SDimitry Andric #include "llvm/CodeGen/MachineJumpTableInfo.h" 200b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 215f757f3fSDimitry Andric #include "llvm/CodeGen/PseudoSourceValueManager.h" 220b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h" 230b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h" 240b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h" 250b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 260b57cec5SDimitry Andric #include "llvm/IR/IRPrintingPasses.h" 275ffd83dbSDimitry Andric #include "llvm/IR/Instructions.h" 280b57cec5SDimitry Andric #include "llvm/IR/ModuleSlotTracker.h" 290b57cec5SDimitry Andric #include "llvm/MC/MCDwarf.h" 300b57cec5SDimitry Andric #include "llvm/Target/TargetIntrinsicInfo.h" 310b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h" 32bdd1243dSDimitry Andric #include <optional> 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric using namespace llvm; 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric static cl::opt<int> 370b57cec5SDimitry Andric PrintRegMaskNumRegs("print-regmask-num-regs", 380b57cec5SDimitry Andric cl::desc("Number of registers to limit to when " 390b57cec5SDimitry Andric "printing regmask operands in IR dumps. " 400b57cec5SDimitry Andric "unlimited = -1"), 410b57cec5SDimitry Andric cl::init(32), cl::Hidden); 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric static const MachineFunction *getMFIfAvailable(const MachineOperand &MO) { 440b57cec5SDimitry Andric if (const MachineInstr *MI = MO.getParent()) 450b57cec5SDimitry Andric if (const MachineBasicBlock *MBB = MI->getParent()) 460b57cec5SDimitry Andric if (const MachineFunction *MF = MBB->getParent()) 470b57cec5SDimitry Andric return MF; 480b57cec5SDimitry Andric return nullptr; 490b57cec5SDimitry Andric } 50bdd1243dSDimitry Andric 510b57cec5SDimitry Andric static MachineFunction *getMFIfAvailable(MachineOperand &MO) { 520b57cec5SDimitry Andric return const_cast<MachineFunction *>( 530b57cec5SDimitry Andric getMFIfAvailable(const_cast<const MachineOperand &>(MO))); 540b57cec5SDimitry Andric } 550b57cec5SDimitry Andric 5606c3fb27SDimitry Andric unsigned MachineOperand::getOperandNo() const { 5706c3fb27SDimitry Andric assert(getParent() && "Operand does not belong to any instruction!"); 5806c3fb27SDimitry Andric return getParent()->getOperandNo(this); 5906c3fb27SDimitry Andric } 6006c3fb27SDimitry Andric 618bcb0991SDimitry Andric void MachineOperand::setReg(Register Reg) { 620b57cec5SDimitry Andric if (getReg() == Reg) 630b57cec5SDimitry Andric return; // No change. 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric // Clear the IsRenamable bit to keep it conservatively correct. 660b57cec5SDimitry Andric IsRenamable = false; 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric // Otherwise, we have to change the register. If this operand is embedded 690b57cec5SDimitry Andric // into a machine function, we need to update the old and new register's 700b57cec5SDimitry Andric // use/def lists. 710b57cec5SDimitry Andric if (MachineFunction *MF = getMFIfAvailable(*this)) { 720b57cec5SDimitry Andric MachineRegisterInfo &MRI = MF->getRegInfo(); 730b57cec5SDimitry Andric MRI.removeRegOperandFromUseList(this); 740b57cec5SDimitry Andric SmallContents.RegNo = Reg; 750b57cec5SDimitry Andric MRI.addRegOperandToUseList(this); 760b57cec5SDimitry Andric return; 770b57cec5SDimitry Andric } 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric // Otherwise, just change the register, no problem. :) 800b57cec5SDimitry Andric SmallContents.RegNo = Reg; 810b57cec5SDimitry Andric } 820b57cec5SDimitry Andric 838bcb0991SDimitry Andric void MachineOperand::substVirtReg(Register Reg, unsigned SubIdx, 840b57cec5SDimitry Andric const TargetRegisterInfo &TRI) { 858bcb0991SDimitry Andric assert(Reg.isVirtual()); 860b57cec5SDimitry Andric if (SubIdx && getSubReg()) 870b57cec5SDimitry Andric SubIdx = TRI.composeSubRegIndices(SubIdx, getSubReg()); 880b57cec5SDimitry Andric setReg(Reg); 890b57cec5SDimitry Andric if (SubIdx) 900b57cec5SDimitry Andric setSubReg(SubIdx); 910b57cec5SDimitry Andric } 920b57cec5SDimitry Andric 938bcb0991SDimitry Andric void MachineOperand::substPhysReg(MCRegister Reg, const TargetRegisterInfo &TRI) { 94e8d8bef9SDimitry Andric assert(Register::isPhysicalRegister(Reg)); 950b57cec5SDimitry Andric if (getSubReg()) { 960b57cec5SDimitry Andric Reg = TRI.getSubReg(Reg, getSubReg()); 970b57cec5SDimitry Andric // Note that getSubReg() may return 0 if the sub-register doesn't exist. 980b57cec5SDimitry Andric // That won't happen in legal code. 990b57cec5SDimitry Andric setSubReg(0); 1000b57cec5SDimitry Andric if (isDef()) 1010b57cec5SDimitry Andric setIsUndef(false); 1020b57cec5SDimitry Andric } 1030b57cec5SDimitry Andric setReg(Reg); 1040b57cec5SDimitry Andric } 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andric /// Change a def to a use, or a use to a def. 1070b57cec5SDimitry Andric void MachineOperand::setIsDef(bool Val) { 1080b57cec5SDimitry Andric assert(isReg() && "Wrong MachineOperand accessor"); 1090b57cec5SDimitry Andric assert((!Val || !isDebug()) && "Marking a debug operation as def"); 1100b57cec5SDimitry Andric if (IsDef == Val) 1110b57cec5SDimitry Andric return; 1120b57cec5SDimitry Andric assert(!IsDeadOrKill && "Changing def/use with dead/kill set not supported"); 1130b57cec5SDimitry Andric // MRI may keep uses and defs in different list positions. 1140b57cec5SDimitry Andric if (MachineFunction *MF = getMFIfAvailable(*this)) { 1150b57cec5SDimitry Andric MachineRegisterInfo &MRI = MF->getRegInfo(); 1160b57cec5SDimitry Andric MRI.removeRegOperandFromUseList(this); 1170b57cec5SDimitry Andric IsDef = Val; 1180b57cec5SDimitry Andric MRI.addRegOperandToUseList(this); 1190b57cec5SDimitry Andric return; 1200b57cec5SDimitry Andric } 1210b57cec5SDimitry Andric IsDef = Val; 1220b57cec5SDimitry Andric } 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric bool MachineOperand::isRenamable() const { 1250b57cec5SDimitry Andric assert(isReg() && "Wrong MachineOperand accessor"); 126bdd1243dSDimitry Andric assert(getReg().isPhysical() && 1270b57cec5SDimitry Andric "isRenamable should only be checked on physical registers"); 1280b57cec5SDimitry Andric if (!IsRenamable) 1290b57cec5SDimitry Andric return false; 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric const MachineInstr *MI = getParent(); 1320b57cec5SDimitry Andric if (!MI) 1330b57cec5SDimitry Andric return true; 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric if (isDef()) 1360b57cec5SDimitry Andric return !MI->hasExtraDefRegAllocReq(MachineInstr::IgnoreBundle); 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric assert(isUse() && "Reg is not def or use"); 1390b57cec5SDimitry Andric return !MI->hasExtraSrcRegAllocReq(MachineInstr::IgnoreBundle); 1400b57cec5SDimitry Andric } 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric void MachineOperand::setIsRenamable(bool Val) { 1430b57cec5SDimitry Andric assert(isReg() && "Wrong MachineOperand accessor"); 144bdd1243dSDimitry Andric assert(getReg().isPhysical() && 1450b57cec5SDimitry Andric "setIsRenamable should only be called on physical registers"); 1460b57cec5SDimitry Andric IsRenamable = Val; 1470b57cec5SDimitry Andric } 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric // If this operand is currently a register operand, and if this is in a 1500b57cec5SDimitry Andric // function, deregister the operand from the register's use/def list. 1510b57cec5SDimitry Andric void MachineOperand::removeRegFromUses() { 1520b57cec5SDimitry Andric if (!isReg() || !isOnRegUseList()) 1530b57cec5SDimitry Andric return; 1540b57cec5SDimitry Andric 1550b57cec5SDimitry Andric if (MachineFunction *MF = getMFIfAvailable(*this)) 1560b57cec5SDimitry Andric MF->getRegInfo().removeRegOperandFromUseList(this); 1570b57cec5SDimitry Andric } 1580b57cec5SDimitry Andric 1590b57cec5SDimitry Andric /// ChangeToImmediate - Replace this operand with a new immediate operand of 1600b57cec5SDimitry Andric /// the specified value. If an operand is known to be an immediate already, 1610b57cec5SDimitry Andric /// the setImm method should be used. 162e8d8bef9SDimitry Andric void MachineOperand::ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags) { 1630b57cec5SDimitry Andric assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm"); 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric removeRegFromUses(); 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andric OpKind = MO_Immediate; 1680b57cec5SDimitry Andric Contents.ImmVal = ImmVal; 169e8d8bef9SDimitry Andric setTargetFlags(TargetFlags); 1700b57cec5SDimitry Andric } 1710b57cec5SDimitry Andric 172e8d8bef9SDimitry Andric void MachineOperand::ChangeToFPImmediate(const ConstantFP *FPImm, 173e8d8bef9SDimitry Andric unsigned TargetFlags) { 1740b57cec5SDimitry Andric assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm"); 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric removeRegFromUses(); 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric OpKind = MO_FPImmediate; 1790b57cec5SDimitry Andric Contents.CFP = FPImm; 180e8d8bef9SDimitry Andric setTargetFlags(TargetFlags); 1810b57cec5SDimitry Andric } 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric void MachineOperand::ChangeToES(const char *SymName, 1848bcb0991SDimitry Andric unsigned TargetFlags) { 1850b57cec5SDimitry Andric assert((!isReg() || !isTied()) && 1860b57cec5SDimitry Andric "Cannot change a tied operand into an external symbol"); 1870b57cec5SDimitry Andric 1880b57cec5SDimitry Andric removeRegFromUses(); 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric OpKind = MO_ExternalSymbol; 1910b57cec5SDimitry Andric Contents.OffsetedInfo.Val.SymbolName = SymName; 1920b57cec5SDimitry Andric setOffset(0); // Offset is always 0. 1930b57cec5SDimitry Andric setTargetFlags(TargetFlags); 1940b57cec5SDimitry Andric } 1950b57cec5SDimitry Andric 1960b57cec5SDimitry Andric void MachineOperand::ChangeToGA(const GlobalValue *GV, int64_t Offset, 1978bcb0991SDimitry Andric unsigned TargetFlags) { 1980b57cec5SDimitry Andric assert((!isReg() || !isTied()) && 1990b57cec5SDimitry Andric "Cannot change a tied operand into a global address"); 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric removeRegFromUses(); 2020b57cec5SDimitry Andric 2030b57cec5SDimitry Andric OpKind = MO_GlobalAddress; 2040b57cec5SDimitry Andric Contents.OffsetedInfo.Val.GV = GV; 2050b57cec5SDimitry Andric setOffset(Offset); 2060b57cec5SDimitry Andric setTargetFlags(TargetFlags); 2070b57cec5SDimitry Andric } 2080b57cec5SDimitry Andric 2097a6dacacSDimitry Andric void MachineOperand::ChangeToBA(const BlockAddress *BA, int64_t Offset, 2107a6dacacSDimitry Andric unsigned TargetFlags) { 2117a6dacacSDimitry Andric assert((!isReg() || !isTied()) && 2127a6dacacSDimitry Andric "Cannot change a tied operand into a block address"); 2137a6dacacSDimitry Andric 2147a6dacacSDimitry Andric removeRegFromUses(); 2157a6dacacSDimitry Andric 2167a6dacacSDimitry Andric OpKind = MO_BlockAddress; 2177a6dacacSDimitry Andric Contents.OffsetedInfo.Val.BA = BA; 2187a6dacacSDimitry Andric setOffset(Offset); 2197a6dacacSDimitry Andric setTargetFlags(TargetFlags); 2207a6dacacSDimitry Andric } 2217a6dacacSDimitry Andric 222e8d8bef9SDimitry Andric void MachineOperand::ChangeToMCSymbol(MCSymbol *Sym, unsigned TargetFlags) { 2230b57cec5SDimitry Andric assert((!isReg() || !isTied()) && 2240b57cec5SDimitry Andric "Cannot change a tied operand into an MCSymbol"); 2250b57cec5SDimitry Andric 2260b57cec5SDimitry Andric removeRegFromUses(); 2270b57cec5SDimitry Andric 2280b57cec5SDimitry Andric OpKind = MO_MCSymbol; 2290b57cec5SDimitry Andric Contents.Sym = Sym; 230e8d8bef9SDimitry Andric setTargetFlags(TargetFlags); 2310b57cec5SDimitry Andric } 2320b57cec5SDimitry Andric 233e8d8bef9SDimitry Andric void MachineOperand::ChangeToFrameIndex(int Idx, unsigned TargetFlags) { 2340b57cec5SDimitry Andric assert((!isReg() || !isTied()) && 2350b57cec5SDimitry Andric "Cannot change a tied operand into a FrameIndex"); 2360b57cec5SDimitry Andric 2370b57cec5SDimitry Andric removeRegFromUses(); 2380b57cec5SDimitry Andric 2390b57cec5SDimitry Andric OpKind = MO_FrameIndex; 2400b57cec5SDimitry Andric setIndex(Idx); 241e8d8bef9SDimitry Andric setTargetFlags(TargetFlags); 2420b57cec5SDimitry Andric } 2430b57cec5SDimitry Andric 2440b57cec5SDimitry Andric void MachineOperand::ChangeToTargetIndex(unsigned Idx, int64_t Offset, 2458bcb0991SDimitry Andric unsigned TargetFlags) { 2460b57cec5SDimitry Andric assert((!isReg() || !isTied()) && 2470b57cec5SDimitry Andric "Cannot change a tied operand into a FrameIndex"); 2480b57cec5SDimitry Andric 2490b57cec5SDimitry Andric removeRegFromUses(); 2500b57cec5SDimitry Andric 2510b57cec5SDimitry Andric OpKind = MO_TargetIndex; 2520b57cec5SDimitry Andric setIndex(Idx); 2530b57cec5SDimitry Andric setOffset(Offset); 2540b57cec5SDimitry Andric setTargetFlags(TargetFlags); 2550b57cec5SDimitry Andric } 2560b57cec5SDimitry Andric 257bdd1243dSDimitry Andric void MachineOperand::ChangeToDbgInstrRef(unsigned InstrIdx, unsigned OpIdx, 258bdd1243dSDimitry Andric unsigned TargetFlags) { 259bdd1243dSDimitry Andric assert((!isReg() || !isTied()) && 260bdd1243dSDimitry Andric "Cannot change a tied operand into a DbgInstrRef"); 261bdd1243dSDimitry Andric 262bdd1243dSDimitry Andric removeRegFromUses(); 263bdd1243dSDimitry Andric 264bdd1243dSDimitry Andric OpKind = MO_DbgInstrRef; 265bdd1243dSDimitry Andric setInstrRefInstrIndex(InstrIdx); 266bdd1243dSDimitry Andric setInstrRefOpIndex(OpIdx); 267bdd1243dSDimitry Andric setTargetFlags(TargetFlags); 268bdd1243dSDimitry Andric } 269bdd1243dSDimitry Andric 2700b57cec5SDimitry Andric /// ChangeToRegister - Replace this operand with a new register operand of 2710b57cec5SDimitry Andric /// the specified value. If an operand is known to be an register already, 2720b57cec5SDimitry Andric /// the setReg method should be used. 2738bcb0991SDimitry Andric void MachineOperand::ChangeToRegister(Register Reg, bool isDef, bool isImp, 2740b57cec5SDimitry Andric bool isKill, bool isDead, bool isUndef, 2750b57cec5SDimitry Andric bool isDebug) { 2760b57cec5SDimitry Andric MachineRegisterInfo *RegInfo = nullptr; 2770b57cec5SDimitry Andric if (MachineFunction *MF = getMFIfAvailable(*this)) 2780b57cec5SDimitry Andric RegInfo = &MF->getRegInfo(); 2790b57cec5SDimitry Andric // If this operand is already a register operand, remove it from the 2800b57cec5SDimitry Andric // register's use/def lists. 2810b57cec5SDimitry Andric bool WasReg = isReg(); 2820b57cec5SDimitry Andric if (RegInfo && WasReg) 2830b57cec5SDimitry Andric RegInfo->removeRegOperandFromUseList(this); 2840b57cec5SDimitry Andric 285349cc55cSDimitry Andric // Ensure debug instructions set debug flag on register uses. 286349cc55cSDimitry Andric const MachineInstr *MI = getParent(); 287349cc55cSDimitry Andric if (!isDef && MI && MI->isDebugInstr()) 288349cc55cSDimitry Andric isDebug = true; 289349cc55cSDimitry Andric 2900b57cec5SDimitry Andric // Change this to a register and set the reg#. 2910b57cec5SDimitry Andric assert(!(isDead && !isDef) && "Dead flag on non-def"); 2920b57cec5SDimitry Andric assert(!(isKill && isDef) && "Kill flag on def"); 2930b57cec5SDimitry Andric OpKind = MO_Register; 2940b57cec5SDimitry Andric SmallContents.RegNo = Reg; 2950b57cec5SDimitry Andric SubReg_TargetFlags = 0; 2960b57cec5SDimitry Andric IsDef = isDef; 2970b57cec5SDimitry Andric IsImp = isImp; 2980b57cec5SDimitry Andric IsDeadOrKill = isKill | isDead; 2990b57cec5SDimitry Andric IsRenamable = false; 3000b57cec5SDimitry Andric IsUndef = isUndef; 3010b57cec5SDimitry Andric IsInternalRead = false; 3020b57cec5SDimitry Andric IsEarlyClobber = false; 3030b57cec5SDimitry Andric IsDebug = isDebug; 3040b57cec5SDimitry Andric // Ensure isOnRegUseList() returns false. 3050b57cec5SDimitry Andric Contents.Reg.Prev = nullptr; 3060b57cec5SDimitry Andric // Preserve the tie when the operand was already a register. 3070b57cec5SDimitry Andric if (!WasReg) 3080b57cec5SDimitry Andric TiedTo = 0; 3090b57cec5SDimitry Andric 3100b57cec5SDimitry Andric // If this operand is embedded in a function, add the operand to the 3110b57cec5SDimitry Andric // register's use/def list. 3120b57cec5SDimitry Andric if (RegInfo) 3130b57cec5SDimitry Andric RegInfo->addRegOperandToUseList(this); 3140b57cec5SDimitry Andric } 3150b57cec5SDimitry Andric 3160b57cec5SDimitry Andric /// isIdenticalTo - Return true if this operand is identical to the specified 3170b57cec5SDimitry Andric /// operand. Note that this should stay in sync with the hash_value overload 3180b57cec5SDimitry Andric /// below. 3190b57cec5SDimitry Andric bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const { 3200b57cec5SDimitry Andric if (getType() != Other.getType() || 3210b57cec5SDimitry Andric getTargetFlags() != Other.getTargetFlags()) 3220b57cec5SDimitry Andric return false; 3230b57cec5SDimitry Andric 3240b57cec5SDimitry Andric switch (getType()) { 3250b57cec5SDimitry Andric case MachineOperand::MO_Register: 3260b57cec5SDimitry Andric return getReg() == Other.getReg() && isDef() == Other.isDef() && 3270b57cec5SDimitry Andric getSubReg() == Other.getSubReg(); 3280b57cec5SDimitry Andric case MachineOperand::MO_Immediate: 3290b57cec5SDimitry Andric return getImm() == Other.getImm(); 3300b57cec5SDimitry Andric case MachineOperand::MO_CImmediate: 3310b57cec5SDimitry Andric return getCImm() == Other.getCImm(); 3320b57cec5SDimitry Andric case MachineOperand::MO_FPImmediate: 3330b57cec5SDimitry Andric return getFPImm() == Other.getFPImm(); 3340b57cec5SDimitry Andric case MachineOperand::MO_MachineBasicBlock: 3350b57cec5SDimitry Andric return getMBB() == Other.getMBB(); 3360b57cec5SDimitry Andric case MachineOperand::MO_FrameIndex: 3370b57cec5SDimitry Andric return getIndex() == Other.getIndex(); 3380b57cec5SDimitry Andric case MachineOperand::MO_ConstantPoolIndex: 3390b57cec5SDimitry Andric case MachineOperand::MO_TargetIndex: 3400b57cec5SDimitry Andric return getIndex() == Other.getIndex() && getOffset() == Other.getOffset(); 3410b57cec5SDimitry Andric case MachineOperand::MO_JumpTableIndex: 3420b57cec5SDimitry Andric return getIndex() == Other.getIndex(); 3430b57cec5SDimitry Andric case MachineOperand::MO_GlobalAddress: 3440b57cec5SDimitry Andric return getGlobal() == Other.getGlobal() && getOffset() == Other.getOffset(); 3450b57cec5SDimitry Andric case MachineOperand::MO_ExternalSymbol: 3460b57cec5SDimitry Andric return strcmp(getSymbolName(), Other.getSymbolName()) == 0 && 3470b57cec5SDimitry Andric getOffset() == Other.getOffset(); 3480b57cec5SDimitry Andric case MachineOperand::MO_BlockAddress: 3490b57cec5SDimitry Andric return getBlockAddress() == Other.getBlockAddress() && 3500b57cec5SDimitry Andric getOffset() == Other.getOffset(); 3510b57cec5SDimitry Andric case MachineOperand::MO_RegisterMask: 3520b57cec5SDimitry Andric case MachineOperand::MO_RegisterLiveOut: { 3530b57cec5SDimitry Andric // Shallow compare of the two RegMasks 3540b57cec5SDimitry Andric const uint32_t *RegMask = getRegMask(); 3550b57cec5SDimitry Andric const uint32_t *OtherRegMask = Other.getRegMask(); 3560b57cec5SDimitry Andric if (RegMask == OtherRegMask) 3570b57cec5SDimitry Andric return true; 3580b57cec5SDimitry Andric 3590b57cec5SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(*this)) { 3600b57cec5SDimitry Andric const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); 361bdd1243dSDimitry Andric unsigned RegMaskSize = MachineOperand::getRegMaskSize(TRI->getNumRegs()); 3620b57cec5SDimitry Andric // Deep compare of the two RegMasks 3630b57cec5SDimitry Andric return std::equal(RegMask, RegMask + RegMaskSize, OtherRegMask); 3640b57cec5SDimitry Andric } 3650b57cec5SDimitry Andric // We don't know the size of the RegMask, so we can't deep compare the two 3660b57cec5SDimitry Andric // reg masks. 3670b57cec5SDimitry Andric return false; 3680b57cec5SDimitry Andric } 3690b57cec5SDimitry Andric case MachineOperand::MO_MCSymbol: 3700b57cec5SDimitry Andric return getMCSymbol() == Other.getMCSymbol(); 371bdd1243dSDimitry Andric case MachineOperand::MO_DbgInstrRef: 372bdd1243dSDimitry Andric return getInstrRefInstrIndex() == Other.getInstrRefInstrIndex() && 373bdd1243dSDimitry Andric getInstrRefOpIndex() == Other.getInstrRefOpIndex(); 3740b57cec5SDimitry Andric case MachineOperand::MO_CFIIndex: 3750b57cec5SDimitry Andric return getCFIIndex() == Other.getCFIIndex(); 3760b57cec5SDimitry Andric case MachineOperand::MO_Metadata: 3770b57cec5SDimitry Andric return getMetadata() == Other.getMetadata(); 3780b57cec5SDimitry Andric case MachineOperand::MO_IntrinsicID: 3790b57cec5SDimitry Andric return getIntrinsicID() == Other.getIntrinsicID(); 3800b57cec5SDimitry Andric case MachineOperand::MO_Predicate: 3810b57cec5SDimitry Andric return getPredicate() == Other.getPredicate(); 3828bcb0991SDimitry Andric case MachineOperand::MO_ShuffleMask: 3838bcb0991SDimitry Andric return getShuffleMask() == Other.getShuffleMask(); 3840b57cec5SDimitry Andric } 3850b57cec5SDimitry Andric llvm_unreachable("Invalid machine operand type"); 3860b57cec5SDimitry Andric } 3870b57cec5SDimitry Andric 3880b57cec5SDimitry Andric // Note: this must stay exactly in sync with isIdenticalTo above. 3890b57cec5SDimitry Andric hash_code llvm::hash_value(const MachineOperand &MO) { 3900b57cec5SDimitry Andric switch (MO.getType()) { 3910b57cec5SDimitry Andric case MachineOperand::MO_Register: 3920b57cec5SDimitry Andric // Register operands don't have target flags. 3930b57cec5SDimitry Andric return hash_combine(MO.getType(), (unsigned)MO.getReg(), MO.getSubReg(), MO.isDef()); 3940b57cec5SDimitry Andric case MachineOperand::MO_Immediate: 3950b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getImm()); 3960b57cec5SDimitry Andric case MachineOperand::MO_CImmediate: 3970b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCImm()); 3980b57cec5SDimitry Andric case MachineOperand::MO_FPImmediate: 3990b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getFPImm()); 4000b57cec5SDimitry Andric case MachineOperand::MO_MachineBasicBlock: 4010b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMBB()); 4020b57cec5SDimitry Andric case MachineOperand::MO_FrameIndex: 4030b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex()); 4040b57cec5SDimitry Andric case MachineOperand::MO_ConstantPoolIndex: 4050b57cec5SDimitry Andric case MachineOperand::MO_TargetIndex: 4060b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex(), 4070b57cec5SDimitry Andric MO.getOffset()); 4080b57cec5SDimitry Andric case MachineOperand::MO_JumpTableIndex: 4090b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex()); 4100b57cec5SDimitry Andric case MachineOperand::MO_ExternalSymbol: 4110b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getOffset(), 4120b57cec5SDimitry Andric StringRef(MO.getSymbolName())); 4130b57cec5SDimitry Andric case MachineOperand::MO_GlobalAddress: 4140b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getGlobal(), 4150b57cec5SDimitry Andric MO.getOffset()); 4160b57cec5SDimitry Andric case MachineOperand::MO_BlockAddress: 4170b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getBlockAddress(), 4180b57cec5SDimitry Andric MO.getOffset()); 4190b57cec5SDimitry Andric case MachineOperand::MO_RegisterMask: 420bdd1243dSDimitry Andric case MachineOperand::MO_RegisterLiveOut: { 421bdd1243dSDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(MO)) { 422bdd1243dSDimitry Andric const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); 423bdd1243dSDimitry Andric unsigned RegMaskSize = MachineOperand::getRegMaskSize(TRI->getNumRegs()); 424bdd1243dSDimitry Andric const uint32_t *RegMask = MO.getRegMask(); 425bdd1243dSDimitry Andric std::vector<stable_hash> RegMaskHashes(RegMask, RegMask + RegMaskSize); 426bdd1243dSDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), 427bdd1243dSDimitry Andric stable_hash_combine_array(RegMaskHashes.data(), 428bdd1243dSDimitry Andric RegMaskHashes.size())); 429bdd1243dSDimitry Andric } 430bdd1243dSDimitry Andric 431bdd1243dSDimitry Andric assert(0 && "MachineOperand not associated with any MachineFunction"); 432bdd1243dSDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags()); 433bdd1243dSDimitry Andric } 4340b57cec5SDimitry Andric case MachineOperand::MO_Metadata: 4350b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMetadata()); 4360b57cec5SDimitry Andric case MachineOperand::MO_MCSymbol: 4370b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMCSymbol()); 438bdd1243dSDimitry Andric case MachineOperand::MO_DbgInstrRef: 439bdd1243dSDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), 440bdd1243dSDimitry Andric MO.getInstrRefInstrIndex(), MO.getInstrRefOpIndex()); 4410b57cec5SDimitry Andric case MachineOperand::MO_CFIIndex: 4420b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCFIIndex()); 4430b57cec5SDimitry Andric case MachineOperand::MO_IntrinsicID: 4440b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIntrinsicID()); 4450b57cec5SDimitry Andric case MachineOperand::MO_Predicate: 4460b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getPredicate()); 4478bcb0991SDimitry Andric case MachineOperand::MO_ShuffleMask: 4488bcb0991SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getShuffleMask()); 4490b57cec5SDimitry Andric } 4500b57cec5SDimitry Andric llvm_unreachable("Invalid machine operand type"); 4510b57cec5SDimitry Andric } 4520b57cec5SDimitry Andric 4530b57cec5SDimitry Andric // Try to crawl up to the machine function and get TRI and IntrinsicInfo from 4540b57cec5SDimitry Andric // it. 4550b57cec5SDimitry Andric static void tryToGetTargetInfo(const MachineOperand &MO, 4560b57cec5SDimitry Andric const TargetRegisterInfo *&TRI, 4570b57cec5SDimitry Andric const TargetIntrinsicInfo *&IntrinsicInfo) { 4580b57cec5SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(MO)) { 4590b57cec5SDimitry Andric TRI = MF->getSubtarget().getRegisterInfo(); 4600b57cec5SDimitry Andric IntrinsicInfo = MF->getTarget().getIntrinsicInfo(); 4610b57cec5SDimitry Andric } 4620b57cec5SDimitry Andric } 4630b57cec5SDimitry Andric 4640b57cec5SDimitry Andric static const char *getTargetIndexName(const MachineFunction &MF, int Index) { 4650b57cec5SDimitry Andric const auto *TII = MF.getSubtarget().getInstrInfo(); 4660b57cec5SDimitry Andric assert(TII && "expected instruction info"); 4670b57cec5SDimitry Andric auto Indices = TII->getSerializableTargetIndices(); 4680b57cec5SDimitry Andric auto Found = find_if(Indices, [&](const std::pair<int, const char *> &I) { 4690b57cec5SDimitry Andric return I.first == Index; 4700b57cec5SDimitry Andric }); 4710b57cec5SDimitry Andric if (Found != Indices.end()) 4720b57cec5SDimitry Andric return Found->second; 4730b57cec5SDimitry Andric return nullptr; 4740b57cec5SDimitry Andric } 4750b57cec5SDimitry Andric 476e8d8bef9SDimitry Andric const char *MachineOperand::getTargetIndexName() const { 477e8d8bef9SDimitry Andric const MachineFunction *MF = getMFIfAvailable(*this); 478e8d8bef9SDimitry Andric return MF ? ::getTargetIndexName(*MF, this->getIndex()) : nullptr; 479e8d8bef9SDimitry Andric } 480e8d8bef9SDimitry Andric 4810b57cec5SDimitry Andric static const char *getTargetFlagName(const TargetInstrInfo *TII, unsigned TF) { 4820b57cec5SDimitry Andric auto Flags = TII->getSerializableDirectMachineOperandTargetFlags(); 4830b57cec5SDimitry Andric for (const auto &I : Flags) { 4840b57cec5SDimitry Andric if (I.first == TF) { 4850b57cec5SDimitry Andric return I.second; 4860b57cec5SDimitry Andric } 4870b57cec5SDimitry Andric } 4880b57cec5SDimitry Andric return nullptr; 4890b57cec5SDimitry Andric } 4900b57cec5SDimitry Andric 4910b57cec5SDimitry Andric static void printCFIRegister(unsigned DwarfReg, raw_ostream &OS, 4920b57cec5SDimitry Andric const TargetRegisterInfo *TRI) { 4930b57cec5SDimitry Andric if (!TRI) { 4940b57cec5SDimitry Andric OS << "%dwarfreg." << DwarfReg; 4950b57cec5SDimitry Andric return; 4960b57cec5SDimitry Andric } 4970b57cec5SDimitry Andric 498bdd1243dSDimitry Andric if (std::optional<unsigned> Reg = TRI->getLLVMRegNum(DwarfReg, true)) 4998bcb0991SDimitry Andric OS << printReg(*Reg, TRI); 5008bcb0991SDimitry Andric else 5010b57cec5SDimitry Andric OS << "<badreg>"; 5020b57cec5SDimitry Andric } 5030b57cec5SDimitry Andric 5040b57cec5SDimitry Andric static void printIRBlockReference(raw_ostream &OS, const BasicBlock &BB, 5050b57cec5SDimitry Andric ModuleSlotTracker &MST) { 5060b57cec5SDimitry Andric OS << "%ir-block."; 5070b57cec5SDimitry Andric if (BB.hasName()) { 5080b57cec5SDimitry Andric printLLVMNameWithoutPrefix(OS, BB.getName()); 5090b57cec5SDimitry Andric return; 5100b57cec5SDimitry Andric } 511bdd1243dSDimitry Andric std::optional<int> Slot; 5120b57cec5SDimitry Andric if (const Function *F = BB.getParent()) { 5130b57cec5SDimitry Andric if (F == MST.getCurrentFunction()) { 5140b57cec5SDimitry Andric Slot = MST.getLocalSlot(&BB); 5150b57cec5SDimitry Andric } else if (const Module *M = F->getParent()) { 5160b57cec5SDimitry Andric ModuleSlotTracker CustomMST(M, /*ShouldInitializeAllMetadata=*/false); 5170b57cec5SDimitry Andric CustomMST.incorporateFunction(*F); 5180b57cec5SDimitry Andric Slot = CustomMST.getLocalSlot(&BB); 5190b57cec5SDimitry Andric } 5200b57cec5SDimitry Andric } 5210b57cec5SDimitry Andric if (Slot) 5220b57cec5SDimitry Andric MachineOperand::printIRSlotNumber(OS, *Slot); 5230b57cec5SDimitry Andric else 5240b57cec5SDimitry Andric OS << "<unknown>"; 5250b57cec5SDimitry Andric } 5260b57cec5SDimitry Andric 5270b57cec5SDimitry Andric static void printSyncScope(raw_ostream &OS, const LLVMContext &Context, 5280b57cec5SDimitry Andric SyncScope::ID SSID, 5290b57cec5SDimitry Andric SmallVectorImpl<StringRef> &SSNs) { 5300b57cec5SDimitry Andric switch (SSID) { 5310b57cec5SDimitry Andric case SyncScope::System: 5320b57cec5SDimitry Andric break; 5330b57cec5SDimitry Andric default: 5340b57cec5SDimitry Andric if (SSNs.empty()) 5350b57cec5SDimitry Andric Context.getSyncScopeNames(SSNs); 5360b57cec5SDimitry Andric 5370b57cec5SDimitry Andric OS << "syncscope(\""; 5380b57cec5SDimitry Andric printEscapedString(SSNs[SSID], OS); 5390b57cec5SDimitry Andric OS << "\") "; 5400b57cec5SDimitry Andric break; 5410b57cec5SDimitry Andric } 5420b57cec5SDimitry Andric } 5430b57cec5SDimitry Andric 5440b57cec5SDimitry Andric static const char *getTargetMMOFlagName(const TargetInstrInfo &TII, 5450b57cec5SDimitry Andric unsigned TMMOFlag) { 5460b57cec5SDimitry Andric auto Flags = TII.getSerializableMachineMemOperandTargetFlags(); 5470b57cec5SDimitry Andric for (const auto &I : Flags) { 5480b57cec5SDimitry Andric if (I.first == TMMOFlag) { 5490b57cec5SDimitry Andric return I.second; 5500b57cec5SDimitry Andric } 5510b57cec5SDimitry Andric } 5520b57cec5SDimitry Andric return nullptr; 5530b57cec5SDimitry Andric } 5540b57cec5SDimitry Andric 5550b57cec5SDimitry Andric static void printFrameIndex(raw_ostream& OS, int FrameIndex, bool IsFixed, 5560b57cec5SDimitry Andric const MachineFrameInfo *MFI) { 5570b57cec5SDimitry Andric StringRef Name; 5580b57cec5SDimitry Andric if (MFI) { 5590b57cec5SDimitry Andric IsFixed = MFI->isFixedObjectIndex(FrameIndex); 5600b57cec5SDimitry Andric if (const AllocaInst *Alloca = MFI->getObjectAllocation(FrameIndex)) 5610b57cec5SDimitry Andric if (Alloca->hasName()) 5620b57cec5SDimitry Andric Name = Alloca->getName(); 5630b57cec5SDimitry Andric if (IsFixed) 5640b57cec5SDimitry Andric FrameIndex -= MFI->getObjectIndexBegin(); 5650b57cec5SDimitry Andric } 5660b57cec5SDimitry Andric MachineOperand::printStackObjectReference(OS, FrameIndex, IsFixed, Name); 5670b57cec5SDimitry Andric } 5680b57cec5SDimitry Andric 5690b57cec5SDimitry Andric void MachineOperand::printSubRegIdx(raw_ostream &OS, uint64_t Index, 5700b57cec5SDimitry Andric const TargetRegisterInfo *TRI) { 5710b57cec5SDimitry Andric OS << "%subreg."; 572bdd1243dSDimitry Andric if (TRI && Index != 0 && Index < TRI->getNumSubRegIndices()) 5730b57cec5SDimitry Andric OS << TRI->getSubRegIndexName(Index); 5740b57cec5SDimitry Andric else 5750b57cec5SDimitry Andric OS << Index; 5760b57cec5SDimitry Andric } 5770b57cec5SDimitry Andric 5780b57cec5SDimitry Andric void MachineOperand::printTargetFlags(raw_ostream &OS, 5790b57cec5SDimitry Andric const MachineOperand &Op) { 5800b57cec5SDimitry Andric if (!Op.getTargetFlags()) 5810b57cec5SDimitry Andric return; 5820b57cec5SDimitry Andric const MachineFunction *MF = getMFIfAvailable(Op); 5830b57cec5SDimitry Andric if (!MF) 5840b57cec5SDimitry Andric return; 5850b57cec5SDimitry Andric 5860b57cec5SDimitry Andric const auto *TII = MF->getSubtarget().getInstrInfo(); 5870b57cec5SDimitry Andric assert(TII && "expected instruction info"); 5880b57cec5SDimitry Andric auto Flags = TII->decomposeMachineOperandsTargetFlags(Op.getTargetFlags()); 5890b57cec5SDimitry Andric OS << "target-flags("; 5900b57cec5SDimitry Andric const bool HasDirectFlags = Flags.first; 5910b57cec5SDimitry Andric const bool HasBitmaskFlags = Flags.second; 5920b57cec5SDimitry Andric if (!HasDirectFlags && !HasBitmaskFlags) { 5930b57cec5SDimitry Andric OS << "<unknown>) "; 5940b57cec5SDimitry Andric return; 5950b57cec5SDimitry Andric } 5960b57cec5SDimitry Andric if (HasDirectFlags) { 5970b57cec5SDimitry Andric if (const auto *Name = getTargetFlagName(TII, Flags.first)) 5980b57cec5SDimitry Andric OS << Name; 5990b57cec5SDimitry Andric else 6000b57cec5SDimitry Andric OS << "<unknown target flag>"; 6010b57cec5SDimitry Andric } 6020b57cec5SDimitry Andric if (!HasBitmaskFlags) { 6030b57cec5SDimitry Andric OS << ") "; 6040b57cec5SDimitry Andric return; 6050b57cec5SDimitry Andric } 6060b57cec5SDimitry Andric bool IsCommaNeeded = HasDirectFlags; 6070b57cec5SDimitry Andric unsigned BitMask = Flags.second; 6080b57cec5SDimitry Andric auto BitMasks = TII->getSerializableBitmaskMachineOperandTargetFlags(); 6090b57cec5SDimitry Andric for (const auto &Mask : BitMasks) { 6100b57cec5SDimitry Andric // Check if the flag's bitmask has the bits of the current mask set. 6110b57cec5SDimitry Andric if ((BitMask & Mask.first) == Mask.first) { 6120b57cec5SDimitry Andric if (IsCommaNeeded) 6130b57cec5SDimitry Andric OS << ", "; 6140b57cec5SDimitry Andric IsCommaNeeded = true; 6150b57cec5SDimitry Andric OS << Mask.second; 6160b57cec5SDimitry Andric // Clear the bits which were serialized from the flag's bitmask. 6170b57cec5SDimitry Andric BitMask &= ~(Mask.first); 6180b57cec5SDimitry Andric } 6190b57cec5SDimitry Andric } 6200b57cec5SDimitry Andric if (BitMask) { 6210b57cec5SDimitry Andric // When the resulting flag's bitmask isn't zero, we know that we didn't 6220b57cec5SDimitry Andric // serialize all of the bit flags. 6230b57cec5SDimitry Andric if (IsCommaNeeded) 6240b57cec5SDimitry Andric OS << ", "; 6250b57cec5SDimitry Andric OS << "<unknown bitmask target flag>"; 6260b57cec5SDimitry Andric } 6270b57cec5SDimitry Andric OS << ") "; 6280b57cec5SDimitry Andric } 6290b57cec5SDimitry Andric 6300b57cec5SDimitry Andric void MachineOperand::printSymbol(raw_ostream &OS, MCSymbol &Sym) { 6310b57cec5SDimitry Andric OS << "<mcsymbol " << Sym << ">"; 6320b57cec5SDimitry Andric } 6330b57cec5SDimitry Andric 6340b57cec5SDimitry Andric void MachineOperand::printStackObjectReference(raw_ostream &OS, 6350b57cec5SDimitry Andric unsigned FrameIndex, 6360b57cec5SDimitry Andric bool IsFixed, StringRef Name) { 6370b57cec5SDimitry Andric if (IsFixed) { 6380b57cec5SDimitry Andric OS << "%fixed-stack." << FrameIndex; 6390b57cec5SDimitry Andric return; 6400b57cec5SDimitry Andric } 6410b57cec5SDimitry Andric 6420b57cec5SDimitry Andric OS << "%stack." << FrameIndex; 6430b57cec5SDimitry Andric if (!Name.empty()) 6440b57cec5SDimitry Andric OS << '.' << Name; 6450b57cec5SDimitry Andric } 6460b57cec5SDimitry Andric 6470b57cec5SDimitry Andric void MachineOperand::printOperandOffset(raw_ostream &OS, int64_t Offset) { 6480b57cec5SDimitry Andric if (Offset == 0) 6490b57cec5SDimitry Andric return; 6500b57cec5SDimitry Andric if (Offset < 0) { 6510b57cec5SDimitry Andric OS << " - " << -Offset; 6520b57cec5SDimitry Andric return; 6530b57cec5SDimitry Andric } 6540b57cec5SDimitry Andric OS << " + " << Offset; 6550b57cec5SDimitry Andric } 6560b57cec5SDimitry Andric 6570b57cec5SDimitry Andric void MachineOperand::printIRSlotNumber(raw_ostream &OS, int Slot) { 6580b57cec5SDimitry Andric if (Slot == -1) 6590b57cec5SDimitry Andric OS << "<badref>"; 6600b57cec5SDimitry Andric else 6610b57cec5SDimitry Andric OS << Slot; 6620b57cec5SDimitry Andric } 6630b57cec5SDimitry Andric 6640b57cec5SDimitry Andric static void printCFI(raw_ostream &OS, const MCCFIInstruction &CFI, 6650b57cec5SDimitry Andric const TargetRegisterInfo *TRI) { 6660b57cec5SDimitry Andric switch (CFI.getOperation()) { 6670b57cec5SDimitry Andric case MCCFIInstruction::OpSameValue: 6680b57cec5SDimitry Andric OS << "same_value "; 6690b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 6700b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 6710b57cec5SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI); 6720b57cec5SDimitry Andric break; 6730b57cec5SDimitry Andric case MCCFIInstruction::OpRememberState: 6740b57cec5SDimitry Andric OS << "remember_state "; 6750b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 6760b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 6770b57cec5SDimitry Andric break; 6780b57cec5SDimitry Andric case MCCFIInstruction::OpRestoreState: 6790b57cec5SDimitry Andric OS << "restore_state "; 6800b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 6810b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 6820b57cec5SDimitry Andric break; 6830b57cec5SDimitry Andric case MCCFIInstruction::OpOffset: 6840b57cec5SDimitry Andric OS << "offset "; 6850b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 6860b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 6870b57cec5SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI); 6880b57cec5SDimitry Andric OS << ", " << CFI.getOffset(); 6890b57cec5SDimitry Andric break; 6900b57cec5SDimitry Andric case MCCFIInstruction::OpDefCfaRegister: 6910b57cec5SDimitry Andric OS << "def_cfa_register "; 6920b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 6930b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 6940b57cec5SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI); 6950b57cec5SDimitry Andric break; 6960b57cec5SDimitry Andric case MCCFIInstruction::OpDefCfaOffset: 6970b57cec5SDimitry Andric OS << "def_cfa_offset "; 6980b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 6990b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 7000b57cec5SDimitry Andric OS << CFI.getOffset(); 7010b57cec5SDimitry Andric break; 7020b57cec5SDimitry Andric case MCCFIInstruction::OpDefCfa: 7030b57cec5SDimitry Andric OS << "def_cfa "; 7040b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 7050b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 7060b57cec5SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI); 7070b57cec5SDimitry Andric OS << ", " << CFI.getOffset(); 7080b57cec5SDimitry Andric break; 709fe6060f1SDimitry Andric case MCCFIInstruction::OpLLVMDefAspaceCfa: 710fe6060f1SDimitry Andric OS << "llvm_def_aspace_cfa "; 711fe6060f1SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 712fe6060f1SDimitry Andric MachineOperand::printSymbol(OS, *Label); 713fe6060f1SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI); 714fe6060f1SDimitry Andric OS << ", " << CFI.getOffset(); 715fe6060f1SDimitry Andric OS << ", " << CFI.getAddressSpace(); 716fe6060f1SDimitry Andric break; 7170b57cec5SDimitry Andric case MCCFIInstruction::OpRelOffset: 7180b57cec5SDimitry Andric OS << "rel_offset "; 7190b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 7200b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 7210b57cec5SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI); 7220b57cec5SDimitry Andric OS << ", " << CFI.getOffset(); 7230b57cec5SDimitry Andric break; 7240b57cec5SDimitry Andric case MCCFIInstruction::OpAdjustCfaOffset: 7250b57cec5SDimitry Andric OS << "adjust_cfa_offset "; 7260b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 7270b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 7280b57cec5SDimitry Andric OS << CFI.getOffset(); 7290b57cec5SDimitry Andric break; 7300b57cec5SDimitry Andric case MCCFIInstruction::OpRestore: 7310b57cec5SDimitry Andric OS << "restore "; 7320b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 7330b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 7340b57cec5SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI); 7350b57cec5SDimitry Andric break; 7360b57cec5SDimitry Andric case MCCFIInstruction::OpEscape: { 7370b57cec5SDimitry Andric OS << "escape "; 7380b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 7390b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 7400b57cec5SDimitry Andric if (!CFI.getValues().empty()) { 7410b57cec5SDimitry Andric size_t e = CFI.getValues().size() - 1; 7420b57cec5SDimitry Andric for (size_t i = 0; i < e; ++i) 7430b57cec5SDimitry Andric OS << format("0x%02x", uint8_t(CFI.getValues()[i])) << ", "; 7445ffd83dbSDimitry Andric OS << format("0x%02x", uint8_t(CFI.getValues()[e])); 7450b57cec5SDimitry Andric } 7460b57cec5SDimitry Andric break; 7470b57cec5SDimitry Andric } 7480b57cec5SDimitry Andric case MCCFIInstruction::OpUndefined: 7490b57cec5SDimitry Andric OS << "undefined "; 7500b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 7510b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 7520b57cec5SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI); 7530b57cec5SDimitry Andric break; 7540b57cec5SDimitry Andric case MCCFIInstruction::OpRegister: 7550b57cec5SDimitry Andric OS << "register "; 7560b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 7570b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 7580b57cec5SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI); 7590b57cec5SDimitry Andric OS << ", "; 7600b57cec5SDimitry Andric printCFIRegister(CFI.getRegister2(), OS, TRI); 7610b57cec5SDimitry Andric break; 7620b57cec5SDimitry Andric case MCCFIInstruction::OpWindowSave: 7630b57cec5SDimitry Andric OS << "window_save "; 7640b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 7650b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 7660b57cec5SDimitry Andric break; 7670b57cec5SDimitry Andric case MCCFIInstruction::OpNegateRAState: 7680b57cec5SDimitry Andric OS << "negate_ra_sign_state "; 7690b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 7700b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 7710b57cec5SDimitry Andric break; 7720b57cec5SDimitry Andric default: 7730b57cec5SDimitry Andric // TODO: Print the other CFI Operations. 7740b57cec5SDimitry Andric OS << "<unserializable cfi directive>"; 7750b57cec5SDimitry Andric break; 7760b57cec5SDimitry Andric } 7770b57cec5SDimitry Andric } 7780b57cec5SDimitry Andric 7790b57cec5SDimitry Andric void MachineOperand::print(raw_ostream &OS, const TargetRegisterInfo *TRI, 7800b57cec5SDimitry Andric const TargetIntrinsicInfo *IntrinsicInfo) const { 7810b57cec5SDimitry Andric print(OS, LLT{}, TRI, IntrinsicInfo); 7820b57cec5SDimitry Andric } 7830b57cec5SDimitry Andric 7840b57cec5SDimitry Andric void MachineOperand::print(raw_ostream &OS, LLT TypeToPrint, 7850b57cec5SDimitry Andric const TargetRegisterInfo *TRI, 7860b57cec5SDimitry Andric const TargetIntrinsicInfo *IntrinsicInfo) const { 7870b57cec5SDimitry Andric tryToGetTargetInfo(*this, TRI, IntrinsicInfo); 7880b57cec5SDimitry Andric ModuleSlotTracker DummyMST(nullptr); 789bdd1243dSDimitry Andric print(OS, DummyMST, TypeToPrint, std::nullopt, /*PrintDef=*/false, 790480093f4SDimitry Andric /*IsStandalone=*/true, 7910b57cec5SDimitry Andric /*ShouldPrintRegisterTies=*/true, 7920b57cec5SDimitry Andric /*TiedOperandIdx=*/0, TRI, IntrinsicInfo); 7930b57cec5SDimitry Andric } 7940b57cec5SDimitry Andric 7950b57cec5SDimitry Andric void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST, 796bdd1243dSDimitry Andric LLT TypeToPrint, std::optional<unsigned> OpIdx, 797bdd1243dSDimitry Andric bool PrintDef, bool IsStandalone, 798bdd1243dSDimitry Andric bool ShouldPrintRegisterTies, 7990b57cec5SDimitry Andric unsigned TiedOperandIdx, 8000b57cec5SDimitry Andric const TargetRegisterInfo *TRI, 8010b57cec5SDimitry Andric const TargetIntrinsicInfo *IntrinsicInfo) const { 8020b57cec5SDimitry Andric printTargetFlags(OS, *this); 8030b57cec5SDimitry Andric switch (getType()) { 8040b57cec5SDimitry Andric case MachineOperand::MO_Register: { 8058bcb0991SDimitry Andric Register Reg = getReg(); 8060b57cec5SDimitry Andric if (isImplicit()) 8070b57cec5SDimitry Andric OS << (isDef() ? "implicit-def " : "implicit "); 8080b57cec5SDimitry Andric else if (PrintDef && isDef()) 8090b57cec5SDimitry Andric // Print the 'def' flag only when the operand is defined after '='. 8100b57cec5SDimitry Andric OS << "def "; 8110b57cec5SDimitry Andric if (isInternalRead()) 8120b57cec5SDimitry Andric OS << "internal "; 8130b57cec5SDimitry Andric if (isDead()) 8140b57cec5SDimitry Andric OS << "dead "; 8150b57cec5SDimitry Andric if (isKill()) 8160b57cec5SDimitry Andric OS << "killed "; 8170b57cec5SDimitry Andric if (isUndef()) 8180b57cec5SDimitry Andric OS << "undef "; 8190b57cec5SDimitry Andric if (isEarlyClobber()) 8200b57cec5SDimitry Andric OS << "early-clobber "; 821bdd1243dSDimitry Andric if (getReg().isPhysical() && isRenamable()) 8220b57cec5SDimitry Andric OS << "renamable "; 8230b57cec5SDimitry Andric // isDebug() is exactly true for register operands of a DBG_VALUE. So we 8240b57cec5SDimitry Andric // simply infer it when parsing and do not need to print it. 8250b57cec5SDimitry Andric 8260b57cec5SDimitry Andric const MachineRegisterInfo *MRI = nullptr; 827bdd1243dSDimitry Andric if (Reg.isVirtual()) { 8280b57cec5SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(*this)) { 8290b57cec5SDimitry Andric MRI = &MF->getRegInfo(); 8300b57cec5SDimitry Andric } 8310b57cec5SDimitry Andric } 8320b57cec5SDimitry Andric 8330b57cec5SDimitry Andric OS << printReg(Reg, TRI, 0, MRI); 8340b57cec5SDimitry Andric // Print the sub register. 8350b57cec5SDimitry Andric if (unsigned SubReg = getSubReg()) { 8360b57cec5SDimitry Andric if (TRI) 8370b57cec5SDimitry Andric OS << '.' << TRI->getSubRegIndexName(SubReg); 8380b57cec5SDimitry Andric else 8390b57cec5SDimitry Andric OS << ".subreg" << SubReg; 8400b57cec5SDimitry Andric } 8410b57cec5SDimitry Andric // Print the register class / bank. 842bdd1243dSDimitry Andric if (Reg.isVirtual()) { 8430b57cec5SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(*this)) { 8440b57cec5SDimitry Andric const MachineRegisterInfo &MRI = MF->getRegInfo(); 8450b57cec5SDimitry Andric if (IsStandalone || !PrintDef || MRI.def_empty(Reg)) { 8460b57cec5SDimitry Andric OS << ':'; 8470b57cec5SDimitry Andric OS << printRegClassOrBank(Reg, MRI, TRI); 8480b57cec5SDimitry Andric } 8490b57cec5SDimitry Andric } 8500b57cec5SDimitry Andric } 8510b57cec5SDimitry Andric // Print ties. 8520b57cec5SDimitry Andric if (ShouldPrintRegisterTies && isTied() && !isDef()) 8530b57cec5SDimitry Andric OS << "(tied-def " << TiedOperandIdx << ")"; 8540b57cec5SDimitry Andric // Print types. 8550b57cec5SDimitry Andric if (TypeToPrint.isValid()) 8560b57cec5SDimitry Andric OS << '(' << TypeToPrint << ')'; 8570b57cec5SDimitry Andric break; 8580b57cec5SDimitry Andric } 859480093f4SDimitry Andric case MachineOperand::MO_Immediate: { 860480093f4SDimitry Andric const MIRFormatter *Formatter = nullptr; 861480093f4SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(*this)) { 862480093f4SDimitry Andric const auto *TII = MF->getSubtarget().getInstrInfo(); 863480093f4SDimitry Andric assert(TII && "expected instruction info"); 864480093f4SDimitry Andric Formatter = TII->getMIRFormatter(); 865480093f4SDimitry Andric } 866480093f4SDimitry Andric if (Formatter) 867480093f4SDimitry Andric Formatter->printImm(OS, *getParent(), OpIdx, getImm()); 868480093f4SDimitry Andric else 8690b57cec5SDimitry Andric OS << getImm(); 8700b57cec5SDimitry Andric break; 871480093f4SDimitry Andric } 8720b57cec5SDimitry Andric case MachineOperand::MO_CImmediate: 8730b57cec5SDimitry Andric getCImm()->printAsOperand(OS, /*PrintType=*/true, MST); 8740b57cec5SDimitry Andric break; 8750b57cec5SDimitry Andric case MachineOperand::MO_FPImmediate: 8760b57cec5SDimitry Andric getFPImm()->printAsOperand(OS, /*PrintType=*/true, MST); 8770b57cec5SDimitry Andric break; 8780b57cec5SDimitry Andric case MachineOperand::MO_MachineBasicBlock: 8790b57cec5SDimitry Andric OS << printMBBReference(*getMBB()); 8800b57cec5SDimitry Andric break; 8810b57cec5SDimitry Andric case MachineOperand::MO_FrameIndex: { 8820b57cec5SDimitry Andric int FrameIndex = getIndex(); 8830b57cec5SDimitry Andric bool IsFixed = false; 8840b57cec5SDimitry Andric const MachineFrameInfo *MFI = nullptr; 8850b57cec5SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(*this)) 8860b57cec5SDimitry Andric MFI = &MF->getFrameInfo(); 8870b57cec5SDimitry Andric printFrameIndex(OS, FrameIndex, IsFixed, MFI); 8880b57cec5SDimitry Andric break; 8890b57cec5SDimitry Andric } 8900b57cec5SDimitry Andric case MachineOperand::MO_ConstantPoolIndex: 8910b57cec5SDimitry Andric OS << "%const." << getIndex(); 8920b57cec5SDimitry Andric printOperandOffset(OS, getOffset()); 8930b57cec5SDimitry Andric break; 8940b57cec5SDimitry Andric case MachineOperand::MO_TargetIndex: { 8950b57cec5SDimitry Andric OS << "target-index("; 8960b57cec5SDimitry Andric const char *Name = "<unknown>"; 8970b57cec5SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(*this)) 898e8d8bef9SDimitry Andric if (const auto *TargetIndexName = ::getTargetIndexName(*MF, getIndex())) 8990b57cec5SDimitry Andric Name = TargetIndexName; 9000b57cec5SDimitry Andric OS << Name << ')'; 9010b57cec5SDimitry Andric printOperandOffset(OS, getOffset()); 9020b57cec5SDimitry Andric break; 9030b57cec5SDimitry Andric } 9040b57cec5SDimitry Andric case MachineOperand::MO_JumpTableIndex: 9050b57cec5SDimitry Andric OS << printJumpTableEntryReference(getIndex()); 9060b57cec5SDimitry Andric break; 9070b57cec5SDimitry Andric case MachineOperand::MO_GlobalAddress: 9080b57cec5SDimitry Andric getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST); 9090b57cec5SDimitry Andric printOperandOffset(OS, getOffset()); 9100b57cec5SDimitry Andric break; 9110b57cec5SDimitry Andric case MachineOperand::MO_ExternalSymbol: { 9120b57cec5SDimitry Andric StringRef Name = getSymbolName(); 9130b57cec5SDimitry Andric OS << '&'; 9140b57cec5SDimitry Andric if (Name.empty()) { 9150b57cec5SDimitry Andric OS << "\"\""; 9160b57cec5SDimitry Andric } else { 9170b57cec5SDimitry Andric printLLVMNameWithoutPrefix(OS, Name); 9180b57cec5SDimitry Andric } 9190b57cec5SDimitry Andric printOperandOffset(OS, getOffset()); 9200b57cec5SDimitry Andric break; 9210b57cec5SDimitry Andric } 9220b57cec5SDimitry Andric case MachineOperand::MO_BlockAddress: { 9230b57cec5SDimitry Andric OS << "blockaddress("; 9240b57cec5SDimitry Andric getBlockAddress()->getFunction()->printAsOperand(OS, /*PrintType=*/false, 9250b57cec5SDimitry Andric MST); 9260b57cec5SDimitry Andric OS << ", "; 9270b57cec5SDimitry Andric printIRBlockReference(OS, *getBlockAddress()->getBasicBlock(), MST); 9280b57cec5SDimitry Andric OS << ')'; 9290b57cec5SDimitry Andric MachineOperand::printOperandOffset(OS, getOffset()); 9300b57cec5SDimitry Andric break; 9310b57cec5SDimitry Andric } 9320b57cec5SDimitry Andric case MachineOperand::MO_RegisterMask: { 9330b57cec5SDimitry Andric OS << "<regmask"; 9340b57cec5SDimitry Andric if (TRI) { 9350b57cec5SDimitry Andric unsigned NumRegsInMask = 0; 9360b57cec5SDimitry Andric unsigned NumRegsEmitted = 0; 9370b57cec5SDimitry Andric for (unsigned i = 0; i < TRI->getNumRegs(); ++i) { 9380b57cec5SDimitry Andric unsigned MaskWord = i / 32; 9390b57cec5SDimitry Andric unsigned MaskBit = i % 32; 9400b57cec5SDimitry Andric if (getRegMask()[MaskWord] & (1 << MaskBit)) { 9410b57cec5SDimitry Andric if (PrintRegMaskNumRegs < 0 || 9420b57cec5SDimitry Andric NumRegsEmitted <= static_cast<unsigned>(PrintRegMaskNumRegs)) { 9430b57cec5SDimitry Andric OS << " " << printReg(i, TRI); 9440b57cec5SDimitry Andric NumRegsEmitted++; 9450b57cec5SDimitry Andric } 9460b57cec5SDimitry Andric NumRegsInMask++; 9470b57cec5SDimitry Andric } 9480b57cec5SDimitry Andric } 9490b57cec5SDimitry Andric if (NumRegsEmitted != NumRegsInMask) 9500b57cec5SDimitry Andric OS << " and " << (NumRegsInMask - NumRegsEmitted) << " more..."; 9510b57cec5SDimitry Andric } else { 9520b57cec5SDimitry Andric OS << " ..."; 9530b57cec5SDimitry Andric } 9540b57cec5SDimitry Andric OS << ">"; 9550b57cec5SDimitry Andric break; 9560b57cec5SDimitry Andric } 9570b57cec5SDimitry Andric case MachineOperand::MO_RegisterLiveOut: { 9580b57cec5SDimitry Andric const uint32_t *RegMask = getRegLiveOut(); 9590b57cec5SDimitry Andric OS << "liveout("; 9600b57cec5SDimitry Andric if (!TRI) { 9610b57cec5SDimitry Andric OS << "<unknown>"; 9620b57cec5SDimitry Andric } else { 9630b57cec5SDimitry Andric bool IsCommaNeeded = false; 9640b57cec5SDimitry Andric for (unsigned Reg = 0, E = TRI->getNumRegs(); Reg < E; ++Reg) { 9650b57cec5SDimitry Andric if (RegMask[Reg / 32] & (1U << (Reg % 32))) { 9660b57cec5SDimitry Andric if (IsCommaNeeded) 9670b57cec5SDimitry Andric OS << ", "; 9680b57cec5SDimitry Andric OS << printReg(Reg, TRI); 9690b57cec5SDimitry Andric IsCommaNeeded = true; 9700b57cec5SDimitry Andric } 9710b57cec5SDimitry Andric } 9720b57cec5SDimitry Andric } 9730b57cec5SDimitry Andric OS << ")"; 9740b57cec5SDimitry Andric break; 9750b57cec5SDimitry Andric } 9760b57cec5SDimitry Andric case MachineOperand::MO_Metadata: 9770b57cec5SDimitry Andric getMetadata()->printAsOperand(OS, MST); 9780b57cec5SDimitry Andric break; 9790b57cec5SDimitry Andric case MachineOperand::MO_MCSymbol: 9800b57cec5SDimitry Andric printSymbol(OS, *getMCSymbol()); 9810b57cec5SDimitry Andric break; 982bdd1243dSDimitry Andric case MachineOperand::MO_DbgInstrRef: { 983bdd1243dSDimitry Andric OS << "dbg-instr-ref(" << getInstrRefInstrIndex() << ", " 984bdd1243dSDimitry Andric << getInstrRefOpIndex() << ')'; 985bdd1243dSDimitry Andric break; 986bdd1243dSDimitry Andric } 9870b57cec5SDimitry Andric case MachineOperand::MO_CFIIndex: { 9880b57cec5SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(*this)) 9890b57cec5SDimitry Andric printCFI(OS, MF->getFrameInstructions()[getCFIIndex()], TRI); 9900b57cec5SDimitry Andric else 9910b57cec5SDimitry Andric OS << "<cfi directive>"; 9920b57cec5SDimitry Andric break; 9930b57cec5SDimitry Andric } 9940b57cec5SDimitry Andric case MachineOperand::MO_IntrinsicID: { 9950b57cec5SDimitry Andric Intrinsic::ID ID = getIntrinsicID(); 9960b57cec5SDimitry Andric if (ID < Intrinsic::num_intrinsics) 997fe6060f1SDimitry Andric OS << "intrinsic(@" << Intrinsic::getBaseName(ID) << ')'; 9980b57cec5SDimitry Andric else if (IntrinsicInfo) 9990b57cec5SDimitry Andric OS << "intrinsic(@" << IntrinsicInfo->getName(ID) << ')'; 10000b57cec5SDimitry Andric else 10010b57cec5SDimitry Andric OS << "intrinsic(" << ID << ')'; 10020b57cec5SDimitry Andric break; 10030b57cec5SDimitry Andric } 10040b57cec5SDimitry Andric case MachineOperand::MO_Predicate: { 10050b57cec5SDimitry Andric auto Pred = static_cast<CmpInst::Predicate>(getPredicate()); 10060b57cec5SDimitry Andric OS << (CmpInst::isIntPredicate(Pred) ? "int" : "float") << "pred(" 100706c3fb27SDimitry Andric << Pred << ')'; 10080b57cec5SDimitry Andric break; 10090b57cec5SDimitry Andric } 10108bcb0991SDimitry Andric case MachineOperand::MO_ShuffleMask: 10118bcb0991SDimitry Andric OS << "shufflemask("; 1012480093f4SDimitry Andric ArrayRef<int> Mask = getShuffleMask(); 10138bcb0991SDimitry Andric StringRef Separator; 1014480093f4SDimitry Andric for (int Elt : Mask) { 1015480093f4SDimitry Andric if (Elt == -1) 1016480093f4SDimitry Andric OS << Separator << "undef"; 1017480093f4SDimitry Andric else 1018480093f4SDimitry Andric OS << Separator << Elt; 10198bcb0991SDimitry Andric Separator = ", "; 10208bcb0991SDimitry Andric } 10218bcb0991SDimitry Andric 10228bcb0991SDimitry Andric OS << ')'; 10238bcb0991SDimitry Andric break; 10240b57cec5SDimitry Andric } 10250b57cec5SDimitry Andric } 10260b57cec5SDimitry Andric 10270b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 10280b57cec5SDimitry Andric LLVM_DUMP_METHOD void MachineOperand::dump() const { dbgs() << *this << '\n'; } 10290b57cec5SDimitry Andric #endif 10300b57cec5SDimitry Andric 10310b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 10320b57cec5SDimitry Andric // MachineMemOperand Implementation 10330b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 10340b57cec5SDimitry Andric 10350b57cec5SDimitry Andric /// getAddrSpace - Return the LLVM IR address space number that this pointer 10360b57cec5SDimitry Andric /// points into. 10370b57cec5SDimitry Andric unsigned MachinePointerInfo::getAddrSpace() const { return AddrSpace; } 10380b57cec5SDimitry Andric 10390b57cec5SDimitry Andric /// isDereferenceable - Return true if V is always dereferenceable for 10400b57cec5SDimitry Andric /// Offset + Size byte. 10410b57cec5SDimitry Andric bool MachinePointerInfo::isDereferenceable(unsigned Size, LLVMContext &C, 10420b57cec5SDimitry Andric const DataLayout &DL) const { 104306c3fb27SDimitry Andric if (!isa<const Value *>(V)) 10440b57cec5SDimitry Andric return false; 10450b57cec5SDimitry Andric 104606c3fb27SDimitry Andric const Value *BasePtr = cast<const Value *>(V); 10470b57cec5SDimitry Andric if (BasePtr == nullptr) 10480b57cec5SDimitry Andric return false; 10490b57cec5SDimitry Andric 10500b57cec5SDimitry Andric return isDereferenceableAndAlignedPointer( 10515ffd83dbSDimitry Andric BasePtr, Align(1), APInt(DL.getPointerSizeInBits(), Offset + Size), DL); 10520b57cec5SDimitry Andric } 10530b57cec5SDimitry Andric 10540b57cec5SDimitry Andric /// getConstantPool - Return a MachinePointerInfo record that refers to the 10550b57cec5SDimitry Andric /// constant pool. 10560b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getConstantPool(MachineFunction &MF) { 10570b57cec5SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getConstantPool()); 10580b57cec5SDimitry Andric } 10590b57cec5SDimitry Andric 10600b57cec5SDimitry Andric /// getFixedStack - Return a MachinePointerInfo record that refers to the 10610b57cec5SDimitry Andric /// the specified FrameIndex. 10620b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getFixedStack(MachineFunction &MF, 10630b57cec5SDimitry Andric int FI, int64_t Offset) { 10640b57cec5SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getFixedStack(FI), Offset); 10650b57cec5SDimitry Andric } 10660b57cec5SDimitry Andric 10670b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getJumpTable(MachineFunction &MF) { 10680b57cec5SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getJumpTable()); 10690b57cec5SDimitry Andric } 10700b57cec5SDimitry Andric 10710b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getGOT(MachineFunction &MF) { 10720b57cec5SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getGOT()); 10730b57cec5SDimitry Andric } 10740b57cec5SDimitry Andric 10750b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getStack(MachineFunction &MF, 10760b57cec5SDimitry Andric int64_t Offset, uint8_t ID) { 10770b57cec5SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getStack(), Offset, ID); 10780b57cec5SDimitry Andric } 10790b57cec5SDimitry Andric 10800b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getUnknownStack(MachineFunction &MF) { 10810b57cec5SDimitry Andric return MachinePointerInfo(MF.getDataLayout().getAllocaAddrSpace()); 10820b57cec5SDimitry Andric } 10830b57cec5SDimitry Andric 10840b57cec5SDimitry Andric MachineMemOperand::MachineMemOperand(MachinePointerInfo ptrinfo, Flags f, 1085fe6060f1SDimitry Andric LLT type, Align a, const AAMDNodes &AAInfo, 10860b57cec5SDimitry Andric const MDNode *Ranges, SyncScope::ID SSID, 10870b57cec5SDimitry Andric AtomicOrdering Ordering, 10880b57cec5SDimitry Andric AtomicOrdering FailureOrdering) 1089fe6060f1SDimitry Andric : PtrInfo(ptrinfo), MemoryType(type), FlagVals(f), BaseAlign(a), 1090fe6060f1SDimitry Andric AAInfo(AAInfo), Ranges(Ranges) { 109106c3fb27SDimitry Andric assert((PtrInfo.V.isNull() || isa<const PseudoSourceValue *>(PtrInfo.V) || 109206c3fb27SDimitry Andric isa<PointerType>(cast<const Value *>(PtrInfo.V)->getType())) && 10930b57cec5SDimitry Andric "invalid pointer value"); 10940b57cec5SDimitry Andric assert((isLoad() || isStore()) && "Not a load/store!"); 10950b57cec5SDimitry Andric 10960b57cec5SDimitry Andric AtomicInfo.SSID = static_cast<unsigned>(SSID); 10970b57cec5SDimitry Andric assert(getSyncScopeID() == SSID && "Value truncated"); 10980b57cec5SDimitry Andric AtomicInfo.Ordering = static_cast<unsigned>(Ordering); 1099fe6060f1SDimitry Andric assert(getSuccessOrdering() == Ordering && "Value truncated"); 11000b57cec5SDimitry Andric AtomicInfo.FailureOrdering = static_cast<unsigned>(FailureOrdering); 11010b57cec5SDimitry Andric assert(getFailureOrdering() == FailureOrdering && "Value truncated"); 11020b57cec5SDimitry Andric } 11030b57cec5SDimitry Andric 1104*0fca6ea1SDimitry Andric MachineMemOperand::MachineMemOperand(MachinePointerInfo ptrinfo, Flags F, 1105*0fca6ea1SDimitry Andric LocationSize TS, Align BaseAlignment, 1106fe6060f1SDimitry Andric const AAMDNodes &AAInfo, 1107fe6060f1SDimitry Andric const MDNode *Ranges, SyncScope::ID SSID, 1108fe6060f1SDimitry Andric AtomicOrdering Ordering, 1109fe6060f1SDimitry Andric AtomicOrdering FailureOrdering) 1110*0fca6ea1SDimitry Andric : MachineMemOperand( 1111*0fca6ea1SDimitry Andric ptrinfo, F, 1112*0fca6ea1SDimitry Andric !TS.hasValue() ? LLT() 1113*0fca6ea1SDimitry Andric : TS.isScalable() 1114*0fca6ea1SDimitry Andric ? LLT::scalable_vector(1, 8 * TS.getValue().getKnownMinValue()) 1115*0fca6ea1SDimitry Andric : LLT::scalar(8 * TS.getValue().getKnownMinValue()), 1116*0fca6ea1SDimitry Andric BaseAlignment, AAInfo, Ranges, SSID, Ordering, FailureOrdering) {} 1117fe6060f1SDimitry Andric 11180b57cec5SDimitry Andric void MachineMemOperand::refineAlignment(const MachineMemOperand *MMO) { 11190b57cec5SDimitry Andric // The Value and Offset may differ due to CSE. But the flags and size 11200b57cec5SDimitry Andric // should be the same. 11210b57cec5SDimitry Andric assert(MMO->getFlags() == getFlags() && "Flags mismatch!"); 1122*0fca6ea1SDimitry Andric assert((!MMO->getSize().hasValue() || !getSize().hasValue() || 11234824e7fdSDimitry Andric MMO->getSize() == getSize()) && 11244824e7fdSDimitry Andric "Size mismatch!"); 11255ffd83dbSDimitry Andric if (MMO->getBaseAlign() >= getBaseAlign()) { 11260b57cec5SDimitry Andric // Update the alignment value. 11275ffd83dbSDimitry Andric BaseAlign = MMO->getBaseAlign(); 11280b57cec5SDimitry Andric // Also update the base and offset, because the new alignment may 11290b57cec5SDimitry Andric // not be applicable with the old ones. 11300b57cec5SDimitry Andric PtrInfo = MMO->PtrInfo; 11310b57cec5SDimitry Andric } 11320b57cec5SDimitry Andric } 11330b57cec5SDimitry Andric 11345ffd83dbSDimitry Andric /// getAlign - Return the minimum known alignment in bytes of the 11355ffd83dbSDimitry Andric /// actual memory reference. 11365ffd83dbSDimitry Andric Align MachineMemOperand::getAlign() const { 11375ffd83dbSDimitry Andric return commonAlignment(getBaseAlign(), getOffset()); 11380b57cec5SDimitry Andric } 11390b57cec5SDimitry Andric 11400b57cec5SDimitry Andric void MachineMemOperand::print(raw_ostream &OS, ModuleSlotTracker &MST, 11410b57cec5SDimitry Andric SmallVectorImpl<StringRef> &SSNs, 11420b57cec5SDimitry Andric const LLVMContext &Context, 11430b57cec5SDimitry Andric const MachineFrameInfo *MFI, 11440b57cec5SDimitry Andric const TargetInstrInfo *TII) const { 11450b57cec5SDimitry Andric OS << '('; 11460b57cec5SDimitry Andric if (isVolatile()) 11470b57cec5SDimitry Andric OS << "volatile "; 11480b57cec5SDimitry Andric if (isNonTemporal()) 11490b57cec5SDimitry Andric OS << "non-temporal "; 11500b57cec5SDimitry Andric if (isDereferenceable()) 11510b57cec5SDimitry Andric OS << "dereferenceable "; 11520b57cec5SDimitry Andric if (isInvariant()) 11530b57cec5SDimitry Andric OS << "invariant "; 1154bdd1243dSDimitry Andric if (TII) { 11550b57cec5SDimitry Andric if (getFlags() & MachineMemOperand::MOTargetFlag1) 11560b57cec5SDimitry Andric OS << '"' << getTargetMMOFlagName(*TII, MachineMemOperand::MOTargetFlag1) 11570b57cec5SDimitry Andric << "\" "; 11580b57cec5SDimitry Andric if (getFlags() & MachineMemOperand::MOTargetFlag2) 11590b57cec5SDimitry Andric OS << '"' << getTargetMMOFlagName(*TII, MachineMemOperand::MOTargetFlag2) 11600b57cec5SDimitry Andric << "\" "; 11610b57cec5SDimitry Andric if (getFlags() & MachineMemOperand::MOTargetFlag3) 11620b57cec5SDimitry Andric OS << '"' << getTargetMMOFlagName(*TII, MachineMemOperand::MOTargetFlag3) 11630b57cec5SDimitry Andric << "\" "; 1164bdd1243dSDimitry Andric } else { 1165bdd1243dSDimitry Andric if (getFlags() & MachineMemOperand::MOTargetFlag1) 1166bdd1243dSDimitry Andric OS << "\"MOTargetFlag1\" "; 1167bdd1243dSDimitry Andric if (getFlags() & MachineMemOperand::MOTargetFlag2) 1168bdd1243dSDimitry Andric OS << "\"MOTargetFlag2\" "; 1169bdd1243dSDimitry Andric if (getFlags() & MachineMemOperand::MOTargetFlag3) 1170bdd1243dSDimitry Andric OS << "\"MOTargetFlag3\" "; 1171bdd1243dSDimitry Andric } 11720b57cec5SDimitry Andric 11730b57cec5SDimitry Andric assert((isLoad() || isStore()) && 11740b57cec5SDimitry Andric "machine memory operand must be a load or store (or both)"); 11750b57cec5SDimitry Andric if (isLoad()) 11760b57cec5SDimitry Andric OS << "load "; 11770b57cec5SDimitry Andric if (isStore()) 11780b57cec5SDimitry Andric OS << "store "; 11790b57cec5SDimitry Andric 11800b57cec5SDimitry Andric printSyncScope(OS, Context, getSyncScopeID(), SSNs); 11810b57cec5SDimitry Andric 1182fe6060f1SDimitry Andric if (getSuccessOrdering() != AtomicOrdering::NotAtomic) 1183fe6060f1SDimitry Andric OS << toIRString(getSuccessOrdering()) << ' '; 11840b57cec5SDimitry Andric if (getFailureOrdering() != AtomicOrdering::NotAtomic) 11850b57cec5SDimitry Andric OS << toIRString(getFailureOrdering()) << ' '; 11860b57cec5SDimitry Andric 1187fe6060f1SDimitry Andric if (getMemoryType().isValid()) 1188fe6060f1SDimitry Andric OS << '(' << getMemoryType() << ')'; 11890b57cec5SDimitry Andric else 1190fe6060f1SDimitry Andric OS << "unknown-size"; 11910b57cec5SDimitry Andric 11920b57cec5SDimitry Andric if (const Value *Val = getValue()) { 11930b57cec5SDimitry Andric OS << ((isLoad() && isStore()) ? " on " : isLoad() ? " from " : " into "); 1194480093f4SDimitry Andric MIRFormatter::printIRValue(OS, *Val, MST); 11950b57cec5SDimitry Andric } else if (const PseudoSourceValue *PVal = getPseudoValue()) { 11960b57cec5SDimitry Andric OS << ((isLoad() && isStore()) ? " on " : isLoad() ? " from " : " into "); 11970b57cec5SDimitry Andric assert(PVal && "Expected a pseudo source value"); 11980b57cec5SDimitry Andric switch (PVal->kind()) { 11990b57cec5SDimitry Andric case PseudoSourceValue::Stack: 12000b57cec5SDimitry Andric OS << "stack"; 12010b57cec5SDimitry Andric break; 12020b57cec5SDimitry Andric case PseudoSourceValue::GOT: 12030b57cec5SDimitry Andric OS << "got"; 12040b57cec5SDimitry Andric break; 12050b57cec5SDimitry Andric case PseudoSourceValue::JumpTable: 12060b57cec5SDimitry Andric OS << "jump-table"; 12070b57cec5SDimitry Andric break; 12080b57cec5SDimitry Andric case PseudoSourceValue::ConstantPool: 12090b57cec5SDimitry Andric OS << "constant-pool"; 12100b57cec5SDimitry Andric break; 12110b57cec5SDimitry Andric case PseudoSourceValue::FixedStack: { 12120b57cec5SDimitry Andric int FrameIndex = cast<FixedStackPseudoSourceValue>(PVal)->getFrameIndex(); 12130b57cec5SDimitry Andric bool IsFixed = true; 12140b57cec5SDimitry Andric printFrameIndex(OS, FrameIndex, IsFixed, MFI); 12150b57cec5SDimitry Andric break; 12160b57cec5SDimitry Andric } 12170b57cec5SDimitry Andric case PseudoSourceValue::GlobalValueCallEntry: 12180b57cec5SDimitry Andric OS << "call-entry "; 12190b57cec5SDimitry Andric cast<GlobalValuePseudoSourceValue>(PVal)->getValue()->printAsOperand( 12200b57cec5SDimitry Andric OS, /*PrintType=*/false, MST); 12210b57cec5SDimitry Andric break; 12220b57cec5SDimitry Andric case PseudoSourceValue::ExternalSymbolCallEntry: 12230b57cec5SDimitry Andric OS << "call-entry &"; 12240b57cec5SDimitry Andric printLLVMNameWithoutPrefix( 12250b57cec5SDimitry Andric OS, cast<ExternalSymbolPseudoSourceValue>(PVal)->getSymbol()); 12260b57cec5SDimitry Andric break; 1227480093f4SDimitry Andric default: { 1228480093f4SDimitry Andric const MIRFormatter *Formatter = TII->getMIRFormatter(); 12290b57cec5SDimitry Andric // FIXME: This is not necessarily the correct MIR serialization format for 12300b57cec5SDimitry Andric // a custom pseudo source value, but at least it allows 1231e8d8bef9SDimitry Andric // MIR printing to work on a target with custom pseudo source 12320b57cec5SDimitry Andric // values. 1233480093f4SDimitry Andric OS << "custom \""; 1234480093f4SDimitry Andric Formatter->printCustomPseudoSourceValue(OS, MST, *PVal); 1235480093f4SDimitry Andric OS << '\"'; 12360b57cec5SDimitry Andric break; 12370b57cec5SDimitry Andric } 12380b57cec5SDimitry Andric } 1239fe6060f1SDimitry Andric } else if (getOpaqueValue() == nullptr && getOffset() != 0) { 1240fe6060f1SDimitry Andric OS << ((isLoad() && isStore()) ? " on " 1241fe6060f1SDimitry Andric : isLoad() ? " from " 1242fe6060f1SDimitry Andric : " into ") 1243fe6060f1SDimitry Andric << "unknown-address"; 1244480093f4SDimitry Andric } 12450b57cec5SDimitry Andric MachineOperand::printOperandOffset(OS, getOffset()); 1246*0fca6ea1SDimitry Andric if (!getSize().hasValue() || 1247*0fca6ea1SDimitry Andric getAlign() != getSize().getValue().getKnownMinValue()) 1248e8d8bef9SDimitry Andric OS << ", align " << getAlign().value(); 1249e8d8bef9SDimitry Andric if (getAlign() != getBaseAlign()) 1250e8d8bef9SDimitry Andric OS << ", basealign " << getBaseAlign().value(); 12510b57cec5SDimitry Andric auto AAInfo = getAAInfo(); 12520b57cec5SDimitry Andric if (AAInfo.TBAA) { 12530b57cec5SDimitry Andric OS << ", !tbaa "; 12540b57cec5SDimitry Andric AAInfo.TBAA->printAsOperand(OS, MST); 12550b57cec5SDimitry Andric } 12560b57cec5SDimitry Andric if (AAInfo.Scope) { 12570b57cec5SDimitry Andric OS << ", !alias.scope "; 12580b57cec5SDimitry Andric AAInfo.Scope->printAsOperand(OS, MST); 12590b57cec5SDimitry Andric } 12600b57cec5SDimitry Andric if (AAInfo.NoAlias) { 12610b57cec5SDimitry Andric OS << ", !noalias "; 12620b57cec5SDimitry Andric AAInfo.NoAlias->printAsOperand(OS, MST); 12630b57cec5SDimitry Andric } 12640b57cec5SDimitry Andric if (getRanges()) { 12650b57cec5SDimitry Andric OS << ", !range "; 12660b57cec5SDimitry Andric getRanges()->printAsOperand(OS, MST); 12670b57cec5SDimitry Andric } 12680b57cec5SDimitry Andric // FIXME: Implement addrspace printing/parsing in MIR. 12690b57cec5SDimitry Andric // For now, print this even though parsing it is not available in MIR. 12700b57cec5SDimitry Andric if (unsigned AS = getAddrSpace()) 12710b57cec5SDimitry Andric OS << ", addrspace " << AS; 12720b57cec5SDimitry Andric 12730b57cec5SDimitry Andric OS << ')'; 12740b57cec5SDimitry Andric } 1275