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