1*0b57cec5SDimitry Andric //===- lib/CodeGen/MachineOperand.cpp -------------------------------------===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric //
9*0b57cec5SDimitry Andric /// \file Methods common to all machine operands.
10*0b57cec5SDimitry Andric //
11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
12*0b57cec5SDimitry Andric 
13*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
145ffd83dbSDimitry Andric #include "llvm/ADT/FoldingSet.h"
15*0b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h"
16*0b57cec5SDimitry Andric #include "llvm/Analysis/Loads.h"
17*0b57cec5SDimitry Andric #include "llvm/Analysis/MemoryLocation.h"
18480093f4SDimitry Andric #include "llvm/CodeGen/MIRFormatter.h"
19*0b57cec5SDimitry Andric #include "llvm/CodeGen/MIRPrinter.h"
20*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
21*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineJumpTableInfo.h"
22*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
23*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
24*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
25*0b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h"
26*0b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
27*0b57cec5SDimitry Andric #include "llvm/IR/IRPrintingPasses.h"
285ffd83dbSDimitry Andric #include "llvm/IR/Instructions.h"
29*0b57cec5SDimitry Andric #include "llvm/IR/ModuleSlotTracker.h"
30*0b57cec5SDimitry Andric #include "llvm/MC/MCDwarf.h"
31*0b57cec5SDimitry Andric #include "llvm/Target/TargetIntrinsicInfo.h"
32*0b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h"
33*0b57cec5SDimitry Andric 
34*0b57cec5SDimitry Andric using namespace llvm;
35*0b57cec5SDimitry Andric 
36*0b57cec5SDimitry Andric static cl::opt<int>
37*0b57cec5SDimitry Andric     PrintRegMaskNumRegs("print-regmask-num-regs",
38*0b57cec5SDimitry Andric                         cl::desc("Number of registers to limit to when "
39*0b57cec5SDimitry Andric                                  "printing regmask operands in IR dumps. "
40*0b57cec5SDimitry Andric                                  "unlimited = -1"),
41*0b57cec5SDimitry Andric                         cl::init(32), cl::Hidden);
42*0b57cec5SDimitry Andric 
43*0b57cec5SDimitry Andric static const MachineFunction *getMFIfAvailable(const MachineOperand &MO) {
44*0b57cec5SDimitry Andric   if (const MachineInstr *MI = MO.getParent())
45*0b57cec5SDimitry Andric     if (const MachineBasicBlock *MBB = MI->getParent())
46*0b57cec5SDimitry Andric       if (const MachineFunction *MF = MBB->getParent())
47*0b57cec5SDimitry Andric         return MF;
48*0b57cec5SDimitry Andric   return nullptr;
49*0b57cec5SDimitry Andric }
50*0b57cec5SDimitry Andric static MachineFunction *getMFIfAvailable(MachineOperand &MO) {
51*0b57cec5SDimitry Andric   return const_cast<MachineFunction *>(
52*0b57cec5SDimitry Andric       getMFIfAvailable(const_cast<const MachineOperand &>(MO)));
53*0b57cec5SDimitry Andric }
54*0b57cec5SDimitry Andric 
558bcb0991SDimitry Andric void MachineOperand::setReg(Register Reg) {
56*0b57cec5SDimitry Andric   if (getReg() == Reg)
57*0b57cec5SDimitry Andric     return; // No change.
58*0b57cec5SDimitry Andric 
59*0b57cec5SDimitry Andric   // Clear the IsRenamable bit to keep it conservatively correct.
60*0b57cec5SDimitry Andric   IsRenamable = false;
61*0b57cec5SDimitry Andric 
62*0b57cec5SDimitry Andric   // Otherwise, we have to change the register.  If this operand is embedded
63*0b57cec5SDimitry Andric   // into a machine function, we need to update the old and new register's
64*0b57cec5SDimitry Andric   // use/def lists.
65*0b57cec5SDimitry Andric   if (MachineFunction *MF = getMFIfAvailable(*this)) {
66*0b57cec5SDimitry Andric     MachineRegisterInfo &MRI = MF->getRegInfo();
67*0b57cec5SDimitry Andric     MRI.removeRegOperandFromUseList(this);
68*0b57cec5SDimitry Andric     SmallContents.RegNo = Reg;
69*0b57cec5SDimitry Andric     MRI.addRegOperandToUseList(this);
70*0b57cec5SDimitry Andric     return;
71*0b57cec5SDimitry Andric   }
72*0b57cec5SDimitry Andric 
73*0b57cec5SDimitry Andric   // Otherwise, just change the register, no problem.  :)
74*0b57cec5SDimitry Andric   SmallContents.RegNo = Reg;
75*0b57cec5SDimitry Andric }
76*0b57cec5SDimitry Andric 
778bcb0991SDimitry Andric void MachineOperand::substVirtReg(Register Reg, unsigned SubIdx,
78*0b57cec5SDimitry Andric                                   const TargetRegisterInfo &TRI) {
798bcb0991SDimitry Andric   assert(Reg.isVirtual());
80*0b57cec5SDimitry Andric   if (SubIdx && getSubReg())
81*0b57cec5SDimitry Andric     SubIdx = TRI.composeSubRegIndices(SubIdx, getSubReg());
82*0b57cec5SDimitry Andric   setReg(Reg);
83*0b57cec5SDimitry Andric   if (SubIdx)
84*0b57cec5SDimitry Andric     setSubReg(SubIdx);
85*0b57cec5SDimitry Andric }
86*0b57cec5SDimitry Andric 
878bcb0991SDimitry Andric void MachineOperand::substPhysReg(MCRegister Reg, const TargetRegisterInfo &TRI) {
88e8d8bef9SDimitry Andric   assert(Register::isPhysicalRegister(Reg));
89*0b57cec5SDimitry Andric   if (getSubReg()) {
90*0b57cec5SDimitry Andric     Reg = TRI.getSubReg(Reg, getSubReg());
91*0b57cec5SDimitry Andric     // Note that getSubReg() may return 0 if the sub-register doesn't exist.
92*0b57cec5SDimitry Andric     // That won't happen in legal code.
93*0b57cec5SDimitry Andric     setSubReg(0);
94*0b57cec5SDimitry Andric     if (isDef())
95*0b57cec5SDimitry Andric       setIsUndef(false);
96*0b57cec5SDimitry Andric   }
97*0b57cec5SDimitry Andric   setReg(Reg);
98*0b57cec5SDimitry Andric }
99*0b57cec5SDimitry Andric 
100*0b57cec5SDimitry Andric /// Change a def to a use, or a use to a def.
101*0b57cec5SDimitry Andric void MachineOperand::setIsDef(bool Val) {
102*0b57cec5SDimitry Andric   assert(isReg() && "Wrong MachineOperand accessor");
103*0b57cec5SDimitry Andric   assert((!Val || !isDebug()) && "Marking a debug operation as def");
104*0b57cec5SDimitry Andric   if (IsDef == Val)
105*0b57cec5SDimitry Andric     return;
106*0b57cec5SDimitry Andric   assert(!IsDeadOrKill && "Changing def/use with dead/kill set not supported");
107*0b57cec5SDimitry Andric   // MRI may keep uses and defs in different list positions.
108*0b57cec5SDimitry Andric   if (MachineFunction *MF = getMFIfAvailable(*this)) {
109*0b57cec5SDimitry Andric     MachineRegisterInfo &MRI = MF->getRegInfo();
110*0b57cec5SDimitry Andric     MRI.removeRegOperandFromUseList(this);
111*0b57cec5SDimitry Andric     IsDef = Val;
112*0b57cec5SDimitry Andric     MRI.addRegOperandToUseList(this);
113*0b57cec5SDimitry Andric     return;
114*0b57cec5SDimitry Andric   }
115*0b57cec5SDimitry Andric   IsDef = Val;
116*0b57cec5SDimitry Andric }
117*0b57cec5SDimitry Andric 
118*0b57cec5SDimitry Andric bool MachineOperand::isRenamable() const {
119*0b57cec5SDimitry Andric   assert(isReg() && "Wrong MachineOperand accessor");
1208bcb0991SDimitry Andric   assert(Register::isPhysicalRegister(getReg()) &&
121*0b57cec5SDimitry Andric          "isRenamable should only be checked on physical registers");
122*0b57cec5SDimitry Andric   if (!IsRenamable)
123*0b57cec5SDimitry Andric     return false;
124*0b57cec5SDimitry Andric 
125*0b57cec5SDimitry Andric   const MachineInstr *MI = getParent();
126*0b57cec5SDimitry Andric   if (!MI)
127*0b57cec5SDimitry Andric     return true;
128*0b57cec5SDimitry Andric 
129*0b57cec5SDimitry Andric   if (isDef())
130*0b57cec5SDimitry Andric     return !MI->hasExtraDefRegAllocReq(MachineInstr::IgnoreBundle);
131*0b57cec5SDimitry Andric 
132*0b57cec5SDimitry Andric   assert(isUse() && "Reg is not def or use");
133*0b57cec5SDimitry Andric   return !MI->hasExtraSrcRegAllocReq(MachineInstr::IgnoreBundle);
134*0b57cec5SDimitry Andric }
135*0b57cec5SDimitry Andric 
136*0b57cec5SDimitry Andric void MachineOperand::setIsRenamable(bool Val) {
137*0b57cec5SDimitry Andric   assert(isReg() && "Wrong MachineOperand accessor");
1388bcb0991SDimitry Andric   assert(Register::isPhysicalRegister(getReg()) &&
139*0b57cec5SDimitry Andric          "setIsRenamable should only be called on physical registers");
140*0b57cec5SDimitry Andric   IsRenamable = Val;
141*0b57cec5SDimitry Andric }
142*0b57cec5SDimitry Andric 
143*0b57cec5SDimitry Andric // If this operand is currently a register operand, and if this is in a
144*0b57cec5SDimitry Andric // function, deregister the operand from the register's use/def list.
145*0b57cec5SDimitry Andric void MachineOperand::removeRegFromUses() {
146*0b57cec5SDimitry Andric   if (!isReg() || !isOnRegUseList())
147*0b57cec5SDimitry Andric     return;
148*0b57cec5SDimitry Andric 
149*0b57cec5SDimitry Andric   if (MachineFunction *MF = getMFIfAvailable(*this))
150*0b57cec5SDimitry Andric     MF->getRegInfo().removeRegOperandFromUseList(this);
151*0b57cec5SDimitry Andric }
152*0b57cec5SDimitry Andric 
153*0b57cec5SDimitry Andric /// ChangeToImmediate - Replace this operand with a new immediate operand of
154*0b57cec5SDimitry Andric /// the specified value.  If an operand is known to be an immediate already,
155*0b57cec5SDimitry Andric /// the setImm method should be used.
156e8d8bef9SDimitry Andric void MachineOperand::ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags) {
157*0b57cec5SDimitry Andric   assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm");
158*0b57cec5SDimitry Andric 
159*0b57cec5SDimitry Andric   removeRegFromUses();
160*0b57cec5SDimitry Andric 
161*0b57cec5SDimitry Andric   OpKind = MO_Immediate;
162*0b57cec5SDimitry Andric   Contents.ImmVal = ImmVal;
163e8d8bef9SDimitry Andric   setTargetFlags(TargetFlags);
164*0b57cec5SDimitry Andric }
165*0b57cec5SDimitry Andric 
166e8d8bef9SDimitry Andric void MachineOperand::ChangeToFPImmediate(const ConstantFP *FPImm,
167e8d8bef9SDimitry Andric                                          unsigned TargetFlags) {
168*0b57cec5SDimitry Andric   assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm");
169*0b57cec5SDimitry Andric 
170*0b57cec5SDimitry Andric   removeRegFromUses();
171*0b57cec5SDimitry Andric 
172*0b57cec5SDimitry Andric   OpKind = MO_FPImmediate;
173*0b57cec5SDimitry Andric   Contents.CFP = FPImm;
174e8d8bef9SDimitry Andric   setTargetFlags(TargetFlags);
175*0b57cec5SDimitry Andric }
176*0b57cec5SDimitry Andric 
177*0b57cec5SDimitry Andric void MachineOperand::ChangeToES(const char *SymName,
1788bcb0991SDimitry Andric                                 unsigned TargetFlags) {
179*0b57cec5SDimitry Andric   assert((!isReg() || !isTied()) &&
180*0b57cec5SDimitry Andric          "Cannot change a tied operand into an external symbol");
181*0b57cec5SDimitry Andric 
182*0b57cec5SDimitry Andric   removeRegFromUses();
183*0b57cec5SDimitry Andric 
184*0b57cec5SDimitry Andric   OpKind = MO_ExternalSymbol;
185*0b57cec5SDimitry Andric   Contents.OffsetedInfo.Val.SymbolName = SymName;
186*0b57cec5SDimitry Andric   setOffset(0); // Offset is always 0.
187*0b57cec5SDimitry Andric   setTargetFlags(TargetFlags);
188*0b57cec5SDimitry Andric }
189*0b57cec5SDimitry Andric 
190*0b57cec5SDimitry Andric void MachineOperand::ChangeToGA(const GlobalValue *GV, int64_t Offset,
1918bcb0991SDimitry Andric                                 unsigned TargetFlags) {
192*0b57cec5SDimitry Andric   assert((!isReg() || !isTied()) &&
193*0b57cec5SDimitry Andric          "Cannot change a tied operand into a global address");
194*0b57cec5SDimitry Andric 
195*0b57cec5SDimitry Andric   removeRegFromUses();
196*0b57cec5SDimitry Andric 
197*0b57cec5SDimitry Andric   OpKind = MO_GlobalAddress;
198*0b57cec5SDimitry Andric   Contents.OffsetedInfo.Val.GV = GV;
199*0b57cec5SDimitry Andric   setOffset(Offset);
200*0b57cec5SDimitry Andric   setTargetFlags(TargetFlags);
201*0b57cec5SDimitry Andric }
202*0b57cec5SDimitry Andric 
203e8d8bef9SDimitry Andric void MachineOperand::ChangeToMCSymbol(MCSymbol *Sym, unsigned TargetFlags) {
204*0b57cec5SDimitry Andric   assert((!isReg() || !isTied()) &&
205*0b57cec5SDimitry Andric          "Cannot change a tied operand into an MCSymbol");
206*0b57cec5SDimitry Andric 
207*0b57cec5SDimitry Andric   removeRegFromUses();
208*0b57cec5SDimitry Andric 
209*0b57cec5SDimitry Andric   OpKind = MO_MCSymbol;
210*0b57cec5SDimitry Andric   Contents.Sym = Sym;
211e8d8bef9SDimitry Andric   setTargetFlags(TargetFlags);
212*0b57cec5SDimitry Andric }
213*0b57cec5SDimitry Andric 
214e8d8bef9SDimitry Andric void MachineOperand::ChangeToFrameIndex(int Idx, unsigned TargetFlags) {
215*0b57cec5SDimitry Andric   assert((!isReg() || !isTied()) &&
216*0b57cec5SDimitry Andric          "Cannot change a tied operand into a FrameIndex");
217*0b57cec5SDimitry Andric 
218*0b57cec5SDimitry Andric   removeRegFromUses();
219*0b57cec5SDimitry Andric 
220*0b57cec5SDimitry Andric   OpKind = MO_FrameIndex;
221*0b57cec5SDimitry Andric   setIndex(Idx);
222e8d8bef9SDimitry Andric   setTargetFlags(TargetFlags);
223*0b57cec5SDimitry Andric }
224*0b57cec5SDimitry Andric 
225*0b57cec5SDimitry Andric void MachineOperand::ChangeToTargetIndex(unsigned Idx, int64_t Offset,
2268bcb0991SDimitry Andric                                          unsigned TargetFlags) {
227*0b57cec5SDimitry Andric   assert((!isReg() || !isTied()) &&
228*0b57cec5SDimitry Andric          "Cannot change a tied operand into a FrameIndex");
229*0b57cec5SDimitry Andric 
230*0b57cec5SDimitry Andric   removeRegFromUses();
231*0b57cec5SDimitry Andric 
232*0b57cec5SDimitry Andric   OpKind = MO_TargetIndex;
233*0b57cec5SDimitry Andric   setIndex(Idx);
234*0b57cec5SDimitry Andric   setOffset(Offset);
235*0b57cec5SDimitry Andric   setTargetFlags(TargetFlags);
236*0b57cec5SDimitry Andric }
237*0b57cec5SDimitry Andric 
238*0b57cec5SDimitry Andric /// ChangeToRegister - Replace this operand with a new register operand of
239*0b57cec5SDimitry Andric /// the specified value.  If an operand is known to be an register already,
240*0b57cec5SDimitry Andric /// the setReg method should be used.
2418bcb0991SDimitry Andric void MachineOperand::ChangeToRegister(Register Reg, bool isDef, bool isImp,
242*0b57cec5SDimitry Andric                                       bool isKill, bool isDead, bool isUndef,
243*0b57cec5SDimitry Andric                                       bool isDebug) {
244*0b57cec5SDimitry Andric   MachineRegisterInfo *RegInfo = nullptr;
245*0b57cec5SDimitry Andric   if (MachineFunction *MF = getMFIfAvailable(*this))
246*0b57cec5SDimitry Andric     RegInfo = &MF->getRegInfo();
247*0b57cec5SDimitry Andric   // If this operand is already a register operand, remove it from the
248*0b57cec5SDimitry Andric   // register's use/def lists.
249*0b57cec5SDimitry Andric   bool WasReg = isReg();
250*0b57cec5SDimitry Andric   if (RegInfo && WasReg)
251*0b57cec5SDimitry Andric     RegInfo->removeRegOperandFromUseList(this);
252*0b57cec5SDimitry Andric 
253*0b57cec5SDimitry Andric   // Change this to a register and set the reg#.
254*0b57cec5SDimitry Andric   assert(!(isDead && !isDef) && "Dead flag on non-def");
255*0b57cec5SDimitry Andric   assert(!(isKill && isDef) && "Kill flag on def");
256*0b57cec5SDimitry Andric   OpKind = MO_Register;
257*0b57cec5SDimitry Andric   SmallContents.RegNo = Reg;
258*0b57cec5SDimitry Andric   SubReg_TargetFlags = 0;
259*0b57cec5SDimitry Andric   IsDef = isDef;
260*0b57cec5SDimitry Andric   IsImp = isImp;
261*0b57cec5SDimitry Andric   IsDeadOrKill = isKill | isDead;
262*0b57cec5SDimitry Andric   IsRenamable = false;
263*0b57cec5SDimitry Andric   IsUndef = isUndef;
264*0b57cec5SDimitry Andric   IsInternalRead = false;
265*0b57cec5SDimitry Andric   IsEarlyClobber = false;
266*0b57cec5SDimitry Andric   IsDebug = isDebug;
267*0b57cec5SDimitry Andric   // Ensure isOnRegUseList() returns false.
268*0b57cec5SDimitry Andric   Contents.Reg.Prev = nullptr;
269*0b57cec5SDimitry Andric   // Preserve the tie when the operand was already a register.
270*0b57cec5SDimitry Andric   if (!WasReg)
271*0b57cec5SDimitry Andric     TiedTo = 0;
272*0b57cec5SDimitry Andric 
273*0b57cec5SDimitry Andric   // If this operand is embedded in a function, add the operand to the
274*0b57cec5SDimitry Andric   // register's use/def list.
275*0b57cec5SDimitry Andric   if (RegInfo)
276*0b57cec5SDimitry Andric     RegInfo->addRegOperandToUseList(this);
277*0b57cec5SDimitry Andric }
278*0b57cec5SDimitry Andric 
279*0b57cec5SDimitry Andric /// isIdenticalTo - Return true if this operand is identical to the specified
280*0b57cec5SDimitry Andric /// operand. Note that this should stay in sync with the hash_value overload
281*0b57cec5SDimitry Andric /// below.
282*0b57cec5SDimitry Andric bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const {
283*0b57cec5SDimitry Andric   if (getType() != Other.getType() ||
284*0b57cec5SDimitry Andric       getTargetFlags() != Other.getTargetFlags())
285*0b57cec5SDimitry Andric     return false;
286*0b57cec5SDimitry Andric 
287*0b57cec5SDimitry Andric   switch (getType()) {
288*0b57cec5SDimitry Andric   case MachineOperand::MO_Register:
289*0b57cec5SDimitry Andric     return getReg() == Other.getReg() && isDef() == Other.isDef() &&
290*0b57cec5SDimitry Andric            getSubReg() == Other.getSubReg();
291*0b57cec5SDimitry Andric   case MachineOperand::MO_Immediate:
292*0b57cec5SDimitry Andric     return getImm() == Other.getImm();
293*0b57cec5SDimitry Andric   case MachineOperand::MO_CImmediate:
294*0b57cec5SDimitry Andric     return getCImm() == Other.getCImm();
295*0b57cec5SDimitry Andric   case MachineOperand::MO_FPImmediate:
296*0b57cec5SDimitry Andric     return getFPImm() == Other.getFPImm();
297*0b57cec5SDimitry Andric   case MachineOperand::MO_MachineBasicBlock:
298*0b57cec5SDimitry Andric     return getMBB() == Other.getMBB();
299*0b57cec5SDimitry Andric   case MachineOperand::MO_FrameIndex:
300*0b57cec5SDimitry Andric     return getIndex() == Other.getIndex();
301*0b57cec5SDimitry Andric   case MachineOperand::MO_ConstantPoolIndex:
302*0b57cec5SDimitry Andric   case MachineOperand::MO_TargetIndex:
303*0b57cec5SDimitry Andric     return getIndex() == Other.getIndex() && getOffset() == Other.getOffset();
304*0b57cec5SDimitry Andric   case MachineOperand::MO_JumpTableIndex:
305*0b57cec5SDimitry Andric     return getIndex() == Other.getIndex();
306*0b57cec5SDimitry Andric   case MachineOperand::MO_GlobalAddress:
307*0b57cec5SDimitry Andric     return getGlobal() == Other.getGlobal() && getOffset() == Other.getOffset();
308*0b57cec5SDimitry Andric   case MachineOperand::MO_ExternalSymbol:
309*0b57cec5SDimitry Andric     return strcmp(getSymbolName(), Other.getSymbolName()) == 0 &&
310*0b57cec5SDimitry Andric            getOffset() == Other.getOffset();
311*0b57cec5SDimitry Andric   case MachineOperand::MO_BlockAddress:
312*0b57cec5SDimitry Andric     return getBlockAddress() == Other.getBlockAddress() &&
313*0b57cec5SDimitry Andric            getOffset() == Other.getOffset();
314*0b57cec5SDimitry Andric   case MachineOperand::MO_RegisterMask:
315*0b57cec5SDimitry Andric   case MachineOperand::MO_RegisterLiveOut: {
316*0b57cec5SDimitry Andric     // Shallow compare of the two RegMasks
317*0b57cec5SDimitry Andric     const uint32_t *RegMask = getRegMask();
318*0b57cec5SDimitry Andric     const uint32_t *OtherRegMask = Other.getRegMask();
319*0b57cec5SDimitry Andric     if (RegMask == OtherRegMask)
320*0b57cec5SDimitry Andric       return true;
321*0b57cec5SDimitry Andric 
322*0b57cec5SDimitry Andric     if (const MachineFunction *MF = getMFIfAvailable(*this)) {
323*0b57cec5SDimitry Andric       // Calculate the size of the RegMask
324*0b57cec5SDimitry Andric       const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
325*0b57cec5SDimitry Andric       unsigned RegMaskSize = (TRI->getNumRegs() + 31) / 32;
326*0b57cec5SDimitry Andric 
327*0b57cec5SDimitry Andric       // Deep compare of the two RegMasks
328*0b57cec5SDimitry Andric       return std::equal(RegMask, RegMask + RegMaskSize, OtherRegMask);
329*0b57cec5SDimitry Andric     }
330*0b57cec5SDimitry Andric     // We don't know the size of the RegMask, so we can't deep compare the two
331*0b57cec5SDimitry Andric     // reg masks.
332*0b57cec5SDimitry Andric     return false;
333*0b57cec5SDimitry Andric   }
334*0b57cec5SDimitry Andric   case MachineOperand::MO_MCSymbol:
335*0b57cec5SDimitry Andric     return getMCSymbol() == Other.getMCSymbol();
336*0b57cec5SDimitry Andric   case MachineOperand::MO_CFIIndex:
337*0b57cec5SDimitry Andric     return getCFIIndex() == Other.getCFIIndex();
338*0b57cec5SDimitry Andric   case MachineOperand::MO_Metadata:
339*0b57cec5SDimitry Andric     return getMetadata() == Other.getMetadata();
340*0b57cec5SDimitry Andric   case MachineOperand::MO_IntrinsicID:
341*0b57cec5SDimitry Andric     return getIntrinsicID() == Other.getIntrinsicID();
342*0b57cec5SDimitry Andric   case MachineOperand::MO_Predicate:
343*0b57cec5SDimitry Andric     return getPredicate() == Other.getPredicate();
3448bcb0991SDimitry Andric   case MachineOperand::MO_ShuffleMask:
3458bcb0991SDimitry Andric     return getShuffleMask() == Other.getShuffleMask();
346*0b57cec5SDimitry Andric   }
347*0b57cec5SDimitry Andric   llvm_unreachable("Invalid machine operand type");
348*0b57cec5SDimitry Andric }
349*0b57cec5SDimitry Andric 
350*0b57cec5SDimitry Andric // Note: this must stay exactly in sync with isIdenticalTo above.
351*0b57cec5SDimitry Andric hash_code llvm::hash_value(const MachineOperand &MO) {
352*0b57cec5SDimitry Andric   switch (MO.getType()) {
353*0b57cec5SDimitry Andric   case MachineOperand::MO_Register:
354*0b57cec5SDimitry Andric     // Register operands don't have target flags.
355*0b57cec5SDimitry Andric     return hash_combine(MO.getType(), (unsigned)MO.getReg(), MO.getSubReg(), MO.isDef());
356*0b57cec5SDimitry Andric   case MachineOperand::MO_Immediate:
357*0b57cec5SDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getImm());
358*0b57cec5SDimitry Andric   case MachineOperand::MO_CImmediate:
359*0b57cec5SDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCImm());
360*0b57cec5SDimitry Andric   case MachineOperand::MO_FPImmediate:
361*0b57cec5SDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getFPImm());
362*0b57cec5SDimitry Andric   case MachineOperand::MO_MachineBasicBlock:
363*0b57cec5SDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMBB());
364*0b57cec5SDimitry Andric   case MachineOperand::MO_FrameIndex:
365*0b57cec5SDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex());
366*0b57cec5SDimitry Andric   case MachineOperand::MO_ConstantPoolIndex:
367*0b57cec5SDimitry Andric   case MachineOperand::MO_TargetIndex:
368*0b57cec5SDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex(),
369*0b57cec5SDimitry Andric                         MO.getOffset());
370*0b57cec5SDimitry Andric   case MachineOperand::MO_JumpTableIndex:
371*0b57cec5SDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex());
372*0b57cec5SDimitry Andric   case MachineOperand::MO_ExternalSymbol:
373*0b57cec5SDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getOffset(),
374*0b57cec5SDimitry Andric                         StringRef(MO.getSymbolName()));
375*0b57cec5SDimitry Andric   case MachineOperand::MO_GlobalAddress:
376*0b57cec5SDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getGlobal(),
377*0b57cec5SDimitry Andric                         MO.getOffset());
378*0b57cec5SDimitry Andric   case MachineOperand::MO_BlockAddress:
379*0b57cec5SDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getBlockAddress(),
380*0b57cec5SDimitry Andric                         MO.getOffset());
381*0b57cec5SDimitry Andric   case MachineOperand::MO_RegisterMask:
382*0b57cec5SDimitry Andric   case MachineOperand::MO_RegisterLiveOut:
383*0b57cec5SDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getRegMask());
384*0b57cec5SDimitry Andric   case MachineOperand::MO_Metadata:
385*0b57cec5SDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMetadata());
386*0b57cec5SDimitry Andric   case MachineOperand::MO_MCSymbol:
387*0b57cec5SDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMCSymbol());
388*0b57cec5SDimitry Andric   case MachineOperand::MO_CFIIndex:
389*0b57cec5SDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCFIIndex());
390*0b57cec5SDimitry Andric   case MachineOperand::MO_IntrinsicID:
391*0b57cec5SDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIntrinsicID());
392*0b57cec5SDimitry Andric   case MachineOperand::MO_Predicate:
393*0b57cec5SDimitry 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());
396*0b57cec5SDimitry Andric   }
397*0b57cec5SDimitry Andric   llvm_unreachable("Invalid machine operand type");
398*0b57cec5SDimitry Andric }
399*0b57cec5SDimitry Andric 
400*0b57cec5SDimitry Andric // Try to crawl up to the machine function and get TRI and IntrinsicInfo from
401*0b57cec5SDimitry Andric // it.
402*0b57cec5SDimitry Andric static void tryToGetTargetInfo(const MachineOperand &MO,
403*0b57cec5SDimitry Andric                                const TargetRegisterInfo *&TRI,
404*0b57cec5SDimitry Andric                                const TargetIntrinsicInfo *&IntrinsicInfo) {
405*0b57cec5SDimitry Andric   if (const MachineFunction *MF = getMFIfAvailable(MO)) {
406*0b57cec5SDimitry Andric     TRI = MF->getSubtarget().getRegisterInfo();
407*0b57cec5SDimitry Andric     IntrinsicInfo = MF->getTarget().getIntrinsicInfo();
408*0b57cec5SDimitry Andric   }
409*0b57cec5SDimitry Andric }
410*0b57cec5SDimitry Andric 
411*0b57cec5SDimitry Andric static const char *getTargetIndexName(const MachineFunction &MF, int Index) {
412*0b57cec5SDimitry Andric   const auto *TII = MF.getSubtarget().getInstrInfo();
413*0b57cec5SDimitry Andric   assert(TII && "expected instruction info");
414*0b57cec5SDimitry Andric   auto Indices = TII->getSerializableTargetIndices();
415*0b57cec5SDimitry Andric   auto Found = find_if(Indices, [&](const std::pair<int, const char *> &I) {
416*0b57cec5SDimitry Andric     return I.first == Index;
417*0b57cec5SDimitry Andric   });
418*0b57cec5SDimitry Andric   if (Found != Indices.end())
419*0b57cec5SDimitry Andric     return Found->second;
420*0b57cec5SDimitry Andric   return nullptr;
421*0b57cec5SDimitry Andric }
422*0b57cec5SDimitry Andric 
423e8d8bef9SDimitry Andric const char *MachineOperand::getTargetIndexName() const {
424e8d8bef9SDimitry Andric   const MachineFunction *MF = getMFIfAvailable(*this);
425e8d8bef9SDimitry Andric   return MF ? ::getTargetIndexName(*MF, this->getIndex()) : nullptr;
426e8d8bef9SDimitry Andric }
427e8d8bef9SDimitry Andric 
428*0b57cec5SDimitry Andric static const char *getTargetFlagName(const TargetInstrInfo *TII, unsigned TF) {
429*0b57cec5SDimitry Andric   auto Flags = TII->getSerializableDirectMachineOperandTargetFlags();
430*0b57cec5SDimitry Andric   for (const auto &I : Flags) {
431*0b57cec5SDimitry Andric     if (I.first == TF) {
432*0b57cec5SDimitry Andric       return I.second;
433*0b57cec5SDimitry Andric     }
434*0b57cec5SDimitry Andric   }
435*0b57cec5SDimitry Andric   return nullptr;
436*0b57cec5SDimitry Andric }
437*0b57cec5SDimitry Andric 
438*0b57cec5SDimitry Andric static void printCFIRegister(unsigned DwarfReg, raw_ostream &OS,
439*0b57cec5SDimitry Andric                              const TargetRegisterInfo *TRI) {
440*0b57cec5SDimitry Andric   if (!TRI) {
441*0b57cec5SDimitry Andric     OS << "%dwarfreg." << DwarfReg;
442*0b57cec5SDimitry Andric     return;
443*0b57cec5SDimitry Andric   }
444*0b57cec5SDimitry Andric 
4458bcb0991SDimitry Andric   if (Optional<unsigned> Reg = TRI->getLLVMRegNum(DwarfReg, true))
4468bcb0991SDimitry Andric     OS << printReg(*Reg, TRI);
4478bcb0991SDimitry Andric   else
448*0b57cec5SDimitry Andric     OS << "<badreg>";
449*0b57cec5SDimitry Andric }
450*0b57cec5SDimitry Andric 
451*0b57cec5SDimitry Andric static void printIRBlockReference(raw_ostream &OS, const BasicBlock &BB,
452*0b57cec5SDimitry Andric                                   ModuleSlotTracker &MST) {
453*0b57cec5SDimitry Andric   OS << "%ir-block.";
454*0b57cec5SDimitry Andric   if (BB.hasName()) {
455*0b57cec5SDimitry Andric     printLLVMNameWithoutPrefix(OS, BB.getName());
456*0b57cec5SDimitry Andric     return;
457*0b57cec5SDimitry Andric   }
458*0b57cec5SDimitry Andric   Optional<int> Slot;
459*0b57cec5SDimitry Andric   if (const Function *F = BB.getParent()) {
460*0b57cec5SDimitry Andric     if (F == MST.getCurrentFunction()) {
461*0b57cec5SDimitry Andric       Slot = MST.getLocalSlot(&BB);
462*0b57cec5SDimitry Andric     } else if (const Module *M = F->getParent()) {
463*0b57cec5SDimitry Andric       ModuleSlotTracker CustomMST(M, /*ShouldInitializeAllMetadata=*/false);
464*0b57cec5SDimitry Andric       CustomMST.incorporateFunction(*F);
465*0b57cec5SDimitry Andric       Slot = CustomMST.getLocalSlot(&BB);
466*0b57cec5SDimitry Andric     }
467*0b57cec5SDimitry Andric   }
468*0b57cec5SDimitry Andric   if (Slot)
469*0b57cec5SDimitry Andric     MachineOperand::printIRSlotNumber(OS, *Slot);
470*0b57cec5SDimitry Andric   else
471*0b57cec5SDimitry Andric     OS << "<unknown>";
472*0b57cec5SDimitry Andric }
473*0b57cec5SDimitry Andric 
474*0b57cec5SDimitry Andric static void printSyncScope(raw_ostream &OS, const LLVMContext &Context,
475*0b57cec5SDimitry Andric                            SyncScope::ID SSID,
476*0b57cec5SDimitry Andric                            SmallVectorImpl<StringRef> &SSNs) {
477*0b57cec5SDimitry Andric   switch (SSID) {
478*0b57cec5SDimitry Andric   case SyncScope::System:
479*0b57cec5SDimitry Andric     break;
480*0b57cec5SDimitry Andric   default:
481*0b57cec5SDimitry Andric     if (SSNs.empty())
482*0b57cec5SDimitry Andric       Context.getSyncScopeNames(SSNs);
483*0b57cec5SDimitry Andric 
484*0b57cec5SDimitry Andric     OS << "syncscope(\"";
485*0b57cec5SDimitry Andric     printEscapedString(SSNs[SSID], OS);
486*0b57cec5SDimitry Andric     OS << "\") ";
487*0b57cec5SDimitry Andric     break;
488*0b57cec5SDimitry Andric   }
489*0b57cec5SDimitry Andric }
490*0b57cec5SDimitry Andric 
491*0b57cec5SDimitry Andric static const char *getTargetMMOFlagName(const TargetInstrInfo &TII,
492*0b57cec5SDimitry Andric                                         unsigned TMMOFlag) {
493*0b57cec5SDimitry Andric   auto Flags = TII.getSerializableMachineMemOperandTargetFlags();
494*0b57cec5SDimitry Andric   for (const auto &I : Flags) {
495*0b57cec5SDimitry Andric     if (I.first == TMMOFlag) {
496*0b57cec5SDimitry Andric       return I.second;
497*0b57cec5SDimitry Andric     }
498*0b57cec5SDimitry Andric   }
499*0b57cec5SDimitry Andric   return nullptr;
500*0b57cec5SDimitry Andric }
501*0b57cec5SDimitry Andric 
502*0b57cec5SDimitry Andric static void printFrameIndex(raw_ostream& OS, int FrameIndex, bool IsFixed,
503*0b57cec5SDimitry Andric                             const MachineFrameInfo *MFI) {
504*0b57cec5SDimitry Andric   StringRef Name;
505*0b57cec5SDimitry Andric   if (MFI) {
506*0b57cec5SDimitry Andric     IsFixed = MFI->isFixedObjectIndex(FrameIndex);
507*0b57cec5SDimitry Andric     if (const AllocaInst *Alloca = MFI->getObjectAllocation(FrameIndex))
508*0b57cec5SDimitry Andric       if (Alloca->hasName())
509*0b57cec5SDimitry Andric         Name = Alloca->getName();
510*0b57cec5SDimitry Andric     if (IsFixed)
511*0b57cec5SDimitry Andric       FrameIndex -= MFI->getObjectIndexBegin();
512*0b57cec5SDimitry Andric   }
513*0b57cec5SDimitry Andric   MachineOperand::printStackObjectReference(OS, FrameIndex, IsFixed, Name);
514*0b57cec5SDimitry Andric }
515*0b57cec5SDimitry Andric 
516*0b57cec5SDimitry Andric void MachineOperand::printSubRegIdx(raw_ostream &OS, uint64_t Index,
517*0b57cec5SDimitry Andric                                     const TargetRegisterInfo *TRI) {
518*0b57cec5SDimitry Andric   OS << "%subreg.";
519*0b57cec5SDimitry Andric   if (TRI)
520*0b57cec5SDimitry Andric     OS << TRI->getSubRegIndexName(Index);
521*0b57cec5SDimitry Andric   else
522*0b57cec5SDimitry Andric     OS << Index;
523*0b57cec5SDimitry Andric }
524*0b57cec5SDimitry Andric 
525*0b57cec5SDimitry Andric void MachineOperand::printTargetFlags(raw_ostream &OS,
526*0b57cec5SDimitry Andric                                       const MachineOperand &Op) {
527*0b57cec5SDimitry Andric   if (!Op.getTargetFlags())
528*0b57cec5SDimitry Andric     return;
529*0b57cec5SDimitry Andric   const MachineFunction *MF = getMFIfAvailable(Op);
530*0b57cec5SDimitry Andric   if (!MF)
531*0b57cec5SDimitry Andric     return;
532*0b57cec5SDimitry Andric 
533*0b57cec5SDimitry Andric   const auto *TII = MF->getSubtarget().getInstrInfo();
534*0b57cec5SDimitry Andric   assert(TII && "expected instruction info");
535*0b57cec5SDimitry Andric   auto Flags = TII->decomposeMachineOperandsTargetFlags(Op.getTargetFlags());
536*0b57cec5SDimitry Andric   OS << "target-flags(";
537*0b57cec5SDimitry Andric   const bool HasDirectFlags = Flags.first;
538*0b57cec5SDimitry Andric   const bool HasBitmaskFlags = Flags.second;
539*0b57cec5SDimitry Andric   if (!HasDirectFlags && !HasBitmaskFlags) {
540*0b57cec5SDimitry Andric     OS << "<unknown>) ";
541*0b57cec5SDimitry Andric     return;
542*0b57cec5SDimitry Andric   }
543*0b57cec5SDimitry Andric   if (HasDirectFlags) {
544*0b57cec5SDimitry Andric     if (const auto *Name = getTargetFlagName(TII, Flags.first))
545*0b57cec5SDimitry Andric       OS << Name;
546*0b57cec5SDimitry Andric     else
547*0b57cec5SDimitry Andric       OS << "<unknown target flag>";
548*0b57cec5SDimitry Andric   }
549*0b57cec5SDimitry Andric   if (!HasBitmaskFlags) {
550*0b57cec5SDimitry Andric     OS << ") ";
551*0b57cec5SDimitry Andric     return;
552*0b57cec5SDimitry Andric   }
553*0b57cec5SDimitry Andric   bool IsCommaNeeded = HasDirectFlags;
554*0b57cec5SDimitry Andric   unsigned BitMask = Flags.second;
555*0b57cec5SDimitry Andric   auto BitMasks = TII->getSerializableBitmaskMachineOperandTargetFlags();
556*0b57cec5SDimitry Andric   for (const auto &Mask : BitMasks) {
557*0b57cec5SDimitry Andric     // Check if the flag's bitmask has the bits of the current mask set.
558*0b57cec5SDimitry Andric     if ((BitMask & Mask.first) == Mask.first) {
559*0b57cec5SDimitry Andric       if (IsCommaNeeded)
560*0b57cec5SDimitry Andric         OS << ", ";
561*0b57cec5SDimitry Andric       IsCommaNeeded = true;
562*0b57cec5SDimitry Andric       OS << Mask.second;
563*0b57cec5SDimitry Andric       // Clear the bits which were serialized from the flag's bitmask.
564*0b57cec5SDimitry Andric       BitMask &= ~(Mask.first);
565*0b57cec5SDimitry Andric     }
566*0b57cec5SDimitry Andric   }
567*0b57cec5SDimitry Andric   if (BitMask) {
568*0b57cec5SDimitry Andric     // When the resulting flag's bitmask isn't zero, we know that we didn't
569*0b57cec5SDimitry Andric     // serialize all of the bit flags.
570*0b57cec5SDimitry Andric     if (IsCommaNeeded)
571*0b57cec5SDimitry Andric       OS << ", ";
572*0b57cec5SDimitry Andric     OS << "<unknown bitmask target flag>";
573*0b57cec5SDimitry Andric   }
574*0b57cec5SDimitry Andric   OS << ") ";
575*0b57cec5SDimitry Andric }
576*0b57cec5SDimitry Andric 
577*0b57cec5SDimitry Andric void MachineOperand::printSymbol(raw_ostream &OS, MCSymbol &Sym) {
578*0b57cec5SDimitry Andric   OS << "<mcsymbol " << Sym << ">";
579*0b57cec5SDimitry Andric }
580*0b57cec5SDimitry Andric 
581*0b57cec5SDimitry Andric void MachineOperand::printStackObjectReference(raw_ostream &OS,
582*0b57cec5SDimitry Andric                                                unsigned FrameIndex,
583*0b57cec5SDimitry Andric                                                bool IsFixed, StringRef Name) {
584*0b57cec5SDimitry Andric   if (IsFixed) {
585*0b57cec5SDimitry Andric     OS << "%fixed-stack." << FrameIndex;
586*0b57cec5SDimitry Andric     return;
587*0b57cec5SDimitry Andric   }
588*0b57cec5SDimitry Andric 
589*0b57cec5SDimitry Andric   OS << "%stack." << FrameIndex;
590*0b57cec5SDimitry Andric   if (!Name.empty())
591*0b57cec5SDimitry Andric     OS << '.' << Name;
592*0b57cec5SDimitry Andric }
593*0b57cec5SDimitry Andric 
594*0b57cec5SDimitry Andric void MachineOperand::printOperandOffset(raw_ostream &OS, int64_t Offset) {
595*0b57cec5SDimitry Andric   if (Offset == 0)
596*0b57cec5SDimitry Andric     return;
597*0b57cec5SDimitry Andric   if (Offset < 0) {
598*0b57cec5SDimitry Andric     OS << " - " << -Offset;
599*0b57cec5SDimitry Andric     return;
600*0b57cec5SDimitry Andric   }
601*0b57cec5SDimitry Andric   OS << " + " << Offset;
602*0b57cec5SDimitry Andric }
603*0b57cec5SDimitry Andric 
604*0b57cec5SDimitry Andric void MachineOperand::printIRSlotNumber(raw_ostream &OS, int Slot) {
605*0b57cec5SDimitry Andric   if (Slot == -1)
606*0b57cec5SDimitry Andric     OS << "<badref>";
607*0b57cec5SDimitry Andric   else
608*0b57cec5SDimitry Andric     OS << Slot;
609*0b57cec5SDimitry Andric }
610*0b57cec5SDimitry Andric 
611*0b57cec5SDimitry Andric static void printCFI(raw_ostream &OS, const MCCFIInstruction &CFI,
612*0b57cec5SDimitry Andric                      const TargetRegisterInfo *TRI) {
613*0b57cec5SDimitry Andric   switch (CFI.getOperation()) {
614*0b57cec5SDimitry Andric   case MCCFIInstruction::OpSameValue:
615*0b57cec5SDimitry Andric     OS << "same_value ";
616*0b57cec5SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
617*0b57cec5SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
618*0b57cec5SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
619*0b57cec5SDimitry Andric     break;
620*0b57cec5SDimitry Andric   case MCCFIInstruction::OpRememberState:
621*0b57cec5SDimitry Andric     OS << "remember_state ";
622*0b57cec5SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
623*0b57cec5SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
624*0b57cec5SDimitry Andric     break;
625*0b57cec5SDimitry Andric   case MCCFIInstruction::OpRestoreState:
626*0b57cec5SDimitry Andric     OS << "restore_state ";
627*0b57cec5SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
628*0b57cec5SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
629*0b57cec5SDimitry Andric     break;
630*0b57cec5SDimitry Andric   case MCCFIInstruction::OpOffset:
631*0b57cec5SDimitry Andric     OS << "offset ";
632*0b57cec5SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
633*0b57cec5SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
634*0b57cec5SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
635*0b57cec5SDimitry Andric     OS << ", " << CFI.getOffset();
636*0b57cec5SDimitry Andric     break;
637*0b57cec5SDimitry Andric   case MCCFIInstruction::OpDefCfaRegister:
638*0b57cec5SDimitry Andric     OS << "def_cfa_register ";
639*0b57cec5SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
640*0b57cec5SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
641*0b57cec5SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
642*0b57cec5SDimitry Andric     break;
643*0b57cec5SDimitry Andric   case MCCFIInstruction::OpDefCfaOffset:
644*0b57cec5SDimitry Andric     OS << "def_cfa_offset ";
645*0b57cec5SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
646*0b57cec5SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
647*0b57cec5SDimitry Andric     OS << CFI.getOffset();
648*0b57cec5SDimitry Andric     break;
649*0b57cec5SDimitry Andric   case MCCFIInstruction::OpDefCfa:
650*0b57cec5SDimitry Andric     OS << "def_cfa ";
651*0b57cec5SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
652*0b57cec5SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
653*0b57cec5SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
654*0b57cec5SDimitry Andric     OS << ", " << CFI.getOffset();
655*0b57cec5SDimitry Andric     break;
656*0b57cec5SDimitry Andric   case MCCFIInstruction::OpRelOffset:
657*0b57cec5SDimitry Andric     OS << "rel_offset ";
658*0b57cec5SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
659*0b57cec5SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
660*0b57cec5SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
661*0b57cec5SDimitry Andric     OS << ", " << CFI.getOffset();
662*0b57cec5SDimitry Andric     break;
663*0b57cec5SDimitry Andric   case MCCFIInstruction::OpAdjustCfaOffset:
664*0b57cec5SDimitry Andric     OS << "adjust_cfa_offset ";
665*0b57cec5SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
666*0b57cec5SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
667*0b57cec5SDimitry Andric     OS << CFI.getOffset();
668*0b57cec5SDimitry Andric     break;
669*0b57cec5SDimitry Andric   case MCCFIInstruction::OpRestore:
670*0b57cec5SDimitry Andric     OS << "restore ";
671*0b57cec5SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
672*0b57cec5SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
673*0b57cec5SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
674*0b57cec5SDimitry Andric     break;
675*0b57cec5SDimitry Andric   case MCCFIInstruction::OpEscape: {
676*0b57cec5SDimitry Andric     OS << "escape ";
677*0b57cec5SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
678*0b57cec5SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
679*0b57cec5SDimitry Andric     if (!CFI.getValues().empty()) {
680*0b57cec5SDimitry Andric       size_t e = CFI.getValues().size() - 1;
681*0b57cec5SDimitry Andric       for (size_t i = 0; i < e; ++i)
682*0b57cec5SDimitry Andric         OS << format("0x%02x", uint8_t(CFI.getValues()[i])) << ", ";
6835ffd83dbSDimitry Andric       OS << format("0x%02x", uint8_t(CFI.getValues()[e]));
684*0b57cec5SDimitry Andric     }
685*0b57cec5SDimitry Andric     break;
686*0b57cec5SDimitry Andric   }
687*0b57cec5SDimitry Andric   case MCCFIInstruction::OpUndefined:
688*0b57cec5SDimitry Andric     OS << "undefined ";
689*0b57cec5SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
690*0b57cec5SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
691*0b57cec5SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
692*0b57cec5SDimitry Andric     break;
693*0b57cec5SDimitry Andric   case MCCFIInstruction::OpRegister:
694*0b57cec5SDimitry Andric     OS << "register ";
695*0b57cec5SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
696*0b57cec5SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
697*0b57cec5SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
698*0b57cec5SDimitry Andric     OS << ", ";
699*0b57cec5SDimitry Andric     printCFIRegister(CFI.getRegister2(), OS, TRI);
700*0b57cec5SDimitry Andric     break;
701*0b57cec5SDimitry Andric   case MCCFIInstruction::OpWindowSave:
702*0b57cec5SDimitry Andric     OS << "window_save ";
703*0b57cec5SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
704*0b57cec5SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
705*0b57cec5SDimitry Andric     break;
706*0b57cec5SDimitry Andric   case MCCFIInstruction::OpNegateRAState:
707*0b57cec5SDimitry Andric     OS << "negate_ra_sign_state ";
708*0b57cec5SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
709*0b57cec5SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
710*0b57cec5SDimitry Andric     break;
711*0b57cec5SDimitry Andric   default:
712*0b57cec5SDimitry Andric     // TODO: Print the other CFI Operations.
713*0b57cec5SDimitry Andric     OS << "<unserializable cfi directive>";
714*0b57cec5SDimitry Andric     break;
715*0b57cec5SDimitry Andric   }
716*0b57cec5SDimitry Andric }
717*0b57cec5SDimitry Andric 
718*0b57cec5SDimitry Andric void MachineOperand::print(raw_ostream &OS, const TargetRegisterInfo *TRI,
719*0b57cec5SDimitry Andric                            const TargetIntrinsicInfo *IntrinsicInfo) const {
720*0b57cec5SDimitry Andric   print(OS, LLT{}, TRI, IntrinsicInfo);
721*0b57cec5SDimitry Andric }
722*0b57cec5SDimitry Andric 
723*0b57cec5SDimitry Andric void MachineOperand::print(raw_ostream &OS, LLT TypeToPrint,
724*0b57cec5SDimitry Andric                            const TargetRegisterInfo *TRI,
725*0b57cec5SDimitry Andric                            const TargetIntrinsicInfo *IntrinsicInfo) const {
726*0b57cec5SDimitry Andric   tryToGetTargetInfo(*this, TRI, IntrinsicInfo);
727*0b57cec5SDimitry Andric   ModuleSlotTracker DummyMST(nullptr);
728480093f4SDimitry Andric   print(OS, DummyMST, TypeToPrint, None, /*PrintDef=*/false,
729480093f4SDimitry Andric         /*IsStandalone=*/true,
730*0b57cec5SDimitry Andric         /*ShouldPrintRegisterTies=*/true,
731*0b57cec5SDimitry Andric         /*TiedOperandIdx=*/0, TRI, IntrinsicInfo);
732*0b57cec5SDimitry Andric }
733*0b57cec5SDimitry Andric 
734*0b57cec5SDimitry Andric void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
735480093f4SDimitry Andric                            LLT TypeToPrint, Optional<unsigned> OpIdx, bool PrintDef,
736480093f4SDimitry Andric                            bool IsStandalone, bool ShouldPrintRegisterTies,
737*0b57cec5SDimitry Andric                            unsigned TiedOperandIdx,
738*0b57cec5SDimitry Andric                            const TargetRegisterInfo *TRI,
739*0b57cec5SDimitry Andric                            const TargetIntrinsicInfo *IntrinsicInfo) const {
740*0b57cec5SDimitry Andric   printTargetFlags(OS, *this);
741*0b57cec5SDimitry Andric   switch (getType()) {
742*0b57cec5SDimitry Andric   case MachineOperand::MO_Register: {
7438bcb0991SDimitry Andric     Register Reg = getReg();
744*0b57cec5SDimitry Andric     if (isImplicit())
745*0b57cec5SDimitry Andric       OS << (isDef() ? "implicit-def " : "implicit ");
746*0b57cec5SDimitry Andric     else if (PrintDef && isDef())
747*0b57cec5SDimitry Andric       // Print the 'def' flag only when the operand is defined after '='.
748*0b57cec5SDimitry Andric       OS << "def ";
749*0b57cec5SDimitry Andric     if (isInternalRead())
750*0b57cec5SDimitry Andric       OS << "internal ";
751*0b57cec5SDimitry Andric     if (isDead())
752*0b57cec5SDimitry Andric       OS << "dead ";
753*0b57cec5SDimitry Andric     if (isKill())
754*0b57cec5SDimitry Andric       OS << "killed ";
755*0b57cec5SDimitry Andric     if (isUndef())
756*0b57cec5SDimitry Andric       OS << "undef ";
757*0b57cec5SDimitry Andric     if (isEarlyClobber())
758*0b57cec5SDimitry Andric       OS << "early-clobber ";
7598bcb0991SDimitry Andric     if (Register::isPhysicalRegister(getReg()) && isRenamable())
760*0b57cec5SDimitry Andric       OS << "renamable ";
761*0b57cec5SDimitry Andric     // isDebug() is exactly true for register operands of a DBG_VALUE. So we
762*0b57cec5SDimitry Andric     // simply infer it when parsing and do not need to print it.
763*0b57cec5SDimitry Andric 
764*0b57cec5SDimitry Andric     const MachineRegisterInfo *MRI = nullptr;
7658bcb0991SDimitry Andric     if (Register::isVirtualRegister(Reg)) {
766*0b57cec5SDimitry Andric       if (const MachineFunction *MF = getMFIfAvailable(*this)) {
767*0b57cec5SDimitry Andric         MRI = &MF->getRegInfo();
768*0b57cec5SDimitry Andric       }
769*0b57cec5SDimitry Andric     }
770*0b57cec5SDimitry Andric 
771*0b57cec5SDimitry Andric     OS << printReg(Reg, TRI, 0, MRI);
772*0b57cec5SDimitry Andric     // Print the sub register.
773*0b57cec5SDimitry Andric     if (unsigned SubReg = getSubReg()) {
774*0b57cec5SDimitry Andric       if (TRI)
775*0b57cec5SDimitry Andric         OS << '.' << TRI->getSubRegIndexName(SubReg);
776*0b57cec5SDimitry Andric       else
777*0b57cec5SDimitry Andric         OS << ".subreg" << SubReg;
778*0b57cec5SDimitry Andric     }
779*0b57cec5SDimitry Andric     // Print the register class / bank.
7808bcb0991SDimitry Andric     if (Register::isVirtualRegister(Reg)) {
781*0b57cec5SDimitry Andric       if (const MachineFunction *MF = getMFIfAvailable(*this)) {
782*0b57cec5SDimitry Andric         const MachineRegisterInfo &MRI = MF->getRegInfo();
783*0b57cec5SDimitry Andric         if (IsStandalone || !PrintDef || MRI.def_empty(Reg)) {
784*0b57cec5SDimitry Andric           OS << ':';
785*0b57cec5SDimitry Andric           OS << printRegClassOrBank(Reg, MRI, TRI);
786*0b57cec5SDimitry Andric         }
787*0b57cec5SDimitry Andric       }
788*0b57cec5SDimitry Andric     }
789*0b57cec5SDimitry Andric     // Print ties.
790*0b57cec5SDimitry Andric     if (ShouldPrintRegisterTies && isTied() && !isDef())
791*0b57cec5SDimitry Andric       OS << "(tied-def " << TiedOperandIdx << ")";
792*0b57cec5SDimitry Andric     // Print types.
793*0b57cec5SDimitry Andric     if (TypeToPrint.isValid())
794*0b57cec5SDimitry Andric       OS << '(' << TypeToPrint << ')';
795*0b57cec5SDimitry Andric     break;
796*0b57cec5SDimitry Andric   }
797480093f4SDimitry Andric   case MachineOperand::MO_Immediate: {
798480093f4SDimitry Andric     const MIRFormatter *Formatter = nullptr;
799480093f4SDimitry Andric     if (const MachineFunction *MF = getMFIfAvailable(*this)) {
800480093f4SDimitry Andric       const auto *TII = MF->getSubtarget().getInstrInfo();
801480093f4SDimitry Andric       assert(TII && "expected instruction info");
802480093f4SDimitry Andric       Formatter = TII->getMIRFormatter();
803480093f4SDimitry Andric     }
804480093f4SDimitry Andric     if (Formatter)
805480093f4SDimitry Andric       Formatter->printImm(OS, *getParent(), OpIdx, getImm());
806480093f4SDimitry Andric     else
807*0b57cec5SDimitry Andric       OS << getImm();
808*0b57cec5SDimitry Andric     break;
809480093f4SDimitry Andric   }
810*0b57cec5SDimitry Andric   case MachineOperand::MO_CImmediate:
811*0b57cec5SDimitry Andric     getCImm()->printAsOperand(OS, /*PrintType=*/true, MST);
812*0b57cec5SDimitry Andric     break;
813*0b57cec5SDimitry Andric   case MachineOperand::MO_FPImmediate:
814*0b57cec5SDimitry Andric     getFPImm()->printAsOperand(OS, /*PrintType=*/true, MST);
815*0b57cec5SDimitry Andric     break;
816*0b57cec5SDimitry Andric   case MachineOperand::MO_MachineBasicBlock:
817*0b57cec5SDimitry Andric     OS << printMBBReference(*getMBB());
818*0b57cec5SDimitry Andric     break;
819*0b57cec5SDimitry Andric   case MachineOperand::MO_FrameIndex: {
820*0b57cec5SDimitry Andric     int FrameIndex = getIndex();
821*0b57cec5SDimitry Andric     bool IsFixed = false;
822*0b57cec5SDimitry Andric     const MachineFrameInfo *MFI = nullptr;
823*0b57cec5SDimitry Andric     if (const MachineFunction *MF = getMFIfAvailable(*this))
824*0b57cec5SDimitry Andric       MFI = &MF->getFrameInfo();
825*0b57cec5SDimitry Andric     printFrameIndex(OS, FrameIndex, IsFixed, MFI);
826*0b57cec5SDimitry Andric     break;
827*0b57cec5SDimitry Andric   }
828*0b57cec5SDimitry Andric   case MachineOperand::MO_ConstantPoolIndex:
829*0b57cec5SDimitry Andric     OS << "%const." << getIndex();
830*0b57cec5SDimitry Andric     printOperandOffset(OS, getOffset());
831*0b57cec5SDimitry Andric     break;
832*0b57cec5SDimitry Andric   case MachineOperand::MO_TargetIndex: {
833*0b57cec5SDimitry Andric     OS << "target-index(";
834*0b57cec5SDimitry Andric     const char *Name = "<unknown>";
835*0b57cec5SDimitry Andric     if (const MachineFunction *MF = getMFIfAvailable(*this))
836e8d8bef9SDimitry Andric       if (const auto *TargetIndexName = ::getTargetIndexName(*MF, getIndex()))
837*0b57cec5SDimitry Andric         Name = TargetIndexName;
838*0b57cec5SDimitry Andric     OS << Name << ')';
839*0b57cec5SDimitry Andric     printOperandOffset(OS, getOffset());
840*0b57cec5SDimitry Andric     break;
841*0b57cec5SDimitry Andric   }
842*0b57cec5SDimitry Andric   case MachineOperand::MO_JumpTableIndex:
843*0b57cec5SDimitry Andric     OS << printJumpTableEntryReference(getIndex());
844*0b57cec5SDimitry Andric     break;
845*0b57cec5SDimitry Andric   case MachineOperand::MO_GlobalAddress:
846*0b57cec5SDimitry Andric     getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST);
847*0b57cec5SDimitry Andric     printOperandOffset(OS, getOffset());
848*0b57cec5SDimitry Andric     break;
849*0b57cec5SDimitry Andric   case MachineOperand::MO_ExternalSymbol: {
850*0b57cec5SDimitry Andric     StringRef Name = getSymbolName();
851*0b57cec5SDimitry Andric     OS << '&';
852*0b57cec5SDimitry Andric     if (Name.empty()) {
853*0b57cec5SDimitry Andric       OS << "\"\"";
854*0b57cec5SDimitry Andric     } else {
855*0b57cec5SDimitry Andric       printLLVMNameWithoutPrefix(OS, Name);
856*0b57cec5SDimitry Andric     }
857*0b57cec5SDimitry Andric     printOperandOffset(OS, getOffset());
858*0b57cec5SDimitry Andric     break;
859*0b57cec5SDimitry Andric   }
860*0b57cec5SDimitry Andric   case MachineOperand::MO_BlockAddress: {
861*0b57cec5SDimitry Andric     OS << "blockaddress(";
862*0b57cec5SDimitry Andric     getBlockAddress()->getFunction()->printAsOperand(OS, /*PrintType=*/false,
863*0b57cec5SDimitry Andric                                                      MST);
864*0b57cec5SDimitry Andric     OS << ", ";
865*0b57cec5SDimitry Andric     printIRBlockReference(OS, *getBlockAddress()->getBasicBlock(), MST);
866*0b57cec5SDimitry Andric     OS << ')';
867*0b57cec5SDimitry Andric     MachineOperand::printOperandOffset(OS, getOffset());
868*0b57cec5SDimitry Andric     break;
869*0b57cec5SDimitry Andric   }
870*0b57cec5SDimitry Andric   case MachineOperand::MO_RegisterMask: {
871*0b57cec5SDimitry Andric     OS << "<regmask";
872*0b57cec5SDimitry Andric     if (TRI) {
873*0b57cec5SDimitry Andric       unsigned NumRegsInMask = 0;
874*0b57cec5SDimitry Andric       unsigned NumRegsEmitted = 0;
875*0b57cec5SDimitry Andric       for (unsigned i = 0; i < TRI->getNumRegs(); ++i) {
876*0b57cec5SDimitry Andric         unsigned MaskWord = i / 32;
877*0b57cec5SDimitry Andric         unsigned MaskBit = i % 32;
878*0b57cec5SDimitry Andric         if (getRegMask()[MaskWord] & (1 << MaskBit)) {
879*0b57cec5SDimitry Andric           if (PrintRegMaskNumRegs < 0 ||
880*0b57cec5SDimitry Andric               NumRegsEmitted <= static_cast<unsigned>(PrintRegMaskNumRegs)) {
881*0b57cec5SDimitry Andric             OS << " " << printReg(i, TRI);
882*0b57cec5SDimitry Andric             NumRegsEmitted++;
883*0b57cec5SDimitry Andric           }
884*0b57cec5SDimitry Andric           NumRegsInMask++;
885*0b57cec5SDimitry Andric         }
886*0b57cec5SDimitry Andric       }
887*0b57cec5SDimitry Andric       if (NumRegsEmitted != NumRegsInMask)
888*0b57cec5SDimitry Andric         OS << " and " << (NumRegsInMask - NumRegsEmitted) << " more...";
889*0b57cec5SDimitry Andric     } else {
890*0b57cec5SDimitry Andric       OS << " ...";
891*0b57cec5SDimitry Andric     }
892*0b57cec5SDimitry Andric     OS << ">";
893*0b57cec5SDimitry Andric     break;
894*0b57cec5SDimitry Andric   }
895*0b57cec5SDimitry Andric   case MachineOperand::MO_RegisterLiveOut: {
896*0b57cec5SDimitry Andric     const uint32_t *RegMask = getRegLiveOut();
897*0b57cec5SDimitry Andric     OS << "liveout(";
898*0b57cec5SDimitry Andric     if (!TRI) {
899*0b57cec5SDimitry Andric       OS << "<unknown>";
900*0b57cec5SDimitry Andric     } else {
901*0b57cec5SDimitry Andric       bool IsCommaNeeded = false;
902*0b57cec5SDimitry Andric       for (unsigned Reg = 0, E = TRI->getNumRegs(); Reg < E; ++Reg) {
903*0b57cec5SDimitry Andric         if (RegMask[Reg / 32] & (1U << (Reg % 32))) {
904*0b57cec5SDimitry Andric           if (IsCommaNeeded)
905*0b57cec5SDimitry Andric             OS << ", ";
906*0b57cec5SDimitry Andric           OS << printReg(Reg, TRI);
907*0b57cec5SDimitry Andric           IsCommaNeeded = true;
908*0b57cec5SDimitry Andric         }
909*0b57cec5SDimitry Andric       }
910*0b57cec5SDimitry Andric     }
911*0b57cec5SDimitry Andric     OS << ")";
912*0b57cec5SDimitry Andric     break;
913*0b57cec5SDimitry Andric   }
914*0b57cec5SDimitry Andric   case MachineOperand::MO_Metadata:
915*0b57cec5SDimitry Andric     getMetadata()->printAsOperand(OS, MST);
916*0b57cec5SDimitry Andric     break;
917*0b57cec5SDimitry Andric   case MachineOperand::MO_MCSymbol:
918*0b57cec5SDimitry Andric     printSymbol(OS, *getMCSymbol());
919*0b57cec5SDimitry Andric     break;
920*0b57cec5SDimitry Andric   case MachineOperand::MO_CFIIndex: {
921*0b57cec5SDimitry Andric     if (const MachineFunction *MF = getMFIfAvailable(*this))
922*0b57cec5SDimitry Andric       printCFI(OS, MF->getFrameInstructions()[getCFIIndex()], TRI);
923*0b57cec5SDimitry Andric     else
924*0b57cec5SDimitry Andric       OS << "<cfi directive>";
925*0b57cec5SDimitry Andric     break;
926*0b57cec5SDimitry Andric   }
927*0b57cec5SDimitry Andric   case MachineOperand::MO_IntrinsicID: {
928*0b57cec5SDimitry Andric     Intrinsic::ID ID = getIntrinsicID();
929*0b57cec5SDimitry Andric     if (ID < Intrinsic::num_intrinsics)
930*0b57cec5SDimitry Andric       OS << "intrinsic(@" << Intrinsic::getName(ID, None) << ')';
931*0b57cec5SDimitry Andric     else if (IntrinsicInfo)
932*0b57cec5SDimitry Andric       OS << "intrinsic(@" << IntrinsicInfo->getName(ID) << ')';
933*0b57cec5SDimitry Andric     else
934*0b57cec5SDimitry Andric       OS << "intrinsic(" << ID << ')';
935*0b57cec5SDimitry Andric     break;
936*0b57cec5SDimitry Andric   }
937*0b57cec5SDimitry Andric   case MachineOperand::MO_Predicate: {
938*0b57cec5SDimitry Andric     auto Pred = static_cast<CmpInst::Predicate>(getPredicate());
939*0b57cec5SDimitry Andric     OS << (CmpInst::isIntPredicate(Pred) ? "int" : "float") << "pred("
940*0b57cec5SDimitry Andric        << CmpInst::getPredicateName(Pred) << ')';
941*0b57cec5SDimitry Andric     break;
942*0b57cec5SDimitry Andric   }
9438bcb0991SDimitry Andric   case MachineOperand::MO_ShuffleMask:
9448bcb0991SDimitry Andric     OS << "shufflemask(";
945480093f4SDimitry Andric     ArrayRef<int> Mask = getShuffleMask();
9468bcb0991SDimitry Andric     StringRef Separator;
947480093f4SDimitry Andric     for (int Elt : Mask) {
948480093f4SDimitry Andric       if (Elt == -1)
949480093f4SDimitry Andric         OS << Separator << "undef";
950480093f4SDimitry Andric       else
951480093f4SDimitry Andric         OS << Separator << Elt;
9528bcb0991SDimitry Andric       Separator = ", ";
9538bcb0991SDimitry Andric     }
9548bcb0991SDimitry Andric 
9558bcb0991SDimitry Andric     OS << ')';
9568bcb0991SDimitry Andric     break;
957*0b57cec5SDimitry Andric   }
958*0b57cec5SDimitry Andric }
959*0b57cec5SDimitry Andric 
960*0b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
961*0b57cec5SDimitry Andric LLVM_DUMP_METHOD void MachineOperand::dump() const { dbgs() << *this << '\n'; }
962*0b57cec5SDimitry Andric #endif
963*0b57cec5SDimitry Andric 
964*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
965*0b57cec5SDimitry Andric // MachineMemOperand Implementation
966*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
967*0b57cec5SDimitry Andric 
968*0b57cec5SDimitry Andric /// getAddrSpace - Return the LLVM IR address space number that this pointer
969*0b57cec5SDimitry Andric /// points into.
970*0b57cec5SDimitry Andric unsigned MachinePointerInfo::getAddrSpace() const { return AddrSpace; }
971*0b57cec5SDimitry Andric 
972*0b57cec5SDimitry Andric /// isDereferenceable - Return true if V is always dereferenceable for
973*0b57cec5SDimitry Andric /// Offset + Size byte.
974*0b57cec5SDimitry Andric bool MachinePointerInfo::isDereferenceable(unsigned Size, LLVMContext &C,
975*0b57cec5SDimitry Andric                                            const DataLayout &DL) const {
976*0b57cec5SDimitry Andric   if (!V.is<const Value *>())
977*0b57cec5SDimitry Andric     return false;
978*0b57cec5SDimitry Andric 
979*0b57cec5SDimitry Andric   const Value *BasePtr = V.get<const Value *>();
980*0b57cec5SDimitry Andric   if (BasePtr == nullptr)
981*0b57cec5SDimitry Andric     return false;
982*0b57cec5SDimitry Andric 
983*0b57cec5SDimitry Andric   return isDereferenceableAndAlignedPointer(
9845ffd83dbSDimitry Andric       BasePtr, Align(1), APInt(DL.getPointerSizeInBits(), Offset + Size), DL);
985*0b57cec5SDimitry Andric }
986*0b57cec5SDimitry Andric 
987*0b57cec5SDimitry Andric /// getConstantPool - Return a MachinePointerInfo record that refers to the
988*0b57cec5SDimitry Andric /// constant pool.
989*0b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getConstantPool(MachineFunction &MF) {
990*0b57cec5SDimitry Andric   return MachinePointerInfo(MF.getPSVManager().getConstantPool());
991*0b57cec5SDimitry Andric }
992*0b57cec5SDimitry Andric 
993*0b57cec5SDimitry Andric /// getFixedStack - Return a MachinePointerInfo record that refers to the
994*0b57cec5SDimitry Andric /// the specified FrameIndex.
995*0b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getFixedStack(MachineFunction &MF,
996*0b57cec5SDimitry Andric                                                      int FI, int64_t Offset) {
997*0b57cec5SDimitry Andric   return MachinePointerInfo(MF.getPSVManager().getFixedStack(FI), Offset);
998*0b57cec5SDimitry Andric }
999*0b57cec5SDimitry Andric 
1000*0b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getJumpTable(MachineFunction &MF) {
1001*0b57cec5SDimitry Andric   return MachinePointerInfo(MF.getPSVManager().getJumpTable());
1002*0b57cec5SDimitry Andric }
1003*0b57cec5SDimitry Andric 
1004*0b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getGOT(MachineFunction &MF) {
1005*0b57cec5SDimitry Andric   return MachinePointerInfo(MF.getPSVManager().getGOT());
1006*0b57cec5SDimitry Andric }
1007*0b57cec5SDimitry Andric 
1008*0b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getStack(MachineFunction &MF,
1009*0b57cec5SDimitry Andric                                                 int64_t Offset, uint8_t ID) {
1010*0b57cec5SDimitry Andric   return MachinePointerInfo(MF.getPSVManager().getStack(), Offset, ID);
1011*0b57cec5SDimitry Andric }
1012*0b57cec5SDimitry Andric 
1013*0b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getUnknownStack(MachineFunction &MF) {
1014*0b57cec5SDimitry Andric   return MachinePointerInfo(MF.getDataLayout().getAllocaAddrSpace());
1015*0b57cec5SDimitry Andric }
1016*0b57cec5SDimitry Andric 
1017*0b57cec5SDimitry Andric MachineMemOperand::MachineMemOperand(MachinePointerInfo ptrinfo, Flags f,
10185ffd83dbSDimitry Andric                                      uint64_t s, Align a,
1019*0b57cec5SDimitry Andric                                      const AAMDNodes &AAInfo,
1020*0b57cec5SDimitry Andric                                      const MDNode *Ranges, SyncScope::ID SSID,
1021*0b57cec5SDimitry Andric                                      AtomicOrdering Ordering,
1022*0b57cec5SDimitry Andric                                      AtomicOrdering FailureOrdering)
10235ffd83dbSDimitry Andric     : PtrInfo(ptrinfo), Size(s), FlagVals(f), BaseAlign(a), AAInfo(AAInfo),
10245ffd83dbSDimitry Andric       Ranges(Ranges) {
1025*0b57cec5SDimitry Andric   assert((PtrInfo.V.isNull() || PtrInfo.V.is<const PseudoSourceValue *>() ||
1026*0b57cec5SDimitry Andric           isa<PointerType>(PtrInfo.V.get<const Value *>()->getType())) &&
1027*0b57cec5SDimitry Andric          "invalid pointer value");
1028*0b57cec5SDimitry Andric   assert((isLoad() || isStore()) && "Not a load/store!");
1029*0b57cec5SDimitry Andric 
1030*0b57cec5SDimitry Andric   AtomicInfo.SSID = static_cast<unsigned>(SSID);
1031*0b57cec5SDimitry Andric   assert(getSyncScopeID() == SSID && "Value truncated");
1032*0b57cec5SDimitry Andric   AtomicInfo.Ordering = static_cast<unsigned>(Ordering);
1033*0b57cec5SDimitry Andric   assert(getOrdering() == Ordering && "Value truncated");
1034*0b57cec5SDimitry Andric   AtomicInfo.FailureOrdering = static_cast<unsigned>(FailureOrdering);
1035*0b57cec5SDimitry Andric   assert(getFailureOrdering() == FailureOrdering && "Value truncated");
1036*0b57cec5SDimitry Andric }
1037*0b57cec5SDimitry Andric 
1038*0b57cec5SDimitry Andric /// Profile - Gather unique data for the object.
1039*0b57cec5SDimitry Andric ///
1040*0b57cec5SDimitry Andric void MachineMemOperand::Profile(FoldingSetNodeID &ID) const {
1041*0b57cec5SDimitry Andric   ID.AddInteger(getOffset());
1042*0b57cec5SDimitry Andric   ID.AddInteger(Size);
1043*0b57cec5SDimitry Andric   ID.AddPointer(getOpaqueValue());
1044*0b57cec5SDimitry Andric   ID.AddInteger(getFlags());
10455ffd83dbSDimitry Andric   ID.AddInteger(getBaseAlign().value());
1046*0b57cec5SDimitry Andric }
1047*0b57cec5SDimitry Andric 
1048*0b57cec5SDimitry Andric void MachineMemOperand::refineAlignment(const MachineMemOperand *MMO) {
1049*0b57cec5SDimitry Andric   // The Value and Offset may differ due to CSE. But the flags and size
1050*0b57cec5SDimitry Andric   // should be the same.
1051*0b57cec5SDimitry Andric   assert(MMO->getFlags() == getFlags() && "Flags mismatch!");
1052*0b57cec5SDimitry Andric   assert(MMO->getSize() == getSize() && "Size mismatch!");
1053*0b57cec5SDimitry Andric 
10545ffd83dbSDimitry Andric   if (MMO->getBaseAlign() >= getBaseAlign()) {
1055*0b57cec5SDimitry Andric     // Update the alignment value.
10565ffd83dbSDimitry Andric     BaseAlign = MMO->getBaseAlign();
1057*0b57cec5SDimitry Andric     // Also update the base and offset, because the new alignment may
1058*0b57cec5SDimitry Andric     // not be applicable with the old ones.
1059*0b57cec5SDimitry Andric     PtrInfo = MMO->PtrInfo;
1060*0b57cec5SDimitry Andric   }
1061*0b57cec5SDimitry Andric }
1062*0b57cec5SDimitry Andric 
1063*0b57cec5SDimitry Andric /// getAlignment - Return the minimum known alignment in bytes of the
1064*0b57cec5SDimitry Andric /// actual memory reference.
10655ffd83dbSDimitry Andric uint64_t MachineMemOperand::getAlignment() const { return getAlign().value(); }
10665ffd83dbSDimitry Andric 
10675ffd83dbSDimitry Andric /// getAlign - Return the minimum known alignment in bytes of the
10685ffd83dbSDimitry Andric /// actual memory reference.
10695ffd83dbSDimitry Andric Align MachineMemOperand::getAlign() const {
10705ffd83dbSDimitry Andric   return commonAlignment(getBaseAlign(), getOffset());
1071*0b57cec5SDimitry Andric }
1072*0b57cec5SDimitry Andric 
1073*0b57cec5SDimitry Andric void MachineMemOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
1074*0b57cec5SDimitry Andric                               SmallVectorImpl<StringRef> &SSNs,
1075*0b57cec5SDimitry Andric                               const LLVMContext &Context,
1076*0b57cec5SDimitry Andric                               const MachineFrameInfo *MFI,
1077*0b57cec5SDimitry Andric                               const TargetInstrInfo *TII) const {
1078*0b57cec5SDimitry Andric   OS << '(';
1079*0b57cec5SDimitry Andric   if (isVolatile())
1080*0b57cec5SDimitry Andric     OS << "volatile ";
1081*0b57cec5SDimitry Andric   if (isNonTemporal())
1082*0b57cec5SDimitry Andric     OS << "non-temporal ";
1083*0b57cec5SDimitry Andric   if (isDereferenceable())
1084*0b57cec5SDimitry Andric     OS << "dereferenceable ";
1085*0b57cec5SDimitry Andric   if (isInvariant())
1086*0b57cec5SDimitry Andric     OS << "invariant ";
1087*0b57cec5SDimitry Andric   if (getFlags() & MachineMemOperand::MOTargetFlag1)
1088*0b57cec5SDimitry Andric     OS << '"' << getTargetMMOFlagName(*TII, MachineMemOperand::MOTargetFlag1)
1089*0b57cec5SDimitry Andric        << "\" ";
1090*0b57cec5SDimitry Andric   if (getFlags() & MachineMemOperand::MOTargetFlag2)
1091*0b57cec5SDimitry Andric     OS << '"' << getTargetMMOFlagName(*TII, MachineMemOperand::MOTargetFlag2)
1092*0b57cec5SDimitry Andric        << "\" ";
1093*0b57cec5SDimitry Andric   if (getFlags() & MachineMemOperand::MOTargetFlag3)
1094*0b57cec5SDimitry Andric     OS << '"' << getTargetMMOFlagName(*TII, MachineMemOperand::MOTargetFlag3)
1095*0b57cec5SDimitry Andric        << "\" ";
1096*0b57cec5SDimitry Andric 
1097*0b57cec5SDimitry Andric   assert((isLoad() || isStore()) &&
1098*0b57cec5SDimitry Andric          "machine memory operand must be a load or store (or both)");
1099*0b57cec5SDimitry Andric   if (isLoad())
1100*0b57cec5SDimitry Andric     OS << "load ";
1101*0b57cec5SDimitry Andric   if (isStore())
1102*0b57cec5SDimitry Andric     OS << "store ";
1103*0b57cec5SDimitry Andric 
1104*0b57cec5SDimitry Andric   printSyncScope(OS, Context, getSyncScopeID(), SSNs);
1105*0b57cec5SDimitry Andric 
1106*0b57cec5SDimitry Andric   if (getOrdering() != AtomicOrdering::NotAtomic)
1107*0b57cec5SDimitry Andric     OS << toIRString(getOrdering()) << ' ';
1108*0b57cec5SDimitry Andric   if (getFailureOrdering() != AtomicOrdering::NotAtomic)
1109*0b57cec5SDimitry Andric     OS << toIRString(getFailureOrdering()) << ' ';
1110*0b57cec5SDimitry Andric 
1111*0b57cec5SDimitry Andric   if (getSize() == MemoryLocation::UnknownSize)
1112*0b57cec5SDimitry Andric     OS << "unknown-size";
1113*0b57cec5SDimitry Andric   else
1114*0b57cec5SDimitry Andric     OS << getSize();
1115*0b57cec5SDimitry Andric 
1116*0b57cec5SDimitry Andric   if (const Value *Val = getValue()) {
1117*0b57cec5SDimitry Andric     OS << ((isLoad() && isStore()) ? " on " : isLoad() ? " from " : " into ");
1118480093f4SDimitry Andric     MIRFormatter::printIRValue(OS, *Val, MST);
1119*0b57cec5SDimitry Andric   } else if (const PseudoSourceValue *PVal = getPseudoValue()) {
1120*0b57cec5SDimitry Andric     OS << ((isLoad() && isStore()) ? " on " : isLoad() ? " from " : " into ");
1121*0b57cec5SDimitry Andric     assert(PVal && "Expected a pseudo source value");
1122*0b57cec5SDimitry Andric     switch (PVal->kind()) {
1123*0b57cec5SDimitry Andric     case PseudoSourceValue::Stack:
1124*0b57cec5SDimitry Andric       OS << "stack";
1125*0b57cec5SDimitry Andric       break;
1126*0b57cec5SDimitry Andric     case PseudoSourceValue::GOT:
1127*0b57cec5SDimitry Andric       OS << "got";
1128*0b57cec5SDimitry Andric       break;
1129*0b57cec5SDimitry Andric     case PseudoSourceValue::JumpTable:
1130*0b57cec5SDimitry Andric       OS << "jump-table";
1131*0b57cec5SDimitry Andric       break;
1132*0b57cec5SDimitry Andric     case PseudoSourceValue::ConstantPool:
1133*0b57cec5SDimitry Andric       OS << "constant-pool";
1134*0b57cec5SDimitry Andric       break;
1135*0b57cec5SDimitry Andric     case PseudoSourceValue::FixedStack: {
1136*0b57cec5SDimitry Andric       int FrameIndex = cast<FixedStackPseudoSourceValue>(PVal)->getFrameIndex();
1137*0b57cec5SDimitry Andric       bool IsFixed = true;
1138*0b57cec5SDimitry Andric       printFrameIndex(OS, FrameIndex, IsFixed, MFI);
1139*0b57cec5SDimitry Andric       break;
1140*0b57cec5SDimitry Andric     }
1141*0b57cec5SDimitry Andric     case PseudoSourceValue::GlobalValueCallEntry:
1142*0b57cec5SDimitry Andric       OS << "call-entry ";
1143*0b57cec5SDimitry Andric       cast<GlobalValuePseudoSourceValue>(PVal)->getValue()->printAsOperand(
1144*0b57cec5SDimitry Andric           OS, /*PrintType=*/false, MST);
1145*0b57cec5SDimitry Andric       break;
1146*0b57cec5SDimitry Andric     case PseudoSourceValue::ExternalSymbolCallEntry:
1147*0b57cec5SDimitry Andric       OS << "call-entry &";
1148*0b57cec5SDimitry Andric       printLLVMNameWithoutPrefix(
1149*0b57cec5SDimitry Andric           OS, cast<ExternalSymbolPseudoSourceValue>(PVal)->getSymbol());
1150*0b57cec5SDimitry Andric       break;
1151480093f4SDimitry Andric     default: {
1152480093f4SDimitry Andric       const MIRFormatter *Formatter = TII->getMIRFormatter();
1153*0b57cec5SDimitry Andric       // FIXME: This is not necessarily the correct MIR serialization format for
1154*0b57cec5SDimitry Andric       // a custom pseudo source value, but at least it allows
1155e8d8bef9SDimitry Andric       // MIR printing to work on a target with custom pseudo source
1156*0b57cec5SDimitry Andric       // values.
1157480093f4SDimitry Andric       OS << "custom \"";
1158480093f4SDimitry Andric       Formatter->printCustomPseudoSourceValue(OS, MST, *PVal);
1159480093f4SDimitry Andric       OS << '\"';
1160*0b57cec5SDimitry Andric       break;
1161*0b57cec5SDimitry Andric     }
1162*0b57cec5SDimitry Andric     }
1163480093f4SDimitry Andric   }
1164*0b57cec5SDimitry Andric   MachineOperand::printOperandOffset(OS, getOffset());
1165e8d8bef9SDimitry Andric   if (getAlign() != getSize())
1166e8d8bef9SDimitry Andric     OS << ", align " << getAlign().value();
1167e8d8bef9SDimitry Andric   if (getAlign() != getBaseAlign())
1168e8d8bef9SDimitry Andric     OS << ", basealign " << getBaseAlign().value();
1169*0b57cec5SDimitry Andric   auto AAInfo = getAAInfo();
1170*0b57cec5SDimitry Andric   if (AAInfo.TBAA) {
1171*0b57cec5SDimitry Andric     OS << ", !tbaa ";
1172*0b57cec5SDimitry Andric     AAInfo.TBAA->printAsOperand(OS, MST);
1173*0b57cec5SDimitry Andric   }
1174*0b57cec5SDimitry Andric   if (AAInfo.Scope) {
1175*0b57cec5SDimitry Andric     OS << ", !alias.scope ";
1176*0b57cec5SDimitry Andric     AAInfo.Scope->printAsOperand(OS, MST);
1177*0b57cec5SDimitry Andric   }
1178*0b57cec5SDimitry Andric   if (AAInfo.NoAlias) {
1179*0b57cec5SDimitry Andric     OS << ", !noalias ";
1180*0b57cec5SDimitry Andric     AAInfo.NoAlias->printAsOperand(OS, MST);
1181*0b57cec5SDimitry Andric   }
1182*0b57cec5SDimitry Andric   if (getRanges()) {
1183*0b57cec5SDimitry Andric     OS << ", !range ";
1184*0b57cec5SDimitry Andric     getRanges()->printAsOperand(OS, MST);
1185*0b57cec5SDimitry Andric   }
1186*0b57cec5SDimitry Andric   // FIXME: Implement addrspace printing/parsing in MIR.
1187*0b57cec5SDimitry Andric   // For now, print this even though parsing it is not available in MIR.
1188*0b57cec5SDimitry Andric   if (unsigned AS = getAddrSpace())
1189*0b57cec5SDimitry Andric     OS << ", addrspace " << AS;
1190*0b57cec5SDimitry Andric 
1191*0b57cec5SDimitry Andric   OS << ')';
1192*0b57cec5SDimitry Andric }
1193