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