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"
145ffd83dbSDimitry Andric #include "llvm/ADT/FoldingSet.h"
150b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h"
160b57cec5SDimitry Andric #include "llvm/Analysis/Loads.h"
170b57cec5SDimitry Andric #include "llvm/Analysis/MemoryLocation.h"
18480093f4SDimitry Andric #include "llvm/CodeGen/MIRFormatter.h"
190b57cec5SDimitry Andric #include "llvm/CodeGen/MIRPrinter.h"
200b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
210b57cec5SDimitry Andric #include "llvm/CodeGen/MachineJumpTableInfo.h"
220b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
230b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
240b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
250b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h"
260b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
270b57cec5SDimitry Andric #include "llvm/IR/IRPrintingPasses.h"
285ffd83dbSDimitry Andric #include "llvm/IR/Instructions.h"
290b57cec5SDimitry Andric #include "llvm/IR/ModuleSlotTracker.h"
300b57cec5SDimitry Andric #include "llvm/MC/MCDwarf.h"
310b57cec5SDimitry Andric #include "llvm/Target/TargetIntrinsicInfo.h"
320b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h"
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
getMFIfAvailable(const MachineOperand & MO)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 }
getMFIfAvailable(MachineOperand & MO)500b57cec5SDimitry Andric static MachineFunction *getMFIfAvailable(MachineOperand &MO) {
510b57cec5SDimitry Andric return const_cast<MachineFunction *>(
520b57cec5SDimitry Andric getMFIfAvailable(const_cast<const MachineOperand &>(MO)));
530b57cec5SDimitry Andric }
540b57cec5SDimitry Andric
setReg(Register Reg)558bcb0991SDimitry Andric void MachineOperand::setReg(Register Reg) {
560b57cec5SDimitry Andric if (getReg() == Reg)
570b57cec5SDimitry Andric return; // No change.
580b57cec5SDimitry Andric
590b57cec5SDimitry Andric // Clear the IsRenamable bit to keep it conservatively correct.
600b57cec5SDimitry Andric IsRenamable = false;
610b57cec5SDimitry Andric
620b57cec5SDimitry Andric // Otherwise, we have to change the register. If this operand is embedded
630b57cec5SDimitry Andric // into a machine function, we need to update the old and new register's
640b57cec5SDimitry Andric // use/def lists.
650b57cec5SDimitry Andric if (MachineFunction *MF = getMFIfAvailable(*this)) {
660b57cec5SDimitry Andric MachineRegisterInfo &MRI = MF->getRegInfo();
670b57cec5SDimitry Andric MRI.removeRegOperandFromUseList(this);
680b57cec5SDimitry Andric SmallContents.RegNo = Reg;
690b57cec5SDimitry Andric MRI.addRegOperandToUseList(this);
700b57cec5SDimitry Andric return;
710b57cec5SDimitry Andric }
720b57cec5SDimitry Andric
730b57cec5SDimitry Andric // Otherwise, just change the register, no problem. :)
740b57cec5SDimitry Andric SmallContents.RegNo = Reg;
750b57cec5SDimitry Andric }
760b57cec5SDimitry Andric
substVirtReg(Register Reg,unsigned SubIdx,const TargetRegisterInfo & TRI)778bcb0991SDimitry Andric void MachineOperand::substVirtReg(Register Reg, unsigned SubIdx,
780b57cec5SDimitry Andric const TargetRegisterInfo &TRI) {
798bcb0991SDimitry Andric assert(Reg.isVirtual());
800b57cec5SDimitry Andric if (SubIdx && getSubReg())
810b57cec5SDimitry Andric SubIdx = TRI.composeSubRegIndices(SubIdx, getSubReg());
820b57cec5SDimitry Andric setReg(Reg);
830b57cec5SDimitry Andric if (SubIdx)
840b57cec5SDimitry Andric setSubReg(SubIdx);
850b57cec5SDimitry Andric }
860b57cec5SDimitry Andric
substPhysReg(MCRegister Reg,const TargetRegisterInfo & TRI)878bcb0991SDimitry Andric void MachineOperand::substPhysReg(MCRegister Reg, const TargetRegisterInfo &TRI) {
88af732203SDimitry Andric assert(Register::isPhysicalRegister(Reg));
890b57cec5SDimitry Andric if (getSubReg()) {
900b57cec5SDimitry Andric Reg = TRI.getSubReg(Reg, getSubReg());
910b57cec5SDimitry Andric // Note that getSubReg() may return 0 if the sub-register doesn't exist.
920b57cec5SDimitry Andric // That won't happen in legal code.
930b57cec5SDimitry Andric setSubReg(0);
940b57cec5SDimitry Andric if (isDef())
950b57cec5SDimitry Andric setIsUndef(false);
960b57cec5SDimitry Andric }
970b57cec5SDimitry Andric setReg(Reg);
980b57cec5SDimitry Andric }
990b57cec5SDimitry Andric
1000b57cec5SDimitry Andric /// Change a def to a use, or a use to a def.
setIsDef(bool Val)1010b57cec5SDimitry Andric void MachineOperand::setIsDef(bool Val) {
1020b57cec5SDimitry Andric assert(isReg() && "Wrong MachineOperand accessor");
1030b57cec5SDimitry Andric assert((!Val || !isDebug()) && "Marking a debug operation as def");
1040b57cec5SDimitry Andric if (IsDef == Val)
1050b57cec5SDimitry Andric return;
1060b57cec5SDimitry Andric assert(!IsDeadOrKill && "Changing def/use with dead/kill set not supported");
1070b57cec5SDimitry Andric // MRI may keep uses and defs in different list positions.
1080b57cec5SDimitry Andric if (MachineFunction *MF = getMFIfAvailable(*this)) {
1090b57cec5SDimitry Andric MachineRegisterInfo &MRI = MF->getRegInfo();
1100b57cec5SDimitry Andric MRI.removeRegOperandFromUseList(this);
1110b57cec5SDimitry Andric IsDef = Val;
1120b57cec5SDimitry Andric MRI.addRegOperandToUseList(this);
1130b57cec5SDimitry Andric return;
1140b57cec5SDimitry Andric }
1150b57cec5SDimitry Andric IsDef = Val;
1160b57cec5SDimitry Andric }
1170b57cec5SDimitry Andric
isRenamable() const1180b57cec5SDimitry Andric bool MachineOperand::isRenamable() const {
1190b57cec5SDimitry Andric assert(isReg() && "Wrong MachineOperand accessor");
1208bcb0991SDimitry Andric assert(Register::isPhysicalRegister(getReg()) &&
1210b57cec5SDimitry Andric "isRenamable should only be checked on physical registers");
1220b57cec5SDimitry Andric if (!IsRenamable)
1230b57cec5SDimitry Andric return false;
1240b57cec5SDimitry Andric
1250b57cec5SDimitry Andric const MachineInstr *MI = getParent();
1260b57cec5SDimitry Andric if (!MI)
1270b57cec5SDimitry Andric return true;
1280b57cec5SDimitry Andric
1290b57cec5SDimitry Andric if (isDef())
1300b57cec5SDimitry Andric return !MI->hasExtraDefRegAllocReq(MachineInstr::IgnoreBundle);
1310b57cec5SDimitry Andric
1320b57cec5SDimitry Andric assert(isUse() && "Reg is not def or use");
1330b57cec5SDimitry Andric return !MI->hasExtraSrcRegAllocReq(MachineInstr::IgnoreBundle);
1340b57cec5SDimitry Andric }
1350b57cec5SDimitry Andric
setIsRenamable(bool Val)1360b57cec5SDimitry Andric void MachineOperand::setIsRenamable(bool Val) {
1370b57cec5SDimitry Andric assert(isReg() && "Wrong MachineOperand accessor");
1388bcb0991SDimitry Andric assert(Register::isPhysicalRegister(getReg()) &&
1390b57cec5SDimitry Andric "setIsRenamable should only be called on physical registers");
1400b57cec5SDimitry Andric IsRenamable = Val;
1410b57cec5SDimitry Andric }
1420b57cec5SDimitry Andric
1430b57cec5SDimitry Andric // If this operand is currently a register operand, and if this is in a
1440b57cec5SDimitry Andric // function, deregister the operand from the register's use/def list.
removeRegFromUses()1450b57cec5SDimitry Andric void MachineOperand::removeRegFromUses() {
1460b57cec5SDimitry Andric if (!isReg() || !isOnRegUseList())
1470b57cec5SDimitry Andric return;
1480b57cec5SDimitry Andric
1490b57cec5SDimitry Andric if (MachineFunction *MF = getMFIfAvailable(*this))
1500b57cec5SDimitry Andric MF->getRegInfo().removeRegOperandFromUseList(this);
1510b57cec5SDimitry Andric }
1520b57cec5SDimitry Andric
1530b57cec5SDimitry Andric /// ChangeToImmediate - Replace this operand with a new immediate operand of
1540b57cec5SDimitry Andric /// the specified value. If an operand is known to be an immediate already,
1550b57cec5SDimitry Andric /// the setImm method should be used.
ChangeToImmediate(int64_t ImmVal,unsigned TargetFlags)156af732203SDimitry Andric void MachineOperand::ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags) {
1570b57cec5SDimitry Andric assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm");
1580b57cec5SDimitry Andric
1590b57cec5SDimitry Andric removeRegFromUses();
1600b57cec5SDimitry Andric
1610b57cec5SDimitry Andric OpKind = MO_Immediate;
1620b57cec5SDimitry Andric Contents.ImmVal = ImmVal;
163af732203SDimitry Andric setTargetFlags(TargetFlags);
1640b57cec5SDimitry Andric }
1650b57cec5SDimitry Andric
ChangeToFPImmediate(const ConstantFP * FPImm,unsigned TargetFlags)166af732203SDimitry Andric void MachineOperand::ChangeToFPImmediate(const ConstantFP *FPImm,
167af732203SDimitry Andric unsigned TargetFlags) {
1680b57cec5SDimitry Andric assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm");
1690b57cec5SDimitry Andric
1700b57cec5SDimitry Andric removeRegFromUses();
1710b57cec5SDimitry Andric
1720b57cec5SDimitry Andric OpKind = MO_FPImmediate;
1730b57cec5SDimitry Andric Contents.CFP = FPImm;
174af732203SDimitry Andric setTargetFlags(TargetFlags);
1750b57cec5SDimitry Andric }
1760b57cec5SDimitry Andric
ChangeToES(const char * SymName,unsigned TargetFlags)1770b57cec5SDimitry Andric void MachineOperand::ChangeToES(const char *SymName,
1788bcb0991SDimitry Andric unsigned TargetFlags) {
1790b57cec5SDimitry Andric assert((!isReg() || !isTied()) &&
1800b57cec5SDimitry Andric "Cannot change a tied operand into an external symbol");
1810b57cec5SDimitry Andric
1820b57cec5SDimitry Andric removeRegFromUses();
1830b57cec5SDimitry Andric
1840b57cec5SDimitry Andric OpKind = MO_ExternalSymbol;
1850b57cec5SDimitry Andric Contents.OffsetedInfo.Val.SymbolName = SymName;
1860b57cec5SDimitry Andric setOffset(0); // Offset is always 0.
1870b57cec5SDimitry Andric setTargetFlags(TargetFlags);
1880b57cec5SDimitry Andric }
1890b57cec5SDimitry Andric
ChangeToGA(const GlobalValue * GV,int64_t Offset,unsigned TargetFlags)1900b57cec5SDimitry Andric void MachineOperand::ChangeToGA(const GlobalValue *GV, int64_t Offset,
1918bcb0991SDimitry Andric unsigned TargetFlags) {
1920b57cec5SDimitry Andric assert((!isReg() || !isTied()) &&
1930b57cec5SDimitry Andric "Cannot change a tied operand into a global address");
1940b57cec5SDimitry Andric
1950b57cec5SDimitry Andric removeRegFromUses();
1960b57cec5SDimitry Andric
1970b57cec5SDimitry Andric OpKind = MO_GlobalAddress;
1980b57cec5SDimitry Andric Contents.OffsetedInfo.Val.GV = GV;
1990b57cec5SDimitry Andric setOffset(Offset);
2000b57cec5SDimitry Andric setTargetFlags(TargetFlags);
2010b57cec5SDimitry Andric }
2020b57cec5SDimitry Andric
ChangeToMCSymbol(MCSymbol * Sym,unsigned TargetFlags)203af732203SDimitry Andric void MachineOperand::ChangeToMCSymbol(MCSymbol *Sym, unsigned TargetFlags) {
2040b57cec5SDimitry Andric assert((!isReg() || !isTied()) &&
2050b57cec5SDimitry Andric "Cannot change a tied operand into an MCSymbol");
2060b57cec5SDimitry Andric
2070b57cec5SDimitry Andric removeRegFromUses();
2080b57cec5SDimitry Andric
2090b57cec5SDimitry Andric OpKind = MO_MCSymbol;
2100b57cec5SDimitry Andric Contents.Sym = Sym;
211af732203SDimitry Andric setTargetFlags(TargetFlags);
2120b57cec5SDimitry Andric }
2130b57cec5SDimitry Andric
ChangeToFrameIndex(int Idx,unsigned TargetFlags)214af732203SDimitry Andric void MachineOperand::ChangeToFrameIndex(int Idx, unsigned TargetFlags) {
2150b57cec5SDimitry Andric assert((!isReg() || !isTied()) &&
2160b57cec5SDimitry Andric "Cannot change a tied operand into a FrameIndex");
2170b57cec5SDimitry Andric
2180b57cec5SDimitry Andric removeRegFromUses();
2190b57cec5SDimitry Andric
2200b57cec5SDimitry Andric OpKind = MO_FrameIndex;
2210b57cec5SDimitry Andric setIndex(Idx);
222af732203SDimitry Andric setTargetFlags(TargetFlags);
2230b57cec5SDimitry Andric }
2240b57cec5SDimitry Andric
ChangeToTargetIndex(unsigned Idx,int64_t Offset,unsigned TargetFlags)2250b57cec5SDimitry Andric void MachineOperand::ChangeToTargetIndex(unsigned Idx, int64_t Offset,
2268bcb0991SDimitry Andric unsigned TargetFlags) {
2270b57cec5SDimitry Andric assert((!isReg() || !isTied()) &&
2280b57cec5SDimitry Andric "Cannot change a tied operand into a FrameIndex");
2290b57cec5SDimitry Andric
2300b57cec5SDimitry Andric removeRegFromUses();
2310b57cec5SDimitry Andric
2320b57cec5SDimitry Andric OpKind = MO_TargetIndex;
2330b57cec5SDimitry Andric setIndex(Idx);
2340b57cec5SDimitry Andric setOffset(Offset);
2350b57cec5SDimitry Andric setTargetFlags(TargetFlags);
2360b57cec5SDimitry Andric }
2370b57cec5SDimitry Andric
2380b57cec5SDimitry Andric /// ChangeToRegister - Replace this operand with a new register operand of
2390b57cec5SDimitry Andric /// the specified value. If an operand is known to be an register already,
2400b57cec5SDimitry Andric /// the setReg method should be used.
ChangeToRegister(Register Reg,bool isDef,bool isImp,bool isKill,bool isDead,bool isUndef,bool isDebug)2418bcb0991SDimitry Andric void MachineOperand::ChangeToRegister(Register Reg, bool isDef, bool isImp,
2420b57cec5SDimitry Andric bool isKill, bool isDead, bool isUndef,
2430b57cec5SDimitry Andric bool isDebug) {
2440b57cec5SDimitry Andric MachineRegisterInfo *RegInfo = nullptr;
2450b57cec5SDimitry Andric if (MachineFunction *MF = getMFIfAvailable(*this))
2460b57cec5SDimitry Andric RegInfo = &MF->getRegInfo();
2470b57cec5SDimitry Andric // If this operand is already a register operand, remove it from the
2480b57cec5SDimitry Andric // register's use/def lists.
2490b57cec5SDimitry Andric bool WasReg = isReg();
2500b57cec5SDimitry Andric if (RegInfo && WasReg)
2510b57cec5SDimitry Andric RegInfo->removeRegOperandFromUseList(this);
2520b57cec5SDimitry Andric
2530b57cec5SDimitry Andric // Change this to a register and set the reg#.
2540b57cec5SDimitry Andric assert(!(isDead && !isDef) && "Dead flag on non-def");
2550b57cec5SDimitry Andric assert(!(isKill && isDef) && "Kill flag on def");
2560b57cec5SDimitry Andric OpKind = MO_Register;
2570b57cec5SDimitry Andric SmallContents.RegNo = Reg;
2580b57cec5SDimitry Andric SubReg_TargetFlags = 0;
2590b57cec5SDimitry Andric IsDef = isDef;
2600b57cec5SDimitry Andric IsImp = isImp;
2610b57cec5SDimitry Andric IsDeadOrKill = isKill | isDead;
2620b57cec5SDimitry Andric IsRenamable = false;
2630b57cec5SDimitry Andric IsUndef = isUndef;
2640b57cec5SDimitry Andric IsInternalRead = false;
2650b57cec5SDimitry Andric IsEarlyClobber = false;
2660b57cec5SDimitry Andric IsDebug = isDebug;
2670b57cec5SDimitry Andric // Ensure isOnRegUseList() returns false.
2680b57cec5SDimitry Andric Contents.Reg.Prev = nullptr;
2690b57cec5SDimitry Andric // Preserve the tie when the operand was already a register.
2700b57cec5SDimitry Andric if (!WasReg)
2710b57cec5SDimitry Andric TiedTo = 0;
2720b57cec5SDimitry Andric
2730b57cec5SDimitry Andric // If this operand is embedded in a function, add the operand to the
2740b57cec5SDimitry Andric // register's use/def list.
2750b57cec5SDimitry Andric if (RegInfo)
2760b57cec5SDimitry Andric RegInfo->addRegOperandToUseList(this);
2770b57cec5SDimitry Andric }
2780b57cec5SDimitry Andric
2790b57cec5SDimitry Andric /// isIdenticalTo - Return true if this operand is identical to the specified
2800b57cec5SDimitry Andric /// operand. Note that this should stay in sync with the hash_value overload
2810b57cec5SDimitry Andric /// below.
isIdenticalTo(const MachineOperand & Other) const2820b57cec5SDimitry Andric bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const {
2830b57cec5SDimitry Andric if (getType() != Other.getType() ||
2840b57cec5SDimitry Andric getTargetFlags() != Other.getTargetFlags())
2850b57cec5SDimitry Andric return false;
2860b57cec5SDimitry Andric
2870b57cec5SDimitry Andric switch (getType()) {
2880b57cec5SDimitry Andric case MachineOperand::MO_Register:
2890b57cec5SDimitry Andric return getReg() == Other.getReg() && isDef() == Other.isDef() &&
2900b57cec5SDimitry Andric getSubReg() == Other.getSubReg();
2910b57cec5SDimitry Andric case MachineOperand::MO_Immediate:
2920b57cec5SDimitry Andric return getImm() == Other.getImm();
2930b57cec5SDimitry Andric case MachineOperand::MO_CImmediate:
2940b57cec5SDimitry Andric return getCImm() == Other.getCImm();
2950b57cec5SDimitry Andric case MachineOperand::MO_FPImmediate:
2960b57cec5SDimitry Andric return getFPImm() == Other.getFPImm();
2970b57cec5SDimitry Andric case MachineOperand::MO_MachineBasicBlock:
2980b57cec5SDimitry Andric return getMBB() == Other.getMBB();
2990b57cec5SDimitry Andric case MachineOperand::MO_FrameIndex:
3000b57cec5SDimitry Andric return getIndex() == Other.getIndex();
3010b57cec5SDimitry Andric case MachineOperand::MO_ConstantPoolIndex:
3020b57cec5SDimitry Andric case MachineOperand::MO_TargetIndex:
3030b57cec5SDimitry Andric return getIndex() == Other.getIndex() && getOffset() == Other.getOffset();
3040b57cec5SDimitry Andric case MachineOperand::MO_JumpTableIndex:
3050b57cec5SDimitry Andric return getIndex() == Other.getIndex();
3060b57cec5SDimitry Andric case MachineOperand::MO_GlobalAddress:
3070b57cec5SDimitry Andric return getGlobal() == Other.getGlobal() && getOffset() == Other.getOffset();
3080b57cec5SDimitry Andric case MachineOperand::MO_ExternalSymbol:
3090b57cec5SDimitry Andric return strcmp(getSymbolName(), Other.getSymbolName()) == 0 &&
3100b57cec5SDimitry Andric getOffset() == Other.getOffset();
3110b57cec5SDimitry Andric case MachineOperand::MO_BlockAddress:
3120b57cec5SDimitry Andric return getBlockAddress() == Other.getBlockAddress() &&
3130b57cec5SDimitry Andric getOffset() == Other.getOffset();
3140b57cec5SDimitry Andric case MachineOperand::MO_RegisterMask:
3150b57cec5SDimitry Andric case MachineOperand::MO_RegisterLiveOut: {
3160b57cec5SDimitry Andric // Shallow compare of the two RegMasks
3170b57cec5SDimitry Andric const uint32_t *RegMask = getRegMask();
3180b57cec5SDimitry Andric const uint32_t *OtherRegMask = Other.getRegMask();
3190b57cec5SDimitry Andric if (RegMask == OtherRegMask)
3200b57cec5SDimitry Andric return true;
3210b57cec5SDimitry Andric
3220b57cec5SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(*this)) {
3230b57cec5SDimitry Andric // Calculate the size of the RegMask
3240b57cec5SDimitry Andric const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
3250b57cec5SDimitry Andric unsigned RegMaskSize = (TRI->getNumRegs() + 31) / 32;
3260b57cec5SDimitry Andric
3270b57cec5SDimitry Andric // Deep compare of the two RegMasks
3280b57cec5SDimitry Andric return std::equal(RegMask, RegMask + RegMaskSize, OtherRegMask);
3290b57cec5SDimitry Andric }
3300b57cec5SDimitry Andric // We don't know the size of the RegMask, so we can't deep compare the two
3310b57cec5SDimitry Andric // reg masks.
3320b57cec5SDimitry Andric return false;
3330b57cec5SDimitry Andric }
3340b57cec5SDimitry Andric case MachineOperand::MO_MCSymbol:
3350b57cec5SDimitry Andric return getMCSymbol() == Other.getMCSymbol();
3360b57cec5SDimitry Andric case MachineOperand::MO_CFIIndex:
3370b57cec5SDimitry Andric return getCFIIndex() == Other.getCFIIndex();
3380b57cec5SDimitry Andric case MachineOperand::MO_Metadata:
3390b57cec5SDimitry Andric return getMetadata() == Other.getMetadata();
3400b57cec5SDimitry Andric case MachineOperand::MO_IntrinsicID:
3410b57cec5SDimitry Andric return getIntrinsicID() == Other.getIntrinsicID();
3420b57cec5SDimitry Andric case MachineOperand::MO_Predicate:
3430b57cec5SDimitry Andric return getPredicate() == Other.getPredicate();
3448bcb0991SDimitry Andric case MachineOperand::MO_ShuffleMask:
3458bcb0991SDimitry Andric return getShuffleMask() == Other.getShuffleMask();
3460b57cec5SDimitry Andric }
3470b57cec5SDimitry Andric llvm_unreachable("Invalid machine operand type");
3480b57cec5SDimitry Andric }
3490b57cec5SDimitry Andric
3500b57cec5SDimitry Andric // Note: this must stay exactly in sync with isIdenticalTo above.
hash_value(const MachineOperand & MO)3510b57cec5SDimitry Andric hash_code llvm::hash_value(const MachineOperand &MO) {
3520b57cec5SDimitry Andric switch (MO.getType()) {
3530b57cec5SDimitry Andric case MachineOperand::MO_Register:
3540b57cec5SDimitry Andric // Register operands don't have target flags.
3550b57cec5SDimitry Andric return hash_combine(MO.getType(), (unsigned)MO.getReg(), MO.getSubReg(), MO.isDef());
3560b57cec5SDimitry Andric case MachineOperand::MO_Immediate:
3570b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getImm());
3580b57cec5SDimitry Andric case MachineOperand::MO_CImmediate:
3590b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCImm());
3600b57cec5SDimitry Andric case MachineOperand::MO_FPImmediate:
3610b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getFPImm());
3620b57cec5SDimitry Andric case MachineOperand::MO_MachineBasicBlock:
3630b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMBB());
3640b57cec5SDimitry Andric case MachineOperand::MO_FrameIndex:
3650b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex());
3660b57cec5SDimitry Andric case MachineOperand::MO_ConstantPoolIndex:
3670b57cec5SDimitry Andric case MachineOperand::MO_TargetIndex:
3680b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex(),
3690b57cec5SDimitry Andric MO.getOffset());
3700b57cec5SDimitry Andric case MachineOperand::MO_JumpTableIndex:
3710b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex());
3720b57cec5SDimitry Andric case MachineOperand::MO_ExternalSymbol:
3730b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getOffset(),
3740b57cec5SDimitry Andric StringRef(MO.getSymbolName()));
3750b57cec5SDimitry Andric case MachineOperand::MO_GlobalAddress:
3760b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getGlobal(),
3770b57cec5SDimitry Andric MO.getOffset());
3780b57cec5SDimitry Andric case MachineOperand::MO_BlockAddress:
3790b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getBlockAddress(),
3800b57cec5SDimitry Andric MO.getOffset());
3810b57cec5SDimitry Andric case MachineOperand::MO_RegisterMask:
3820b57cec5SDimitry Andric case MachineOperand::MO_RegisterLiveOut:
3830b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getRegMask());
3840b57cec5SDimitry Andric case MachineOperand::MO_Metadata:
3850b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMetadata());
3860b57cec5SDimitry Andric case MachineOperand::MO_MCSymbol:
3870b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMCSymbol());
3880b57cec5SDimitry Andric case MachineOperand::MO_CFIIndex:
3890b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCFIIndex());
3900b57cec5SDimitry Andric case MachineOperand::MO_IntrinsicID:
3910b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIntrinsicID());
3920b57cec5SDimitry Andric case MachineOperand::MO_Predicate:
3930b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getPredicate());
3948bcb0991SDimitry Andric case MachineOperand::MO_ShuffleMask:
3958bcb0991SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getShuffleMask());
3960b57cec5SDimitry Andric }
3970b57cec5SDimitry Andric llvm_unreachable("Invalid machine operand type");
3980b57cec5SDimitry Andric }
3990b57cec5SDimitry Andric
4000b57cec5SDimitry Andric // Try to crawl up to the machine function and get TRI and IntrinsicInfo from
4010b57cec5SDimitry Andric // it.
tryToGetTargetInfo(const MachineOperand & MO,const TargetRegisterInfo * & TRI,const TargetIntrinsicInfo * & IntrinsicInfo)4020b57cec5SDimitry Andric static void tryToGetTargetInfo(const MachineOperand &MO,
4030b57cec5SDimitry Andric const TargetRegisterInfo *&TRI,
4040b57cec5SDimitry Andric const TargetIntrinsicInfo *&IntrinsicInfo) {
4050b57cec5SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(MO)) {
4060b57cec5SDimitry Andric TRI = MF->getSubtarget().getRegisterInfo();
4070b57cec5SDimitry Andric IntrinsicInfo = MF->getTarget().getIntrinsicInfo();
4080b57cec5SDimitry Andric }
4090b57cec5SDimitry Andric }
4100b57cec5SDimitry Andric
getTargetIndexName(const MachineFunction & MF,int Index)4110b57cec5SDimitry Andric static const char *getTargetIndexName(const MachineFunction &MF, int Index) {
4120b57cec5SDimitry Andric const auto *TII = MF.getSubtarget().getInstrInfo();
4130b57cec5SDimitry Andric assert(TII && "expected instruction info");
4140b57cec5SDimitry Andric auto Indices = TII->getSerializableTargetIndices();
4150b57cec5SDimitry Andric auto Found = find_if(Indices, [&](const std::pair<int, const char *> &I) {
4160b57cec5SDimitry Andric return I.first == Index;
4170b57cec5SDimitry Andric });
4180b57cec5SDimitry Andric if (Found != Indices.end())
4190b57cec5SDimitry Andric return Found->second;
4200b57cec5SDimitry Andric return nullptr;
4210b57cec5SDimitry Andric }
4220b57cec5SDimitry Andric
getTargetIndexName() const423af732203SDimitry Andric const char *MachineOperand::getTargetIndexName() const {
424af732203SDimitry Andric const MachineFunction *MF = getMFIfAvailable(*this);
425af732203SDimitry Andric return MF ? ::getTargetIndexName(*MF, this->getIndex()) : nullptr;
426af732203SDimitry Andric }
427af732203SDimitry Andric
getTargetFlagName(const TargetInstrInfo * TII,unsigned TF)4280b57cec5SDimitry Andric static const char *getTargetFlagName(const TargetInstrInfo *TII, unsigned TF) {
4290b57cec5SDimitry Andric auto Flags = TII->getSerializableDirectMachineOperandTargetFlags();
4300b57cec5SDimitry Andric for (const auto &I : Flags) {
4310b57cec5SDimitry Andric if (I.first == TF) {
4320b57cec5SDimitry Andric return I.second;
4330b57cec5SDimitry Andric }
4340b57cec5SDimitry Andric }
4350b57cec5SDimitry Andric return nullptr;
4360b57cec5SDimitry Andric }
4370b57cec5SDimitry Andric
printCFIRegister(unsigned DwarfReg,raw_ostream & OS,const TargetRegisterInfo * TRI)4380b57cec5SDimitry Andric static void printCFIRegister(unsigned DwarfReg, raw_ostream &OS,
4390b57cec5SDimitry Andric const TargetRegisterInfo *TRI) {
4400b57cec5SDimitry Andric if (!TRI) {
4410b57cec5SDimitry Andric OS << "%dwarfreg." << DwarfReg;
4420b57cec5SDimitry Andric return;
4430b57cec5SDimitry Andric }
4440b57cec5SDimitry Andric
4458bcb0991SDimitry Andric if (Optional<unsigned> Reg = TRI->getLLVMRegNum(DwarfReg, true))
4468bcb0991SDimitry Andric OS << printReg(*Reg, TRI);
4478bcb0991SDimitry Andric else
4480b57cec5SDimitry Andric OS << "<badreg>";
4490b57cec5SDimitry Andric }
4500b57cec5SDimitry Andric
printIRBlockReference(raw_ostream & OS,const BasicBlock & BB,ModuleSlotTracker & MST)4510b57cec5SDimitry Andric static void printIRBlockReference(raw_ostream &OS, const BasicBlock &BB,
4520b57cec5SDimitry Andric ModuleSlotTracker &MST) {
4530b57cec5SDimitry Andric OS << "%ir-block.";
4540b57cec5SDimitry Andric if (BB.hasName()) {
4550b57cec5SDimitry Andric printLLVMNameWithoutPrefix(OS, BB.getName());
4560b57cec5SDimitry Andric return;
4570b57cec5SDimitry Andric }
4580b57cec5SDimitry Andric Optional<int> Slot;
4590b57cec5SDimitry Andric if (const Function *F = BB.getParent()) {
4600b57cec5SDimitry Andric if (F == MST.getCurrentFunction()) {
4610b57cec5SDimitry Andric Slot = MST.getLocalSlot(&BB);
4620b57cec5SDimitry Andric } else if (const Module *M = F->getParent()) {
4630b57cec5SDimitry Andric ModuleSlotTracker CustomMST(M, /*ShouldInitializeAllMetadata=*/false);
4640b57cec5SDimitry Andric CustomMST.incorporateFunction(*F);
4650b57cec5SDimitry Andric Slot = CustomMST.getLocalSlot(&BB);
4660b57cec5SDimitry Andric }
4670b57cec5SDimitry Andric }
4680b57cec5SDimitry Andric if (Slot)
4690b57cec5SDimitry Andric MachineOperand::printIRSlotNumber(OS, *Slot);
4700b57cec5SDimitry Andric else
4710b57cec5SDimitry Andric OS << "<unknown>";
4720b57cec5SDimitry Andric }
4730b57cec5SDimitry Andric
printSyncScope(raw_ostream & OS,const LLVMContext & Context,SyncScope::ID SSID,SmallVectorImpl<StringRef> & SSNs)4740b57cec5SDimitry Andric static void printSyncScope(raw_ostream &OS, const LLVMContext &Context,
4750b57cec5SDimitry Andric SyncScope::ID SSID,
4760b57cec5SDimitry Andric SmallVectorImpl<StringRef> &SSNs) {
4770b57cec5SDimitry Andric switch (SSID) {
4780b57cec5SDimitry Andric case SyncScope::System:
4790b57cec5SDimitry Andric break;
4800b57cec5SDimitry Andric default:
4810b57cec5SDimitry Andric if (SSNs.empty())
4820b57cec5SDimitry Andric Context.getSyncScopeNames(SSNs);
4830b57cec5SDimitry Andric
4840b57cec5SDimitry Andric OS << "syncscope(\"";
4850b57cec5SDimitry Andric printEscapedString(SSNs[SSID], OS);
4860b57cec5SDimitry Andric OS << "\") ";
4870b57cec5SDimitry Andric break;
4880b57cec5SDimitry Andric }
4890b57cec5SDimitry Andric }
4900b57cec5SDimitry Andric
getTargetMMOFlagName(const TargetInstrInfo & TII,unsigned TMMOFlag)4910b57cec5SDimitry Andric static const char *getTargetMMOFlagName(const TargetInstrInfo &TII,
4920b57cec5SDimitry Andric unsigned TMMOFlag) {
4930b57cec5SDimitry Andric auto Flags = TII.getSerializableMachineMemOperandTargetFlags();
4940b57cec5SDimitry Andric for (const auto &I : Flags) {
4950b57cec5SDimitry Andric if (I.first == TMMOFlag) {
4960b57cec5SDimitry Andric return I.second;
4970b57cec5SDimitry Andric }
4980b57cec5SDimitry Andric }
4990b57cec5SDimitry Andric return nullptr;
5000b57cec5SDimitry Andric }
5010b57cec5SDimitry Andric
printFrameIndex(raw_ostream & OS,int FrameIndex,bool IsFixed,const MachineFrameInfo * MFI)5020b57cec5SDimitry Andric static void printFrameIndex(raw_ostream& OS, int FrameIndex, bool IsFixed,
5030b57cec5SDimitry Andric const MachineFrameInfo *MFI) {
5040b57cec5SDimitry Andric StringRef Name;
5050b57cec5SDimitry Andric if (MFI) {
5060b57cec5SDimitry Andric IsFixed = MFI->isFixedObjectIndex(FrameIndex);
5070b57cec5SDimitry Andric if (const AllocaInst *Alloca = MFI->getObjectAllocation(FrameIndex))
5080b57cec5SDimitry Andric if (Alloca->hasName())
5090b57cec5SDimitry Andric Name = Alloca->getName();
5100b57cec5SDimitry Andric if (IsFixed)
5110b57cec5SDimitry Andric FrameIndex -= MFI->getObjectIndexBegin();
5120b57cec5SDimitry Andric }
5130b57cec5SDimitry Andric MachineOperand::printStackObjectReference(OS, FrameIndex, IsFixed, Name);
5140b57cec5SDimitry Andric }
5150b57cec5SDimitry Andric
printSubRegIdx(raw_ostream & OS,uint64_t Index,const TargetRegisterInfo * TRI)5160b57cec5SDimitry Andric void MachineOperand::printSubRegIdx(raw_ostream &OS, uint64_t Index,
5170b57cec5SDimitry Andric const TargetRegisterInfo *TRI) {
5180b57cec5SDimitry Andric OS << "%subreg.";
5190b57cec5SDimitry Andric if (TRI)
5200b57cec5SDimitry Andric OS << TRI->getSubRegIndexName(Index);
5210b57cec5SDimitry Andric else
5220b57cec5SDimitry Andric OS << Index;
5230b57cec5SDimitry Andric }
5240b57cec5SDimitry Andric
printTargetFlags(raw_ostream & OS,const MachineOperand & Op)5250b57cec5SDimitry Andric void MachineOperand::printTargetFlags(raw_ostream &OS,
5260b57cec5SDimitry Andric const MachineOperand &Op) {
5270b57cec5SDimitry Andric if (!Op.getTargetFlags())
5280b57cec5SDimitry Andric return;
5290b57cec5SDimitry Andric const MachineFunction *MF = getMFIfAvailable(Op);
5300b57cec5SDimitry Andric if (!MF)
5310b57cec5SDimitry Andric return;
5320b57cec5SDimitry Andric
5330b57cec5SDimitry Andric const auto *TII = MF->getSubtarget().getInstrInfo();
5340b57cec5SDimitry Andric assert(TII && "expected instruction info");
5350b57cec5SDimitry Andric auto Flags = TII->decomposeMachineOperandsTargetFlags(Op.getTargetFlags());
5360b57cec5SDimitry Andric OS << "target-flags(";
5370b57cec5SDimitry Andric const bool HasDirectFlags = Flags.first;
5380b57cec5SDimitry Andric const bool HasBitmaskFlags = Flags.second;
5390b57cec5SDimitry Andric if (!HasDirectFlags && !HasBitmaskFlags) {
5400b57cec5SDimitry Andric OS << "<unknown>) ";
5410b57cec5SDimitry Andric return;
5420b57cec5SDimitry Andric }
5430b57cec5SDimitry Andric if (HasDirectFlags) {
5440b57cec5SDimitry Andric if (const auto *Name = getTargetFlagName(TII, Flags.first))
5450b57cec5SDimitry Andric OS << Name;
5460b57cec5SDimitry Andric else
5470b57cec5SDimitry Andric OS << "<unknown target flag>";
5480b57cec5SDimitry Andric }
5490b57cec5SDimitry Andric if (!HasBitmaskFlags) {
5500b57cec5SDimitry Andric OS << ") ";
5510b57cec5SDimitry Andric return;
5520b57cec5SDimitry Andric }
5530b57cec5SDimitry Andric bool IsCommaNeeded = HasDirectFlags;
5540b57cec5SDimitry Andric unsigned BitMask = Flags.second;
5550b57cec5SDimitry Andric auto BitMasks = TII->getSerializableBitmaskMachineOperandTargetFlags();
5560b57cec5SDimitry Andric for (const auto &Mask : BitMasks) {
5570b57cec5SDimitry Andric // Check if the flag's bitmask has the bits of the current mask set.
5580b57cec5SDimitry Andric if ((BitMask & Mask.first) == Mask.first) {
5590b57cec5SDimitry Andric if (IsCommaNeeded)
5600b57cec5SDimitry Andric OS << ", ";
5610b57cec5SDimitry Andric IsCommaNeeded = true;
5620b57cec5SDimitry Andric OS << Mask.second;
5630b57cec5SDimitry Andric // Clear the bits which were serialized from the flag's bitmask.
5640b57cec5SDimitry Andric BitMask &= ~(Mask.first);
5650b57cec5SDimitry Andric }
5660b57cec5SDimitry Andric }
5670b57cec5SDimitry Andric if (BitMask) {
5680b57cec5SDimitry Andric // When the resulting flag's bitmask isn't zero, we know that we didn't
5690b57cec5SDimitry Andric // serialize all of the bit flags.
5700b57cec5SDimitry Andric if (IsCommaNeeded)
5710b57cec5SDimitry Andric OS << ", ";
5720b57cec5SDimitry Andric OS << "<unknown bitmask target flag>";
5730b57cec5SDimitry Andric }
5740b57cec5SDimitry Andric OS << ") ";
5750b57cec5SDimitry Andric }
5760b57cec5SDimitry Andric
printSymbol(raw_ostream & OS,MCSymbol & Sym)5770b57cec5SDimitry Andric void MachineOperand::printSymbol(raw_ostream &OS, MCSymbol &Sym) {
5780b57cec5SDimitry Andric OS << "<mcsymbol " << Sym << ">";
5790b57cec5SDimitry Andric }
5800b57cec5SDimitry Andric
printStackObjectReference(raw_ostream & OS,unsigned FrameIndex,bool IsFixed,StringRef Name)5810b57cec5SDimitry Andric void MachineOperand::printStackObjectReference(raw_ostream &OS,
5820b57cec5SDimitry Andric unsigned FrameIndex,
5830b57cec5SDimitry Andric bool IsFixed, StringRef Name) {
5840b57cec5SDimitry Andric if (IsFixed) {
5850b57cec5SDimitry Andric OS << "%fixed-stack." << FrameIndex;
5860b57cec5SDimitry Andric return;
5870b57cec5SDimitry Andric }
5880b57cec5SDimitry Andric
5890b57cec5SDimitry Andric OS << "%stack." << FrameIndex;
5900b57cec5SDimitry Andric if (!Name.empty())
5910b57cec5SDimitry Andric OS << '.' << Name;
5920b57cec5SDimitry Andric }
5930b57cec5SDimitry Andric
printOperandOffset(raw_ostream & OS,int64_t Offset)5940b57cec5SDimitry Andric void MachineOperand::printOperandOffset(raw_ostream &OS, int64_t Offset) {
5950b57cec5SDimitry Andric if (Offset == 0)
5960b57cec5SDimitry Andric return;
5970b57cec5SDimitry Andric if (Offset < 0) {
5980b57cec5SDimitry Andric OS << " - " << -Offset;
5990b57cec5SDimitry Andric return;
6000b57cec5SDimitry Andric }
6010b57cec5SDimitry Andric OS << " + " << Offset;
6020b57cec5SDimitry Andric }
6030b57cec5SDimitry Andric
printIRSlotNumber(raw_ostream & OS,int Slot)6040b57cec5SDimitry Andric void MachineOperand::printIRSlotNumber(raw_ostream &OS, int Slot) {
6050b57cec5SDimitry Andric if (Slot == -1)
6060b57cec5SDimitry Andric OS << "<badref>";
6070b57cec5SDimitry Andric else
6080b57cec5SDimitry Andric OS << Slot;
6090b57cec5SDimitry Andric }
6100b57cec5SDimitry Andric
printCFI(raw_ostream & OS,const MCCFIInstruction & CFI,const TargetRegisterInfo * TRI)6110b57cec5SDimitry Andric static void printCFI(raw_ostream &OS, const MCCFIInstruction &CFI,
6120b57cec5SDimitry Andric const TargetRegisterInfo *TRI) {
6130b57cec5SDimitry Andric switch (CFI.getOperation()) {
6140b57cec5SDimitry Andric case MCCFIInstruction::OpSameValue:
6150b57cec5SDimitry Andric OS << "same_value ";
6160b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel())
6170b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label);
6180b57cec5SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI);
6190b57cec5SDimitry Andric break;
6200b57cec5SDimitry Andric case MCCFIInstruction::OpRememberState:
6210b57cec5SDimitry Andric OS << "remember_state ";
6220b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel())
6230b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label);
6240b57cec5SDimitry Andric break;
6250b57cec5SDimitry Andric case MCCFIInstruction::OpRestoreState:
6260b57cec5SDimitry Andric OS << "restore_state ";
6270b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel())
6280b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label);
6290b57cec5SDimitry Andric break;
6300b57cec5SDimitry Andric case MCCFIInstruction::OpOffset:
6310b57cec5SDimitry Andric OS << "offset ";
6320b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel())
6330b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label);
6340b57cec5SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI);
6350b57cec5SDimitry Andric OS << ", " << CFI.getOffset();
6360b57cec5SDimitry Andric break;
6370b57cec5SDimitry Andric case MCCFIInstruction::OpDefCfaRegister:
6380b57cec5SDimitry Andric OS << "def_cfa_register ";
6390b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel())
6400b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label);
6410b57cec5SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI);
6420b57cec5SDimitry Andric break;
6430b57cec5SDimitry Andric case MCCFIInstruction::OpDefCfaOffset:
6440b57cec5SDimitry Andric OS << "def_cfa_offset ";
6450b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel())
6460b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label);
6470b57cec5SDimitry Andric OS << CFI.getOffset();
6480b57cec5SDimitry Andric break;
6490b57cec5SDimitry Andric case MCCFIInstruction::OpDefCfa:
6500b57cec5SDimitry Andric OS << "def_cfa ";
6510b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel())
6520b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label);
6530b57cec5SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI);
6540b57cec5SDimitry Andric OS << ", " << CFI.getOffset();
6550b57cec5SDimitry Andric break;
656*5f7ddb14SDimitry Andric case MCCFIInstruction::OpLLVMDefAspaceCfa:
657*5f7ddb14SDimitry Andric OS << "llvm_def_aspace_cfa ";
658*5f7ddb14SDimitry Andric if (MCSymbol *Label = CFI.getLabel())
659*5f7ddb14SDimitry Andric MachineOperand::printSymbol(OS, *Label);
660*5f7ddb14SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI);
661*5f7ddb14SDimitry Andric OS << ", " << CFI.getOffset();
662*5f7ddb14SDimitry Andric OS << ", " << CFI.getAddressSpace();
663*5f7ddb14SDimitry Andric break;
6640b57cec5SDimitry Andric case MCCFIInstruction::OpRelOffset:
6650b57cec5SDimitry Andric OS << "rel_offset ";
6660b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel())
6670b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label);
6680b57cec5SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI);
6690b57cec5SDimitry Andric OS << ", " << CFI.getOffset();
6700b57cec5SDimitry Andric break;
6710b57cec5SDimitry Andric case MCCFIInstruction::OpAdjustCfaOffset:
6720b57cec5SDimitry Andric OS << "adjust_cfa_offset ";
6730b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel())
6740b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label);
6750b57cec5SDimitry Andric OS << CFI.getOffset();
6760b57cec5SDimitry Andric break;
6770b57cec5SDimitry Andric case MCCFIInstruction::OpRestore:
6780b57cec5SDimitry Andric OS << "restore ";
6790b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel())
6800b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label);
6810b57cec5SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI);
6820b57cec5SDimitry Andric break;
6830b57cec5SDimitry Andric case MCCFIInstruction::OpEscape: {
6840b57cec5SDimitry Andric OS << "escape ";
6850b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel())
6860b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label);
6870b57cec5SDimitry Andric if (!CFI.getValues().empty()) {
6880b57cec5SDimitry Andric size_t e = CFI.getValues().size() - 1;
6890b57cec5SDimitry Andric for (size_t i = 0; i < e; ++i)
6900b57cec5SDimitry Andric OS << format("0x%02x", uint8_t(CFI.getValues()[i])) << ", ";
6915ffd83dbSDimitry Andric OS << format("0x%02x", uint8_t(CFI.getValues()[e]));
6920b57cec5SDimitry Andric }
6930b57cec5SDimitry Andric break;
6940b57cec5SDimitry Andric }
6950b57cec5SDimitry Andric case MCCFIInstruction::OpUndefined:
6960b57cec5SDimitry Andric OS << "undefined ";
6970b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel())
6980b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label);
6990b57cec5SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI);
7000b57cec5SDimitry Andric break;
7010b57cec5SDimitry Andric case MCCFIInstruction::OpRegister:
7020b57cec5SDimitry Andric OS << "register ";
7030b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel())
7040b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label);
7050b57cec5SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI);
7060b57cec5SDimitry Andric OS << ", ";
7070b57cec5SDimitry Andric printCFIRegister(CFI.getRegister2(), OS, TRI);
7080b57cec5SDimitry Andric break;
7090b57cec5SDimitry Andric case MCCFIInstruction::OpWindowSave:
7100b57cec5SDimitry Andric OS << "window_save ";
7110b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel())
7120b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label);
7130b57cec5SDimitry Andric break;
7140b57cec5SDimitry Andric case MCCFIInstruction::OpNegateRAState:
7150b57cec5SDimitry Andric OS << "negate_ra_sign_state ";
7160b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel())
7170b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label);
7180b57cec5SDimitry Andric break;
7190b57cec5SDimitry Andric default:
7200b57cec5SDimitry Andric // TODO: Print the other CFI Operations.
7210b57cec5SDimitry Andric OS << "<unserializable cfi directive>";
7220b57cec5SDimitry Andric break;
7230b57cec5SDimitry Andric }
7240b57cec5SDimitry Andric }
7250b57cec5SDimitry Andric
print(raw_ostream & OS,const TargetRegisterInfo * TRI,const TargetIntrinsicInfo * IntrinsicInfo) const7260b57cec5SDimitry Andric void MachineOperand::print(raw_ostream &OS, const TargetRegisterInfo *TRI,
7270b57cec5SDimitry Andric const TargetIntrinsicInfo *IntrinsicInfo) const {
7280b57cec5SDimitry Andric print(OS, LLT{}, TRI, IntrinsicInfo);
7290b57cec5SDimitry Andric }
7300b57cec5SDimitry Andric
print(raw_ostream & OS,LLT TypeToPrint,const TargetRegisterInfo * TRI,const TargetIntrinsicInfo * IntrinsicInfo) const7310b57cec5SDimitry Andric void MachineOperand::print(raw_ostream &OS, LLT TypeToPrint,
7320b57cec5SDimitry Andric const TargetRegisterInfo *TRI,
7330b57cec5SDimitry Andric const TargetIntrinsicInfo *IntrinsicInfo) const {
7340b57cec5SDimitry Andric tryToGetTargetInfo(*this, TRI, IntrinsicInfo);
7350b57cec5SDimitry Andric ModuleSlotTracker DummyMST(nullptr);
736480093f4SDimitry Andric print(OS, DummyMST, TypeToPrint, None, /*PrintDef=*/false,
737480093f4SDimitry Andric /*IsStandalone=*/true,
7380b57cec5SDimitry Andric /*ShouldPrintRegisterTies=*/true,
7390b57cec5SDimitry Andric /*TiedOperandIdx=*/0, TRI, IntrinsicInfo);
7400b57cec5SDimitry Andric }
7410b57cec5SDimitry Andric
print(raw_ostream & OS,ModuleSlotTracker & MST,LLT TypeToPrint,Optional<unsigned> OpIdx,bool PrintDef,bool IsStandalone,bool ShouldPrintRegisterTies,unsigned TiedOperandIdx,const TargetRegisterInfo * TRI,const TargetIntrinsicInfo * IntrinsicInfo) const7420b57cec5SDimitry Andric void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
743480093f4SDimitry Andric LLT TypeToPrint, Optional<unsigned> OpIdx, bool PrintDef,
744480093f4SDimitry Andric bool IsStandalone, bool ShouldPrintRegisterTies,
7450b57cec5SDimitry Andric unsigned TiedOperandIdx,
7460b57cec5SDimitry Andric const TargetRegisterInfo *TRI,
7470b57cec5SDimitry Andric const TargetIntrinsicInfo *IntrinsicInfo) const {
7480b57cec5SDimitry Andric printTargetFlags(OS, *this);
7490b57cec5SDimitry Andric switch (getType()) {
7500b57cec5SDimitry Andric case MachineOperand::MO_Register: {
7518bcb0991SDimitry Andric Register Reg = getReg();
7520b57cec5SDimitry Andric if (isImplicit())
7530b57cec5SDimitry Andric OS << (isDef() ? "implicit-def " : "implicit ");
7540b57cec5SDimitry Andric else if (PrintDef && isDef())
7550b57cec5SDimitry Andric // Print the 'def' flag only when the operand is defined after '='.
7560b57cec5SDimitry Andric OS << "def ";
7570b57cec5SDimitry Andric if (isInternalRead())
7580b57cec5SDimitry Andric OS << "internal ";
7590b57cec5SDimitry Andric if (isDead())
7600b57cec5SDimitry Andric OS << "dead ";
7610b57cec5SDimitry Andric if (isKill())
7620b57cec5SDimitry Andric OS << "killed ";
7630b57cec5SDimitry Andric if (isUndef())
7640b57cec5SDimitry Andric OS << "undef ";
7650b57cec5SDimitry Andric if (isEarlyClobber())
7660b57cec5SDimitry Andric OS << "early-clobber ";
7678bcb0991SDimitry Andric if (Register::isPhysicalRegister(getReg()) && isRenamable())
7680b57cec5SDimitry Andric OS << "renamable ";
7690b57cec5SDimitry Andric // isDebug() is exactly true for register operands of a DBG_VALUE. So we
7700b57cec5SDimitry Andric // simply infer it when parsing and do not need to print it.
7710b57cec5SDimitry Andric
7720b57cec5SDimitry Andric const MachineRegisterInfo *MRI = nullptr;
7738bcb0991SDimitry Andric if (Register::isVirtualRegister(Reg)) {
7740b57cec5SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(*this)) {
7750b57cec5SDimitry Andric MRI = &MF->getRegInfo();
7760b57cec5SDimitry Andric }
7770b57cec5SDimitry Andric }
7780b57cec5SDimitry Andric
7790b57cec5SDimitry Andric OS << printReg(Reg, TRI, 0, MRI);
7800b57cec5SDimitry Andric // Print the sub register.
7810b57cec5SDimitry Andric if (unsigned SubReg = getSubReg()) {
7820b57cec5SDimitry Andric if (TRI)
7830b57cec5SDimitry Andric OS << '.' << TRI->getSubRegIndexName(SubReg);
7840b57cec5SDimitry Andric else
7850b57cec5SDimitry Andric OS << ".subreg" << SubReg;
7860b57cec5SDimitry Andric }
7870b57cec5SDimitry Andric // Print the register class / bank.
7888bcb0991SDimitry Andric if (Register::isVirtualRegister(Reg)) {
7890b57cec5SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(*this)) {
7900b57cec5SDimitry Andric const MachineRegisterInfo &MRI = MF->getRegInfo();
7910b57cec5SDimitry Andric if (IsStandalone || !PrintDef || MRI.def_empty(Reg)) {
7920b57cec5SDimitry Andric OS << ':';
7930b57cec5SDimitry Andric OS << printRegClassOrBank(Reg, MRI, TRI);
7940b57cec5SDimitry Andric }
7950b57cec5SDimitry Andric }
7960b57cec5SDimitry Andric }
7970b57cec5SDimitry Andric // Print ties.
7980b57cec5SDimitry Andric if (ShouldPrintRegisterTies && isTied() && !isDef())
7990b57cec5SDimitry Andric OS << "(tied-def " << TiedOperandIdx << ")";
8000b57cec5SDimitry Andric // Print types.
8010b57cec5SDimitry Andric if (TypeToPrint.isValid())
8020b57cec5SDimitry Andric OS << '(' << TypeToPrint << ')';
8030b57cec5SDimitry Andric break;
8040b57cec5SDimitry Andric }
805480093f4SDimitry Andric case MachineOperand::MO_Immediate: {
806480093f4SDimitry Andric const MIRFormatter *Formatter = nullptr;
807480093f4SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(*this)) {
808480093f4SDimitry Andric const auto *TII = MF->getSubtarget().getInstrInfo();
809480093f4SDimitry Andric assert(TII && "expected instruction info");
810480093f4SDimitry Andric Formatter = TII->getMIRFormatter();
811480093f4SDimitry Andric }
812480093f4SDimitry Andric if (Formatter)
813480093f4SDimitry Andric Formatter->printImm(OS, *getParent(), OpIdx, getImm());
814480093f4SDimitry Andric else
8150b57cec5SDimitry Andric OS << getImm();
8160b57cec5SDimitry Andric break;
817480093f4SDimitry Andric }
8180b57cec5SDimitry Andric case MachineOperand::MO_CImmediate:
8190b57cec5SDimitry Andric getCImm()->printAsOperand(OS, /*PrintType=*/true, MST);
8200b57cec5SDimitry Andric break;
8210b57cec5SDimitry Andric case MachineOperand::MO_FPImmediate:
8220b57cec5SDimitry Andric getFPImm()->printAsOperand(OS, /*PrintType=*/true, MST);
8230b57cec5SDimitry Andric break;
8240b57cec5SDimitry Andric case MachineOperand::MO_MachineBasicBlock:
8250b57cec5SDimitry Andric OS << printMBBReference(*getMBB());
8260b57cec5SDimitry Andric break;
8270b57cec5SDimitry Andric case MachineOperand::MO_FrameIndex: {
8280b57cec5SDimitry Andric int FrameIndex = getIndex();
8290b57cec5SDimitry Andric bool IsFixed = false;
8300b57cec5SDimitry Andric const MachineFrameInfo *MFI = nullptr;
8310b57cec5SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(*this))
8320b57cec5SDimitry Andric MFI = &MF->getFrameInfo();
8330b57cec5SDimitry Andric printFrameIndex(OS, FrameIndex, IsFixed, MFI);
8340b57cec5SDimitry Andric break;
8350b57cec5SDimitry Andric }
8360b57cec5SDimitry Andric case MachineOperand::MO_ConstantPoolIndex:
8370b57cec5SDimitry Andric OS << "%const." << getIndex();
8380b57cec5SDimitry Andric printOperandOffset(OS, getOffset());
8390b57cec5SDimitry Andric break;
8400b57cec5SDimitry Andric case MachineOperand::MO_TargetIndex: {
8410b57cec5SDimitry Andric OS << "target-index(";
8420b57cec5SDimitry Andric const char *Name = "<unknown>";
8430b57cec5SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(*this))
844af732203SDimitry Andric if (const auto *TargetIndexName = ::getTargetIndexName(*MF, getIndex()))
8450b57cec5SDimitry Andric Name = TargetIndexName;
8460b57cec5SDimitry Andric OS << Name << ')';
8470b57cec5SDimitry Andric printOperandOffset(OS, getOffset());
8480b57cec5SDimitry Andric break;
8490b57cec5SDimitry Andric }
8500b57cec5SDimitry Andric case MachineOperand::MO_JumpTableIndex:
8510b57cec5SDimitry Andric OS << printJumpTableEntryReference(getIndex());
8520b57cec5SDimitry Andric break;
8530b57cec5SDimitry Andric case MachineOperand::MO_GlobalAddress:
8540b57cec5SDimitry Andric getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST);
8550b57cec5SDimitry Andric printOperandOffset(OS, getOffset());
8560b57cec5SDimitry Andric break;
8570b57cec5SDimitry Andric case MachineOperand::MO_ExternalSymbol: {
8580b57cec5SDimitry Andric StringRef Name = getSymbolName();
8590b57cec5SDimitry Andric OS << '&';
8600b57cec5SDimitry Andric if (Name.empty()) {
8610b57cec5SDimitry Andric OS << "\"\"";
8620b57cec5SDimitry Andric } else {
8630b57cec5SDimitry Andric printLLVMNameWithoutPrefix(OS, Name);
8640b57cec5SDimitry Andric }
8650b57cec5SDimitry Andric printOperandOffset(OS, getOffset());
8660b57cec5SDimitry Andric break;
8670b57cec5SDimitry Andric }
8680b57cec5SDimitry Andric case MachineOperand::MO_BlockAddress: {
8690b57cec5SDimitry Andric OS << "blockaddress(";
8700b57cec5SDimitry Andric getBlockAddress()->getFunction()->printAsOperand(OS, /*PrintType=*/false,
8710b57cec5SDimitry Andric MST);
8720b57cec5SDimitry Andric OS << ", ";
8730b57cec5SDimitry Andric printIRBlockReference(OS, *getBlockAddress()->getBasicBlock(), MST);
8740b57cec5SDimitry Andric OS << ')';
8750b57cec5SDimitry Andric MachineOperand::printOperandOffset(OS, getOffset());
8760b57cec5SDimitry Andric break;
8770b57cec5SDimitry Andric }
8780b57cec5SDimitry Andric case MachineOperand::MO_RegisterMask: {
8790b57cec5SDimitry Andric OS << "<regmask";
8800b57cec5SDimitry Andric if (TRI) {
8810b57cec5SDimitry Andric unsigned NumRegsInMask = 0;
8820b57cec5SDimitry Andric unsigned NumRegsEmitted = 0;
8830b57cec5SDimitry Andric for (unsigned i = 0; i < TRI->getNumRegs(); ++i) {
8840b57cec5SDimitry Andric unsigned MaskWord = i / 32;
8850b57cec5SDimitry Andric unsigned MaskBit = i % 32;
8860b57cec5SDimitry Andric if (getRegMask()[MaskWord] & (1 << MaskBit)) {
8870b57cec5SDimitry Andric if (PrintRegMaskNumRegs < 0 ||
8880b57cec5SDimitry Andric NumRegsEmitted <= static_cast<unsigned>(PrintRegMaskNumRegs)) {
8890b57cec5SDimitry Andric OS << " " << printReg(i, TRI);
8900b57cec5SDimitry Andric NumRegsEmitted++;
8910b57cec5SDimitry Andric }
8920b57cec5SDimitry Andric NumRegsInMask++;
8930b57cec5SDimitry Andric }
8940b57cec5SDimitry Andric }
8950b57cec5SDimitry Andric if (NumRegsEmitted != NumRegsInMask)
8960b57cec5SDimitry Andric OS << " and " << (NumRegsInMask - NumRegsEmitted) << " more...";
8970b57cec5SDimitry Andric } else {
8980b57cec5SDimitry Andric OS << " ...";
8990b57cec5SDimitry Andric }
9000b57cec5SDimitry Andric OS << ">";
9010b57cec5SDimitry Andric break;
9020b57cec5SDimitry Andric }
9030b57cec5SDimitry Andric case MachineOperand::MO_RegisterLiveOut: {
9040b57cec5SDimitry Andric const uint32_t *RegMask = getRegLiveOut();
9050b57cec5SDimitry Andric OS << "liveout(";
9060b57cec5SDimitry Andric if (!TRI) {
9070b57cec5SDimitry Andric OS << "<unknown>";
9080b57cec5SDimitry Andric } else {
9090b57cec5SDimitry Andric bool IsCommaNeeded = false;
9100b57cec5SDimitry Andric for (unsigned Reg = 0, E = TRI->getNumRegs(); Reg < E; ++Reg) {
9110b57cec5SDimitry Andric if (RegMask[Reg / 32] & (1U << (Reg % 32))) {
9120b57cec5SDimitry Andric if (IsCommaNeeded)
9130b57cec5SDimitry Andric OS << ", ";
9140b57cec5SDimitry Andric OS << printReg(Reg, TRI);
9150b57cec5SDimitry Andric IsCommaNeeded = true;
9160b57cec5SDimitry Andric }
9170b57cec5SDimitry Andric }
9180b57cec5SDimitry Andric }
9190b57cec5SDimitry Andric OS << ")";
9200b57cec5SDimitry Andric break;
9210b57cec5SDimitry Andric }
9220b57cec5SDimitry Andric case MachineOperand::MO_Metadata:
9230b57cec5SDimitry Andric getMetadata()->printAsOperand(OS, MST);
9240b57cec5SDimitry Andric break;
9250b57cec5SDimitry Andric case MachineOperand::MO_MCSymbol:
9260b57cec5SDimitry Andric printSymbol(OS, *getMCSymbol());
9270b57cec5SDimitry Andric break;
9280b57cec5SDimitry Andric case MachineOperand::MO_CFIIndex: {
9290b57cec5SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(*this))
9300b57cec5SDimitry Andric printCFI(OS, MF->getFrameInstructions()[getCFIIndex()], TRI);
9310b57cec5SDimitry Andric else
9320b57cec5SDimitry Andric OS << "<cfi directive>";
9330b57cec5SDimitry Andric break;
9340b57cec5SDimitry Andric }
9350b57cec5SDimitry Andric case MachineOperand::MO_IntrinsicID: {
9360b57cec5SDimitry Andric Intrinsic::ID ID = getIntrinsicID();
9370b57cec5SDimitry Andric if (ID < Intrinsic::num_intrinsics)
938*5f7ddb14SDimitry Andric OS << "intrinsic(@" << Intrinsic::getBaseName(ID) << ')';
9390b57cec5SDimitry Andric else if (IntrinsicInfo)
9400b57cec5SDimitry Andric OS << "intrinsic(@" << IntrinsicInfo->getName(ID) << ')';
9410b57cec5SDimitry Andric else
9420b57cec5SDimitry Andric OS << "intrinsic(" << ID << ')';
9430b57cec5SDimitry Andric break;
9440b57cec5SDimitry Andric }
9450b57cec5SDimitry Andric case MachineOperand::MO_Predicate: {
9460b57cec5SDimitry Andric auto Pred = static_cast<CmpInst::Predicate>(getPredicate());
9470b57cec5SDimitry Andric OS << (CmpInst::isIntPredicate(Pred) ? "int" : "float") << "pred("
9480b57cec5SDimitry Andric << CmpInst::getPredicateName(Pred) << ')';
9490b57cec5SDimitry Andric break;
9500b57cec5SDimitry Andric }
9518bcb0991SDimitry Andric case MachineOperand::MO_ShuffleMask:
9528bcb0991SDimitry Andric OS << "shufflemask(";
953480093f4SDimitry Andric ArrayRef<int> Mask = getShuffleMask();
9548bcb0991SDimitry Andric StringRef Separator;
955480093f4SDimitry Andric for (int Elt : Mask) {
956480093f4SDimitry Andric if (Elt == -1)
957480093f4SDimitry Andric OS << Separator << "undef";
958480093f4SDimitry Andric else
959480093f4SDimitry Andric OS << Separator << Elt;
9608bcb0991SDimitry Andric Separator = ", ";
9618bcb0991SDimitry Andric }
9628bcb0991SDimitry Andric
9638bcb0991SDimitry Andric OS << ')';
9648bcb0991SDimitry Andric break;
9650b57cec5SDimitry Andric }
9660b57cec5SDimitry Andric }
9670b57cec5SDimitry Andric
9680b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const9690b57cec5SDimitry Andric LLVM_DUMP_METHOD void MachineOperand::dump() const { dbgs() << *this << '\n'; }
9700b57cec5SDimitry Andric #endif
9710b57cec5SDimitry Andric
9720b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
9730b57cec5SDimitry Andric // MachineMemOperand Implementation
9740b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
9750b57cec5SDimitry Andric
9760b57cec5SDimitry Andric /// getAddrSpace - Return the LLVM IR address space number that this pointer
9770b57cec5SDimitry Andric /// points into.
getAddrSpace() const9780b57cec5SDimitry Andric unsigned MachinePointerInfo::getAddrSpace() const { return AddrSpace; }
9790b57cec5SDimitry Andric
9800b57cec5SDimitry Andric /// isDereferenceable - Return true if V is always dereferenceable for
9810b57cec5SDimitry Andric /// Offset + Size byte.
isDereferenceable(unsigned Size,LLVMContext & C,const DataLayout & DL) const9820b57cec5SDimitry Andric bool MachinePointerInfo::isDereferenceable(unsigned Size, LLVMContext &C,
9830b57cec5SDimitry Andric const DataLayout &DL) const {
9840b57cec5SDimitry Andric if (!V.is<const Value *>())
9850b57cec5SDimitry Andric return false;
9860b57cec5SDimitry Andric
9870b57cec5SDimitry Andric const Value *BasePtr = V.get<const Value *>();
9880b57cec5SDimitry Andric if (BasePtr == nullptr)
9890b57cec5SDimitry Andric return false;
9900b57cec5SDimitry Andric
9910b57cec5SDimitry Andric return isDereferenceableAndAlignedPointer(
9925ffd83dbSDimitry Andric BasePtr, Align(1), APInt(DL.getPointerSizeInBits(), Offset + Size), DL);
9930b57cec5SDimitry Andric }
9940b57cec5SDimitry Andric
9950b57cec5SDimitry Andric /// getConstantPool - Return a MachinePointerInfo record that refers to the
9960b57cec5SDimitry Andric /// constant pool.
getConstantPool(MachineFunction & MF)9970b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getConstantPool(MachineFunction &MF) {
9980b57cec5SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getConstantPool());
9990b57cec5SDimitry Andric }
10000b57cec5SDimitry Andric
10010b57cec5SDimitry Andric /// getFixedStack - Return a MachinePointerInfo record that refers to the
10020b57cec5SDimitry Andric /// the specified FrameIndex.
getFixedStack(MachineFunction & MF,int FI,int64_t Offset)10030b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getFixedStack(MachineFunction &MF,
10040b57cec5SDimitry Andric int FI, int64_t Offset) {
10050b57cec5SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getFixedStack(FI), Offset);
10060b57cec5SDimitry Andric }
10070b57cec5SDimitry Andric
getJumpTable(MachineFunction & MF)10080b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getJumpTable(MachineFunction &MF) {
10090b57cec5SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getJumpTable());
10100b57cec5SDimitry Andric }
10110b57cec5SDimitry Andric
getGOT(MachineFunction & MF)10120b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getGOT(MachineFunction &MF) {
10130b57cec5SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getGOT());
10140b57cec5SDimitry Andric }
10150b57cec5SDimitry Andric
getStack(MachineFunction & MF,int64_t Offset,uint8_t ID)10160b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getStack(MachineFunction &MF,
10170b57cec5SDimitry Andric int64_t Offset, uint8_t ID) {
10180b57cec5SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getStack(), Offset, ID);
10190b57cec5SDimitry Andric }
10200b57cec5SDimitry Andric
getUnknownStack(MachineFunction & MF)10210b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getUnknownStack(MachineFunction &MF) {
10220b57cec5SDimitry Andric return MachinePointerInfo(MF.getDataLayout().getAllocaAddrSpace());
10230b57cec5SDimitry Andric }
10240b57cec5SDimitry Andric
MachineMemOperand(MachinePointerInfo ptrinfo,Flags f,LLT type,Align a,const AAMDNodes & AAInfo,const MDNode * Ranges,SyncScope::ID SSID,AtomicOrdering Ordering,AtomicOrdering FailureOrdering)10250b57cec5SDimitry Andric MachineMemOperand::MachineMemOperand(MachinePointerInfo ptrinfo, Flags f,
1026*5f7ddb14SDimitry Andric LLT type, Align a, const AAMDNodes &AAInfo,
10270b57cec5SDimitry Andric const MDNode *Ranges, SyncScope::ID SSID,
10280b57cec5SDimitry Andric AtomicOrdering Ordering,
10290b57cec5SDimitry Andric AtomicOrdering FailureOrdering)
1030*5f7ddb14SDimitry Andric : PtrInfo(ptrinfo), MemoryType(type), FlagVals(f), BaseAlign(a),
1031*5f7ddb14SDimitry Andric AAInfo(AAInfo), Ranges(Ranges) {
10320b57cec5SDimitry Andric assert((PtrInfo.V.isNull() || PtrInfo.V.is<const PseudoSourceValue *>() ||
10330b57cec5SDimitry Andric isa<PointerType>(PtrInfo.V.get<const Value *>()->getType())) &&
10340b57cec5SDimitry Andric "invalid pointer value");
10350b57cec5SDimitry Andric assert((isLoad() || isStore()) && "Not a load/store!");
10360b57cec5SDimitry Andric
10370b57cec5SDimitry Andric AtomicInfo.SSID = static_cast<unsigned>(SSID);
10380b57cec5SDimitry Andric assert(getSyncScopeID() == SSID && "Value truncated");
10390b57cec5SDimitry Andric AtomicInfo.Ordering = static_cast<unsigned>(Ordering);
1040*5f7ddb14SDimitry Andric assert(getSuccessOrdering() == Ordering && "Value truncated");
10410b57cec5SDimitry Andric AtomicInfo.FailureOrdering = static_cast<unsigned>(FailureOrdering);
10420b57cec5SDimitry Andric assert(getFailureOrdering() == FailureOrdering && "Value truncated");
10430b57cec5SDimitry Andric }
10440b57cec5SDimitry Andric
MachineMemOperand(MachinePointerInfo ptrinfo,Flags f,uint64_t s,Align a,const AAMDNodes & AAInfo,const MDNode * Ranges,SyncScope::ID SSID,AtomicOrdering Ordering,AtomicOrdering FailureOrdering)1045*5f7ddb14SDimitry Andric MachineMemOperand::MachineMemOperand(MachinePointerInfo ptrinfo, Flags f,
1046*5f7ddb14SDimitry Andric uint64_t s, Align a,
1047*5f7ddb14SDimitry Andric const AAMDNodes &AAInfo,
1048*5f7ddb14SDimitry Andric const MDNode *Ranges, SyncScope::ID SSID,
1049*5f7ddb14SDimitry Andric AtomicOrdering Ordering,
1050*5f7ddb14SDimitry Andric AtomicOrdering FailureOrdering)
1051*5f7ddb14SDimitry Andric : MachineMemOperand(ptrinfo, f,
1052*5f7ddb14SDimitry Andric s == ~UINT64_C(0) ? LLT() : LLT::scalar(8 * s), a,
1053*5f7ddb14SDimitry Andric AAInfo, Ranges, SSID, Ordering, FailureOrdering) {}
1054*5f7ddb14SDimitry Andric
10550b57cec5SDimitry Andric /// Profile - Gather unique data for the object.
10560b57cec5SDimitry Andric ///
Profile(FoldingSetNodeID & ID) const10570b57cec5SDimitry Andric void MachineMemOperand::Profile(FoldingSetNodeID &ID) const {
10580b57cec5SDimitry Andric ID.AddInteger(getOffset());
1059*5f7ddb14SDimitry Andric ID.AddInteger(getMemoryType().getUniqueRAWLLTData());
10600b57cec5SDimitry Andric ID.AddPointer(getOpaqueValue());
10610b57cec5SDimitry Andric ID.AddInteger(getFlags());
10625ffd83dbSDimitry Andric ID.AddInteger(getBaseAlign().value());
10630b57cec5SDimitry Andric }
10640b57cec5SDimitry Andric
refineAlignment(const MachineMemOperand * MMO)10650b57cec5SDimitry Andric void MachineMemOperand::refineAlignment(const MachineMemOperand *MMO) {
10660b57cec5SDimitry Andric // The Value and Offset may differ due to CSE. But the flags and size
10670b57cec5SDimitry Andric // should be the same.
10680b57cec5SDimitry Andric assert(MMO->getFlags() == getFlags() && "Flags mismatch!");
10690b57cec5SDimitry Andric assert(MMO->getSize() == getSize() && "Size mismatch!");
10700b57cec5SDimitry Andric
10715ffd83dbSDimitry Andric if (MMO->getBaseAlign() >= getBaseAlign()) {
10720b57cec5SDimitry Andric // Update the alignment value.
10735ffd83dbSDimitry Andric BaseAlign = MMO->getBaseAlign();
10740b57cec5SDimitry Andric // Also update the base and offset, because the new alignment may
10750b57cec5SDimitry Andric // not be applicable with the old ones.
10760b57cec5SDimitry Andric PtrInfo = MMO->PtrInfo;
10770b57cec5SDimitry Andric }
10780b57cec5SDimitry Andric }
10790b57cec5SDimitry Andric
10805ffd83dbSDimitry Andric /// getAlign - Return the minimum known alignment in bytes of the
10815ffd83dbSDimitry Andric /// actual memory reference.
getAlign() const10825ffd83dbSDimitry Andric Align MachineMemOperand::getAlign() const {
10835ffd83dbSDimitry Andric return commonAlignment(getBaseAlign(), getOffset());
10840b57cec5SDimitry Andric }
10850b57cec5SDimitry Andric
print(raw_ostream & OS,ModuleSlotTracker & MST,SmallVectorImpl<StringRef> & SSNs,const LLVMContext & Context,const MachineFrameInfo * MFI,const TargetInstrInfo * TII) const10860b57cec5SDimitry Andric void MachineMemOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
10870b57cec5SDimitry Andric SmallVectorImpl<StringRef> &SSNs,
10880b57cec5SDimitry Andric const LLVMContext &Context,
10890b57cec5SDimitry Andric const MachineFrameInfo *MFI,
10900b57cec5SDimitry Andric const TargetInstrInfo *TII) const {
10910b57cec5SDimitry Andric OS << '(';
10920b57cec5SDimitry Andric if (isVolatile())
10930b57cec5SDimitry Andric OS << "volatile ";
10940b57cec5SDimitry Andric if (isNonTemporal())
10950b57cec5SDimitry Andric OS << "non-temporal ";
10960b57cec5SDimitry Andric if (isDereferenceable())
10970b57cec5SDimitry Andric OS << "dereferenceable ";
10980b57cec5SDimitry Andric if (isInvariant())
10990b57cec5SDimitry Andric OS << "invariant ";
11000b57cec5SDimitry Andric if (getFlags() & MachineMemOperand::MOTargetFlag1)
11010b57cec5SDimitry Andric OS << '"' << getTargetMMOFlagName(*TII, MachineMemOperand::MOTargetFlag1)
11020b57cec5SDimitry Andric << "\" ";
11030b57cec5SDimitry Andric if (getFlags() & MachineMemOperand::MOTargetFlag2)
11040b57cec5SDimitry Andric OS << '"' << getTargetMMOFlagName(*TII, MachineMemOperand::MOTargetFlag2)
11050b57cec5SDimitry Andric << "\" ";
11060b57cec5SDimitry Andric if (getFlags() & MachineMemOperand::MOTargetFlag3)
11070b57cec5SDimitry Andric OS << '"' << getTargetMMOFlagName(*TII, MachineMemOperand::MOTargetFlag3)
11080b57cec5SDimitry Andric << "\" ";
11090b57cec5SDimitry Andric
11100b57cec5SDimitry Andric assert((isLoad() || isStore()) &&
11110b57cec5SDimitry Andric "machine memory operand must be a load or store (or both)");
11120b57cec5SDimitry Andric if (isLoad())
11130b57cec5SDimitry Andric OS << "load ";
11140b57cec5SDimitry Andric if (isStore())
11150b57cec5SDimitry Andric OS << "store ";
11160b57cec5SDimitry Andric
11170b57cec5SDimitry Andric printSyncScope(OS, Context, getSyncScopeID(), SSNs);
11180b57cec5SDimitry Andric
1119*5f7ddb14SDimitry Andric if (getSuccessOrdering() != AtomicOrdering::NotAtomic)
1120*5f7ddb14SDimitry Andric OS << toIRString(getSuccessOrdering()) << ' ';
11210b57cec5SDimitry Andric if (getFailureOrdering() != AtomicOrdering::NotAtomic)
11220b57cec5SDimitry Andric OS << toIRString(getFailureOrdering()) << ' ';
11230b57cec5SDimitry Andric
1124*5f7ddb14SDimitry Andric if (getMemoryType().isValid())
1125*5f7ddb14SDimitry Andric OS << '(' << getMemoryType() << ')';
11260b57cec5SDimitry Andric else
1127*5f7ddb14SDimitry Andric OS << "unknown-size";
11280b57cec5SDimitry Andric
11290b57cec5SDimitry Andric if (const Value *Val = getValue()) {
11300b57cec5SDimitry Andric OS << ((isLoad() && isStore()) ? " on " : isLoad() ? " from " : " into ");
1131480093f4SDimitry Andric MIRFormatter::printIRValue(OS, *Val, MST);
11320b57cec5SDimitry Andric } else if (const PseudoSourceValue *PVal = getPseudoValue()) {
11330b57cec5SDimitry Andric OS << ((isLoad() && isStore()) ? " on " : isLoad() ? " from " : " into ");
11340b57cec5SDimitry Andric assert(PVal && "Expected a pseudo source value");
11350b57cec5SDimitry Andric switch (PVal->kind()) {
11360b57cec5SDimitry Andric case PseudoSourceValue::Stack:
11370b57cec5SDimitry Andric OS << "stack";
11380b57cec5SDimitry Andric break;
11390b57cec5SDimitry Andric case PseudoSourceValue::GOT:
11400b57cec5SDimitry Andric OS << "got";
11410b57cec5SDimitry Andric break;
11420b57cec5SDimitry Andric case PseudoSourceValue::JumpTable:
11430b57cec5SDimitry Andric OS << "jump-table";
11440b57cec5SDimitry Andric break;
11450b57cec5SDimitry Andric case PseudoSourceValue::ConstantPool:
11460b57cec5SDimitry Andric OS << "constant-pool";
11470b57cec5SDimitry Andric break;
11480b57cec5SDimitry Andric case PseudoSourceValue::FixedStack: {
11490b57cec5SDimitry Andric int FrameIndex = cast<FixedStackPseudoSourceValue>(PVal)->getFrameIndex();
11500b57cec5SDimitry Andric bool IsFixed = true;
11510b57cec5SDimitry Andric printFrameIndex(OS, FrameIndex, IsFixed, MFI);
11520b57cec5SDimitry Andric break;
11530b57cec5SDimitry Andric }
11540b57cec5SDimitry Andric case PseudoSourceValue::GlobalValueCallEntry:
11550b57cec5SDimitry Andric OS << "call-entry ";
11560b57cec5SDimitry Andric cast<GlobalValuePseudoSourceValue>(PVal)->getValue()->printAsOperand(
11570b57cec5SDimitry Andric OS, /*PrintType=*/false, MST);
11580b57cec5SDimitry Andric break;
11590b57cec5SDimitry Andric case PseudoSourceValue::ExternalSymbolCallEntry:
11600b57cec5SDimitry Andric OS << "call-entry &";
11610b57cec5SDimitry Andric printLLVMNameWithoutPrefix(
11620b57cec5SDimitry Andric OS, cast<ExternalSymbolPseudoSourceValue>(PVal)->getSymbol());
11630b57cec5SDimitry Andric break;
1164480093f4SDimitry Andric default: {
1165480093f4SDimitry Andric const MIRFormatter *Formatter = TII->getMIRFormatter();
11660b57cec5SDimitry Andric // FIXME: This is not necessarily the correct MIR serialization format for
11670b57cec5SDimitry Andric // a custom pseudo source value, but at least it allows
1168af732203SDimitry Andric // MIR printing to work on a target with custom pseudo source
11690b57cec5SDimitry Andric // values.
1170480093f4SDimitry Andric OS << "custom \"";
1171480093f4SDimitry Andric Formatter->printCustomPseudoSourceValue(OS, MST, *PVal);
1172480093f4SDimitry Andric OS << '\"';
11730b57cec5SDimitry Andric break;
11740b57cec5SDimitry Andric }
11750b57cec5SDimitry Andric }
1176*5f7ddb14SDimitry Andric } else if (getOpaqueValue() == nullptr && getOffset() != 0) {
1177*5f7ddb14SDimitry Andric OS << ((isLoad() && isStore()) ? " on "
1178*5f7ddb14SDimitry Andric : isLoad() ? " from "
1179*5f7ddb14SDimitry Andric : " into ")
1180*5f7ddb14SDimitry Andric << "unknown-address";
1181480093f4SDimitry Andric }
11820b57cec5SDimitry Andric MachineOperand::printOperandOffset(OS, getOffset());
1183*5f7ddb14SDimitry Andric if (getSize() > 0 && getAlign() != getSize())
1184af732203SDimitry Andric OS << ", align " << getAlign().value();
1185af732203SDimitry Andric if (getAlign() != getBaseAlign())
1186af732203SDimitry Andric OS << ", basealign " << getBaseAlign().value();
11870b57cec5SDimitry Andric auto AAInfo = getAAInfo();
11880b57cec5SDimitry Andric if (AAInfo.TBAA) {
11890b57cec5SDimitry Andric OS << ", !tbaa ";
11900b57cec5SDimitry Andric AAInfo.TBAA->printAsOperand(OS, MST);
11910b57cec5SDimitry Andric }
11920b57cec5SDimitry Andric if (AAInfo.Scope) {
11930b57cec5SDimitry Andric OS << ", !alias.scope ";
11940b57cec5SDimitry Andric AAInfo.Scope->printAsOperand(OS, MST);
11950b57cec5SDimitry Andric }
11960b57cec5SDimitry Andric if (AAInfo.NoAlias) {
11970b57cec5SDimitry Andric OS << ", !noalias ";
11980b57cec5SDimitry Andric AAInfo.NoAlias->printAsOperand(OS, MST);
11990b57cec5SDimitry Andric }
12000b57cec5SDimitry Andric if (getRanges()) {
12010b57cec5SDimitry Andric OS << ", !range ";
12020b57cec5SDimitry Andric getRanges()->printAsOperand(OS, MST);
12030b57cec5SDimitry Andric }
12040b57cec5SDimitry Andric // FIXME: Implement addrspace printing/parsing in MIR.
12050b57cec5SDimitry Andric // For now, print this even though parsing it is not available in MIR.
12060b57cec5SDimitry Andric if (unsigned AS = getAddrSpace())
12070b57cec5SDimitry Andric OS << ", addrspace " << AS;
12080b57cec5SDimitry Andric
12090b57cec5SDimitry Andric OS << ')';
12100b57cec5SDimitry Andric }
1211