1//===- AsmWriter.cpp - Printing LLVM as an assembly file ------------------===//
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// This library implements `print` family of functions in classes like
10// Module, Function, Value, etc. In-memory representation of those classes is
11// converted to IR strings.
12//
13// Note that these routines must be extremely tolerant of various errors in the
14// LLVM code, because it can be used for debugging transformations.
15//
16//===----------------------------------------------------------------------===//
17
18#include "llvm/ADT/APFloat.h"
19#include "llvm/ADT/APInt.h"
20#include "llvm/ADT/ArrayRef.h"
21#include "llvm/ADT/DenseMap.h"
22#include "llvm/ADT/STLExtras.h"
23#include "llvm/ADT/SetVector.h"
24#include "llvm/ADT/SmallPtrSet.h"
25#include "llvm/ADT/SmallString.h"
26#include "llvm/ADT/SmallVector.h"
27#include "llvm/ADT/StringExtras.h"
28#include "llvm/ADT/StringRef.h"
29#include "llvm/ADT/iterator_range.h"
30#include "llvm/BinaryFormat/Dwarf.h"
31#include "llvm/Config/llvm-config.h"
32#include "llvm/IR/Argument.h"
33#include "llvm/IR/AssemblyAnnotationWriter.h"
34#include "llvm/IR/Attributes.h"
35#include "llvm/IR/BasicBlock.h"
36#include "llvm/IR/CFG.h"
37#include "llvm/IR/CallingConv.h"
38#include "llvm/IR/Comdat.h"
39#include "llvm/IR/Constant.h"
40#include "llvm/IR/Constants.h"
41#include "llvm/IR/DebugInfoMetadata.h"
42#include "llvm/IR/DebugProgramInstruction.h"
43#include "llvm/IR/DerivedTypes.h"
44#include "llvm/IR/Function.h"
45#include "llvm/IR/GlobalAlias.h"
46#include "llvm/IR/GlobalIFunc.h"
47#include "llvm/IR/GlobalObject.h"
48#include "llvm/IR/GlobalValue.h"
49#include "llvm/IR/GlobalVariable.h"
50#include "llvm/IR/IRPrintingPasses.h"
51#include "llvm/IR/InlineAsm.h"
52#include "llvm/IR/InstrTypes.h"
53#include "llvm/IR/Instruction.h"
54#include "llvm/IR/Instructions.h"
55#include "llvm/IR/IntrinsicInst.h"
56#include "llvm/IR/LLVMContext.h"
57#include "llvm/IR/Metadata.h"
58#include "llvm/IR/Module.h"
59#include "llvm/IR/ModuleSlotTracker.h"
60#include "llvm/IR/ModuleSummaryIndex.h"
61#include "llvm/IR/Operator.h"
62#include "llvm/IR/Type.h"
63#include "llvm/IR/TypeFinder.h"
64#include "llvm/IR/TypedPointerType.h"
65#include "llvm/IR/Use.h"
66#include "llvm/IR/User.h"
67#include "llvm/IR/Value.h"
68#include "llvm/Support/AtomicOrdering.h"
69#include "llvm/Support/Casting.h"
70#include "llvm/Support/Compiler.h"
71#include "llvm/Support/Debug.h"
72#include "llvm/Support/ErrorHandling.h"
73#include "llvm/Support/Format.h"
74#include "llvm/Support/FormattedStream.h"
75#include "llvm/Support/SaveAndRestore.h"
76#include "llvm/Support/raw_ostream.h"
77#include <algorithm>
78#include <cassert>
79#include <cctype>
80#include <cstddef>
81#include <cstdint>
82#include <iterator>
83#include <memory>
84#include <optional>
85#include <string>
86#include <tuple>
87#include <utility>
88#include <vector>
89
90using namespace llvm;
91
92// Make virtual table appear in this compilation unit.
93AssemblyAnnotationWriter::~AssemblyAnnotationWriter() = default;
94
95//===----------------------------------------------------------------------===//
96// Helper Functions
97//===----------------------------------------------------------------------===//
98
99using OrderMap = MapVector<const Value *, unsigned>;
100
101using UseListOrderMap =
102 DenseMap<const Function *, MapVector<const Value *, std::vector<unsigned>>>;
103
104/// Look for a value that might be wrapped as metadata, e.g. a value in a
105/// metadata operand. Returns the input value as-is if it is not wrapped.
106static const Value *skipMetadataWrapper(const Value *V) {
107 if (const auto *MAV = dyn_cast<MetadataAsValue>(Val: V))
108 if (const auto *VAM = dyn_cast<ValueAsMetadata>(Val: MAV->getMetadata()))
109 return VAM->getValue();
110 return V;
111}
112
113static void orderValue(const Value *V, OrderMap &OM) {
114 if (OM.lookup(Key: V))
115 return;
116
117 if (const Constant *C = dyn_cast<Constant>(Val: V))
118 if (C->getNumOperands() && !isa<GlobalValue>(Val: C))
119 for (const Value *Op : C->operands())
120 if (!isa<BasicBlock>(Val: Op) && !isa<GlobalValue>(Val: Op))
121 orderValue(V: Op, OM);
122
123 // Note: we cannot cache this lookup above, since inserting into the map
124 // changes the map's size, and thus affects the other IDs.
125 unsigned ID = OM.size() + 1;
126 OM[V] = ID;
127}
128
129static OrderMap orderModule(const Module *M) {
130 OrderMap OM;
131
132 for (const GlobalVariable &G : M->globals()) {
133 if (G.hasInitializer())
134 if (!isa<GlobalValue>(Val: G.getInitializer()))
135 orderValue(V: G.getInitializer(), OM);
136 orderValue(V: &G, OM);
137 }
138 for (const GlobalAlias &A : M->aliases()) {
139 if (!isa<GlobalValue>(Val: A.getAliasee()))
140 orderValue(V: A.getAliasee(), OM);
141 orderValue(V: &A, OM);
142 }
143 for (const GlobalIFunc &I : M->ifuncs()) {
144 if (!isa<GlobalValue>(Val: I.getResolver()))
145 orderValue(V: I.getResolver(), OM);
146 orderValue(V: &I, OM);
147 }
148 for (const Function &F : *M) {
149 for (const Use &U : F.operands())
150 if (!isa<GlobalValue>(Val: U.get()))
151 orderValue(V: U.get(), OM);
152
153 orderValue(V: &F, OM);
154
155 if (F.isDeclaration())
156 continue;
157
158 for (const Argument &A : F.args())
159 orderValue(V: &A, OM);
160 for (const BasicBlock &BB : F) {
161 orderValue(V: &BB, OM);
162 for (const Instruction &I : BB) {
163 for (const Value *Op : I.operands()) {
164 Op = skipMetadataWrapper(V: Op);
165 if ((isa<Constant>(Val: *Op) && !isa<GlobalValue>(Val: *Op)) ||
166 isa<InlineAsm>(Val: *Op))
167 orderValue(V: Op, OM);
168 }
169 orderValue(V: &I, OM);
170 }
171 }
172 }
173 return OM;
174}
175
176static std::vector<unsigned>
177predictValueUseListOrder(const Value *V, unsigned ID, const OrderMap &OM) {
178 // Predict use-list order for this one.
179 using Entry = std::pair<const Use *, unsigned>;
180 SmallVector<Entry, 64> List;
181 for (const Use &U : V->uses())
182 // Check if this user will be serialized.
183 if (OM.lookup(Key: U.getUser()))
184 List.push_back(Elt: std::make_pair(x: &U, y: List.size()));
185
186 if (List.size() < 2)
187 // We may have lost some users.
188 return {};
189
190 // When referencing a value before its declaration, a temporary value is
191 // created, which will later be RAUWed with the actual value. This reverses
192 // the use list. This happens for all values apart from basic blocks.
193 bool GetsReversed = !isa<BasicBlock>(Val: V);
194 if (auto *BA = dyn_cast<BlockAddress>(Val: V))
195 ID = OM.lookup(Key: BA->getBasicBlock());
196 llvm::sort(C&: List, Comp: [&](const Entry &L, const Entry &R) {
197 const Use *LU = L.first;
198 const Use *RU = R.first;
199 if (LU == RU)
200 return false;
201
202 auto LID = OM.lookup(Key: LU->getUser());
203 auto RID = OM.lookup(Key: RU->getUser());
204
205 // If ID is 4, then expect: 7 6 5 1 2 3.
206 if (LID < RID) {
207 if (GetsReversed)
208 if (RID <= ID)
209 return true;
210 return false;
211 }
212 if (RID < LID) {
213 if (GetsReversed)
214 if (LID <= ID)
215 return false;
216 return true;
217 }
218
219 // LID and RID are equal, so we have different operands of the same user.
220 // Assume operands are added in order for all instructions.
221 if (GetsReversed)
222 if (LID <= ID)
223 return LU->getOperandNo() < RU->getOperandNo();
224 return LU->getOperandNo() > RU->getOperandNo();
225 });
226
227 if (llvm::is_sorted(Range&: List, C: llvm::less_second()))
228 // Order is already correct.
229 return {};
230
231 // Store the shuffle.
232 std::vector<unsigned> Shuffle(List.size());
233 for (size_t I = 0, E = List.size(); I != E; ++I)
234 Shuffle[I] = List[I].second;
235 return Shuffle;
236}
237
238static UseListOrderMap predictUseListOrder(const Module *M) {
239 OrderMap OM = orderModule(M);
240 UseListOrderMap ULOM;
241 for (const auto &Pair : OM) {
242 const Value *V = Pair.first;
243 if (V->use_empty() || std::next(x: V->use_begin()) == V->use_end())
244 continue;
245
246 std::vector<unsigned> Shuffle =
247 predictValueUseListOrder(V, ID: Pair.second, OM);
248 if (Shuffle.empty())
249 continue;
250
251 const Function *F = nullptr;
252 if (auto *I = dyn_cast<Instruction>(Val: V))
253 F = I->getFunction();
254 if (auto *A = dyn_cast<Argument>(Val: V))
255 F = A->getParent();
256 if (auto *BB = dyn_cast<BasicBlock>(Val: V))
257 F = BB->getParent();
258 ULOM[F][V] = std::move(Shuffle);
259 }
260 return ULOM;
261}
262
263static const Module *getModuleFromVal(const Value *V) {
264 if (const Argument *MA = dyn_cast<Argument>(Val: V))
265 return MA->getParent() ? MA->getParent()->getParent() : nullptr;
266
267 if (const BasicBlock *BB = dyn_cast<BasicBlock>(Val: V))
268 return BB->getParent() ? BB->getParent()->getParent() : nullptr;
269
270 if (const Instruction *I = dyn_cast<Instruction>(Val: V)) {
271 const Function *M = I->getParent() ? I->getParent()->getParent() : nullptr;
272 return M ? M->getParent() : nullptr;
273 }
274
275 if (const GlobalValue *GV = dyn_cast<GlobalValue>(Val: V))
276 return GV->getParent();
277
278 if (const auto *MAV = dyn_cast<MetadataAsValue>(Val: V)) {
279 for (const User *U : MAV->users())
280 if (isa<Instruction>(Val: U))
281 if (const Module *M = getModuleFromVal(V: U))
282 return M;
283 return nullptr;
284 }
285
286 return nullptr;
287}
288
289static const Module *getModuleFromDPI(const DPMarker *Marker) {
290 const Function *M =
291 Marker->getParent() ? Marker->getParent()->getParent() : nullptr;
292 return M ? M->getParent() : nullptr;
293}
294
295static const Module *getModuleFromDPI(const DPValue *DPV) {
296 return getModuleFromDPI(Marker: DPV->getMarker());
297}
298
299static void PrintCallingConv(unsigned cc, raw_ostream &Out) {
300 switch (cc) {
301 default: Out << "cc" << cc; break;
302 case CallingConv::Fast: Out << "fastcc"; break;
303 case CallingConv::Cold: Out << "coldcc"; break;
304 case CallingConv::AnyReg: Out << "anyregcc"; break;
305 case CallingConv::PreserveMost: Out << "preserve_mostcc"; break;
306 case CallingConv::PreserveAll: Out << "preserve_allcc"; break;
307 case CallingConv::PreserveNone: Out << "preserve_nonecc"; break;
308 case CallingConv::CXX_FAST_TLS: Out << "cxx_fast_tlscc"; break;
309 case CallingConv::GHC: Out << "ghccc"; break;
310 case CallingConv::Tail: Out << "tailcc"; break;
311 case CallingConv::GRAAL: Out << "graalcc"; break;
312 case CallingConv::CFGuard_Check: Out << "cfguard_checkcc"; break;
313 case CallingConv::X86_StdCall: Out << "x86_stdcallcc"; break;
314 case CallingConv::X86_FastCall: Out << "x86_fastcallcc"; break;
315 case CallingConv::X86_ThisCall: Out << "x86_thiscallcc"; break;
316 case CallingConv::X86_RegCall: Out << "x86_regcallcc"; break;
317 case CallingConv::X86_VectorCall:Out << "x86_vectorcallcc"; break;
318 case CallingConv::Intel_OCL_BI: Out << "intel_ocl_bicc"; break;
319 case CallingConv::ARM_APCS: Out << "arm_apcscc"; break;
320 case CallingConv::ARM_AAPCS: Out << "arm_aapcscc"; break;
321 case CallingConv::ARM_AAPCS_VFP: Out << "arm_aapcs_vfpcc"; break;
322 case CallingConv::AArch64_VectorCall: Out << "aarch64_vector_pcs"; break;
323 case CallingConv::AArch64_SVE_VectorCall:
324 Out << "aarch64_sve_vector_pcs";
325 break;
326 case CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0:
327 Out << "aarch64_sme_preservemost_from_x0";
328 break;
329 case CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2:
330 Out << "aarch64_sme_preservemost_from_x2";
331 break;
332 case CallingConv::MSP430_INTR: Out << "msp430_intrcc"; break;
333 case CallingConv::AVR_INTR: Out << "avr_intrcc "; break;
334 case CallingConv::AVR_SIGNAL: Out << "avr_signalcc "; break;
335 case CallingConv::PTX_Kernel: Out << "ptx_kernel"; break;
336 case CallingConv::PTX_Device: Out << "ptx_device"; break;
337 case CallingConv::X86_64_SysV: Out << "x86_64_sysvcc"; break;
338 case CallingConv::Win64: Out << "win64cc"; break;
339 case CallingConv::SPIR_FUNC: Out << "spir_func"; break;
340 case CallingConv::SPIR_KERNEL: Out << "spir_kernel"; break;
341 case CallingConv::Swift: Out << "swiftcc"; break;
342 case CallingConv::SwiftTail: Out << "swifttailcc"; break;
343 case CallingConv::X86_INTR: Out << "x86_intrcc"; break;
344 case CallingConv::DUMMY_HHVM:
345 Out << "hhvmcc";
346 break;
347 case CallingConv::DUMMY_HHVM_C:
348 Out << "hhvm_ccc";
349 break;
350 case CallingConv::AMDGPU_VS: Out << "amdgpu_vs"; break;
351 case CallingConv::AMDGPU_LS: Out << "amdgpu_ls"; break;
352 case CallingConv::AMDGPU_HS: Out << "amdgpu_hs"; break;
353 case CallingConv::AMDGPU_ES: Out << "amdgpu_es"; break;
354 case CallingConv::AMDGPU_GS: Out << "amdgpu_gs"; break;
355 case CallingConv::AMDGPU_PS: Out << "amdgpu_ps"; break;
356 case CallingConv::AMDGPU_CS: Out << "amdgpu_cs"; break;
357 case CallingConv::AMDGPU_CS_Chain:
358 Out << "amdgpu_cs_chain";
359 break;
360 case CallingConv::AMDGPU_CS_ChainPreserve:
361 Out << "amdgpu_cs_chain_preserve";
362 break;
363 case CallingConv::AMDGPU_KERNEL: Out << "amdgpu_kernel"; break;
364 case CallingConv::AMDGPU_Gfx: Out << "amdgpu_gfx"; break;
365 case CallingConv::M68k_RTD: Out << "m68k_rtdcc"; break;
366 }
367}
368
369enum PrefixType {
370 GlobalPrefix,
371 ComdatPrefix,
372 LabelPrefix,
373 LocalPrefix,
374 NoPrefix
375};
376
377void llvm::printLLVMNameWithoutPrefix(raw_ostream &OS, StringRef Name) {
378 assert(!Name.empty() && "Cannot get empty name!");
379
380 // Scan the name to see if it needs quotes first.
381 bool NeedsQuotes = isdigit(static_cast<unsigned char>(Name[0]));
382 if (!NeedsQuotes) {
383 for (unsigned char C : Name) {
384 // By making this unsigned, the value passed in to isalnum will always be
385 // in the range 0-255. This is important when building with MSVC because
386 // its implementation will assert. This situation can arise when dealing
387 // with UTF-8 multibyte characters.
388 if (!isalnum(static_cast<unsigned char>(C)) && C != '-' && C != '.' &&
389 C != '_') {
390 NeedsQuotes = true;
391 break;
392 }
393 }
394 }
395
396 // If we didn't need any quotes, just write out the name in one blast.
397 if (!NeedsQuotes) {
398 OS << Name;
399 return;
400 }
401
402 // Okay, we need quotes. Output the quotes and escape any scary characters as
403 // needed.
404 OS << '"';
405 printEscapedString(Name, Out&: OS);
406 OS << '"';
407}
408
409/// Turn the specified name into an 'LLVM name', which is either prefixed with %
410/// (if the string only contains simple characters) or is surrounded with ""'s
411/// (if it has special chars in it). Print it out.
412static void PrintLLVMName(raw_ostream &OS, StringRef Name, PrefixType Prefix) {
413 switch (Prefix) {
414 case NoPrefix:
415 break;
416 case GlobalPrefix:
417 OS << '@';
418 break;
419 case ComdatPrefix:
420 OS << '$';
421 break;
422 case LabelPrefix:
423 break;
424 case LocalPrefix:
425 OS << '%';
426 break;
427 }
428 printLLVMNameWithoutPrefix(OS, Name);
429}
430
431/// Turn the specified name into an 'LLVM name', which is either prefixed with %
432/// (if the string only contains simple characters) or is surrounded with ""'s
433/// (if it has special chars in it). Print it out.
434static void PrintLLVMName(raw_ostream &OS, const Value *V) {
435 PrintLLVMName(OS, Name: V->getName(),
436 Prefix: isa<GlobalValue>(Val: V) ? GlobalPrefix : LocalPrefix);
437}
438
439static void PrintShuffleMask(raw_ostream &Out, Type *Ty, ArrayRef<int> Mask) {
440 Out << ", <";
441 if (isa<ScalableVectorType>(Val: Ty))
442 Out << "vscale x ";
443 Out << Mask.size() << " x i32> ";
444 bool FirstElt = true;
445 if (all_of(Range&: Mask, P: [](int Elt) { return Elt == 0; })) {
446 Out << "zeroinitializer";
447 } else if (all_of(Range&: Mask, P: [](int Elt) { return Elt == PoisonMaskElem; })) {
448 Out << "poison";
449 } else {
450 Out << "<";
451 for (int Elt : Mask) {
452 if (FirstElt)
453 FirstElt = false;
454 else
455 Out << ", ";
456 Out << "i32 ";
457 if (Elt == PoisonMaskElem)
458 Out << "poison";
459 else
460 Out << Elt;
461 }
462 Out << ">";
463 }
464}
465
466namespace {
467
468class TypePrinting {
469public:
470 TypePrinting(const Module *M = nullptr) : DeferredM(M) {}
471
472 TypePrinting(const TypePrinting &) = delete;
473 TypePrinting &operator=(const TypePrinting &) = delete;
474
475 /// The named types that are used by the current module.
476 TypeFinder &getNamedTypes();
477
478 /// The numbered types, number to type mapping.
479 std::vector<StructType *> &getNumberedTypes();
480
481 bool empty();
482
483 void print(Type *Ty, raw_ostream &OS);
484
485 void printStructBody(StructType *Ty, raw_ostream &OS);
486
487private:
488 void incorporateTypes();
489
490 /// A module to process lazily when needed. Set to nullptr as soon as used.
491 const Module *DeferredM;
492
493 TypeFinder NamedTypes;
494
495 // The numbered types, along with their value.
496 DenseMap<StructType *, unsigned> Type2Number;
497
498 std::vector<StructType *> NumberedTypes;
499};
500
501} // end anonymous namespace
502
503TypeFinder &TypePrinting::getNamedTypes() {
504 incorporateTypes();
505 return NamedTypes;
506}
507
508std::vector<StructType *> &TypePrinting::getNumberedTypes() {
509 incorporateTypes();
510
511 // We know all the numbers that each type is used and we know that it is a
512 // dense assignment. Convert the map to an index table, if it's not done
513 // already (judging from the sizes):
514 if (NumberedTypes.size() == Type2Number.size())
515 return NumberedTypes;
516
517 NumberedTypes.resize(new_size: Type2Number.size());
518 for (const auto &P : Type2Number) {
519 assert(P.second < NumberedTypes.size() && "Didn't get a dense numbering?");
520 assert(!NumberedTypes[P.second] && "Didn't get a unique numbering?");
521 NumberedTypes[P.second] = P.first;
522 }
523 return NumberedTypes;
524}
525
526bool TypePrinting::empty() {
527 incorporateTypes();
528 return NamedTypes.empty() && Type2Number.empty();
529}
530
531void TypePrinting::incorporateTypes() {
532 if (!DeferredM)
533 return;
534
535 NamedTypes.run(M: *DeferredM, onlyNamed: false);
536 DeferredM = nullptr;
537
538 // The list of struct types we got back includes all the struct types, split
539 // the unnamed ones out to a numbering and remove the anonymous structs.
540 unsigned NextNumber = 0;
541
542 std::vector<StructType *>::iterator NextToUse = NamedTypes.begin();
543 for (StructType *STy : NamedTypes) {
544 // Ignore anonymous types.
545 if (STy->isLiteral())
546 continue;
547
548 if (STy->getName().empty())
549 Type2Number[STy] = NextNumber++;
550 else
551 *NextToUse++ = STy;
552 }
553
554 NamedTypes.erase(I: NextToUse, E: NamedTypes.end());
555}
556
557/// Write the specified type to the specified raw_ostream, making use of type
558/// names or up references to shorten the type name where possible.
559void TypePrinting::print(Type *Ty, raw_ostream &OS) {
560 switch (Ty->getTypeID()) {
561 case Type::VoidTyID: OS << "void"; return;
562 case Type::HalfTyID: OS << "half"; return;
563 case Type::BFloatTyID: OS << "bfloat"; return;
564 case Type::FloatTyID: OS << "float"; return;
565 case Type::DoubleTyID: OS << "double"; return;
566 case Type::X86_FP80TyID: OS << "x86_fp80"; return;
567 case Type::FP128TyID: OS << "fp128"; return;
568 case Type::PPC_FP128TyID: OS << "ppc_fp128"; return;
569 case Type::LabelTyID: OS << "label"; return;
570 case Type::MetadataTyID: OS << "metadata"; return;
571 case Type::X86_MMXTyID: OS << "x86_mmx"; return;
572 case Type::X86_AMXTyID: OS << "x86_amx"; return;
573 case Type::TokenTyID: OS << "token"; return;
574 case Type::IntegerTyID:
575 OS << 'i' << cast<IntegerType>(Val: Ty)->getBitWidth();
576 return;
577
578 case Type::FunctionTyID: {
579 FunctionType *FTy = cast<FunctionType>(Val: Ty);
580 print(Ty: FTy->getReturnType(), OS);
581 OS << " (";
582 ListSeparator LS;
583 for (Type *Ty : FTy->params()) {
584 OS << LS;
585 print(Ty, OS);
586 }
587 if (FTy->isVarArg())
588 OS << LS << "...";
589 OS << ')';
590 return;
591 }
592 case Type::StructTyID: {
593 StructType *STy = cast<StructType>(Val: Ty);
594
595 if (STy->isLiteral())
596 return printStructBody(Ty: STy, OS);
597
598 if (!STy->getName().empty())
599 return PrintLLVMName(OS, Name: STy->getName(), Prefix: LocalPrefix);
600
601 incorporateTypes();
602 const auto I = Type2Number.find(Val: STy);
603 if (I != Type2Number.end())
604 OS << '%' << I->second;
605 else // Not enumerated, print the hex address.
606 OS << "%\"type " << STy << '\"';
607 return;
608 }
609 case Type::PointerTyID: {
610 PointerType *PTy = cast<PointerType>(Val: Ty);
611 OS << "ptr";
612 if (unsigned AddressSpace = PTy->getAddressSpace())
613 OS << " addrspace(" << AddressSpace << ')';
614 return;
615 }
616 case Type::ArrayTyID: {
617 ArrayType *ATy = cast<ArrayType>(Val: Ty);
618 OS << '[' << ATy->getNumElements() << " x ";
619 print(Ty: ATy->getElementType(), OS);
620 OS << ']';
621 return;
622 }
623 case Type::FixedVectorTyID:
624 case Type::ScalableVectorTyID: {
625 VectorType *PTy = cast<VectorType>(Val: Ty);
626 ElementCount EC = PTy->getElementCount();
627 OS << "<";
628 if (EC.isScalable())
629 OS << "vscale x ";
630 OS << EC.getKnownMinValue() << " x ";
631 print(Ty: PTy->getElementType(), OS);
632 OS << '>';
633 return;
634 }
635 case Type::TypedPointerTyID: {
636 TypedPointerType *TPTy = cast<TypedPointerType>(Val: Ty);
637 OS << "typedptr(" << *TPTy->getElementType() << ", "
638 << TPTy->getAddressSpace() << ")";
639 return;
640 }
641 case Type::TargetExtTyID:
642 TargetExtType *TETy = cast<TargetExtType>(Val: Ty);
643 OS << "target(\"";
644 printEscapedString(Name: Ty->getTargetExtName(), Out&: OS);
645 OS << "\"";
646 for (Type *Inner : TETy->type_params())
647 OS << ", " << *Inner;
648 for (unsigned IntParam : TETy->int_params())
649 OS << ", " << IntParam;
650 OS << ")";
651 return;
652 }
653 llvm_unreachable("Invalid TypeID");
654}
655
656void TypePrinting::printStructBody(StructType *STy, raw_ostream &OS) {
657 if (STy->isOpaque()) {
658 OS << "opaque";
659 return;
660 }
661
662 if (STy->isPacked())
663 OS << '<';
664
665 if (STy->getNumElements() == 0) {
666 OS << "{}";
667 } else {
668 OS << "{ ";
669 ListSeparator LS;
670 for (Type *Ty : STy->elements()) {
671 OS << LS;
672 print(Ty, OS);
673 }
674
675 OS << " }";
676 }
677 if (STy->isPacked())
678 OS << '>';
679}
680
681AbstractSlotTrackerStorage::~AbstractSlotTrackerStorage() = default;
682
683namespace llvm {
684
685//===----------------------------------------------------------------------===//
686// SlotTracker Class: Enumerate slot numbers for unnamed values
687//===----------------------------------------------------------------------===//
688/// This class provides computation of slot numbers for LLVM Assembly writing.
689///
690class SlotTracker : public AbstractSlotTrackerStorage {
691public:
692 /// ValueMap - A mapping of Values to slot numbers.
693 using ValueMap = DenseMap<const Value *, unsigned>;
694
695private:
696 /// TheModule - The module for which we are holding slot numbers.
697 const Module* TheModule;
698
699 /// TheFunction - The function for which we are holding slot numbers.
700 const Function* TheFunction = nullptr;
701 bool FunctionProcessed = false;
702 bool ShouldInitializeAllMetadata;
703
704 std::function<void(AbstractSlotTrackerStorage *, const Module *, bool)>
705 ProcessModuleHookFn;
706 std::function<void(AbstractSlotTrackerStorage *, const Function *, bool)>
707 ProcessFunctionHookFn;
708
709 /// The summary index for which we are holding slot numbers.
710 const ModuleSummaryIndex *TheIndex = nullptr;
711
712 /// mMap - The slot map for the module level data.
713 ValueMap mMap;
714 unsigned mNext = 0;
715
716 /// fMap - The slot map for the function level data.
717 ValueMap fMap;
718 unsigned fNext = 0;
719
720 /// mdnMap - Map for MDNodes.
721 DenseMap<const MDNode*, unsigned> mdnMap;
722 unsigned mdnNext = 0;
723
724 /// asMap - The slot map for attribute sets.
725 DenseMap<AttributeSet, unsigned> asMap;
726 unsigned asNext = 0;
727
728 /// ModulePathMap - The slot map for Module paths used in the summary index.
729 StringMap<unsigned> ModulePathMap;
730 unsigned ModulePathNext = 0;
731
732 /// GUIDMap - The slot map for GUIDs used in the summary index.
733 DenseMap<GlobalValue::GUID, unsigned> GUIDMap;
734 unsigned GUIDNext = 0;
735
736 /// TypeIdMap - The slot map for type ids used in the summary index.
737 StringMap<unsigned> TypeIdMap;
738 unsigned TypeIdNext = 0;
739
740 /// TypeIdCompatibleVtableMap - The slot map for type compatible vtable ids
741 /// used in the summary index.
742 StringMap<unsigned> TypeIdCompatibleVtableMap;
743 unsigned TypeIdCompatibleVtableNext = 0;
744
745public:
746 /// Construct from a module.
747 ///
748 /// If \c ShouldInitializeAllMetadata, initializes all metadata in all
749 /// functions, giving correct numbering for metadata referenced only from
750 /// within a function (even if no functions have been initialized).
751 explicit SlotTracker(const Module *M,
752 bool ShouldInitializeAllMetadata = false);
753
754 /// Construct from a function, starting out in incorp state.
755 ///
756 /// If \c ShouldInitializeAllMetadata, initializes all metadata in all
757 /// functions, giving correct numbering for metadata referenced only from
758 /// within a function (even if no functions have been initialized).
759 explicit SlotTracker(const Function *F,
760 bool ShouldInitializeAllMetadata = false);
761
762 /// Construct from a module summary index.
763 explicit SlotTracker(const ModuleSummaryIndex *Index);
764
765 SlotTracker(const SlotTracker &) = delete;
766 SlotTracker &operator=(const SlotTracker &) = delete;
767
768 ~SlotTracker() = default;
769
770 void setProcessHook(
771 std::function<void(AbstractSlotTrackerStorage *, const Module *, bool)>);
772 void setProcessHook(std::function<void(AbstractSlotTrackerStorage *,
773 const Function *, bool)>);
774
775 unsigned getNextMetadataSlot() override { return mdnNext; }
776
777 void createMetadataSlot(const MDNode *N) override;
778
779 /// Return the slot number of the specified value in it's type
780 /// plane. If something is not in the SlotTracker, return -1.
781 int getLocalSlot(const Value *V);
782 int getGlobalSlot(const GlobalValue *V);
783 int getMetadataSlot(const MDNode *N) override;
784 int getAttributeGroupSlot(AttributeSet AS);
785 int getModulePathSlot(StringRef Path);
786 int getGUIDSlot(GlobalValue::GUID GUID);
787 int getTypeIdSlot(StringRef Id);
788 int getTypeIdCompatibleVtableSlot(StringRef Id);
789
790 /// If you'd like to deal with a function instead of just a module, use
791 /// this method to get its data into the SlotTracker.
792 void incorporateFunction(const Function *F) {
793 TheFunction = F;
794 FunctionProcessed = false;
795 }
796
797 const Function *getFunction() const { return TheFunction; }
798
799 /// After calling incorporateFunction, use this method to remove the
800 /// most recently incorporated function from the SlotTracker. This
801 /// will reset the state of the machine back to just the module contents.
802 void purgeFunction();
803
804 /// MDNode map iterators.
805 using mdn_iterator = DenseMap<const MDNode*, unsigned>::iterator;
806
807 mdn_iterator mdn_begin() { return mdnMap.begin(); }
808 mdn_iterator mdn_end() { return mdnMap.end(); }
809 unsigned mdn_size() const { return mdnMap.size(); }
810 bool mdn_empty() const { return mdnMap.empty(); }
811
812 /// AttributeSet map iterators.
813 using as_iterator = DenseMap<AttributeSet, unsigned>::iterator;
814
815 as_iterator as_begin() { return asMap.begin(); }
816 as_iterator as_end() { return asMap.end(); }
817 unsigned as_size() const { return asMap.size(); }
818 bool as_empty() const { return asMap.empty(); }
819
820 /// GUID map iterators.
821 using guid_iterator = DenseMap<GlobalValue::GUID, unsigned>::iterator;
822
823 /// These functions do the actual initialization.
824 inline void initializeIfNeeded();
825 int initializeIndexIfNeeded();
826
827 // Implementation Details
828private:
829 /// CreateModuleSlot - Insert the specified GlobalValue* into the slot table.
830 void CreateModuleSlot(const GlobalValue *V);
831
832 /// CreateMetadataSlot - Insert the specified MDNode* into the slot table.
833 void CreateMetadataSlot(const MDNode *N);
834
835 /// CreateFunctionSlot - Insert the specified Value* into the slot table.
836 void CreateFunctionSlot(const Value *V);
837
838 /// Insert the specified AttributeSet into the slot table.
839 void CreateAttributeSetSlot(AttributeSet AS);
840
841 inline void CreateModulePathSlot(StringRef Path);
842 void CreateGUIDSlot(GlobalValue::GUID GUID);
843 void CreateTypeIdSlot(StringRef Id);
844 void CreateTypeIdCompatibleVtableSlot(StringRef Id);
845
846 /// Add all of the module level global variables (and their initializers)
847 /// and function declarations, but not the contents of those functions.
848 void processModule();
849 // Returns number of allocated slots
850 int processIndex();
851
852 /// Add all of the functions arguments, basic blocks, and instructions.
853 void processFunction();
854
855 /// Add the metadata directly attached to a GlobalObject.
856 void processGlobalObjectMetadata(const GlobalObject &GO);
857
858 /// Add all of the metadata from a function.
859 void processFunctionMetadata(const Function &F);
860
861 /// Add all of the metadata from an instruction.
862 void processInstructionMetadata(const Instruction &I);
863
864 /// Add all of the metadata from an instruction.
865 void processDPValueMetadata(const DPValue &DPV);
866};
867
868} // end namespace llvm
869
870ModuleSlotTracker::ModuleSlotTracker(SlotTracker &Machine, const Module *M,
871 const Function *F)
872 : M(M), F(F), Machine(&Machine) {}
873
874ModuleSlotTracker::ModuleSlotTracker(const Module *M,
875 bool ShouldInitializeAllMetadata)
876 : ShouldCreateStorage(M),
877 ShouldInitializeAllMetadata(ShouldInitializeAllMetadata), M(M) {}
878
879ModuleSlotTracker::~ModuleSlotTracker() = default;
880
881SlotTracker *ModuleSlotTracker::getMachine() {
882 if (!ShouldCreateStorage)
883 return Machine;
884
885 ShouldCreateStorage = false;
886 MachineStorage =
887 std::make_unique<SlotTracker>(args&: M, args&: ShouldInitializeAllMetadata);
888 Machine = MachineStorage.get();
889 if (ProcessModuleHookFn)
890 Machine->setProcessHook(ProcessModuleHookFn);
891 if (ProcessFunctionHookFn)
892 Machine->setProcessHook(ProcessFunctionHookFn);
893 return Machine;
894}
895
896void ModuleSlotTracker::incorporateFunction(const Function &F) {
897 // Using getMachine() may lazily create the slot tracker.
898 if (!getMachine())
899 return;
900
901 // Nothing to do if this is the right function already.
902 if (this->F == &F)
903 return;
904 if (this->F)
905 Machine->purgeFunction();
906 Machine->incorporateFunction(F: &F);
907 this->F = &F;
908}
909
910int ModuleSlotTracker::getLocalSlot(const Value *V) {
911 assert(F && "No function incorporated");
912 return Machine->getLocalSlot(V);
913}
914
915void ModuleSlotTracker::setProcessHook(
916 std::function<void(AbstractSlotTrackerStorage *, const Module *, bool)>
917 Fn) {
918 ProcessModuleHookFn = Fn;
919}
920
921void ModuleSlotTracker::setProcessHook(
922 std::function<void(AbstractSlotTrackerStorage *, const Function *, bool)>
923 Fn) {
924 ProcessFunctionHookFn = Fn;
925}
926
927static SlotTracker *createSlotTracker(const Value *V) {
928 if (const Argument *FA = dyn_cast<Argument>(Val: V))
929 return new SlotTracker(FA->getParent());
930
931 if (const Instruction *I = dyn_cast<Instruction>(Val: V))
932 if (I->getParent())
933 return new SlotTracker(I->getParent()->getParent());
934
935 if (const BasicBlock *BB = dyn_cast<BasicBlock>(Val: V))
936 return new SlotTracker(BB->getParent());
937
938 if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Val: V))
939 return new SlotTracker(GV->getParent());
940
941 if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(Val: V))
942 return new SlotTracker(GA->getParent());
943
944 if (const GlobalIFunc *GIF = dyn_cast<GlobalIFunc>(Val: V))
945 return new SlotTracker(GIF->getParent());
946
947 if (const Function *Func = dyn_cast<Function>(Val: V))
948 return new SlotTracker(Func);
949
950 return nullptr;
951}
952
953#if 0
954#define ST_DEBUG(X) dbgs() << X
955#else
956#define ST_DEBUG(X)
957#endif
958
959// Module level constructor. Causes the contents of the Module (sans functions)
960// to be added to the slot table.
961SlotTracker::SlotTracker(const Module *M, bool ShouldInitializeAllMetadata)
962 : TheModule(M), ShouldInitializeAllMetadata(ShouldInitializeAllMetadata) {}
963
964// Function level constructor. Causes the contents of the Module and the one
965// function provided to be added to the slot table.
966SlotTracker::SlotTracker(const Function *F, bool ShouldInitializeAllMetadata)
967 : TheModule(F ? F->getParent() : nullptr), TheFunction(F),
968 ShouldInitializeAllMetadata(ShouldInitializeAllMetadata) {}
969
970SlotTracker::SlotTracker(const ModuleSummaryIndex *Index)
971 : TheModule(nullptr), ShouldInitializeAllMetadata(false), TheIndex(Index) {}
972
973inline void SlotTracker::initializeIfNeeded() {
974 if (TheModule) {
975 processModule();
976 TheModule = nullptr; ///< Prevent re-processing next time we're called.
977 }
978
979 if (TheFunction && !FunctionProcessed)
980 processFunction();
981}
982
983int SlotTracker::initializeIndexIfNeeded() {
984 if (!TheIndex)
985 return 0;
986 int NumSlots = processIndex();
987 TheIndex = nullptr; ///< Prevent re-processing next time we're called.
988 return NumSlots;
989}
990
991// Iterate through all the global variables, functions, and global
992// variable initializers and create slots for them.
993void SlotTracker::processModule() {
994 ST_DEBUG("begin processModule!\n");
995
996 // Add all of the unnamed global variables to the value table.
997 for (const GlobalVariable &Var : TheModule->globals()) {
998 if (!Var.hasName())
999 CreateModuleSlot(V: &Var);
1000 processGlobalObjectMetadata(GO: Var);
1001 auto Attrs = Var.getAttributes();
1002 if (Attrs.hasAttributes())
1003 CreateAttributeSetSlot(AS: Attrs);
1004 }
1005
1006 for (const GlobalAlias &A : TheModule->aliases()) {
1007 if (!A.hasName())
1008 CreateModuleSlot(V: &A);
1009 }
1010
1011 for (const GlobalIFunc &I : TheModule->ifuncs()) {
1012 if (!I.hasName())
1013 CreateModuleSlot(V: &I);
1014 }
1015
1016 // Add metadata used by named metadata.
1017 for (const NamedMDNode &NMD : TheModule->named_metadata()) {
1018 for (unsigned i = 0, e = NMD.getNumOperands(); i != e; ++i)
1019 CreateMetadataSlot(N: NMD.getOperand(i));
1020 }
1021
1022 for (const Function &F : *TheModule) {
1023 if (!F.hasName())
1024 // Add all the unnamed functions to the table.
1025 CreateModuleSlot(V: &F);
1026
1027 if (ShouldInitializeAllMetadata)
1028 processFunctionMetadata(F);
1029
1030 // Add all the function attributes to the table.
1031 // FIXME: Add attributes of other objects?
1032 AttributeSet FnAttrs = F.getAttributes().getFnAttrs();
1033 if (FnAttrs.hasAttributes())
1034 CreateAttributeSetSlot(AS: FnAttrs);
1035 }
1036
1037 if (ProcessModuleHookFn)
1038 ProcessModuleHookFn(this, TheModule, ShouldInitializeAllMetadata);
1039
1040 ST_DEBUG("end processModule!\n");
1041}
1042
1043// Process the arguments, basic blocks, and instructions of a function.
1044void SlotTracker::processFunction() {
1045 ST_DEBUG("begin processFunction!\n");
1046 fNext = 0;
1047
1048 // Process function metadata if it wasn't hit at the module-level.
1049 if (!ShouldInitializeAllMetadata)
1050 processFunctionMetadata(F: *TheFunction);
1051
1052 // Add all the function arguments with no names.
1053 for(Function::const_arg_iterator AI = TheFunction->arg_begin(),
1054 AE = TheFunction->arg_end(); AI != AE; ++AI)
1055 if (!AI->hasName())
1056 CreateFunctionSlot(V: &*AI);
1057
1058 ST_DEBUG("Inserting Instructions:\n");
1059
1060 // Add all of the basic blocks and instructions with no names.
1061 for (auto &BB : *TheFunction) {
1062 if (!BB.hasName())
1063 CreateFunctionSlot(V: &BB);
1064
1065 for (auto &I : BB) {
1066 if (!I.getType()->isVoidTy() && !I.hasName())
1067 CreateFunctionSlot(V: &I);
1068
1069 // We allow direct calls to any llvm.foo function here, because the
1070 // target may not be linked into the optimizer.
1071 if (const auto *Call = dyn_cast<CallBase>(Val: &I)) {
1072 // Add all the call attributes to the table.
1073 AttributeSet Attrs = Call->getAttributes().getFnAttrs();
1074 if (Attrs.hasAttributes())
1075 CreateAttributeSetSlot(AS: Attrs);
1076 }
1077 }
1078 }
1079
1080 if (ProcessFunctionHookFn)
1081 ProcessFunctionHookFn(this, TheFunction, ShouldInitializeAllMetadata);
1082
1083 FunctionProcessed = true;
1084
1085 ST_DEBUG("end processFunction!\n");
1086}
1087
1088// Iterate through all the GUID in the index and create slots for them.
1089int SlotTracker::processIndex() {
1090 ST_DEBUG("begin processIndex!\n");
1091 assert(TheIndex);
1092
1093 // The first block of slots are just the module ids, which start at 0 and are
1094 // assigned consecutively. Since the StringMap iteration order isn't
1095 // guaranteed, order by path string before assigning slots.
1096 std::vector<StringRef> ModulePaths;
1097 for (auto &[ModPath, _] : TheIndex->modulePaths())
1098 ModulePaths.push_back(x: ModPath);
1099 llvm::sort(Start: ModulePaths.begin(), End: ModulePaths.end());
1100 for (auto &ModPath : ModulePaths)
1101 CreateModulePathSlot(Path: ModPath);
1102
1103 // Start numbering the GUIDs after the module ids.
1104 GUIDNext = ModulePathNext;
1105
1106 for (auto &GlobalList : *TheIndex)
1107 CreateGUIDSlot(GUID: GlobalList.first);
1108
1109 // Start numbering the TypeIdCompatibleVtables after the GUIDs.
1110 TypeIdCompatibleVtableNext = GUIDNext;
1111 for (auto &TId : TheIndex->typeIdCompatibleVtableMap())
1112 CreateTypeIdCompatibleVtableSlot(Id: TId.first);
1113
1114 // Start numbering the TypeIds after the TypeIdCompatibleVtables.
1115 TypeIdNext = TypeIdCompatibleVtableNext;
1116 for (const auto &TID : TheIndex->typeIds())
1117 CreateTypeIdSlot(Id: TID.second.first);
1118
1119 ST_DEBUG("end processIndex!\n");
1120 return TypeIdNext;
1121}
1122
1123void SlotTracker::processGlobalObjectMetadata(const GlobalObject &GO) {
1124 SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
1125 GO.getAllMetadata(MDs);
1126 for (auto &MD : MDs)
1127 CreateMetadataSlot(N: MD.second);
1128}
1129
1130void SlotTracker::processFunctionMetadata(const Function &F) {
1131 processGlobalObjectMetadata(GO: F);
1132 for (auto &BB : F) {
1133 for (auto &I : BB) {
1134 for (const DPValue &DPV : I.getDbgValueRange())
1135 processDPValueMetadata(DPV);
1136 processInstructionMetadata(I);
1137 }
1138 }
1139}
1140
1141void SlotTracker::processDPValueMetadata(const DPValue &DPV) {
1142 CreateMetadataSlot(N: DPV.getVariable());
1143 CreateMetadataSlot(N: DPV.getDebugLoc());
1144 if (DPV.isDbgAssign()) {
1145 CreateMetadataSlot(N: DPV.getAssignID());
1146 }
1147}
1148
1149void SlotTracker::processInstructionMetadata(const Instruction &I) {
1150 // Process metadata used directly by intrinsics.
1151 if (const CallInst *CI = dyn_cast<CallInst>(Val: &I))
1152 if (Function *F = CI->getCalledFunction())
1153 if (F->isIntrinsic())
1154 for (auto &Op : I.operands())
1155 if (auto *V = dyn_cast_or_null<MetadataAsValue>(Val: Op))
1156 if (MDNode *N = dyn_cast<MDNode>(Val: V->getMetadata()))
1157 CreateMetadataSlot(N);
1158
1159 // Process metadata attached to this instruction.
1160 SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
1161 I.getAllMetadata(MDs);
1162 for (auto &MD : MDs)
1163 CreateMetadataSlot(N: MD.second);
1164}
1165
1166/// Clean up after incorporating a function. This is the only way to get out of
1167/// the function incorporation state that affects get*Slot/Create*Slot. Function
1168/// incorporation state is indicated by TheFunction != 0.
1169void SlotTracker::purgeFunction() {
1170 ST_DEBUG("begin purgeFunction!\n");
1171 fMap.clear(); // Simply discard the function level map
1172 TheFunction = nullptr;
1173 FunctionProcessed = false;
1174 ST_DEBUG("end purgeFunction!\n");
1175}
1176
1177/// getGlobalSlot - Get the slot number of a global value.
1178int SlotTracker::getGlobalSlot(const GlobalValue *V) {
1179 // Check for uninitialized state and do lazy initialization.
1180 initializeIfNeeded();
1181
1182 // Find the value in the module map
1183 ValueMap::iterator MI = mMap.find(Val: V);
1184 return MI == mMap.end() ? -1 : (int)MI->second;
1185}
1186
1187void SlotTracker::setProcessHook(
1188 std::function<void(AbstractSlotTrackerStorage *, const Module *, bool)>
1189 Fn) {
1190 ProcessModuleHookFn = Fn;
1191}
1192
1193void SlotTracker::setProcessHook(
1194 std::function<void(AbstractSlotTrackerStorage *, const Function *, bool)>
1195 Fn) {
1196 ProcessFunctionHookFn = Fn;
1197}
1198
1199/// getMetadataSlot - Get the slot number of a MDNode.
1200void SlotTracker::createMetadataSlot(const MDNode *N) { CreateMetadataSlot(N); }
1201
1202/// getMetadataSlot - Get the slot number of a MDNode.
1203int SlotTracker::getMetadataSlot(const MDNode *N) {
1204 // Check for uninitialized state and do lazy initialization.
1205 initializeIfNeeded();
1206
1207 // Find the MDNode in the module map
1208 mdn_iterator MI = mdnMap.find(Val: N);
1209 return MI == mdnMap.end() ? -1 : (int)MI->second;
1210}
1211
1212/// getLocalSlot - Get the slot number for a value that is local to a function.
1213int SlotTracker::getLocalSlot(const Value *V) {
1214 assert(!isa<Constant>(V) && "Can't get a constant or global slot with this!");
1215
1216 // Check for uninitialized state and do lazy initialization.
1217 initializeIfNeeded();
1218
1219 ValueMap::iterator FI = fMap.find(Val: V);
1220 return FI == fMap.end() ? -1 : (int)FI->second;
1221}
1222
1223int SlotTracker::getAttributeGroupSlot(AttributeSet AS) {
1224 // Check for uninitialized state and do lazy initialization.
1225 initializeIfNeeded();
1226
1227 // Find the AttributeSet in the module map.
1228 as_iterator AI = asMap.find(Val: AS);
1229 return AI == asMap.end() ? -1 : (int)AI->second;
1230}
1231
1232int SlotTracker::getModulePathSlot(StringRef Path) {
1233 // Check for uninitialized state and do lazy initialization.
1234 initializeIndexIfNeeded();
1235
1236 // Find the Module path in the map
1237 auto I = ModulePathMap.find(Key: Path);
1238 return I == ModulePathMap.end() ? -1 : (int)I->second;
1239}
1240
1241int SlotTracker::getGUIDSlot(GlobalValue::GUID GUID) {
1242 // Check for uninitialized state and do lazy initialization.
1243 initializeIndexIfNeeded();
1244
1245 // Find the GUID in the map
1246 guid_iterator I = GUIDMap.find(Val: GUID);
1247 return I == GUIDMap.end() ? -1 : (int)I->second;
1248}
1249
1250int SlotTracker::getTypeIdSlot(StringRef Id) {
1251 // Check for uninitialized state and do lazy initialization.
1252 initializeIndexIfNeeded();
1253
1254 // Find the TypeId string in the map
1255 auto I = TypeIdMap.find(Key: Id);
1256 return I == TypeIdMap.end() ? -1 : (int)I->second;
1257}
1258
1259int SlotTracker::getTypeIdCompatibleVtableSlot(StringRef Id) {
1260 // Check for uninitialized state and do lazy initialization.
1261 initializeIndexIfNeeded();
1262
1263 // Find the TypeIdCompatibleVtable string in the map
1264 auto I = TypeIdCompatibleVtableMap.find(Key: Id);
1265 return I == TypeIdCompatibleVtableMap.end() ? -1 : (int)I->second;
1266}
1267
1268/// CreateModuleSlot - Insert the specified GlobalValue* into the slot table.
1269void SlotTracker::CreateModuleSlot(const GlobalValue *V) {
1270 assert(V && "Can't insert a null Value into SlotTracker!");
1271 assert(!V->getType()->isVoidTy() && "Doesn't need a slot!");
1272 assert(!V->hasName() && "Doesn't need a slot!");
1273
1274 unsigned DestSlot = mNext++;
1275 mMap[V] = DestSlot;
1276
1277 ST_DEBUG(" Inserting value [" << V->getType() << "] = " << V << " slot=" <<
1278 DestSlot << " [");
1279 // G = Global, F = Function, A = Alias, I = IFunc, o = other
1280 ST_DEBUG((isa<GlobalVariable>(V) ? 'G' :
1281 (isa<Function>(V) ? 'F' :
1282 (isa<GlobalAlias>(V) ? 'A' :
1283 (isa<GlobalIFunc>(V) ? 'I' : 'o')))) << "]\n");
1284}
1285
1286/// CreateSlot - Create a new slot for the specified value if it has no name.
1287void SlotTracker::CreateFunctionSlot(const Value *V) {
1288 assert(!V->getType()->isVoidTy() && !V->hasName() && "Doesn't need a slot!");
1289
1290 unsigned DestSlot = fNext++;
1291 fMap[V] = DestSlot;
1292
1293 // G = Global, F = Function, o = other
1294 ST_DEBUG(" Inserting value [" << V->getType() << "] = " << V << " slot=" <<
1295 DestSlot << " [o]\n");
1296}
1297
1298/// CreateModuleSlot - Insert the specified MDNode* into the slot table.
1299void SlotTracker::CreateMetadataSlot(const MDNode *N) {
1300 assert(N && "Can't insert a null Value into SlotTracker!");
1301
1302 // Don't make slots for DIExpressions. We just print them inline everywhere.
1303 if (isa<DIExpression>(Val: N))
1304 return;
1305
1306 unsigned DestSlot = mdnNext;
1307 if (!mdnMap.insert(KV: std::make_pair(x&: N, y&: DestSlot)).second)
1308 return;
1309 ++mdnNext;
1310
1311 // Recursively add any MDNodes referenced by operands.
1312 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
1313 if (const MDNode *Op = dyn_cast_or_null<MDNode>(Val: N->getOperand(I: i)))
1314 CreateMetadataSlot(N: Op);
1315}
1316
1317void SlotTracker::CreateAttributeSetSlot(AttributeSet AS) {
1318 assert(AS.hasAttributes() && "Doesn't need a slot!");
1319
1320 as_iterator I = asMap.find(Val: AS);
1321 if (I != asMap.end())
1322 return;
1323
1324 unsigned DestSlot = asNext++;
1325 asMap[AS] = DestSlot;
1326}
1327
1328/// Create a new slot for the specified Module
1329void SlotTracker::CreateModulePathSlot(StringRef Path) {
1330 ModulePathMap[Path] = ModulePathNext++;
1331}
1332
1333/// Create a new slot for the specified GUID
1334void SlotTracker::CreateGUIDSlot(GlobalValue::GUID GUID) {
1335 GUIDMap[GUID] = GUIDNext++;
1336}
1337
1338/// Create a new slot for the specified Id
1339void SlotTracker::CreateTypeIdSlot(StringRef Id) {
1340 TypeIdMap[Id] = TypeIdNext++;
1341}
1342
1343/// Create a new slot for the specified Id
1344void SlotTracker::CreateTypeIdCompatibleVtableSlot(StringRef Id) {
1345 TypeIdCompatibleVtableMap[Id] = TypeIdCompatibleVtableNext++;
1346}
1347
1348namespace {
1349/// Common instances used by most of the printer functions.
1350struct AsmWriterContext {
1351 TypePrinting *TypePrinter = nullptr;
1352 SlotTracker *Machine = nullptr;
1353 const Module *Context = nullptr;
1354
1355 AsmWriterContext(TypePrinting *TP, SlotTracker *ST, const Module *M = nullptr)
1356 : TypePrinter(TP), Machine(ST), Context(M) {}
1357
1358 static AsmWriterContext &getEmpty() {
1359 static AsmWriterContext EmptyCtx(nullptr, nullptr);
1360 return EmptyCtx;
1361 }
1362
1363 /// A callback that will be triggered when the underlying printer
1364 /// prints a Metadata as operand.
1365 virtual void onWriteMetadataAsOperand(const Metadata *) {}
1366
1367 virtual ~AsmWriterContext() = default;
1368};
1369} // end anonymous namespace
1370
1371//===----------------------------------------------------------------------===//
1372// AsmWriter Implementation
1373//===----------------------------------------------------------------------===//
1374
1375static void WriteAsOperandInternal(raw_ostream &Out, const Value *V,
1376 AsmWriterContext &WriterCtx);
1377
1378static void WriteAsOperandInternal(raw_ostream &Out, const Metadata *MD,
1379 AsmWriterContext &WriterCtx,
1380 bool FromValue = false);
1381
1382static void WriteOptimizationInfo(raw_ostream &Out, const User *U) {
1383 if (const FPMathOperator *FPO = dyn_cast<const FPMathOperator>(Val: U))
1384 Out << FPO->getFastMathFlags();
1385
1386 if (const OverflowingBinaryOperator *OBO =
1387 dyn_cast<OverflowingBinaryOperator>(Val: U)) {
1388 if (OBO->hasNoUnsignedWrap())
1389 Out << " nuw";
1390 if (OBO->hasNoSignedWrap())
1391 Out << " nsw";
1392 } else if (const PossiblyExactOperator *Div =
1393 dyn_cast<PossiblyExactOperator>(Val: U)) {
1394 if (Div->isExact())
1395 Out << " exact";
1396 } else if (const PossiblyDisjointInst *PDI =
1397 dyn_cast<PossiblyDisjointInst>(Val: U)) {
1398 if (PDI->isDisjoint())
1399 Out << " disjoint";
1400 } else if (const GEPOperator *GEP = dyn_cast<GEPOperator>(Val: U)) {
1401 if (GEP->isInBounds())
1402 Out << " inbounds";
1403 } else if (const auto *NNI = dyn_cast<PossiblyNonNegInst>(Val: U)) {
1404 if (NNI->hasNonNeg())
1405 Out << " nneg";
1406 }
1407}
1408
1409static void WriteAPFloatInternal(raw_ostream &Out, const APFloat &APF) {
1410 if (&APF.getSemantics() == &APFloat::IEEEsingle() ||
1411 &APF.getSemantics() == &APFloat::IEEEdouble()) {
1412 // We would like to output the FP constant value in exponential notation,
1413 // but we cannot do this if doing so will lose precision. Check here to
1414 // make sure that we only output it in exponential format if we can parse
1415 // the value back and get the same value.
1416 //
1417 bool ignored;
1418 bool isDouble = &APF.getSemantics() == &APFloat::IEEEdouble();
1419 bool isInf = APF.isInfinity();
1420 bool isNaN = APF.isNaN();
1421
1422 if (!isInf && !isNaN) {
1423 double Val = APF.convertToDouble();
1424 SmallString<128> StrVal;
1425 APF.toString(Str&: StrVal, FormatPrecision: 6, FormatMaxPadding: 0, TruncateZero: false);
1426 // Check to make sure that the stringized number is not some string like
1427 // "Inf" or NaN, that atof will accept, but the lexer will not. Check
1428 // that the string matches the "[-+]?[0-9]" regex.
1429 //
1430 assert((isDigit(StrVal[0]) ||
1431 ((StrVal[0] == '-' || StrVal[0] == '+') && isDigit(StrVal[1]))) &&
1432 "[-+]?[0-9] regex does not match!");
1433 // Reparse stringized version!
1434 if (APFloat(APFloat::IEEEdouble(), StrVal).convertToDouble() == Val) {
1435 Out << StrVal;
1436 return;
1437 }
1438 }
1439
1440 // Otherwise we could not reparse it to exactly the same value, so we must
1441 // output the string in hexadecimal format! Note that loading and storing
1442 // floating point types changes the bits of NaNs on some hosts, notably
1443 // x86, so we must not use these types.
1444 static_assert(sizeof(double) == sizeof(uint64_t),
1445 "assuming that double is 64 bits!");
1446 APFloat apf = APF;
1447
1448 // Floats are represented in ASCII IR as double, convert.
1449 // FIXME: We should allow 32-bit hex float and remove this.
1450 if (!isDouble) {
1451 // A signaling NaN is quieted on conversion, so we need to recreate the
1452 // expected value after convert (quiet bit of the payload is clear).
1453 bool IsSNAN = apf.isSignaling();
1454 apf.convert(ToSemantics: APFloat::IEEEdouble(), RM: APFloat::rmNearestTiesToEven,
1455 losesInfo: &ignored);
1456 if (IsSNAN) {
1457 APInt Payload = apf.bitcastToAPInt();
1458 apf =
1459 APFloat::getSNaN(Sem: APFloat::IEEEdouble(), Negative: apf.isNegative(), payload: &Payload);
1460 }
1461 }
1462
1463 Out << format_hex(N: apf.bitcastToAPInt().getZExtValue(), Width: 0, /*Upper=*/true);
1464 return;
1465 }
1466
1467 // Either half, bfloat or some form of long double.
1468 // These appear as a magic letter identifying the type, then a
1469 // fixed number of hex digits.
1470 Out << "0x";
1471 APInt API = APF.bitcastToAPInt();
1472 if (&APF.getSemantics() == &APFloat::x87DoubleExtended()) {
1473 Out << 'K';
1474 Out << format_hex_no_prefix(N: API.getHiBits(numBits: 16).getZExtValue(), Width: 4,
1475 /*Upper=*/true);
1476 Out << format_hex_no_prefix(N: API.getLoBits(numBits: 64).getZExtValue(), Width: 16,
1477 /*Upper=*/true);
1478 } else if (&APF.getSemantics() == &APFloat::IEEEquad()) {
1479 Out << 'L';
1480 Out << format_hex_no_prefix(N: API.getLoBits(numBits: 64).getZExtValue(), Width: 16,
1481 /*Upper=*/true);
1482 Out << format_hex_no_prefix(N: API.getHiBits(numBits: 64).getZExtValue(), Width: 16,
1483 /*Upper=*/true);
1484 } else if (&APF.getSemantics() == &APFloat::PPCDoubleDouble()) {
1485 Out << 'M';
1486 Out << format_hex_no_prefix(N: API.getLoBits(numBits: 64).getZExtValue(), Width: 16,
1487 /*Upper=*/true);
1488 Out << format_hex_no_prefix(N: API.getHiBits(numBits: 64).getZExtValue(), Width: 16,
1489 /*Upper=*/true);
1490 } else if (&APF.getSemantics() == &APFloat::IEEEhalf()) {
1491 Out << 'H';
1492 Out << format_hex_no_prefix(N: API.getZExtValue(), Width: 4,
1493 /*Upper=*/true);
1494 } else if (&APF.getSemantics() == &APFloat::BFloat()) {
1495 Out << 'R';
1496 Out << format_hex_no_prefix(N: API.getZExtValue(), Width: 4,
1497 /*Upper=*/true);
1498 } else
1499 llvm_unreachable("Unsupported floating point type");
1500}
1501
1502static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
1503 AsmWriterContext &WriterCtx) {
1504 if (const ConstantInt *CI = dyn_cast<ConstantInt>(Val: CV)) {
1505 if (CI->getType()->isIntegerTy(Bitwidth: 1)) {
1506 Out << (CI->getZExtValue() ? "true" : "false");
1507 return;
1508 }
1509 Out << CI->getValue();
1510 return;
1511 }
1512
1513 if (const ConstantFP *CFP = dyn_cast<ConstantFP>(Val: CV)) {
1514 WriteAPFloatInternal(Out, APF: CFP->getValueAPF());
1515 return;
1516 }
1517
1518 if (isa<ConstantAggregateZero>(Val: CV) || isa<ConstantTargetNone>(Val: CV)) {
1519 Out << "zeroinitializer";
1520 return;
1521 }
1522
1523 if (const BlockAddress *BA = dyn_cast<BlockAddress>(Val: CV)) {
1524 Out << "blockaddress(";
1525 WriteAsOperandInternal(Out, V: BA->getFunction(), WriterCtx);
1526 Out << ", ";
1527 WriteAsOperandInternal(Out, V: BA->getBasicBlock(), WriterCtx);
1528 Out << ")";
1529 return;
1530 }
1531
1532 if (const auto *Equiv = dyn_cast<DSOLocalEquivalent>(Val: CV)) {
1533 Out << "dso_local_equivalent ";
1534 WriteAsOperandInternal(Out, V: Equiv->getGlobalValue(), WriterCtx);
1535 return;
1536 }
1537
1538 if (const auto *NC = dyn_cast<NoCFIValue>(Val: CV)) {
1539 Out << "no_cfi ";
1540 WriteAsOperandInternal(Out, V: NC->getGlobalValue(), WriterCtx);
1541 return;
1542 }
1543
1544 if (const ConstantArray *CA = dyn_cast<ConstantArray>(Val: CV)) {
1545 Type *ETy = CA->getType()->getElementType();
1546 Out << '[';
1547 WriterCtx.TypePrinter->print(Ty: ETy, OS&: Out);
1548 Out << ' ';
1549 WriteAsOperandInternal(Out, V: CA->getOperand(i_nocapture: 0), WriterCtx);
1550 for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) {
1551 Out << ", ";
1552 WriterCtx.TypePrinter->print(Ty: ETy, OS&: Out);
1553 Out << ' ';
1554 WriteAsOperandInternal(Out, V: CA->getOperand(i_nocapture: i), WriterCtx);
1555 }
1556 Out << ']';
1557 return;
1558 }
1559
1560 if (const ConstantDataArray *CA = dyn_cast<ConstantDataArray>(Val: CV)) {
1561 // As a special case, print the array as a string if it is an array of
1562 // i8 with ConstantInt values.
1563 if (CA->isString()) {
1564 Out << "c\"";
1565 printEscapedString(Name: CA->getAsString(), Out);
1566 Out << '"';
1567 return;
1568 }
1569
1570 Type *ETy = CA->getType()->getElementType();
1571 Out << '[';
1572 WriterCtx.TypePrinter->print(Ty: ETy, OS&: Out);
1573 Out << ' ';
1574 WriteAsOperandInternal(Out, V: CA->getElementAsConstant(i: 0), WriterCtx);
1575 for (unsigned i = 1, e = CA->getNumElements(); i != e; ++i) {
1576 Out << ", ";
1577 WriterCtx.TypePrinter->print(Ty: ETy, OS&: Out);
1578 Out << ' ';
1579 WriteAsOperandInternal(Out, V: CA->getElementAsConstant(i), WriterCtx);
1580 }
1581 Out << ']';
1582 return;
1583 }
1584
1585 if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(Val: CV)) {
1586 if (CS->getType()->isPacked())
1587 Out << '<';
1588 Out << '{';
1589 unsigned N = CS->getNumOperands();
1590 if (N) {
1591 Out << ' ';
1592 WriterCtx.TypePrinter->print(Ty: CS->getOperand(i_nocapture: 0)->getType(), OS&: Out);
1593 Out << ' ';
1594
1595 WriteAsOperandInternal(Out, V: CS->getOperand(i_nocapture: 0), WriterCtx);
1596
1597 for (unsigned i = 1; i < N; i++) {
1598 Out << ", ";
1599 WriterCtx.TypePrinter->print(Ty: CS->getOperand(i_nocapture: i)->getType(), OS&: Out);
1600 Out << ' ';
1601
1602 WriteAsOperandInternal(Out, V: CS->getOperand(i_nocapture: i), WriterCtx);
1603 }
1604 Out << ' ';
1605 }
1606
1607 Out << '}';
1608 if (CS->getType()->isPacked())
1609 Out << '>';
1610 return;
1611 }
1612
1613 if (isa<ConstantVector>(Val: CV) || isa<ConstantDataVector>(Val: CV)) {
1614 auto *CVVTy = cast<FixedVectorType>(Val: CV->getType());
1615 Type *ETy = CVVTy->getElementType();
1616 Out << '<';
1617 WriterCtx.TypePrinter->print(Ty: ETy, OS&: Out);
1618 Out << ' ';
1619 WriteAsOperandInternal(Out, V: CV->getAggregateElement(Elt: 0U), WriterCtx);
1620 for (unsigned i = 1, e = CVVTy->getNumElements(); i != e; ++i) {
1621 Out << ", ";
1622 WriterCtx.TypePrinter->print(Ty: ETy, OS&: Out);
1623 Out << ' ';
1624 WriteAsOperandInternal(Out, V: CV->getAggregateElement(Elt: i), WriterCtx);
1625 }
1626 Out << '>';
1627 return;
1628 }
1629
1630 if (isa<ConstantPointerNull>(Val: CV)) {
1631 Out << "null";
1632 return;
1633 }
1634
1635 if (isa<ConstantTokenNone>(Val: CV)) {
1636 Out << "none";
1637 return;
1638 }
1639
1640 if (isa<PoisonValue>(Val: CV)) {
1641 Out << "poison";
1642 return;
1643 }
1644
1645 if (isa<UndefValue>(Val: CV)) {
1646 Out << "undef";
1647 return;
1648 }
1649
1650 if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(Val: CV)) {
1651 Out << CE->getOpcodeName();
1652 WriteOptimizationInfo(Out, U: CE);
1653 if (CE->isCompare())
1654 Out << ' ' << static_cast<CmpInst::Predicate>(CE->getPredicate());
1655 Out << " (";
1656
1657 std::optional<unsigned> InRangeOp;
1658 if (const GEPOperator *GEP = dyn_cast<GEPOperator>(Val: CE)) {
1659 WriterCtx.TypePrinter->print(Ty: GEP->getSourceElementType(), OS&: Out);
1660 Out << ", ";
1661 InRangeOp = GEP->getInRangeIndex();
1662 if (InRangeOp)
1663 ++*InRangeOp;
1664 }
1665
1666 for (User::const_op_iterator OI=CE->op_begin(); OI != CE->op_end(); ++OI) {
1667 if (InRangeOp && unsigned(OI - CE->op_begin()) == *InRangeOp)
1668 Out << "inrange ";
1669 WriterCtx.TypePrinter->print(Ty: (*OI)->getType(), OS&: Out);
1670 Out << ' ';
1671 WriteAsOperandInternal(Out, V: *OI, WriterCtx);
1672 if (OI+1 != CE->op_end())
1673 Out << ", ";
1674 }
1675
1676 if (CE->isCast()) {
1677 Out << " to ";
1678 WriterCtx.TypePrinter->print(Ty: CE->getType(), OS&: Out);
1679 }
1680
1681 if (CE->getOpcode() == Instruction::ShuffleVector)
1682 PrintShuffleMask(Out, Ty: CE->getType(), Mask: CE->getShuffleMask());
1683
1684 Out << ')';
1685 return;
1686 }
1687
1688 Out << "<placeholder or erroneous Constant>";
1689}
1690
1691static void writeMDTuple(raw_ostream &Out, const MDTuple *Node,
1692 AsmWriterContext &WriterCtx) {
1693 Out << "!{";
1694 for (unsigned mi = 0, me = Node->getNumOperands(); mi != me; ++mi) {
1695 const Metadata *MD = Node->getOperand(I: mi);
1696 if (!MD)
1697 Out << "null";
1698 else if (auto *MDV = dyn_cast<ValueAsMetadata>(Val: MD)) {
1699 Value *V = MDV->getValue();
1700 WriterCtx.TypePrinter->print(Ty: V->getType(), OS&: Out);
1701 Out << ' ';
1702 WriteAsOperandInternal(Out, V, WriterCtx);
1703 } else {
1704 WriteAsOperandInternal(Out, MD, WriterCtx);
1705 WriterCtx.onWriteMetadataAsOperand(MD);
1706 }
1707 if (mi + 1 != me)
1708 Out << ", ";
1709 }
1710
1711 Out << "}";
1712}
1713
1714namespace {
1715
1716struct FieldSeparator {
1717 bool Skip = true;
1718 const char *Sep;
1719
1720 FieldSeparator(const char *Sep = ", ") : Sep(Sep) {}
1721};
1722
1723raw_ostream &operator<<(raw_ostream &OS, FieldSeparator &FS) {
1724 if (FS.Skip) {
1725 FS.Skip = false;
1726 return OS;
1727 }
1728 return OS << FS.Sep;
1729}
1730
1731struct MDFieldPrinter {
1732 raw_ostream &Out;
1733 FieldSeparator FS;
1734 AsmWriterContext &WriterCtx;
1735
1736 explicit MDFieldPrinter(raw_ostream &Out)
1737 : Out(Out), WriterCtx(AsmWriterContext::getEmpty()) {}
1738 MDFieldPrinter(raw_ostream &Out, AsmWriterContext &Ctx)
1739 : Out(Out), WriterCtx(Ctx) {}
1740
1741 void printTag(const DINode *N);
1742 void printMacinfoType(const DIMacroNode *N);
1743 void printChecksum(const DIFile::ChecksumInfo<StringRef> &N);
1744 void printString(StringRef Name, StringRef Value,
1745 bool ShouldSkipEmpty = true);
1746 void printMetadata(StringRef Name, const Metadata *MD,
1747 bool ShouldSkipNull = true);
1748 template <class IntTy>
1749 void printInt(StringRef Name, IntTy Int, bool ShouldSkipZero = true);
1750 void printAPInt(StringRef Name, const APInt &Int, bool IsUnsigned,
1751 bool ShouldSkipZero);
1752 void printBool(StringRef Name, bool Value,
1753 std::optional<bool> Default = std::nullopt);
1754 void printDIFlags(StringRef Name, DINode::DIFlags Flags);
1755 void printDISPFlags(StringRef Name, DISubprogram::DISPFlags Flags);
1756 template <class IntTy, class Stringifier>
1757 void printDwarfEnum(StringRef Name, IntTy Value, Stringifier toString,
1758 bool ShouldSkipZero = true);
1759 void printEmissionKind(StringRef Name, DICompileUnit::DebugEmissionKind EK);
1760 void printNameTableKind(StringRef Name,
1761 DICompileUnit::DebugNameTableKind NTK);
1762};
1763
1764} // end anonymous namespace
1765
1766void MDFieldPrinter::printTag(const DINode *N) {
1767 Out << FS << "tag: ";
1768 auto Tag = dwarf::TagString(Tag: N->getTag());
1769 if (!Tag.empty())
1770 Out << Tag;
1771 else
1772 Out << N->getTag();
1773}
1774
1775void MDFieldPrinter::printMacinfoType(const DIMacroNode *N) {
1776 Out << FS << "type: ";
1777 auto Type = dwarf::MacinfoString(Encoding: N->getMacinfoType());
1778 if (!Type.empty())
1779 Out << Type;
1780 else
1781 Out << N->getMacinfoType();
1782}
1783
1784void MDFieldPrinter::printChecksum(
1785 const DIFile::ChecksumInfo<StringRef> &Checksum) {
1786 Out << FS << "checksumkind: " << Checksum.getKindAsString();
1787 printString(Name: "checksum", Value: Checksum.Value, /* ShouldSkipEmpty */ false);
1788}
1789
1790void MDFieldPrinter::printString(StringRef Name, StringRef Value,
1791 bool ShouldSkipEmpty) {
1792 if (ShouldSkipEmpty && Value.empty())
1793 return;
1794
1795 Out << FS << Name << ": \"";
1796 printEscapedString(Name: Value, Out);
1797 Out << "\"";
1798}
1799
1800static void writeMetadataAsOperand(raw_ostream &Out, const Metadata *MD,
1801 AsmWriterContext &WriterCtx) {
1802 if (!MD) {
1803 Out << "null";
1804 return;
1805 }
1806 WriteAsOperandInternal(Out, MD, WriterCtx);
1807 WriterCtx.onWriteMetadataAsOperand(MD);
1808}
1809
1810void MDFieldPrinter::printMetadata(StringRef Name, const Metadata *MD,
1811 bool ShouldSkipNull) {
1812 if (ShouldSkipNull && !MD)
1813 return;
1814
1815 Out << FS << Name << ": ";
1816 writeMetadataAsOperand(Out, MD, WriterCtx);
1817}
1818
1819template <class IntTy>
1820void MDFieldPrinter::printInt(StringRef Name, IntTy Int, bool ShouldSkipZero) {
1821 if (ShouldSkipZero && !Int)
1822 return;
1823
1824 Out << FS << Name << ": " << Int;
1825}
1826
1827void MDFieldPrinter::printAPInt(StringRef Name, const APInt &Int,
1828 bool IsUnsigned, bool ShouldSkipZero) {
1829 if (ShouldSkipZero && Int.isZero())
1830 return;
1831
1832 Out << FS << Name << ": ";
1833 Int.print(OS&: Out, isSigned: !IsUnsigned);
1834}
1835
1836void MDFieldPrinter::printBool(StringRef Name, bool Value,
1837 std::optional<bool> Default) {
1838 if (Default && Value == *Default)
1839 return;
1840 Out << FS << Name << ": " << (Value ? "true" : "false");
1841}
1842
1843void MDFieldPrinter::printDIFlags(StringRef Name, DINode::DIFlags Flags) {
1844 if (!Flags)
1845 return;
1846
1847 Out << FS << Name << ": ";
1848
1849 SmallVector<DINode::DIFlags, 8> SplitFlags;
1850 auto Extra = DINode::splitFlags(Flags, SplitFlags);
1851
1852 FieldSeparator FlagsFS(" | ");
1853 for (auto F : SplitFlags) {
1854 auto StringF = DINode::getFlagString(Flag: F);
1855 assert(!StringF.empty() && "Expected valid flag");
1856 Out << FlagsFS << StringF;
1857 }
1858 if (Extra || SplitFlags.empty())
1859 Out << FlagsFS << Extra;
1860}
1861
1862void MDFieldPrinter::printDISPFlags(StringRef Name,
1863 DISubprogram::DISPFlags Flags) {
1864 // Always print this field, because no flags in the IR at all will be
1865 // interpreted as old-style isDefinition: true.
1866 Out << FS << Name << ": ";
1867
1868 if (!Flags) {
1869 Out << 0;
1870 return;
1871 }
1872
1873 SmallVector<DISubprogram::DISPFlags, 8> SplitFlags;
1874 auto Extra = DISubprogram::splitFlags(Flags, SplitFlags);
1875
1876 FieldSeparator FlagsFS(" | ");
1877 for (auto F : SplitFlags) {
1878 auto StringF = DISubprogram::getFlagString(Flag: F);
1879 assert(!StringF.empty() && "Expected valid flag");
1880 Out << FlagsFS << StringF;
1881 }
1882 if (Extra || SplitFlags.empty())
1883 Out << FlagsFS << Extra;
1884}
1885
1886void MDFieldPrinter::printEmissionKind(StringRef Name,
1887 DICompileUnit::DebugEmissionKind EK) {
1888 Out << FS << Name << ": " << DICompileUnit::emissionKindString(EK);
1889}
1890
1891void MDFieldPrinter::printNameTableKind(StringRef Name,
1892 DICompileUnit::DebugNameTableKind NTK) {
1893 if (NTK == DICompileUnit::DebugNameTableKind::Default)
1894 return;
1895 Out << FS << Name << ": " << DICompileUnit::nameTableKindString(PK: NTK);
1896}
1897
1898template <class IntTy, class Stringifier>
1899void MDFieldPrinter::printDwarfEnum(StringRef Name, IntTy Value,
1900 Stringifier toString, bool ShouldSkipZero) {
1901 if (!Value)
1902 return;
1903
1904 Out << FS << Name << ": ";
1905 auto S = toString(Value);
1906 if (!S.empty())
1907 Out << S;
1908 else
1909 Out << Value;
1910}
1911
1912static void writeGenericDINode(raw_ostream &Out, const GenericDINode *N,
1913 AsmWriterContext &WriterCtx) {
1914 Out << "!GenericDINode(";
1915 MDFieldPrinter Printer(Out, WriterCtx);
1916 Printer.printTag(N);
1917 Printer.printString(Name: "header", Value: N->getHeader());
1918 if (N->getNumDwarfOperands()) {
1919 Out << Printer.FS << "operands: {";
1920 FieldSeparator IFS;
1921 for (auto &I : N->dwarf_operands()) {
1922 Out << IFS;
1923 writeMetadataAsOperand(Out, MD: I, WriterCtx);
1924 }
1925 Out << "}";
1926 }
1927 Out << ")";
1928}
1929
1930static void writeDILocation(raw_ostream &Out, const DILocation *DL,
1931 AsmWriterContext &WriterCtx) {
1932 Out << "!DILocation(";
1933 MDFieldPrinter Printer(Out, WriterCtx);
1934 // Always output the line, since 0 is a relevant and important value for it.
1935 Printer.printInt(Name: "line", Int: DL->getLine(), /* ShouldSkipZero */ false);
1936 Printer.printInt(Name: "column", Int: DL->getColumn());
1937 Printer.printMetadata(Name: "scope", MD: DL->getRawScope(), /* ShouldSkipNull */ false);
1938 Printer.printMetadata(Name: "inlinedAt", MD: DL->getRawInlinedAt());
1939 Printer.printBool(Name: "isImplicitCode", Value: DL->isImplicitCode(),
1940 /* Default */ false);
1941 Out << ")";
1942}
1943
1944static void writeDIAssignID(raw_ostream &Out, const DIAssignID *DL,
1945 AsmWriterContext &WriterCtx) {
1946 Out << "!DIAssignID()";
1947 MDFieldPrinter Printer(Out, WriterCtx);
1948}
1949
1950static void writeDISubrange(raw_ostream &Out, const DISubrange *N,
1951 AsmWriterContext &WriterCtx) {
1952 Out << "!DISubrange(";
1953 MDFieldPrinter Printer(Out, WriterCtx);
1954
1955 auto *Count = N->getRawCountNode();
1956 if (auto *CE = dyn_cast_or_null<ConstantAsMetadata>(Val: Count)) {
1957 auto *CV = cast<ConstantInt>(Val: CE->getValue());
1958 Printer.printInt(Name: "count", Int: CV->getSExtValue(),
1959 /* ShouldSkipZero */ false);
1960 } else
1961 Printer.printMetadata(Name: "count", MD: Count, /*ShouldSkipNull */ true);
1962
1963 // A lowerBound of constant 0 should not be skipped, since it is different
1964 // from an unspecified lower bound (= nullptr).
1965 auto *LBound = N->getRawLowerBound();
1966 if (auto *LE = dyn_cast_or_null<ConstantAsMetadata>(Val: LBound)) {
1967 auto *LV = cast<ConstantInt>(Val: LE->getValue());
1968 Printer.printInt(Name: "lowerBound", Int: LV->getSExtValue(),
1969 /* ShouldSkipZero */ false);
1970 } else
1971 Printer.printMetadata(Name: "lowerBound", MD: LBound, /*ShouldSkipNull */ true);
1972
1973 auto *UBound = N->getRawUpperBound();
1974 if (auto *UE = dyn_cast_or_null<ConstantAsMetadata>(Val: UBound)) {
1975 auto *UV = cast<ConstantInt>(Val: UE->getValue());
1976 Printer.printInt(Name: "upperBound", Int: UV->getSExtValue(),
1977 /* ShouldSkipZero */ false);
1978 } else
1979 Printer.printMetadata(Name: "upperBound", MD: UBound, /*ShouldSkipNull */ true);
1980
1981 auto *Stride = N->getRawStride();
1982 if (auto *SE = dyn_cast_or_null<ConstantAsMetadata>(Val: Stride)) {
1983 auto *SV = cast<ConstantInt>(Val: SE->getValue());
1984 Printer.printInt(Name: "stride", Int: SV->getSExtValue(), /* ShouldSkipZero */ false);
1985 } else
1986 Printer.printMetadata(Name: "stride", MD: Stride, /*ShouldSkipNull */ true);
1987
1988 Out << ")";
1989}
1990
1991static void writeDIGenericSubrange(raw_ostream &Out, const DIGenericSubrange *N,
1992 AsmWriterContext &WriterCtx) {
1993 Out << "!DIGenericSubrange(";
1994 MDFieldPrinter Printer(Out, WriterCtx);
1995
1996 auto IsConstant = [&](Metadata *Bound) -> bool {
1997 if (auto *BE = dyn_cast_or_null<DIExpression>(Val: Bound)) {
1998 return BE->isConstant() &&
1999 DIExpression::SignedOrUnsignedConstant::SignedConstant ==
2000 *BE->isConstant();
2001 }
2002 return false;
2003 };
2004
2005 auto GetConstant = [&](Metadata *Bound) -> int64_t {
2006 assert(IsConstant(Bound) && "Expected constant");
2007 auto *BE = dyn_cast_or_null<DIExpression>(Val: Bound);
2008 return static_cast<int64_t>(BE->getElement(I: 1));
2009 };
2010
2011 auto *Count = N->getRawCountNode();
2012 if (IsConstant(Count))
2013 Printer.printInt(Name: "count", Int: GetConstant(Count),
2014 /* ShouldSkipZero */ false);
2015 else
2016 Printer.printMetadata(Name: "count", MD: Count, /*ShouldSkipNull */ true);
2017
2018 auto *LBound = N->getRawLowerBound();
2019 if (IsConstant(LBound))
2020 Printer.printInt(Name: "lowerBound", Int: GetConstant(LBound),
2021 /* ShouldSkipZero */ false);
2022 else
2023 Printer.printMetadata(Name: "lowerBound", MD: LBound, /*ShouldSkipNull */ true);
2024
2025 auto *UBound = N->getRawUpperBound();
2026 if (IsConstant(UBound))
2027 Printer.printInt(Name: "upperBound", Int: GetConstant(UBound),
2028 /* ShouldSkipZero */ false);
2029 else
2030 Printer.printMetadata(Name: "upperBound", MD: UBound, /*ShouldSkipNull */ true);
2031
2032 auto *Stride = N->getRawStride();
2033 if (IsConstant(Stride))
2034 Printer.printInt(Name: "stride", Int: GetConstant(Stride),
2035 /* ShouldSkipZero */ false);
2036 else
2037 Printer.printMetadata(Name: "stride", MD: Stride, /*ShouldSkipNull */ true);
2038
2039 Out << ")";
2040}
2041
2042static void writeDIEnumerator(raw_ostream &Out, const DIEnumerator *N,
2043 AsmWriterContext &) {
2044 Out << "!DIEnumerator(";
2045 MDFieldPrinter Printer(Out);
2046 Printer.printString(Name: "name", Value: N->getName(), /* ShouldSkipEmpty */ false);
2047 Printer.printAPInt(Name: "value", Int: N->getValue(), IsUnsigned: N->isUnsigned(),
2048 /*ShouldSkipZero=*/false);
2049 if (N->isUnsigned())
2050 Printer.printBool(Name: "isUnsigned", Value: true);
2051 Out << ")";
2052}
2053
2054static void writeDIBasicType(raw_ostream &Out, const DIBasicType *N,
2055 AsmWriterContext &) {
2056 Out << "!DIBasicType(";
2057 MDFieldPrinter Printer(Out);
2058 if (N->getTag() != dwarf::DW_TAG_base_type)
2059 Printer.printTag(N);
2060 Printer.printString(Name: "name", Value: N->getName());
2061 Printer.printInt(Name: "size", Int: N->getSizeInBits());
2062 Printer.printInt(Name: "align", Int: N->getAlignInBits());
2063 Printer.printDwarfEnum(Name: "encoding", Value: N->getEncoding(),
2064 toString: dwarf::AttributeEncodingString);
2065 Printer.printDIFlags(Name: "flags", Flags: N->getFlags());
2066 Out << ")";
2067}
2068
2069static void writeDIStringType(raw_ostream &Out, const DIStringType *N,
2070 AsmWriterContext &WriterCtx) {
2071 Out << "!DIStringType(";
2072 MDFieldPrinter Printer(Out, WriterCtx);
2073 if (N->getTag() != dwarf::DW_TAG_string_type)
2074 Printer.printTag(N);
2075 Printer.printString(Name: "name", Value: N->getName());
2076 Printer.printMetadata(Name: "stringLength", MD: N->getRawStringLength());
2077 Printer.printMetadata(Name: "stringLengthExpression", MD: N->getRawStringLengthExp());
2078 Printer.printMetadata(Name: "stringLocationExpression",
2079 MD: N->getRawStringLocationExp());
2080 Printer.printInt(Name: "size", Int: N->getSizeInBits());
2081 Printer.printInt(Name: "align", Int: N->getAlignInBits());
2082 Printer.printDwarfEnum(Name: "encoding", Value: N->getEncoding(),
2083 toString: dwarf::AttributeEncodingString);
2084 Out << ")";
2085}
2086
2087static void writeDIDerivedType(raw_ostream &Out, const DIDerivedType *N,
2088 AsmWriterContext &WriterCtx) {
2089 Out << "!DIDerivedType(";
2090 MDFieldPrinter Printer(Out, WriterCtx);
2091 Printer.printTag(N);
2092 Printer.printString(Name: "name", Value: N->getName());
2093 Printer.printMetadata(Name: "scope", MD: N->getRawScope());
2094 Printer.printMetadata(Name: "file", MD: N->getRawFile());
2095 Printer.printInt(Name: "line", Int: N->getLine());
2096 Printer.printMetadata(Name: "baseType", MD: N->getRawBaseType(),
2097 /* ShouldSkipNull */ false);
2098 Printer.printInt(Name: "size", Int: N->getSizeInBits());
2099 Printer.printInt(Name: "align", Int: N->getAlignInBits());
2100 Printer.printInt(Name: "offset", Int: N->getOffsetInBits());
2101 Printer.printDIFlags(Name: "flags", Flags: N->getFlags());
2102 Printer.printMetadata(Name: "extraData", MD: N->getRawExtraData());
2103 if (const auto &DWARFAddressSpace = N->getDWARFAddressSpace())
2104 Printer.printInt(Name: "dwarfAddressSpace", Int: *DWARFAddressSpace,
2105 /* ShouldSkipZero */ false);
2106 Printer.printMetadata(Name: "annotations", MD: N->getRawAnnotations());
2107 Out << ")";
2108}
2109
2110static void writeDICompositeType(raw_ostream &Out, const DICompositeType *N,
2111 AsmWriterContext &WriterCtx) {
2112 Out << "!DICompositeType(";
2113 MDFieldPrinter Printer(Out, WriterCtx);
2114 Printer.printTag(N);
2115 Printer.printString(Name: "name", Value: N->getName());
2116 Printer.printMetadata(Name: "scope", MD: N->getRawScope());
2117 Printer.printMetadata(Name: "file", MD: N->getRawFile());
2118 Printer.printInt(Name: "line", Int: N->getLine());
2119 Printer.printMetadata(Name: "baseType", MD: N->getRawBaseType());
2120 Printer.printInt(Name: "size", Int: N->getSizeInBits());
2121 Printer.printInt(Name: "align", Int: N->getAlignInBits());
2122 Printer.printInt(Name: "offset", Int: N->getOffsetInBits());
2123 Printer.printDIFlags(Name: "flags", Flags: N->getFlags());
2124 Printer.printMetadata(Name: "elements", MD: N->getRawElements());
2125 Printer.printDwarfEnum(Name: "runtimeLang", Value: N->getRuntimeLang(),
2126 toString: dwarf::LanguageString);
2127 Printer.printMetadata(Name: "vtableHolder", MD: N->getRawVTableHolder());
2128 Printer.printMetadata(Name: "templateParams", MD: N->getRawTemplateParams());
2129 Printer.printString(Name: "identifier", Value: N->getIdentifier());
2130 Printer.printMetadata(Name: "discriminator", MD: N->getRawDiscriminator());
2131 Printer.printMetadata(Name: "dataLocation", MD: N->getRawDataLocation());
2132 Printer.printMetadata(Name: "associated", MD: N->getRawAssociated());
2133 Printer.printMetadata(Name: "allocated", MD: N->getRawAllocated());
2134 if (auto *RankConst = N->getRankConst())
2135 Printer.printInt(Name: "rank", Int: RankConst->getSExtValue(),
2136 /* ShouldSkipZero */ false);
2137 else
2138 Printer.printMetadata(Name: "rank", MD: N->getRawRank(), /*ShouldSkipNull */ true);
2139 Printer.printMetadata(Name: "annotations", MD: N->getRawAnnotations());
2140 Out << ")";
2141}
2142
2143static void writeDISubroutineType(raw_ostream &Out, const DISubroutineType *N,
2144 AsmWriterContext &WriterCtx) {
2145 Out << "!DISubroutineType(";
2146 MDFieldPrinter Printer(Out, WriterCtx);
2147 Printer.printDIFlags(Name: "flags", Flags: N->getFlags());
2148 Printer.printDwarfEnum(Name: "cc", Value: N->getCC(), toString: dwarf::ConventionString);
2149 Printer.printMetadata(Name: "types", MD: N->getRawTypeArray(),
2150 /* ShouldSkipNull */ false);
2151 Out << ")";
2152}
2153
2154static void writeDIFile(raw_ostream &Out, const DIFile *N, AsmWriterContext &) {
2155 Out << "!DIFile(";
2156 MDFieldPrinter Printer(Out);
2157 Printer.printString(Name: "filename", Value: N->getFilename(),
2158 /* ShouldSkipEmpty */ false);
2159 Printer.printString(Name: "directory", Value: N->getDirectory(),
2160 /* ShouldSkipEmpty */ false);
2161 // Print all values for checksum together, or not at all.
2162 if (N->getChecksum())
2163 Printer.printChecksum(Checksum: *N->getChecksum());
2164 Printer.printString(Name: "source", Value: N->getSource().value_or(u: StringRef()),
2165 /* ShouldSkipEmpty */ true);
2166 Out << ")";
2167}
2168
2169static void writeDICompileUnit(raw_ostream &Out, const DICompileUnit *N,
2170 AsmWriterContext &WriterCtx) {
2171 Out << "!DICompileUnit(";
2172 MDFieldPrinter Printer(Out, WriterCtx);
2173 Printer.printDwarfEnum(Name: "language", Value: N->getSourceLanguage(),
2174 toString: dwarf::LanguageString, /* ShouldSkipZero */ false);
2175 Printer.printMetadata(Name: "file", MD: N->getRawFile(), /* ShouldSkipNull */ false);
2176 Printer.printString(Name: "producer", Value: N->getProducer());
2177 Printer.printBool(Name: "isOptimized", Value: N->isOptimized());
2178 Printer.printString(Name: "flags", Value: N->getFlags());
2179 Printer.printInt(Name: "runtimeVersion", Int: N->getRuntimeVersion(),
2180 /* ShouldSkipZero */ false);
2181 Printer.printString(Name: "splitDebugFilename", Value: N->getSplitDebugFilename());
2182 Printer.printEmissionKind(Name: "emissionKind", EK: N->getEmissionKind());
2183 Printer.printMetadata(Name: "enums", MD: N->getRawEnumTypes());
2184 Printer.printMetadata(Name: "retainedTypes", MD: N->getRawRetainedTypes());
2185 Printer.printMetadata(Name: "globals", MD: N->getRawGlobalVariables());
2186 Printer.printMetadata(Name: "imports", MD: N->getRawImportedEntities());
2187 Printer.printMetadata(Name: "macros", MD: N->getRawMacros());
2188 Printer.printInt(Name: "dwoId", Int: N->getDWOId());
2189 Printer.printBool(Name: "splitDebugInlining", Value: N->getSplitDebugInlining(), Default: true);
2190 Printer.printBool(Name: "debugInfoForProfiling", Value: N->getDebugInfoForProfiling(),
2191 Default: false);
2192 Printer.printNameTableKind(Name: "nameTableKind", NTK: N->getNameTableKind());
2193 Printer.printBool(Name: "rangesBaseAddress", Value: N->getRangesBaseAddress(), Default: false);
2194 Printer.printString(Name: "sysroot", Value: N->getSysRoot());
2195 Printer.printString(Name: "sdk", Value: N->getSDK());
2196 Out << ")";
2197}
2198
2199static void writeDISubprogram(raw_ostream &Out, const DISubprogram *N,
2200 AsmWriterContext &WriterCtx) {
2201 Out << "!DISubprogram(";
2202 MDFieldPrinter Printer(Out, WriterCtx);
2203 Printer.printString(Name: "name", Value: N->getName());
2204 Printer.printString(Name: "linkageName", Value: N->getLinkageName());
2205 Printer.printMetadata(Name: "scope", MD: N->getRawScope(), /* ShouldSkipNull */ false);
2206 Printer.printMetadata(Name: "file", MD: N->getRawFile());
2207 Printer.printInt(Name: "line", Int: N->getLine());
2208 Printer.printMetadata(Name: "type", MD: N->getRawType());
2209 Printer.printInt(Name: "scopeLine", Int: N->getScopeLine());
2210 Printer.printMetadata(Name: "containingType", MD: N->getRawContainingType());
2211 if (N->getVirtuality() != dwarf::DW_VIRTUALITY_none ||
2212 N->getVirtualIndex() != 0)
2213 Printer.printInt(Name: "virtualIndex", Int: N->getVirtualIndex(), ShouldSkipZero: false);
2214 Printer.printInt(Name: "thisAdjustment", Int: N->getThisAdjustment());
2215 Printer.printDIFlags(Name: "flags", Flags: N->getFlags());
2216 Printer.printDISPFlags(Name: "spFlags", Flags: N->getSPFlags());
2217 Printer.printMetadata(Name: "unit", MD: N->getRawUnit());
2218 Printer.printMetadata(Name: "templateParams", MD: N->getRawTemplateParams());
2219 Printer.printMetadata(Name: "declaration", MD: N->getRawDeclaration());
2220 Printer.printMetadata(Name: "retainedNodes", MD: N->getRawRetainedNodes());
2221 Printer.printMetadata(Name: "thrownTypes", MD: N->getRawThrownTypes());
2222 Printer.printMetadata(Name: "annotations", MD: N->getRawAnnotations());
2223 Printer.printString(Name: "targetFuncName", Value: N->getTargetFuncName());
2224 Out << ")";
2225}
2226
2227static void writeDILexicalBlock(raw_ostream &Out, const DILexicalBlock *N,
2228 AsmWriterContext &WriterCtx) {
2229 Out << "!DILexicalBlock(";
2230 MDFieldPrinter Printer(Out, WriterCtx);
2231 Printer.printMetadata(Name: "scope", MD: N->getRawScope(), /* ShouldSkipNull */ false);
2232 Printer.printMetadata(Name: "file", MD: N->getRawFile());
2233 Printer.printInt(Name: "line", Int: N->getLine());
2234 Printer.printInt(Name: "column", Int: N->getColumn());
2235 Out << ")";
2236}
2237
2238static void writeDILexicalBlockFile(raw_ostream &Out,
2239 const DILexicalBlockFile *N,
2240 AsmWriterContext &WriterCtx) {
2241 Out << "!DILexicalBlockFile(";
2242 MDFieldPrinter Printer(Out, WriterCtx);
2243 Printer.printMetadata(Name: "scope", MD: N->getRawScope(), /* ShouldSkipNull */ false);
2244 Printer.printMetadata(Name: "file", MD: N->getRawFile());
2245 Printer.printInt(Name: "discriminator", Int: N->getDiscriminator(),
2246 /* ShouldSkipZero */ false);
2247 Out << ")";
2248}
2249
2250static void writeDINamespace(raw_ostream &Out, const DINamespace *N,
2251 AsmWriterContext &WriterCtx) {
2252 Out << "!DINamespace(";
2253 MDFieldPrinter Printer(Out, WriterCtx);
2254 Printer.printString(Name: "name", Value: N->getName());
2255 Printer.printMetadata(Name: "scope", MD: N->getRawScope(), /* ShouldSkipNull */ false);
2256 Printer.printBool(Name: "exportSymbols", Value: N->getExportSymbols(), Default: false);
2257 Out << ")";
2258}
2259
2260static void writeDICommonBlock(raw_ostream &Out, const DICommonBlock *N,
2261 AsmWriterContext &WriterCtx) {
2262 Out << "!DICommonBlock(";
2263 MDFieldPrinter Printer(Out, WriterCtx);
2264 Printer.printMetadata(Name: "scope", MD: N->getRawScope(), ShouldSkipNull: false);
2265 Printer.printMetadata(Name: "declaration", MD: N->getRawDecl(), ShouldSkipNull: false);
2266 Printer.printString(Name: "name", Value: N->getName());
2267 Printer.printMetadata(Name: "file", MD: N->getRawFile());
2268 Printer.printInt(Name: "line", Int: N->getLineNo());
2269 Out << ")";
2270}
2271
2272static void writeDIMacro(raw_ostream &Out, const DIMacro *N,
2273 AsmWriterContext &WriterCtx) {
2274 Out << "!DIMacro(";
2275 MDFieldPrinter Printer(Out, WriterCtx);
2276 Printer.printMacinfoType(N);
2277 Printer.printInt(Name: "line", Int: N->getLine());
2278 Printer.printString(Name: "name", Value: N->getName());
2279 Printer.printString(Name: "value", Value: N->getValue());
2280 Out << ")";
2281}
2282
2283static void writeDIMacroFile(raw_ostream &Out, const DIMacroFile *N,
2284 AsmWriterContext &WriterCtx) {
2285 Out << "!DIMacroFile(";
2286 MDFieldPrinter Printer(Out, WriterCtx);
2287 Printer.printInt(Name: "line", Int: N->getLine());
2288 Printer.printMetadata(Name: "file", MD: N->getRawFile(), /* ShouldSkipNull */ false);
2289 Printer.printMetadata(Name: "nodes", MD: N->getRawElements());
2290 Out << ")";
2291}
2292
2293static void writeDIModule(raw_ostream &Out, const DIModule *N,
2294 AsmWriterContext &WriterCtx) {
2295 Out << "!DIModule(";
2296 MDFieldPrinter Printer(Out, WriterCtx);
2297 Printer.printMetadata(Name: "scope", MD: N->getRawScope(), /* ShouldSkipNull */ false);
2298 Printer.printString(Name: "name", Value: N->getName());
2299 Printer.printString(Name: "configMacros", Value: N->getConfigurationMacros());
2300 Printer.printString(Name: "includePath", Value: N->getIncludePath());
2301 Printer.printString(Name: "apinotes", Value: N->getAPINotesFile());
2302 Printer.printMetadata(Name: "file", MD: N->getRawFile());
2303 Printer.printInt(Name: "line", Int: N->getLineNo());
2304 Printer.printBool(Name: "isDecl", Value: N->getIsDecl(), /* Default */ false);
2305 Out << ")";
2306}
2307
2308static void writeDITemplateTypeParameter(raw_ostream &Out,
2309 const DITemplateTypeParameter *N,
2310 AsmWriterContext &WriterCtx) {
2311 Out << "!DITemplateTypeParameter(";
2312 MDFieldPrinter Printer(Out, WriterCtx);
2313 Printer.printString(Name: "name", Value: N->getName());
2314 Printer.printMetadata(Name: "type", MD: N->getRawType(), /* ShouldSkipNull */ false);
2315 Printer.printBool(Name: "defaulted", Value: N->isDefault(), /* Default= */ false);
2316 Out << ")";
2317}
2318
2319static void writeDITemplateValueParameter(raw_ostream &Out,
2320 const DITemplateValueParameter *N,
2321 AsmWriterContext &WriterCtx) {
2322 Out << "!DITemplateValueParameter(";
2323 MDFieldPrinter Printer(Out, WriterCtx);
2324 if (N->getTag() != dwarf::DW_TAG_template_value_parameter)
2325 Printer.printTag(N);
2326 Printer.printString(Name: "name", Value: N->getName());
2327 Printer.printMetadata(Name: "type", MD: N->getRawType());
2328 Printer.printBool(Name: "defaulted", Value: N->isDefault(), /* Default= */ false);
2329 Printer.printMetadata(Name: "value", MD: N->getValue(), /* ShouldSkipNull */ false);
2330 Out << ")";
2331}
2332
2333static void writeDIGlobalVariable(raw_ostream &Out, const DIGlobalVariable *N,
2334 AsmWriterContext &WriterCtx) {
2335 Out << "!DIGlobalVariable(";
2336 MDFieldPrinter Printer(Out, WriterCtx);
2337 Printer.printString(Name: "name", Value: N->getName());
2338 Printer.printString(Name: "linkageName", Value: N->getLinkageName());
2339 Printer.printMetadata(Name: "scope", MD: N->getRawScope(), /* ShouldSkipNull */ false);
2340 Printer.printMetadata(Name: "file", MD: N->getRawFile());
2341 Printer.printInt(Name: "line", Int: N->getLine());
2342 Printer.printMetadata(Name: "type", MD: N->getRawType());
2343 Printer.printBool(Name: "isLocal", Value: N->isLocalToUnit());
2344 Printer.printBool(Name: "isDefinition", Value: N->isDefinition());
2345 Printer.printMetadata(Name: "declaration", MD: N->getRawStaticDataMemberDeclaration());
2346 Printer.printMetadata(Name: "templateParams", MD: N->getRawTemplateParams());
2347 Printer.printInt(Name: "align", Int: N->getAlignInBits());
2348 Printer.printMetadata(Name: "annotations", MD: N->getRawAnnotations());
2349 Out << ")";
2350}
2351
2352static void writeDILocalVariable(raw_ostream &Out, const DILocalVariable *N,
2353 AsmWriterContext &WriterCtx) {
2354 Out << "!DILocalVariable(";
2355 MDFieldPrinter Printer(Out, WriterCtx);
2356 Printer.printString(Name: "name", Value: N->getName());
2357 Printer.printInt(Name: "arg", Int: N->getArg());
2358 Printer.printMetadata(Name: "scope", MD: N->getRawScope(), /* ShouldSkipNull */ false);
2359 Printer.printMetadata(Name: "file", MD: N->getRawFile());
2360 Printer.printInt(Name: "line", Int: N->getLine());
2361 Printer.printMetadata(Name: "type", MD: N->getRawType());
2362 Printer.printDIFlags(Name: "flags", Flags: N->getFlags());
2363 Printer.printInt(Name: "align", Int: N->getAlignInBits());
2364 Printer.printMetadata(Name: "annotations", MD: N->getRawAnnotations());
2365 Out << ")";
2366}
2367
2368static void writeDILabel(raw_ostream &Out, const DILabel *N,
2369 AsmWriterContext &WriterCtx) {
2370 Out << "!DILabel(";
2371 MDFieldPrinter Printer(Out, WriterCtx);
2372 Printer.printMetadata(Name: "scope", MD: N->getRawScope(), /* ShouldSkipNull */ false);
2373 Printer.printString(Name: "name", Value: N->getName());
2374 Printer.printMetadata(Name: "file", MD: N->getRawFile());
2375 Printer.printInt(Name: "line", Int: N->getLine());
2376 Out << ")";
2377}
2378
2379static void writeDIExpression(raw_ostream &Out, const DIExpression *N,
2380 AsmWriterContext &WriterCtx) {
2381 Out << "!DIExpression(";
2382 FieldSeparator FS;
2383 if (N->isValid()) {
2384 for (const DIExpression::ExprOperand &Op : N->expr_ops()) {
2385 auto OpStr = dwarf::OperationEncodingString(Encoding: Op.getOp());
2386 assert(!OpStr.empty() && "Expected valid opcode");
2387
2388 Out << FS << OpStr;
2389 if (Op.getOp() == dwarf::DW_OP_LLVM_convert) {
2390 Out << FS << Op.getArg(I: 0);
2391 Out << FS << dwarf::AttributeEncodingString(Encoding: Op.getArg(I: 1));
2392 } else {
2393 for (unsigned A = 0, AE = Op.getNumArgs(); A != AE; ++A)
2394 Out << FS << Op.getArg(I: A);
2395 }
2396 }
2397 } else {
2398 for (const auto &I : N->getElements())
2399 Out << FS << I;
2400 }
2401 Out << ")";
2402}
2403
2404static void writeDIArgList(raw_ostream &Out, const DIArgList *N,
2405 AsmWriterContext &WriterCtx,
2406 bool FromValue = false) {
2407 assert(FromValue &&
2408 "Unexpected DIArgList metadata outside of value argument");
2409 Out << "!DIArgList(";
2410 FieldSeparator FS;
2411 MDFieldPrinter Printer(Out, WriterCtx);
2412 for (Metadata *Arg : N->getArgs()) {
2413 Out << FS;
2414 WriteAsOperandInternal(Out, MD: Arg, WriterCtx, FromValue: true);
2415 }
2416 Out << ")";
2417}
2418
2419static void writeDIGlobalVariableExpression(raw_ostream &Out,
2420 const DIGlobalVariableExpression *N,
2421 AsmWriterContext &WriterCtx) {
2422 Out << "!DIGlobalVariableExpression(";
2423 MDFieldPrinter Printer(Out, WriterCtx);
2424 Printer.printMetadata(Name: "var", MD: N->getVariable());
2425 Printer.printMetadata(Name: "expr", MD: N->getExpression());
2426 Out << ")";
2427}
2428
2429static void writeDIObjCProperty(raw_ostream &Out, const DIObjCProperty *N,
2430 AsmWriterContext &WriterCtx) {
2431 Out << "!DIObjCProperty(";
2432 MDFieldPrinter Printer(Out, WriterCtx);
2433 Printer.printString(Name: "name", Value: N->getName());
2434 Printer.printMetadata(Name: "file", MD: N->getRawFile());
2435 Printer.printInt(Name: "line", Int: N->getLine());
2436 Printer.printString(Name: "setter", Value: N->getSetterName());
2437 Printer.printString(Name: "getter", Value: N->getGetterName());
2438 Printer.printInt(Name: "attributes", Int: N->getAttributes());
2439 Printer.printMetadata(Name: "type", MD: N->getRawType());
2440 Out << ")";
2441}
2442
2443static void writeDIImportedEntity(raw_ostream &Out, const DIImportedEntity *N,
2444 AsmWriterContext &WriterCtx) {
2445 Out << "!DIImportedEntity(";
2446 MDFieldPrinter Printer(Out, WriterCtx);
2447 Printer.printTag(N);
2448 Printer.printString(Name: "name", Value: N->getName());
2449 Printer.printMetadata(Name: "scope", MD: N->getRawScope(), /* ShouldSkipNull */ false);
2450 Printer.printMetadata(Name: "entity", MD: N->getRawEntity());
2451 Printer.printMetadata(Name: "file", MD: N->getRawFile());
2452 Printer.printInt(Name: "line", Int: N->getLine());
2453 Printer.printMetadata(Name: "elements", MD: N->getRawElements());
2454 Out << ")";
2455}
2456
2457static void WriteMDNodeBodyInternal(raw_ostream &Out, const MDNode *Node,
2458 AsmWriterContext &Ctx) {
2459 if (Node->isDistinct())
2460 Out << "distinct ";
2461 else if (Node->isTemporary())
2462 Out << "<temporary!> "; // Handle broken code.
2463
2464 switch (Node->getMetadataID()) {
2465 default:
2466 llvm_unreachable("Expected uniquable MDNode");
2467#define HANDLE_MDNODE_LEAF(CLASS) \
2468 case Metadata::CLASS##Kind: \
2469 write##CLASS(Out, cast<CLASS>(Node), Ctx); \
2470 break;
2471#include "llvm/IR/Metadata.def"
2472 }
2473}
2474
2475// Full implementation of printing a Value as an operand with support for
2476// TypePrinting, etc.
2477static void WriteAsOperandInternal(raw_ostream &Out, const Value *V,
2478 AsmWriterContext &WriterCtx) {
2479 if (V->hasName()) {
2480 PrintLLVMName(OS&: Out, V);
2481 return;
2482 }
2483
2484 const Constant *CV = dyn_cast<Constant>(Val: V);
2485 if (CV && !isa<GlobalValue>(Val: CV)) {
2486 assert(WriterCtx.TypePrinter && "Constants require TypePrinting!");
2487 WriteConstantInternal(Out, CV, WriterCtx);
2488 return;
2489 }
2490
2491 if (const InlineAsm *IA = dyn_cast<InlineAsm>(Val: V)) {
2492 Out << "asm ";
2493 if (IA->hasSideEffects())
2494 Out << "sideeffect ";
2495 if (IA->isAlignStack())
2496 Out << "alignstack ";
2497 // We don't emit the AD_ATT dialect as it's the assumed default.
2498 if (IA->getDialect() == InlineAsm::AD_Intel)
2499 Out << "inteldialect ";
2500 if (IA->canThrow())
2501 Out << "unwind ";
2502 Out << '"';
2503 printEscapedString(Name: IA->getAsmString(), Out);
2504 Out << "\", \"";
2505 printEscapedString(Name: IA->getConstraintString(), Out);
2506 Out << '"';
2507 return;
2508 }
2509
2510 if (auto *MD = dyn_cast<MetadataAsValue>(Val: V)) {
2511 WriteAsOperandInternal(Out, MD: MD->getMetadata(), WriterCtx,
2512 /* FromValue */ true);
2513 return;
2514 }
2515
2516 char Prefix = '%';
2517 int Slot;
2518 auto *Machine = WriterCtx.Machine;
2519 // If we have a SlotTracker, use it.
2520 if (Machine) {
2521 if (const GlobalValue *GV = dyn_cast<GlobalValue>(Val: V)) {
2522 Slot = Machine->getGlobalSlot(V: GV);
2523 Prefix = '@';
2524 } else {
2525 Slot = Machine->getLocalSlot(V);
2526
2527 // If the local value didn't succeed, then we may be referring to a value
2528 // from a different function. Translate it, as this can happen when using
2529 // address of blocks.
2530 if (Slot == -1)
2531 if ((Machine = createSlotTracker(V))) {
2532 Slot = Machine->getLocalSlot(V);
2533 delete Machine;
2534 }
2535 }
2536 } else if ((Machine = createSlotTracker(V))) {
2537 // Otherwise, create one to get the # and then destroy it.
2538 if (const GlobalValue *GV = dyn_cast<GlobalValue>(Val: V)) {
2539 Slot = Machine->getGlobalSlot(V: GV);
2540 Prefix = '@';
2541 } else {
2542 Slot = Machine->getLocalSlot(V);
2543 }
2544 delete Machine;
2545 Machine = nullptr;
2546 } else {
2547 Slot = -1;
2548 }
2549
2550 if (Slot != -1)
2551 Out << Prefix << Slot;
2552 else
2553 Out << "<badref>";
2554}
2555
2556static void WriteAsOperandInternal(raw_ostream &Out, const Metadata *MD,
2557 AsmWriterContext &WriterCtx,
2558 bool FromValue) {
2559 // Write DIExpressions and DIArgLists inline when used as a value. Improves
2560 // readability of debug info intrinsics.
2561 if (const DIExpression *Expr = dyn_cast<DIExpression>(Val: MD)) {
2562 writeDIExpression(Out, N: Expr, WriterCtx);
2563 return;
2564 }
2565 if (const DIArgList *ArgList = dyn_cast<DIArgList>(Val: MD)) {
2566 writeDIArgList(Out, N: ArgList, WriterCtx, FromValue);
2567 return;
2568 }
2569
2570 if (const MDNode *N = dyn_cast<MDNode>(Val: MD)) {
2571 std::unique_ptr<SlotTracker> MachineStorage;
2572 SaveAndRestore SARMachine(WriterCtx.Machine);
2573 if (!WriterCtx.Machine) {
2574 MachineStorage = std::make_unique<SlotTracker>(args&: WriterCtx.Context);
2575 WriterCtx.Machine = MachineStorage.get();
2576 }
2577 int Slot = WriterCtx.Machine->getMetadataSlot(N);
2578 if (Slot == -1) {
2579 if (const DILocation *Loc = dyn_cast<DILocation>(Val: N)) {
2580 writeDILocation(Out, DL: Loc, WriterCtx);
2581 return;
2582 }
2583 // Give the pointer value instead of "badref", since this comes up all
2584 // the time when debugging.
2585 Out << "<" << N << ">";
2586 } else
2587 Out << '!' << Slot;
2588 return;
2589 }
2590
2591 if (const MDString *MDS = dyn_cast<MDString>(Val: MD)) {
2592 Out << "!\"";
2593 printEscapedString(Name: MDS->getString(), Out);
2594 Out << '"';
2595 return;
2596 }
2597
2598 auto *V = cast<ValueAsMetadata>(Val: MD);
2599 assert(WriterCtx.TypePrinter && "TypePrinter required for metadata values");
2600 assert((FromValue || !isa<LocalAsMetadata>(V)) &&
2601 "Unexpected function-local metadata outside of value argument");
2602
2603 WriterCtx.TypePrinter->print(Ty: V->getValue()->getType(), OS&: Out);
2604 Out << ' ';
2605 WriteAsOperandInternal(Out, V: V->getValue(), WriterCtx);
2606}
2607
2608namespace {
2609
2610class AssemblyWriter {
2611 formatted_raw_ostream &Out;
2612 const Module *TheModule = nullptr;
2613 const ModuleSummaryIndex *TheIndex = nullptr;
2614 std::unique_ptr<SlotTracker> SlotTrackerStorage;
2615 SlotTracker &Machine;
2616 TypePrinting TypePrinter;
2617 AssemblyAnnotationWriter *AnnotationWriter = nullptr;
2618 SetVector<const Comdat *> Comdats;
2619 bool IsForDebug;
2620 bool ShouldPreserveUseListOrder;
2621 UseListOrderMap UseListOrders;
2622 SmallVector<StringRef, 8> MDNames;
2623 /// Synchronization scope names registered with LLVMContext.
2624 SmallVector<StringRef, 8> SSNs;
2625 DenseMap<const GlobalValueSummary *, GlobalValue::GUID> SummaryToGUIDMap;
2626
2627public:
2628 /// Construct an AssemblyWriter with an external SlotTracker
2629 AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac, const Module *M,
2630 AssemblyAnnotationWriter *AAW, bool IsForDebug,
2631 bool ShouldPreserveUseListOrder = false);
2632
2633 AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
2634 const ModuleSummaryIndex *Index, bool IsForDebug);
2635
2636 AsmWriterContext getContext() {
2637 return AsmWriterContext(&TypePrinter, &Machine, TheModule);
2638 }
2639
2640 void printMDNodeBody(const MDNode *MD);
2641 void printNamedMDNode(const NamedMDNode *NMD);
2642
2643 void printModule(const Module *M);
2644
2645 void writeOperand(const Value *Op, bool PrintType);
2646 void writeParamOperand(const Value *Operand, AttributeSet Attrs);
2647 void writeOperandBundles(const CallBase *Call);
2648 void writeSyncScope(const LLVMContext &Context,
2649 SyncScope::ID SSID);
2650 void writeAtomic(const LLVMContext &Context,
2651 AtomicOrdering Ordering,
2652 SyncScope::ID SSID);
2653 void writeAtomicCmpXchg(const LLVMContext &Context,
2654 AtomicOrdering SuccessOrdering,
2655 AtomicOrdering FailureOrdering,
2656 SyncScope::ID SSID);
2657
2658 void writeAllMDNodes();
2659 void writeMDNode(unsigned Slot, const MDNode *Node);
2660 void writeAttribute(const Attribute &Attr, bool InAttrGroup = false);
2661 void writeAttributeSet(const AttributeSet &AttrSet, bool InAttrGroup = false);
2662 void writeAllAttributeGroups();
2663
2664 void printTypeIdentities();
2665 void printGlobal(const GlobalVariable *GV);
2666 void printAlias(const GlobalAlias *GA);
2667 void printIFunc(const GlobalIFunc *GI);
2668 void printComdat(const Comdat *C);
2669 void printFunction(const Function *F);
2670 void printArgument(const Argument *FA, AttributeSet Attrs);
2671 void printBasicBlock(const BasicBlock *BB);
2672 void printInstructionLine(const Instruction &I);
2673 void printInstruction(const Instruction &I);
2674 void printDPMarker(const DPMarker &DPI);
2675 void printDPValue(const DPValue &DPI);
2676
2677 void printUseListOrder(const Value *V, const std::vector<unsigned> &Shuffle);
2678 void printUseLists(const Function *F);
2679
2680 void printModuleSummaryIndex();
2681 void printSummaryInfo(unsigned Slot, const ValueInfo &VI);
2682 void printSummary(const GlobalValueSummary &Summary);
2683 void printAliasSummary(const AliasSummary *AS);
2684 void printGlobalVarSummary(const GlobalVarSummary *GS);
2685 void printFunctionSummary(const FunctionSummary *FS);
2686 void printTypeIdSummary(const TypeIdSummary &TIS);
2687 void printTypeIdCompatibleVtableSummary(const TypeIdCompatibleVtableInfo &TI);
2688 void printTypeTestResolution(const TypeTestResolution &TTRes);
2689 void printArgs(const std::vector<uint64_t> &Args);
2690 void printWPDRes(const WholeProgramDevirtResolution &WPDRes);
2691 void printTypeIdInfo(const FunctionSummary::TypeIdInfo &TIDInfo);
2692 void printVFuncId(const FunctionSummary::VFuncId VFId);
2693 void
2694 printNonConstVCalls(const std::vector<FunctionSummary::VFuncId> &VCallList,
2695 const char *Tag);
2696 void
2697 printConstVCalls(const std::vector<FunctionSummary::ConstVCall> &VCallList,
2698 const char *Tag);
2699
2700private:
2701 /// Print out metadata attachments.
2702 void printMetadataAttachments(
2703 const SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs,
2704 StringRef Separator);
2705
2706 // printInfoComment - Print a little comment after the instruction indicating
2707 // which slot it occupies.
2708 void printInfoComment(const Value &V);
2709
2710 // printGCRelocateComment - print comment after call to the gc.relocate
2711 // intrinsic indicating base and derived pointer names.
2712 void printGCRelocateComment(const GCRelocateInst &Relocate);
2713};
2714
2715} // end anonymous namespace
2716
2717AssemblyWriter::AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
2718 const Module *M, AssemblyAnnotationWriter *AAW,
2719 bool IsForDebug, bool ShouldPreserveUseListOrder)
2720 : Out(o), TheModule(M), Machine(Mac), TypePrinter(M), AnnotationWriter(AAW),
2721 IsForDebug(IsForDebug),
2722 ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {
2723 if (!TheModule)
2724 return;
2725 for (const GlobalObject &GO : TheModule->global_objects())
2726 if (const Comdat *C = GO.getComdat())
2727 Comdats.insert(X: C);
2728}
2729
2730AssemblyWriter::AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
2731 const ModuleSummaryIndex *Index, bool IsForDebug)
2732 : Out(o), TheIndex(Index), Machine(Mac), TypePrinter(/*Module=*/nullptr),
2733 IsForDebug(IsForDebug), ShouldPreserveUseListOrder(false) {}
2734
2735void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType) {
2736 if (!Operand) {
2737 Out << "<null operand!>";
2738 return;
2739 }
2740 if (PrintType) {
2741 TypePrinter.print(Ty: Operand->getType(), OS&: Out);
2742 Out << ' ';
2743 }
2744 auto WriterCtx = getContext();
2745 WriteAsOperandInternal(Out, V: Operand, WriterCtx);
2746}
2747
2748void AssemblyWriter::writeSyncScope(const LLVMContext &Context,
2749 SyncScope::ID SSID) {
2750 switch (SSID) {
2751 case SyncScope::System: {
2752 break;
2753 }
2754 default: {
2755 if (SSNs.empty())
2756 Context.getSyncScopeNames(SSNs);
2757
2758 Out << " syncscope(\"";
2759 printEscapedString(Name: SSNs[SSID], Out);
2760 Out << "\")";
2761 break;
2762 }
2763 }
2764}
2765
2766void AssemblyWriter::writeAtomic(const LLVMContext &Context,
2767 AtomicOrdering Ordering,
2768 SyncScope::ID SSID) {
2769 if (Ordering == AtomicOrdering::NotAtomic)
2770 return;
2771
2772 writeSyncScope(Context, SSID);
2773 Out << " " << toIRString(ao: Ordering);
2774}
2775
2776void AssemblyWriter::writeAtomicCmpXchg(const LLVMContext &Context,
2777 AtomicOrdering SuccessOrdering,
2778 AtomicOrdering FailureOrdering,
2779 SyncScope::ID SSID) {
2780 assert(SuccessOrdering != AtomicOrdering::NotAtomic &&
2781 FailureOrdering != AtomicOrdering::NotAtomic);
2782
2783 writeSyncScope(Context, SSID);
2784 Out << " " << toIRString(ao: SuccessOrdering);
2785 Out << " " << toIRString(ao: FailureOrdering);
2786}
2787
2788void AssemblyWriter::writeParamOperand(const Value *Operand,
2789 AttributeSet Attrs) {
2790 if (!Operand) {
2791 Out << "<null operand!>";
2792 return;
2793 }
2794
2795 // Print the type
2796 TypePrinter.print(Ty: Operand->getType(), OS&: Out);
2797 // Print parameter attributes list
2798 if (Attrs.hasAttributes()) {
2799 Out << ' ';
2800 writeAttributeSet(AttrSet: Attrs);
2801 }
2802 Out << ' ';
2803 // Print the operand
2804 auto WriterCtx = getContext();
2805 WriteAsOperandInternal(Out, V: Operand, WriterCtx);
2806}
2807
2808void AssemblyWriter::writeOperandBundles(const CallBase *Call) {
2809 if (!Call->hasOperandBundles())
2810 return;
2811
2812 Out << " [ ";
2813
2814 bool FirstBundle = true;
2815 for (unsigned i = 0, e = Call->getNumOperandBundles(); i != e; ++i) {
2816 OperandBundleUse BU = Call->getOperandBundleAt(Index: i);
2817
2818 if (!FirstBundle)
2819 Out << ", ";
2820 FirstBundle = false;
2821
2822 Out << '"';
2823 printEscapedString(Name: BU.getTagName(), Out);
2824 Out << '"';
2825
2826 Out << '(';
2827
2828 bool FirstInput = true;
2829 auto WriterCtx = getContext();
2830 for (const auto &Input : BU.Inputs) {
2831 if (!FirstInput)
2832 Out << ", ";
2833 FirstInput = false;
2834
2835 if (Input == nullptr)
2836 Out << "<null operand bundle!>";
2837 else {
2838 TypePrinter.print(Ty: Input->getType(), OS&: Out);
2839 Out << " ";
2840 WriteAsOperandInternal(Out, V: Input, WriterCtx);
2841 }
2842 }
2843
2844 Out << ')';
2845 }
2846
2847 Out << " ]";
2848}
2849
2850void AssemblyWriter::printModule(const Module *M) {
2851 Machine.initializeIfNeeded();
2852
2853 if (ShouldPreserveUseListOrder)
2854 UseListOrders = predictUseListOrder(M);
2855
2856 if (!M->getModuleIdentifier().empty() &&
2857 // Don't print the ID if it will start a new line (which would
2858 // require a comment char before it).
2859 M->getModuleIdentifier().find(c: '\n') == std::string::npos)
2860 Out << "; ModuleID = '" << M->getModuleIdentifier() << "'\n";
2861
2862 if (!M->getSourceFileName().empty()) {
2863 Out << "source_filename = \"";
2864 printEscapedString(Name: M->getSourceFileName(), Out);
2865 Out << "\"\n";
2866 }
2867
2868 const std::string &DL = M->getDataLayoutStr();
2869 if (!DL.empty())
2870 Out << "target datalayout = \"" << DL << "\"\n";
2871 if (!M->getTargetTriple().empty())
2872 Out << "target triple = \"" << M->getTargetTriple() << "\"\n";
2873
2874 if (!M->getModuleInlineAsm().empty()) {
2875 Out << '\n';
2876
2877 // Split the string into lines, to make it easier to read the .ll file.
2878 StringRef Asm = M->getModuleInlineAsm();
2879 do {
2880 StringRef Front;
2881 std::tie(args&: Front, args&: Asm) = Asm.split(Separator: '\n');
2882
2883 // We found a newline, print the portion of the asm string from the
2884 // last newline up to this newline.
2885 Out << "module asm \"";
2886 printEscapedString(Name: Front, Out);
2887 Out << "\"\n";
2888 } while (!Asm.empty());
2889 }
2890
2891 printTypeIdentities();
2892
2893 // Output all comdats.
2894 if (!Comdats.empty())
2895 Out << '\n';
2896 for (const Comdat *C : Comdats) {
2897 printComdat(C);
2898 if (C != Comdats.back())
2899 Out << '\n';
2900 }
2901
2902 // Output all globals.
2903 if (!M->global_empty()) Out << '\n';
2904 for (const GlobalVariable &GV : M->globals()) {
2905 printGlobal(GV: &GV); Out << '\n';
2906 }
2907
2908 // Output all aliases.
2909 if (!M->alias_empty()) Out << "\n";
2910 for (const GlobalAlias &GA : M->aliases())
2911 printAlias(GA: &GA);
2912
2913 // Output all ifuncs.
2914 if (!M->ifunc_empty()) Out << "\n";
2915 for (const GlobalIFunc &GI : M->ifuncs())
2916 printIFunc(GI: &GI);
2917
2918 // Output all of the functions.
2919 for (const Function &F : *M) {
2920 Out << '\n';
2921 printFunction(F: &F);
2922 }
2923
2924 // Output global use-lists.
2925 printUseLists(F: nullptr);
2926
2927 // Output all attribute groups.
2928 if (!Machine.as_empty()) {
2929 Out << '\n';
2930 writeAllAttributeGroups();
2931 }
2932
2933 // Output named metadata.
2934 if (!M->named_metadata_empty()) Out << '\n';
2935
2936 for (const NamedMDNode &Node : M->named_metadata())
2937 printNamedMDNode(NMD: &Node);
2938
2939 // Output metadata.
2940 if (!Machine.mdn_empty()) {
2941 Out << '\n';
2942 writeAllMDNodes();
2943 }
2944}
2945
2946void AssemblyWriter::printModuleSummaryIndex() {
2947 assert(TheIndex);
2948 int NumSlots = Machine.initializeIndexIfNeeded();
2949
2950 Out << "\n";
2951
2952 // Print module path entries. To print in order, add paths to a vector
2953 // indexed by module slot.
2954 std::vector<std::pair<std::string, ModuleHash>> moduleVec;
2955 std::string RegularLTOModuleName =
2956 ModuleSummaryIndex::getRegularLTOModuleName();
2957 moduleVec.resize(new_size: TheIndex->modulePaths().size());
2958 for (auto &[ModPath, ModHash] : TheIndex->modulePaths())
2959 moduleVec[Machine.getModulePathSlot(Path: ModPath)] = std::make_pair(
2960 // An empty module path is a special entry for a regular LTO module
2961 // created during the thin link.
2962 x: ModPath.empty() ? RegularLTOModuleName : std::string(ModPath), y: ModHash);
2963
2964 unsigned i = 0;
2965 for (auto &ModPair : moduleVec) {
2966 Out << "^" << i++ << " = module: (";
2967 Out << "path: \"";
2968 printEscapedString(Name: ModPair.first, Out);
2969 Out << "\", hash: (";
2970 FieldSeparator FS;
2971 for (auto Hash : ModPair.second)
2972 Out << FS << Hash;
2973 Out << "))\n";
2974 }
2975
2976 // FIXME: Change AliasSummary to hold a ValueInfo instead of summary pointer
2977 // for aliasee (then update BitcodeWriter.cpp and remove get/setAliaseeGUID).
2978 for (auto &GlobalList : *TheIndex) {
2979 auto GUID = GlobalList.first;
2980 for (auto &Summary : GlobalList.second.SummaryList)
2981 SummaryToGUIDMap[Summary.get()] = GUID;
2982 }
2983
2984 // Print the global value summary entries.
2985 for (auto &GlobalList : *TheIndex) {
2986 auto GUID = GlobalList.first;
2987 auto VI = TheIndex->getValueInfo(R: GlobalList);
2988 printSummaryInfo(Slot: Machine.getGUIDSlot(GUID), VI);
2989 }
2990
2991 // Print the TypeIdMap entries.
2992 for (const auto &TID : TheIndex->typeIds()) {
2993 Out << "^" << Machine.getTypeIdSlot(Id: TID.second.first)
2994 << " = typeid: (name: \"" << TID.second.first << "\"";
2995 printTypeIdSummary(TIS: TID.second.second);
2996 Out << ") ; guid = " << TID.first << "\n";
2997 }
2998
2999 // Print the TypeIdCompatibleVtableMap entries.
3000 for (auto &TId : TheIndex->typeIdCompatibleVtableMap()) {
3001 auto GUID = GlobalValue::getGUID(GlobalName: TId.first);
3002 Out << "^" << Machine.getTypeIdCompatibleVtableSlot(Id: TId.first)
3003 << " = typeidCompatibleVTable: (name: \"" << TId.first << "\"";
3004 printTypeIdCompatibleVtableSummary(TI: TId.second);
3005 Out << ") ; guid = " << GUID << "\n";
3006 }
3007
3008 // Don't emit flags when it's not really needed (value is zero by default).
3009 if (TheIndex->getFlags()) {
3010 Out << "^" << NumSlots << " = flags: " << TheIndex->getFlags() << "\n";
3011 ++NumSlots;
3012 }
3013
3014 Out << "^" << NumSlots << " = blockcount: " << TheIndex->getBlockCount()
3015 << "\n";
3016}
3017
3018static const char *
3019getWholeProgDevirtResKindName(WholeProgramDevirtResolution::Kind K) {
3020 switch (K) {
3021 case WholeProgramDevirtResolution::Indir:
3022 return "indir";
3023 case WholeProgramDevirtResolution::SingleImpl:
3024 return "singleImpl";
3025 case WholeProgramDevirtResolution::BranchFunnel:
3026 return "branchFunnel";
3027 }
3028 llvm_unreachable("invalid WholeProgramDevirtResolution kind");
3029}
3030
3031static const char *getWholeProgDevirtResByArgKindName(
3032 WholeProgramDevirtResolution::ByArg::Kind K) {
3033 switch (K) {
3034 case WholeProgramDevirtResolution::ByArg::Indir:
3035 return "indir";
3036 case WholeProgramDevirtResolution::ByArg::UniformRetVal:
3037 return "uniformRetVal";
3038 case WholeProgramDevirtResolution::ByArg::UniqueRetVal:
3039 return "uniqueRetVal";
3040 case WholeProgramDevirtResolution::ByArg::VirtualConstProp:
3041 return "virtualConstProp";
3042 }
3043 llvm_unreachable("invalid WholeProgramDevirtResolution::ByArg kind");
3044}
3045
3046static const char *getTTResKindName(TypeTestResolution::Kind K) {
3047 switch (K) {
3048 case TypeTestResolution::Unknown:
3049 return "unknown";
3050 case TypeTestResolution::Unsat:
3051 return "unsat";
3052 case TypeTestResolution::ByteArray:
3053 return "byteArray";
3054 case TypeTestResolution::Inline:
3055 return "inline";
3056 case TypeTestResolution::Single:
3057 return "single";
3058 case TypeTestResolution::AllOnes:
3059 return "allOnes";
3060 }
3061 llvm_unreachable("invalid TypeTestResolution kind");
3062}
3063
3064void AssemblyWriter::printTypeTestResolution(const TypeTestResolution &TTRes) {
3065 Out << "typeTestRes: (kind: " << getTTResKindName(K: TTRes.TheKind)
3066 << ", sizeM1BitWidth: " << TTRes.SizeM1BitWidth;
3067
3068 // The following fields are only used if the target does not support the use
3069 // of absolute symbols to store constants. Print only if non-zero.
3070 if (TTRes.AlignLog2)
3071 Out << ", alignLog2: " << TTRes.AlignLog2;
3072 if (TTRes.SizeM1)
3073 Out << ", sizeM1: " << TTRes.SizeM1;
3074 if (TTRes.BitMask)
3075 // BitMask is uint8_t which causes it to print the corresponding char.
3076 Out << ", bitMask: " << (unsigned)TTRes.BitMask;
3077 if (TTRes.InlineBits)
3078 Out << ", inlineBits: " << TTRes.InlineBits;
3079
3080 Out << ")";
3081}
3082
3083void AssemblyWriter::printTypeIdSummary(const TypeIdSummary &TIS) {
3084 Out << ", summary: (";
3085 printTypeTestResolution(TTRes: TIS.TTRes);
3086 if (!TIS.WPDRes.empty()) {
3087 Out << ", wpdResolutions: (";
3088 FieldSeparator FS;
3089 for (auto &WPDRes : TIS.WPDRes) {
3090 Out << FS;
3091 Out << "(offset: " << WPDRes.first << ", ";
3092 printWPDRes(WPDRes: WPDRes.second);
3093 Out << ")";
3094 }
3095 Out << ")";
3096 }
3097 Out << ")";
3098}
3099
3100void AssemblyWriter::printTypeIdCompatibleVtableSummary(
3101 const TypeIdCompatibleVtableInfo &TI) {
3102 Out << ", summary: (";
3103 FieldSeparator FS;
3104 for (auto &P : TI) {
3105 Out << FS;
3106 Out << "(offset: " << P.AddressPointOffset << ", ";
3107 Out << "^" << Machine.getGUIDSlot(GUID: P.VTableVI.getGUID());
3108 Out << ")";
3109 }
3110 Out << ")";
3111}
3112
3113void AssemblyWriter::printArgs(const std::vector<uint64_t> &Args) {
3114 Out << "args: (";
3115 FieldSeparator FS;
3116 for (auto arg : Args) {
3117 Out << FS;
3118 Out << arg;
3119 }
3120 Out << ")";
3121}
3122
3123void AssemblyWriter::printWPDRes(const WholeProgramDevirtResolution &WPDRes) {
3124 Out << "wpdRes: (kind: ";
3125 Out << getWholeProgDevirtResKindName(K: WPDRes.TheKind);
3126
3127 if (WPDRes.TheKind == WholeProgramDevirtResolution::SingleImpl)
3128 Out << ", singleImplName: \"" << WPDRes.SingleImplName << "\"";
3129
3130 if (!WPDRes.ResByArg.empty()) {
3131 Out << ", resByArg: (";
3132 FieldSeparator FS;
3133 for (auto &ResByArg : WPDRes.ResByArg) {
3134 Out << FS;
3135 printArgs(Args: ResByArg.first);
3136 Out << ", byArg: (kind: ";
3137 Out << getWholeProgDevirtResByArgKindName(K: ResByArg.second.TheKind);
3138 if (ResByArg.second.TheKind ==
3139 WholeProgramDevirtResolution::ByArg::UniformRetVal ||
3140 ResByArg.second.TheKind ==
3141 WholeProgramDevirtResolution::ByArg::UniqueRetVal)
3142 Out << ", info: " << ResByArg.second.Info;
3143
3144 // The following fields are only used if the target does not support the
3145 // use of absolute symbols to store constants. Print only if non-zero.
3146 if (ResByArg.second.Byte || ResByArg.second.Bit)
3147 Out << ", byte: " << ResByArg.second.Byte
3148 << ", bit: " << ResByArg.second.Bit;
3149
3150 Out << ")";
3151 }
3152 Out << ")";
3153 }
3154 Out << ")";
3155}
3156
3157static const char *getSummaryKindName(GlobalValueSummary::SummaryKind SK) {
3158 switch (SK) {
3159 case GlobalValueSummary::AliasKind:
3160 return "alias";
3161 case GlobalValueSummary::FunctionKind:
3162 return "function";
3163 case GlobalValueSummary::GlobalVarKind:
3164 return "variable";
3165 }
3166 llvm_unreachable("invalid summary kind");
3167}
3168
3169void AssemblyWriter::printAliasSummary(const AliasSummary *AS) {
3170 Out << ", aliasee: ";
3171 // The indexes emitted for distributed backends may not include the
3172 // aliasee summary (only if it is being imported directly). Handle
3173 // that case by just emitting "null" as the aliasee.
3174 if (AS->hasAliasee())
3175 Out << "^" << Machine.getGUIDSlot(GUID: SummaryToGUIDMap[&AS->getAliasee()]);
3176 else
3177 Out << "null";
3178}
3179
3180void AssemblyWriter::printGlobalVarSummary(const GlobalVarSummary *GS) {
3181 auto VTableFuncs = GS->vTableFuncs();
3182 Out << ", varFlags: (readonly: " << GS->VarFlags.MaybeReadOnly << ", "
3183 << "writeonly: " << GS->VarFlags.MaybeWriteOnly << ", "
3184 << "constant: " << GS->VarFlags.Constant;
3185 if (!VTableFuncs.empty())
3186 Out << ", "
3187 << "vcall_visibility: " << GS->VarFlags.VCallVisibility;
3188 Out << ")";
3189
3190 if (!VTableFuncs.empty()) {
3191 Out << ", vTableFuncs: (";
3192 FieldSeparator FS;
3193 for (auto &P : VTableFuncs) {
3194 Out << FS;
3195 Out << "(virtFunc: ^" << Machine.getGUIDSlot(GUID: P.FuncVI.getGUID())
3196 << ", offset: " << P.VTableOffset;
3197 Out << ")";
3198 }
3199 Out << ")";
3200 }
3201}
3202
3203static std::string getLinkageName(GlobalValue::LinkageTypes LT) {
3204 switch (LT) {
3205 case GlobalValue::ExternalLinkage:
3206 return "external";
3207 case GlobalValue::PrivateLinkage:
3208 return "private";
3209 case GlobalValue::InternalLinkage:
3210 return "internal";
3211 case GlobalValue::LinkOnceAnyLinkage:
3212 return "linkonce";
3213 case GlobalValue::LinkOnceODRLinkage:
3214 return "linkonce_odr";
3215 case GlobalValue::WeakAnyLinkage:
3216 return "weak";
3217 case GlobalValue::WeakODRLinkage:
3218 return "weak_odr";
3219 case GlobalValue::CommonLinkage:
3220 return "common";
3221 case GlobalValue::AppendingLinkage:
3222 return "appending";
3223 case GlobalValue::ExternalWeakLinkage:
3224 return "extern_weak";
3225 case GlobalValue::AvailableExternallyLinkage:
3226 return "available_externally";
3227 }
3228 llvm_unreachable("invalid linkage");
3229}
3230
3231// When printing the linkage types in IR where the ExternalLinkage is
3232// not printed, and other linkage types are expected to be printed with
3233// a space after the name.
3234static std::string getLinkageNameWithSpace(GlobalValue::LinkageTypes LT) {
3235 if (LT == GlobalValue::ExternalLinkage)
3236 return "";
3237 return getLinkageName(LT) + " ";
3238}
3239
3240static const char *getVisibilityName(GlobalValue::VisibilityTypes Vis) {
3241 switch (Vis) {
3242 case GlobalValue::DefaultVisibility:
3243 return "default";
3244 case GlobalValue::HiddenVisibility:
3245 return "hidden";
3246 case GlobalValue::ProtectedVisibility:
3247 return "protected";
3248 }
3249 llvm_unreachable("invalid visibility");
3250}
3251
3252void AssemblyWriter::printFunctionSummary(const FunctionSummary *FS) {
3253 Out << ", insts: " << FS->instCount();
3254 if (FS->fflags().anyFlagSet())
3255 Out << ", " << FS->fflags();
3256
3257 if (!FS->calls().empty()) {
3258 Out << ", calls: (";
3259 FieldSeparator IFS;
3260 for (auto &Call : FS->calls()) {
3261 Out << IFS;
3262 Out << "(callee: ^" << Machine.getGUIDSlot(GUID: Call.first.getGUID());
3263 if (Call.second.getHotness() != CalleeInfo::HotnessType::Unknown)
3264 Out << ", hotness: " << getHotnessName(HT: Call.second.getHotness());
3265 else if (Call.second.RelBlockFreq)
3266 Out << ", relbf: " << Call.second.RelBlockFreq;
3267 // Follow the convention of emitting flags as a boolean value, but only
3268 // emit if true to avoid unnecessary verbosity and test churn.
3269 if (Call.second.HasTailCall)
3270 Out << ", tail: 1";
3271 Out << ")";
3272 }
3273 Out << ")";
3274 }
3275
3276 if (const auto *TIdInfo = FS->getTypeIdInfo())
3277 printTypeIdInfo(TIDInfo: *TIdInfo);
3278
3279 // The AllocationType identifiers capture the profiled context behavior
3280 // reaching a specific static allocation site (possibly cloned).
3281 auto AllocTypeName = [](uint8_t Type) -> const char * {
3282 switch (Type) {
3283 case (uint8_t)AllocationType::None:
3284 return "none";
3285 case (uint8_t)AllocationType::NotCold:
3286 return "notcold";
3287 case (uint8_t)AllocationType::Cold:
3288 return "cold";
3289 case (uint8_t)AllocationType::Hot:
3290 return "hot";
3291 }
3292 llvm_unreachable("Unexpected alloc type");
3293 };
3294
3295 if (!FS->allocs().empty()) {
3296 Out << ", allocs: (";
3297 FieldSeparator AFS;
3298 for (auto &AI : FS->allocs()) {
3299 Out << AFS;
3300 Out << "(versions: (";
3301 FieldSeparator VFS;
3302 for (auto V : AI.Versions) {
3303 Out << VFS;
3304 Out << AllocTypeName(V);
3305 }
3306 Out << "), memProf: (";
3307 FieldSeparator MIBFS;
3308 for (auto &MIB : AI.MIBs) {
3309 Out << MIBFS;
3310 Out << "(type: " << AllocTypeName((uint8_t)MIB.AllocType);
3311 Out << ", stackIds: (";
3312 FieldSeparator SIDFS;
3313 for (auto Id : MIB.StackIdIndices) {
3314 Out << SIDFS;
3315 Out << TheIndex->getStackIdAtIndex(Index: Id);
3316 }
3317 Out << "))";
3318 }
3319 Out << "))";
3320 }
3321 Out << ")";
3322 }
3323
3324 if (!FS->callsites().empty()) {
3325 Out << ", callsites: (";
3326 FieldSeparator SNFS;
3327 for (auto &CI : FS->callsites()) {
3328 Out << SNFS;
3329 if (CI.Callee)
3330 Out << "(callee: ^" << Machine.getGUIDSlot(GUID: CI.Callee.getGUID());
3331 else
3332 Out << "(callee: null";
3333 Out << ", clones: (";
3334 FieldSeparator VFS;
3335 for (auto V : CI.Clones) {
3336 Out << VFS;
3337 Out << V;
3338 }
3339 Out << "), stackIds: (";
3340 FieldSeparator SIDFS;
3341 for (auto Id : CI.StackIdIndices) {
3342 Out << SIDFS;
3343 Out << TheIndex->getStackIdAtIndex(Index: Id);
3344 }
3345 Out << "))";
3346 }
3347 Out << ")";
3348 }
3349
3350 auto PrintRange = [&](const ConstantRange &Range) {
3351 Out << "[" << Range.getSignedMin() << ", " << Range.getSignedMax() << "]";
3352 };
3353
3354 if (!FS->paramAccesses().empty()) {
3355 Out << ", params: (";
3356 FieldSeparator IFS;
3357 for (auto &PS : FS->paramAccesses()) {
3358 Out << IFS;
3359 Out << "(param: " << PS.ParamNo;
3360 Out << ", offset: ";
3361 PrintRange(PS.Use);
3362 if (!PS.Calls.empty()) {
3363 Out << ", calls: (";
3364 FieldSeparator IFS;
3365 for (auto &Call : PS.Calls) {
3366 Out << IFS;
3367 Out << "(callee: ^" << Machine.getGUIDSlot(GUID: Call.Callee.getGUID());
3368 Out << ", param: " << Call.ParamNo;
3369 Out << ", offset: ";
3370 PrintRange(Call.Offsets);
3371 Out << ")";
3372 }
3373 Out << ")";
3374 }
3375 Out << ")";
3376 }
3377 Out << ")";
3378 }
3379}
3380
3381void AssemblyWriter::printTypeIdInfo(
3382 const FunctionSummary::TypeIdInfo &TIDInfo) {
3383 Out << ", typeIdInfo: (";
3384 FieldSeparator TIDFS;
3385 if (!TIDInfo.TypeTests.empty()) {
3386 Out << TIDFS;
3387 Out << "typeTests: (";
3388 FieldSeparator FS;
3389 for (auto &GUID : TIDInfo.TypeTests) {
3390 auto TidIter = TheIndex->typeIds().equal_range(x: GUID);
3391 if (TidIter.first == TidIter.second) {
3392 Out << FS;
3393 Out << GUID;
3394 continue;
3395 }
3396 // Print all type id that correspond to this GUID.
3397 for (auto It = TidIter.first; It != TidIter.second; ++It) {
3398 Out << FS;
3399 auto Slot = Machine.getTypeIdSlot(Id: It->second.first);
3400 assert(Slot != -1);
3401 Out << "^" << Slot;
3402 }
3403 }
3404 Out << ")";
3405 }
3406 if (!TIDInfo.TypeTestAssumeVCalls.empty()) {
3407 Out << TIDFS;
3408 printNonConstVCalls(VCallList: TIDInfo.TypeTestAssumeVCalls, Tag: "typeTestAssumeVCalls");
3409 }
3410 if (!TIDInfo.TypeCheckedLoadVCalls.empty()) {
3411 Out << TIDFS;
3412 printNonConstVCalls(VCallList: TIDInfo.TypeCheckedLoadVCalls, Tag: "typeCheckedLoadVCalls");
3413 }
3414 if (!TIDInfo.TypeTestAssumeConstVCalls.empty()) {
3415 Out << TIDFS;
3416 printConstVCalls(VCallList: TIDInfo.TypeTestAssumeConstVCalls,
3417 Tag: "typeTestAssumeConstVCalls");
3418 }
3419 if (!TIDInfo.TypeCheckedLoadConstVCalls.empty()) {
3420 Out << TIDFS;
3421 printConstVCalls(VCallList: TIDInfo.TypeCheckedLoadConstVCalls,
3422 Tag: "typeCheckedLoadConstVCalls");
3423 }
3424 Out << ")";
3425}
3426
3427void AssemblyWriter::printVFuncId(const FunctionSummary::VFuncId VFId) {
3428 auto TidIter = TheIndex->typeIds().equal_range(x: VFId.GUID);
3429 if (TidIter.first == TidIter.second) {
3430 Out << "vFuncId: (";
3431 Out << "guid: " << VFId.GUID;
3432 Out << ", offset: " << VFId.Offset;
3433 Out << ")";
3434 return;
3435 }
3436 // Print all type id that correspond to this GUID.
3437 FieldSeparator FS;
3438 for (auto It = TidIter.first; It != TidIter.second; ++It) {
3439 Out << FS;
3440 Out << "vFuncId: (";
3441 auto Slot = Machine.getTypeIdSlot(Id: It->second.first);
3442 assert(Slot != -1);
3443 Out << "^" << Slot;
3444 Out << ", offset: " << VFId.Offset;
3445 Out << ")";
3446 }
3447}
3448
3449void AssemblyWriter::printNonConstVCalls(
3450 const std::vector<FunctionSummary::VFuncId> &VCallList, const char *Tag) {
3451 Out << Tag << ": (";
3452 FieldSeparator FS;
3453 for (auto &VFuncId : VCallList) {
3454 Out << FS;
3455 printVFuncId(VFId: VFuncId);
3456 }
3457 Out << ")";
3458}
3459
3460void AssemblyWriter::printConstVCalls(
3461 const std::vector<FunctionSummary::ConstVCall> &VCallList,
3462 const char *Tag) {
3463 Out << Tag << ": (";
3464 FieldSeparator FS;
3465 for (auto &ConstVCall : VCallList) {
3466 Out << FS;
3467 Out << "(";
3468 printVFuncId(VFId: ConstVCall.VFunc);
3469 if (!ConstVCall.Args.empty()) {
3470 Out << ", ";
3471 printArgs(Args: ConstVCall.Args);
3472 }
3473 Out << ")";
3474 }
3475 Out << ")";
3476}
3477
3478void AssemblyWriter::printSummary(const GlobalValueSummary &Summary) {
3479 GlobalValueSummary::GVFlags GVFlags = Summary.flags();
3480 GlobalValue::LinkageTypes LT = (GlobalValue::LinkageTypes)GVFlags.Linkage;
3481 Out << getSummaryKindName(SK: Summary.getSummaryKind()) << ": ";
3482 Out << "(module: ^" << Machine.getModulePathSlot(Path: Summary.modulePath())
3483 << ", flags: (";
3484 Out << "linkage: " << getLinkageName(LT);
3485 Out << ", visibility: "
3486 << getVisibilityName(Vis: (GlobalValue::VisibilityTypes)GVFlags.Visibility);
3487 Out << ", notEligibleToImport: " << GVFlags.NotEligibleToImport;
3488 Out << ", live: " << GVFlags.Live;
3489 Out << ", dsoLocal: " << GVFlags.DSOLocal;
3490 Out << ", canAutoHide: " << GVFlags.CanAutoHide;
3491 Out << ")";
3492
3493 if (Summary.getSummaryKind() == GlobalValueSummary::AliasKind)
3494 printAliasSummary(AS: cast<AliasSummary>(Val: &Summary));
3495 else if (Summary.getSummaryKind() == GlobalValueSummary::FunctionKind)
3496 printFunctionSummary(FS: cast<FunctionSummary>(Val: &Summary));
3497 else
3498 printGlobalVarSummary(GS: cast<GlobalVarSummary>(Val: &Summary));
3499
3500 auto RefList = Summary.refs();
3501 if (!RefList.empty()) {
3502 Out << ", refs: (";
3503 FieldSeparator FS;
3504 for (auto &Ref : RefList) {
3505 Out << FS;
3506 if (Ref.isReadOnly())
3507 Out << "readonly ";
3508 else if (Ref.isWriteOnly())
3509 Out << "writeonly ";
3510 Out << "^" << Machine.getGUIDSlot(GUID: Ref.getGUID());
3511 }
3512 Out << ")";
3513 }
3514
3515 Out << ")";
3516}
3517
3518void AssemblyWriter::printSummaryInfo(unsigned Slot, const ValueInfo &VI) {
3519 Out << "^" << Slot << " = gv: (";
3520 if (!VI.name().empty())
3521 Out << "name: \"" << VI.name() << "\"";
3522 else
3523 Out << "guid: " << VI.getGUID();
3524 if (!VI.getSummaryList().empty()) {
3525 Out << ", summaries: (";
3526 FieldSeparator FS;
3527 for (auto &Summary : VI.getSummaryList()) {
3528 Out << FS;
3529 printSummary(Summary: *Summary);
3530 }
3531 Out << ")";
3532 }
3533 Out << ")";
3534 if (!VI.name().empty())
3535 Out << " ; guid = " << VI.getGUID();
3536 Out << "\n";
3537}
3538
3539static void printMetadataIdentifier(StringRef Name,
3540 formatted_raw_ostream &Out) {
3541 if (Name.empty()) {
3542 Out << "<empty name> ";
3543 } else {
3544 unsigned char FirstC = static_cast<unsigned char>(Name[0]);
3545 if (isalpha(FirstC) || FirstC == '-' || FirstC == '$' || FirstC == '.' ||
3546 FirstC == '_')
3547 Out << FirstC;
3548 else
3549 Out << '\\' << hexdigit(X: FirstC >> 4) << hexdigit(X: FirstC & 0x0F);
3550 for (unsigned i = 1, e = Name.size(); i != e; ++i) {
3551 unsigned char C = Name[i];
3552 if (isalnum(C) || C == '-' || C == '$' || C == '.' || C == '_')
3553 Out << C;
3554 else
3555 Out << '\\' << hexdigit(X: C >> 4) << hexdigit(X: C & 0x0F);
3556 }
3557 }
3558}
3559
3560void AssemblyWriter::printNamedMDNode(const NamedMDNode *NMD) {
3561 Out << '!';
3562 printMetadataIdentifier(Name: NMD->getName(), Out);
3563 Out << " = !{";
3564 for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
3565 if (i)
3566 Out << ", ";
3567
3568 // Write DIExpressions inline.
3569 // FIXME: Ban DIExpressions in NamedMDNodes, they will serve no purpose.
3570 MDNode *Op = NMD->getOperand(i);
3571 if (auto *Expr = dyn_cast<DIExpression>(Val: Op)) {
3572 writeDIExpression(Out, N: Expr, WriterCtx&: AsmWriterContext::getEmpty());
3573 continue;
3574 }
3575
3576 int Slot = Machine.getMetadataSlot(N: Op);
3577 if (Slot == -1)
3578 Out << "<badref>";
3579 else
3580 Out << '!' << Slot;
3581 }
3582 Out << "}\n";
3583}
3584
3585static void PrintVisibility(GlobalValue::VisibilityTypes Vis,
3586 formatted_raw_ostream &Out) {
3587 switch (Vis) {
3588 case GlobalValue::DefaultVisibility: break;
3589 case GlobalValue::HiddenVisibility: Out << "hidden "; break;
3590 case GlobalValue::ProtectedVisibility: Out << "protected "; break;
3591 }
3592}
3593
3594static void PrintDSOLocation(const GlobalValue &GV,
3595 formatted_raw_ostream &Out) {
3596 if (GV.isDSOLocal() && !GV.isImplicitDSOLocal())
3597 Out << "dso_local ";
3598}
3599
3600static void PrintDLLStorageClass(GlobalValue::DLLStorageClassTypes SCT,
3601 formatted_raw_ostream &Out) {
3602 switch (SCT) {
3603 case GlobalValue::DefaultStorageClass: break;
3604 case GlobalValue::DLLImportStorageClass: Out << "dllimport "; break;
3605 case GlobalValue::DLLExportStorageClass: Out << "dllexport "; break;
3606 }
3607}
3608
3609static void PrintThreadLocalModel(GlobalVariable::ThreadLocalMode TLM,
3610 formatted_raw_ostream &Out) {
3611 switch (TLM) {
3612 case GlobalVariable::NotThreadLocal:
3613 break;
3614 case GlobalVariable::GeneralDynamicTLSModel:
3615 Out << "thread_local ";
3616 break;
3617 case GlobalVariable::LocalDynamicTLSModel:
3618 Out << "thread_local(localdynamic) ";
3619 break;
3620 case GlobalVariable::InitialExecTLSModel:
3621 Out << "thread_local(initialexec) ";
3622 break;
3623 case GlobalVariable::LocalExecTLSModel:
3624 Out << "thread_local(localexec) ";
3625 break;
3626 }
3627}
3628
3629static StringRef getUnnamedAddrEncoding(GlobalVariable::UnnamedAddr UA) {
3630 switch (UA) {
3631 case GlobalVariable::UnnamedAddr::None:
3632 return "";
3633 case GlobalVariable::UnnamedAddr::Local:
3634 return "local_unnamed_addr";
3635 case GlobalVariable::UnnamedAddr::Global:
3636 return "unnamed_addr";
3637 }
3638 llvm_unreachable("Unknown UnnamedAddr");
3639}
3640
3641static void maybePrintComdat(formatted_raw_ostream &Out,
3642 const GlobalObject &GO) {
3643 const Comdat *C = GO.getComdat();
3644 if (!C)
3645 return;
3646
3647 if (isa<GlobalVariable>(Val: GO))
3648 Out << ',';
3649 Out << " comdat";
3650
3651 if (GO.getName() == C->getName())
3652 return;
3653
3654 Out << '(';
3655 PrintLLVMName(OS&: Out, Name: C->getName(), Prefix: ComdatPrefix);
3656 Out << ')';
3657}
3658
3659void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
3660 if (GV->isMaterializable())
3661 Out << "; Materializable\n";
3662
3663 AsmWriterContext WriterCtx(&TypePrinter, &Machine, GV->getParent());
3664 WriteAsOperandInternal(Out, V: GV, WriterCtx);
3665 Out << " = ";
3666
3667 if (!GV->hasInitializer() && GV->hasExternalLinkage())
3668 Out << "external ";
3669
3670 Out << getLinkageNameWithSpace(LT: GV->getLinkage());
3671 PrintDSOLocation(GV: *GV, Out);
3672 PrintVisibility(Vis: GV->getVisibility(), Out);
3673 PrintDLLStorageClass(SCT: GV->getDLLStorageClass(), Out);
3674 PrintThreadLocalModel(TLM: GV->getThreadLocalMode(), Out);
3675 StringRef UA = getUnnamedAddrEncoding(UA: GV->getUnnamedAddr());
3676 if (!UA.empty())
3677 Out << UA << ' ';
3678
3679 if (unsigned AddressSpace = GV->getType()->getAddressSpace())
3680 Out << "addrspace(" << AddressSpace << ") ";
3681 if (GV->isExternallyInitialized()) Out << "externally_initialized ";
3682 Out << (GV->isConstant() ? "constant " : "global ");
3683 TypePrinter.print(Ty: GV->getValueType(), OS&: Out);
3684
3685 if (GV->hasInitializer()) {
3686 Out << ' ';
3687 writeOperand(Operand: GV->getInitializer(), PrintType: false);
3688 }
3689
3690 if (GV->hasSection()) {
3691 Out << ", section \"";
3692 printEscapedString(Name: GV->getSection(), Out);
3693 Out << '"';
3694 }
3695 if (GV->hasPartition()) {
3696 Out << ", partition \"";
3697 printEscapedString(Name: GV->getPartition(), Out);
3698 Out << '"';
3699 }
3700 if (auto CM = GV->getCodeModel()) {
3701 Out << ", code_model \"";
3702 switch (*CM) {
3703 case CodeModel::Tiny:
3704 Out << "tiny";
3705 break;
3706 case CodeModel::Small:
3707 Out << "small";
3708 break;
3709 case CodeModel::Kernel:
3710 Out << "kernel";
3711 break;
3712 case CodeModel::Medium:
3713 Out << "medium";
3714 break;
3715 case CodeModel::Large:
3716 Out << "large";
3717 break;
3718 }
3719 Out << '"';
3720 }
3721
3722 using SanitizerMetadata = llvm::GlobalValue::SanitizerMetadata;
3723 if (GV->hasSanitizerMetadata()) {
3724 SanitizerMetadata MD = GV->getSanitizerMetadata();
3725 if (MD.NoAddress)
3726 Out << ", no_sanitize_address";
3727 if (MD.NoHWAddress)
3728 Out << ", no_sanitize_hwaddress";
3729 if (MD.Memtag)
3730 Out << ", sanitize_memtag";
3731 if (MD.IsDynInit)
3732 Out << ", sanitize_address_dyninit";
3733 }
3734
3735 maybePrintComdat(Out, GO: *GV);
3736 if (MaybeAlign A = GV->getAlign())
3737 Out << ", align " << A->value();
3738
3739 SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
3740 GV->getAllMetadata(MDs);
3741 printMetadataAttachments(MDs, Separator: ", ");
3742
3743 auto Attrs = GV->getAttributes();
3744 if (Attrs.hasAttributes())
3745 Out << " #" << Machine.getAttributeGroupSlot(AS: Attrs);
3746
3747 printInfoComment(V: *GV);
3748}
3749
3750void AssemblyWriter::printAlias(const GlobalAlias *GA) {
3751 if (GA->isMaterializable())
3752 Out << "; Materializable\n";
3753
3754 AsmWriterContext WriterCtx(&TypePrinter, &Machine, GA->getParent());
3755 WriteAsOperandInternal(Out, V: GA, WriterCtx);
3756 Out << " = ";
3757
3758 Out << getLinkageNameWithSpace(LT: GA->getLinkage());
3759 PrintDSOLocation(GV: *GA, Out);
3760 PrintVisibility(Vis: GA->getVisibility(), Out);
3761 PrintDLLStorageClass(SCT: GA->getDLLStorageClass(), Out);
3762 PrintThreadLocalModel(TLM: GA->getThreadLocalMode(), Out);
3763 StringRef UA = getUnnamedAddrEncoding(UA: GA->getUnnamedAddr());
3764 if (!UA.empty())
3765 Out << UA << ' ';
3766
3767 Out << "alias ";
3768
3769 TypePrinter.print(Ty: GA->getValueType(), OS&: Out);
3770 Out << ", ";
3771
3772 if (const Constant *Aliasee = GA->getAliasee()) {
3773 writeOperand(Operand: Aliasee, PrintType: !isa<ConstantExpr>(Val: Aliasee));
3774 } else {
3775 TypePrinter.print(Ty: GA->getType(), OS&: Out);
3776 Out << " <<NULL ALIASEE>>";
3777 }
3778
3779 if (GA->hasPartition()) {
3780 Out << ", partition \"";
3781 printEscapedString(Name: GA->getPartition(), Out);
3782 Out << '"';
3783 }
3784
3785 printInfoComment(V: *GA);
3786 Out << '\n';
3787}
3788
3789void AssemblyWriter::printIFunc(const GlobalIFunc *GI) {
3790 if (GI->isMaterializable())
3791 Out << "; Materializable\n";
3792
3793 AsmWriterContext WriterCtx(&TypePrinter, &Machine, GI->getParent());
3794 WriteAsOperandInternal(Out, V: GI, WriterCtx);
3795 Out << " = ";
3796
3797 Out << getLinkageNameWithSpace(LT: GI->getLinkage());
3798 PrintDSOLocation(GV: *GI, Out);
3799 PrintVisibility(Vis: GI->getVisibility(), Out);
3800
3801 Out << "ifunc ";
3802
3803 TypePrinter.print(Ty: GI->getValueType(), OS&: Out);
3804 Out << ", ";
3805
3806 if (const Constant *Resolver = GI->getResolver()) {
3807 writeOperand(Operand: Resolver, PrintType: !isa<ConstantExpr>(Val: Resolver));
3808 } else {
3809 TypePrinter.print(Ty: GI->getType(), OS&: Out);
3810 Out << " <<NULL RESOLVER>>";
3811 }
3812
3813 if (GI->hasPartition()) {
3814 Out << ", partition \"";
3815 printEscapedString(Name: GI->getPartition(), Out);
3816 Out << '"';
3817 }
3818
3819 printInfoComment(V: *GI);
3820 Out << '\n';
3821}
3822
3823void AssemblyWriter::printComdat(const Comdat *C) {
3824 C->print(OS&: Out);
3825}
3826
3827void AssemblyWriter::printTypeIdentities() {
3828 if (TypePrinter.empty())
3829 return;
3830
3831 Out << '\n';
3832
3833 // Emit all numbered types.
3834 auto &NumberedTypes = TypePrinter.getNumberedTypes();
3835 for (unsigned I = 0, E = NumberedTypes.size(); I != E; ++I) {
3836 Out << '%' << I << " = type ";
3837
3838 // Make sure we print out at least one level of the type structure, so
3839 // that we do not get %2 = type %2
3840 TypePrinter.printStructBody(STy: NumberedTypes[I], OS&: Out);
3841 Out << '\n';
3842 }
3843
3844 auto &NamedTypes = TypePrinter.getNamedTypes();
3845 for (StructType *NamedType : NamedTypes) {
3846 PrintLLVMName(OS&: Out, Name: NamedType->getName(), Prefix: LocalPrefix);
3847 Out << " = type ";
3848
3849 // Make sure we print out at least one level of the type structure, so
3850 // that we do not get %FILE = type %FILE
3851 TypePrinter.printStructBody(STy: NamedType, OS&: Out);
3852 Out << '\n';
3853 }
3854}
3855
3856/// printFunction - Print all aspects of a function.
3857void AssemblyWriter::printFunction(const Function *F) {
3858 bool ConvertBack = F->IsNewDbgInfoFormat;
3859 if (ConvertBack)
3860 const_cast<Function *>(F)->convertFromNewDbgValues();
3861 if (AnnotationWriter) AnnotationWriter->emitFunctionAnnot(F, Out);
3862
3863 if (F->isMaterializable())
3864 Out << "; Materializable\n";
3865
3866 const AttributeList &Attrs = F->getAttributes();
3867 if (Attrs.hasFnAttrs()) {
3868 AttributeSet AS = Attrs.getFnAttrs();
3869 std::string AttrStr;
3870
3871 for (const Attribute &Attr : AS) {
3872 if (!Attr.isStringAttribute()) {
3873 if (!AttrStr.empty()) AttrStr += ' ';
3874 AttrStr += Attr.getAsString();
3875 }
3876 }
3877
3878 if (!AttrStr.empty())
3879 Out << "; Function Attrs: " << AttrStr << '\n';
3880 }
3881
3882 Machine.incorporateFunction(F);
3883
3884 if (F->isDeclaration()) {
3885 Out << "declare";
3886 SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
3887 F->getAllMetadata(MDs);
3888 printMetadataAttachments(MDs, Separator: " ");
3889 Out << ' ';
3890 } else
3891 Out << "define ";
3892
3893 Out << getLinkageNameWithSpace(LT: F->getLinkage());
3894 PrintDSOLocation(GV: *F, Out);
3895 PrintVisibility(Vis: F->getVisibility(), Out);
3896 PrintDLLStorageClass(SCT: F->getDLLStorageClass(), Out);
3897
3898 // Print the calling convention.
3899 if (F->getCallingConv() != CallingConv::C) {
3900 PrintCallingConv(cc: F->getCallingConv(), Out);
3901 Out << " ";
3902 }
3903
3904 FunctionType *FT = F->getFunctionType();
3905 if (Attrs.hasRetAttrs())
3906 Out << Attrs.getAsString(Index: AttributeList::ReturnIndex) << ' ';
3907 TypePrinter.print(Ty: F->getReturnType(), OS&: Out);
3908 AsmWriterContext WriterCtx(&TypePrinter, &Machine, F->getParent());
3909 Out << ' ';
3910 WriteAsOperandInternal(Out, V: F, WriterCtx);
3911 Out << '(';
3912
3913 // Loop over the arguments, printing them...
3914 if (F->isDeclaration() && !IsForDebug) {
3915 // We're only interested in the type here - don't print argument names.
3916 for (unsigned I = 0, E = FT->getNumParams(); I != E; ++I) {
3917 // Insert commas as we go... the first arg doesn't get a comma
3918 if (I)
3919 Out << ", ";
3920 // Output type...
3921 TypePrinter.print(Ty: FT->getParamType(i: I), OS&: Out);
3922
3923 AttributeSet ArgAttrs = Attrs.getParamAttrs(ArgNo: I);
3924 if (ArgAttrs.hasAttributes()) {
3925 Out << ' ';
3926 writeAttributeSet(AttrSet: ArgAttrs);
3927 }
3928 }
3929 } else {
3930 // The arguments are meaningful here, print them in detail.
3931 for (const Argument &Arg : F->args()) {
3932 // Insert commas as we go... the first arg doesn't get a comma
3933 if (Arg.getArgNo() != 0)
3934 Out << ", ";
3935 printArgument(FA: &Arg, Attrs: Attrs.getParamAttrs(ArgNo: Arg.getArgNo()));
3936 }
3937 }
3938
3939 // Finish printing arguments...
3940 if (FT->isVarArg()) {
3941 if (FT->getNumParams()) Out << ", ";
3942 Out << "..."; // Output varargs portion of signature!
3943 }
3944 Out << ')';
3945 StringRef UA = getUnnamedAddrEncoding(UA: F->getUnnamedAddr());
3946 if (!UA.empty())
3947 Out << ' ' << UA;
3948 // We print the function address space if it is non-zero or if we are writing
3949 // a module with a non-zero program address space or if there is no valid
3950 // Module* so that the file can be parsed without the datalayout string.
3951 const Module *Mod = F->getParent();
3952 if (F->getAddressSpace() != 0 || !Mod ||
3953 Mod->getDataLayout().getProgramAddressSpace() != 0)
3954 Out << " addrspace(" << F->getAddressSpace() << ")";
3955 if (Attrs.hasFnAttrs())
3956 Out << " #" << Machine.getAttributeGroupSlot(AS: Attrs.getFnAttrs());
3957 if (F->hasSection()) {
3958 Out << " section \"";
3959 printEscapedString(Name: F->getSection(), Out);
3960 Out << '"';
3961 }
3962 if (F->hasPartition()) {
3963 Out << " partition \"";
3964 printEscapedString(Name: F->getPartition(), Out);
3965 Out << '"';
3966 }
3967 maybePrintComdat(Out, GO: *F);
3968 if (MaybeAlign A = F->getAlign())
3969 Out << " align " << A->value();
3970 if (F->hasGC())
3971 Out << " gc \"" << F->getGC() << '"';
3972 if (F->hasPrefixData()) {
3973 Out << " prefix ";
3974 writeOperand(Operand: F->getPrefixData(), PrintType: true);
3975 }
3976 if (F->hasPrologueData()) {
3977 Out << " prologue ";
3978 writeOperand(Operand: F->getPrologueData(), PrintType: true);
3979 }
3980 if (F->hasPersonalityFn()) {
3981 Out << " personality ";
3982 writeOperand(Operand: F->getPersonalityFn(), /*PrintType=*/true);
3983 }
3984
3985 if (F->isDeclaration()) {
3986 Out << '\n';
3987 } else {
3988 SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
3989 F->getAllMetadata(MDs);
3990 printMetadataAttachments(MDs, Separator: " ");
3991
3992 Out << " {";
3993 // Output all of the function's basic blocks.
3994 for (const BasicBlock &BB : *F)
3995 printBasicBlock(BB: &BB);
3996
3997 // Output the function's use-lists.
3998 printUseLists(F);
3999
4000 Out << "}\n";
4001 }
4002
4003 if (ConvertBack)
4004 const_cast<Function *>(F)->convertToNewDbgValues();
4005 Machine.purgeFunction();
4006}
4007
4008/// printArgument - This member is called for every argument that is passed into
4009/// the function. Simply print it out
4010void AssemblyWriter::printArgument(const Argument *Arg, AttributeSet Attrs) {
4011 // Output type...
4012 TypePrinter.print(Ty: Arg->getType(), OS&: Out);
4013
4014 // Output parameter attributes list
4015 if (Attrs.hasAttributes()) {
4016 Out << ' ';
4017 writeAttributeSet(AttrSet: Attrs);
4018 }
4019
4020 // Output name, if available...
4021 if (Arg->hasName()) {
4022 Out << ' ';
4023 PrintLLVMName(OS&: Out, V: Arg);
4024 } else {
4025 int Slot = Machine.getLocalSlot(V: Arg);
4026 assert(Slot != -1 && "expect argument in function here");
4027 Out << " %" << Slot;
4028 }
4029}
4030
4031/// printBasicBlock - This member is called for each basic block in a method.
4032void AssemblyWriter::printBasicBlock(const BasicBlock *BB) {
4033 bool IsEntryBlock = BB->getParent() && BB->isEntryBlock();
4034 if (BB->hasName()) { // Print out the label if it exists...
4035 Out << "\n";
4036 PrintLLVMName(OS&: Out, Name: BB->getName(), Prefix: LabelPrefix);
4037 Out << ':';
4038 } else if (!IsEntryBlock) {
4039 Out << "\n";
4040 int Slot = Machine.getLocalSlot(V: BB);
4041 if (Slot != -1)
4042 Out << Slot << ":";
4043 else
4044 Out << "<badref>:";
4045 }
4046
4047 if (!IsEntryBlock) {
4048 // Output predecessors for the block.
4049 Out.PadToColumn(NewCol: 50);
4050 Out << ";";
4051 const_pred_iterator PI = pred_begin(BB), PE = pred_end(BB);
4052
4053 if (PI == PE) {
4054 Out << " No predecessors!";
4055 } else {
4056 Out << " preds = ";
4057 writeOperand(Operand: *PI, PrintType: false);
4058 for (++PI; PI != PE; ++PI) {
4059 Out << ", ";
4060 writeOperand(Operand: *PI, PrintType: false);
4061 }
4062 }
4063 }
4064
4065 Out << "\n";
4066
4067 if (AnnotationWriter) AnnotationWriter->emitBasicBlockStartAnnot(BB, Out);
4068
4069 // Output all of the instructions in the basic block...
4070 for (const Instruction &I : *BB) {
4071 printInstructionLine(I);
4072 }
4073
4074 if (AnnotationWriter) AnnotationWriter->emitBasicBlockEndAnnot(BB, Out);
4075}
4076
4077/// printInstructionLine - Print an instruction and a newline character.
4078void AssemblyWriter::printInstructionLine(const Instruction &I) {
4079 printInstruction(I);
4080 Out << '\n';
4081}
4082
4083/// printGCRelocateComment - print comment after call to the gc.relocate
4084/// intrinsic indicating base and derived pointer names.
4085void AssemblyWriter::printGCRelocateComment(const GCRelocateInst &Relocate) {
4086 Out << " ; (";
4087 writeOperand(Operand: Relocate.getBasePtr(), PrintType: false);
4088 Out << ", ";
4089 writeOperand(Operand: Relocate.getDerivedPtr(), PrintType: false);
4090 Out << ")";
4091}
4092
4093/// printInfoComment - Print a little comment after the instruction indicating
4094/// which slot it occupies.
4095void AssemblyWriter::printInfoComment(const Value &V) {
4096 if (const auto *Relocate = dyn_cast<GCRelocateInst>(Val: &V))
4097 printGCRelocateComment(Relocate: *Relocate);
4098
4099 if (AnnotationWriter) {
4100 AnnotationWriter->printInfoComment(V, Out);
4101 }
4102}
4103
4104static void maybePrintCallAddrSpace(const Value *Operand, const Instruction *I,
4105 raw_ostream &Out) {
4106 // We print the address space of the call if it is non-zero.
4107 if (Operand == nullptr) {
4108 Out << " <cannot get addrspace!>";
4109 return;
4110 }
4111 unsigned CallAddrSpace = Operand->getType()->getPointerAddressSpace();
4112 bool PrintAddrSpace = CallAddrSpace != 0;
4113 if (!PrintAddrSpace) {
4114 const Module *Mod = getModuleFromVal(V: I);
4115 // We also print it if it is zero but not equal to the program address space
4116 // or if we can't find a valid Module* to make it possible to parse
4117 // the resulting file even without a datalayout string.
4118 if (!Mod || Mod->getDataLayout().getProgramAddressSpace() != 0)
4119 PrintAddrSpace = true;
4120 }
4121 if (PrintAddrSpace)
4122 Out << " addrspace(" << CallAddrSpace << ")";
4123}
4124
4125// This member is called for each Instruction in a function..
4126void AssemblyWriter::printInstruction(const Instruction &I) {
4127 if (AnnotationWriter) AnnotationWriter->emitInstructionAnnot(&I, Out);
4128
4129 // Print out indentation for an instruction.
4130 Out << " ";
4131
4132 // Print out name if it exists...
4133 if (I.hasName()) {
4134 PrintLLVMName(OS&: Out, V: &I);
4135 Out << " = ";
4136 } else if (!I.getType()->isVoidTy()) {
4137 // Print out the def slot taken.
4138 int SlotNum = Machine.getLocalSlot(V: &I);
4139 if (SlotNum == -1)
4140 Out << "<badref> = ";
4141 else
4142 Out << '%' << SlotNum << " = ";
4143 }
4144
4145 if (const CallInst *CI = dyn_cast<CallInst>(Val: &I)) {
4146 if (CI->isMustTailCall())
4147 Out << "musttail ";
4148 else if (CI->isTailCall())
4149 Out << "tail ";
4150 else if (CI->isNoTailCall())
4151 Out << "notail ";
4152 }
4153
4154 // Print out the opcode...
4155 Out << I.getOpcodeName();
4156
4157 // If this is an atomic load or store, print out the atomic marker.
4158 if ((isa<LoadInst>(Val: I) && cast<LoadInst>(Val: I).isAtomic()) ||
4159 (isa<StoreInst>(Val: I) && cast<StoreInst>(Val: I).isAtomic()))
4160 Out << " atomic";
4161
4162 if (isa<AtomicCmpXchgInst>(Val: I) && cast<AtomicCmpXchgInst>(Val: I).isWeak())
4163 Out << " weak";
4164
4165 // If this is a volatile operation, print out the volatile marker.
4166 if ((isa<LoadInst>(Val: I) && cast<LoadInst>(Val: I).isVolatile()) ||
4167 (isa<StoreInst>(Val: I) && cast<StoreInst>(Val: I).isVolatile()) ||
4168 (isa<AtomicCmpXchgInst>(Val: I) && cast<AtomicCmpXchgInst>(Val: I).isVolatile()) ||
4169 (isa<AtomicRMWInst>(Val: I) && cast<AtomicRMWInst>(Val: I).isVolatile()))
4170 Out << " volatile";
4171
4172 // Print out optimization information.
4173 WriteOptimizationInfo(Out, U: &I);
4174
4175 // Print out the compare instruction predicates
4176 if (const CmpInst *CI = dyn_cast<CmpInst>(Val: &I))
4177 Out << ' ' << CI->getPredicate();
4178
4179 // Print out the atomicrmw operation
4180 if (const AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(Val: &I))
4181 Out << ' ' << AtomicRMWInst::getOperationName(Op: RMWI->getOperation());
4182
4183 // Print out the type of the operands...
4184 const Value *Operand = I.getNumOperands() ? I.getOperand(i: 0) : nullptr;
4185
4186 // Special case conditional branches to swizzle the condition out to the front
4187 if (isa<BranchInst>(Val: I) && cast<BranchInst>(Val: I).isConditional()) {
4188 const BranchInst &BI(cast<BranchInst>(Val: I));
4189 Out << ' ';
4190 writeOperand(Operand: BI.getCondition(), PrintType: true);
4191 Out << ", ";
4192 writeOperand(Operand: BI.getSuccessor(i: 0), PrintType: true);
4193 Out << ", ";
4194 writeOperand(Operand: BI.getSuccessor(i: 1), PrintType: true);
4195
4196 } else if (isa<SwitchInst>(Val: I)) {
4197 const SwitchInst& SI(cast<SwitchInst>(Val: I));
4198 // Special case switch instruction to get formatting nice and correct.
4199 Out << ' ';
4200 writeOperand(Operand: SI.getCondition(), PrintType: true);
4201 Out << ", ";
4202 writeOperand(Operand: SI.getDefaultDest(), PrintType: true);
4203 Out << " [";
4204 for (auto Case : SI.cases()) {
4205 Out << "\n ";
4206 writeOperand(Operand: Case.getCaseValue(), PrintType: true);
4207 Out << ", ";
4208 writeOperand(Operand: Case.getCaseSuccessor(), PrintType: true);
4209 }
4210 Out << "\n ]";
4211 } else if (isa<IndirectBrInst>(Val: I)) {
4212 // Special case indirectbr instruction to get formatting nice and correct.
4213 Out << ' ';
4214 writeOperand(Operand, PrintType: true);
4215 Out << ", [";
4216
4217 for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i) {
4218 if (i != 1)
4219 Out << ", ";
4220 writeOperand(Operand: I.getOperand(i), PrintType: true);
4221 }
4222 Out << ']';
4223 } else if (const PHINode *PN = dyn_cast<PHINode>(Val: &I)) {
4224 Out << ' ';
4225 TypePrinter.print(Ty: I.getType(), OS&: Out);
4226 Out << ' ';
4227
4228 for (unsigned op = 0, Eop = PN->getNumIncomingValues(); op < Eop; ++op) {
4229 if (op) Out << ", ";
4230 Out << "[ ";
4231 writeOperand(Operand: PN->getIncomingValue(i: op), PrintType: false); Out << ", ";
4232 writeOperand(Operand: PN->getIncomingBlock(i: op), PrintType: false); Out << " ]";
4233 }
4234 } else if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(Val: &I)) {
4235 Out << ' ';
4236 writeOperand(Operand: I.getOperand(i: 0), PrintType: true);
4237 for (unsigned i : EVI->indices())
4238 Out << ", " << i;
4239 } else if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(Val: &I)) {
4240 Out << ' ';
4241 writeOperand(Operand: I.getOperand(i: 0), PrintType: true); Out << ", ";
4242 writeOperand(Operand: I.getOperand(i: 1), PrintType: true);
4243 for (unsigned i : IVI->indices())
4244 Out << ", " << i;
4245 } else if (const LandingPadInst *LPI = dyn_cast<LandingPadInst>(Val: &I)) {
4246 Out << ' ';
4247 TypePrinter.print(Ty: I.getType(), OS&: Out);
4248 if (LPI->isCleanup() || LPI->getNumClauses() != 0)
4249 Out << '\n';
4250
4251 if (LPI->isCleanup())
4252 Out << " cleanup";
4253
4254 for (unsigned i = 0, e = LPI->getNumClauses(); i != e; ++i) {
4255 if (i != 0 || LPI->isCleanup()) Out << "\n";
4256 if (LPI->isCatch(Idx: i))
4257 Out << " catch ";
4258 else
4259 Out << " filter ";
4260
4261 writeOperand(Operand: LPI->getClause(Idx: i), PrintType: true);
4262 }
4263 } else if (const auto *CatchSwitch = dyn_cast<CatchSwitchInst>(Val: &I)) {
4264 Out << " within ";
4265 writeOperand(Operand: CatchSwitch->getParentPad(), /*PrintType=*/false);
4266 Out << " [";
4267 unsigned Op = 0;
4268 for (const BasicBlock *PadBB : CatchSwitch->handlers()) {
4269 if (Op > 0)
4270 Out << ", ";
4271 writeOperand(Operand: PadBB, /*PrintType=*/true);
4272 ++Op;
4273 }
4274 Out << "] unwind ";
4275 if (const BasicBlock *UnwindDest = CatchSwitch->getUnwindDest())
4276 writeOperand(Operand: UnwindDest, /*PrintType=*/true);
4277 else
4278 Out << "to caller";
4279 } else if (const auto *FPI = dyn_cast<FuncletPadInst>(Val: &I)) {
4280 Out << " within ";
4281 writeOperand(Operand: FPI->getParentPad(), /*PrintType=*/false);
4282 Out << " [";
4283 for (unsigned Op = 0, NumOps = FPI->arg_size(); Op < NumOps; ++Op) {
4284 if (Op > 0)
4285 Out << ", ";
4286 writeOperand(Operand: FPI->getArgOperand(i: Op), /*PrintType=*/true);
4287 }
4288 Out << ']';
4289 } else if (isa<ReturnInst>(Val: I) && !Operand) {
4290 Out << " void";
4291 } else if (const auto *CRI = dyn_cast<CatchReturnInst>(Val: &I)) {
4292 Out << " from ";
4293 writeOperand(Operand: CRI->getOperand(i_nocapture: 0), /*PrintType=*/false);
4294
4295 Out << " to ";
4296 writeOperand(Operand: CRI->getOperand(i_nocapture: 1), /*PrintType=*/true);
4297 } else if (const auto *CRI = dyn_cast<CleanupReturnInst>(Val: &I)) {
4298 Out << " from ";
4299 writeOperand(Operand: CRI->getOperand(i_nocapture: 0), /*PrintType=*/false);
4300
4301 Out << " unwind ";
4302 if (CRI->hasUnwindDest())
4303 writeOperand(Operand: CRI->getOperand(i_nocapture: 1), /*PrintType=*/true);
4304 else
4305 Out << "to caller";
4306 } else if (const CallInst *CI = dyn_cast<CallInst>(Val: &I)) {
4307 // Print the calling convention being used.
4308 if (CI->getCallingConv() != CallingConv::C) {
4309 Out << " ";
4310 PrintCallingConv(cc: CI->getCallingConv(), Out);
4311 }
4312
4313 Operand = CI->getCalledOperand();
4314 FunctionType *FTy = CI->getFunctionType();
4315 Type *RetTy = FTy->getReturnType();
4316 const AttributeList &PAL = CI->getAttributes();
4317
4318 if (PAL.hasRetAttrs())
4319 Out << ' ' << PAL.getAsString(Index: AttributeList::ReturnIndex);
4320
4321 // Only print addrspace(N) if necessary:
4322 maybePrintCallAddrSpace(Operand, I: &I, Out);
4323
4324 // If possible, print out the short form of the call instruction. We can
4325 // only do this if the first argument is a pointer to a nonvararg function,
4326 // and if the return type is not a pointer to a function.
4327 Out << ' ';
4328 TypePrinter.print(Ty: FTy->isVarArg() ? FTy : RetTy, OS&: Out);
4329 Out << ' ';
4330 writeOperand(Operand, PrintType: false);
4331 Out << '(';
4332 for (unsigned op = 0, Eop = CI->arg_size(); op < Eop; ++op) {
4333 if (op > 0)
4334 Out << ", ";
4335 writeParamOperand(Operand: CI->getArgOperand(i: op), Attrs: PAL.getParamAttrs(ArgNo: op));
4336 }
4337
4338 // Emit an ellipsis if this is a musttail call in a vararg function. This
4339 // is only to aid readability, musttail calls forward varargs by default.
4340 if (CI->isMustTailCall() && CI->getParent() &&
4341 CI->getParent()->getParent() &&
4342 CI->getParent()->getParent()->isVarArg()) {
4343 if (CI->arg_size() > 0)
4344 Out << ", ";
4345 Out << "...";
4346 }
4347
4348 Out << ')';
4349 if (PAL.hasFnAttrs())
4350 Out << " #" << Machine.getAttributeGroupSlot(AS: PAL.getFnAttrs());
4351
4352 writeOperandBundles(Call: CI);
4353 } else if (const InvokeInst *II = dyn_cast<InvokeInst>(Val: &I)) {
4354 Operand = II->getCalledOperand();
4355 FunctionType *FTy = II->getFunctionType();
4356 Type *RetTy = FTy->getReturnType();
4357 const AttributeList &PAL = II->getAttributes();
4358
4359 // Print the calling convention being used.
4360 if (II->getCallingConv() != CallingConv::C) {
4361 Out << " ";
4362 PrintCallingConv(cc: II->getCallingConv(), Out);
4363 }
4364
4365 if (PAL.hasRetAttrs())
4366 Out << ' ' << PAL.getAsString(Index: AttributeList::ReturnIndex);
4367
4368 // Only print addrspace(N) if necessary:
4369 maybePrintCallAddrSpace(Operand, I: &I, Out);
4370
4371 // If possible, print out the short form of the invoke instruction. We can
4372 // only do this if the first argument is a pointer to a nonvararg function,
4373 // and if the return type is not a pointer to a function.
4374 //
4375 Out << ' ';
4376 TypePrinter.print(Ty: FTy->isVarArg() ? FTy : RetTy, OS&: Out);
4377 Out << ' ';
4378 writeOperand(Operand, PrintType: false);
4379 Out << '(';
4380 for (unsigned op = 0, Eop = II->arg_size(); op < Eop; ++op) {
4381 if (op)
4382 Out << ", ";
4383 writeParamOperand(Operand: II->getArgOperand(i: op), Attrs: PAL.getParamAttrs(ArgNo: op));
4384 }
4385
4386 Out << ')';
4387 if (PAL.hasFnAttrs())
4388 Out << " #" << Machine.getAttributeGroupSlot(AS: PAL.getFnAttrs());
4389
4390 writeOperandBundles(Call: II);
4391
4392 Out << "\n to ";
4393 writeOperand(Operand: II->getNormalDest(), PrintType: true);
4394 Out << " unwind ";
4395 writeOperand(Operand: II->getUnwindDest(), PrintType: true);
4396 } else if (const CallBrInst *CBI = dyn_cast<CallBrInst>(Val: &I)) {
4397 Operand = CBI->getCalledOperand();
4398 FunctionType *FTy = CBI->getFunctionType();
4399 Type *RetTy = FTy->getReturnType();
4400 const AttributeList &PAL = CBI->getAttributes();
4401
4402 // Print the calling convention being used.
4403 if (CBI->getCallingConv() != CallingConv::C) {
4404 Out << " ";
4405 PrintCallingConv(cc: CBI->getCallingConv(), Out);
4406 }
4407
4408 if (PAL.hasRetAttrs())
4409 Out << ' ' << PAL.getAsString(Index: AttributeList::ReturnIndex);
4410
4411 // If possible, print out the short form of the callbr instruction. We can
4412 // only do this if the first argument is a pointer to a nonvararg function,
4413 // and if the return type is not a pointer to a function.
4414 //
4415 Out << ' ';
4416 TypePrinter.print(Ty: FTy->isVarArg() ? FTy : RetTy, OS&: Out);
4417 Out << ' ';
4418 writeOperand(Operand, PrintType: false);
4419 Out << '(';
4420 for (unsigned op = 0, Eop = CBI->arg_size(); op < Eop; ++op) {
4421 if (op)
4422 Out << ", ";
4423 writeParamOperand(Operand: CBI->getArgOperand(i: op), Attrs: PAL.getParamAttrs(ArgNo: op));
4424 }
4425
4426 Out << ')';
4427 if (PAL.hasFnAttrs())
4428 Out << " #" << Machine.getAttributeGroupSlot(AS: PAL.getFnAttrs());
4429
4430 writeOperandBundles(Call: CBI);
4431
4432 Out << "\n to ";
4433 writeOperand(Operand: CBI->getDefaultDest(), PrintType: true);
4434 Out << " [";
4435 for (unsigned i = 0, e = CBI->getNumIndirectDests(); i != e; ++i) {
4436 if (i != 0)
4437 Out << ", ";
4438 writeOperand(Operand: CBI->getIndirectDest(i), PrintType: true);
4439 }
4440 Out << ']';
4441 } else if (const AllocaInst *AI = dyn_cast<AllocaInst>(Val: &I)) {
4442 Out << ' ';
4443 if (AI->isUsedWithInAlloca())
4444 Out << "inalloca ";
4445 if (AI->isSwiftError())
4446 Out << "swifterror ";
4447 TypePrinter.print(Ty: AI->getAllocatedType(), OS&: Out);
4448
4449 // Explicitly write the array size if the code is broken, if it's an array
4450 // allocation, or if the type is not canonical for scalar allocations. The
4451 // latter case prevents the type from mutating when round-tripping through
4452 // assembly.
4453 if (!AI->getArraySize() || AI->isArrayAllocation() ||
4454 !AI->getArraySize()->getType()->isIntegerTy(Bitwidth: 32)) {
4455 Out << ", ";
4456 writeOperand(Operand: AI->getArraySize(), PrintType: true);
4457 }
4458 if (MaybeAlign A = AI->getAlign()) {
4459 Out << ", align " << A->value();
4460 }
4461
4462 unsigned AddrSpace = AI->getAddressSpace();
4463 if (AddrSpace != 0) {
4464 Out << ", addrspace(" << AddrSpace << ')';
4465 }
4466 } else if (isa<CastInst>(Val: I)) {
4467 if (Operand) {
4468 Out << ' ';
4469 writeOperand(Operand, PrintType: true); // Work with broken code
4470 }
4471 Out << " to ";
4472 TypePrinter.print(Ty: I.getType(), OS&: Out);
4473 } else if (isa<VAArgInst>(Val: I)) {
4474 if (Operand) {
4475 Out << ' ';
4476 writeOperand(Operand, PrintType: true); // Work with broken code
4477 }
4478 Out << ", ";
4479 TypePrinter.print(Ty: I.getType(), OS&: Out);
4480 } else if (Operand) { // Print the normal way.
4481 if (const auto *GEP = dyn_cast<GetElementPtrInst>(Val: &I)) {
4482 Out << ' ';
4483 TypePrinter.print(Ty: GEP->getSourceElementType(), OS&: Out);
4484 Out << ',';
4485 } else if (const auto *LI = dyn_cast<LoadInst>(Val: &I)) {
4486 Out << ' ';
4487 TypePrinter.print(Ty: LI->getType(), OS&: Out);
4488 Out << ',';
4489 }
4490
4491 // PrintAllTypes - Instructions who have operands of all the same type
4492 // omit the type from all but the first operand. If the instruction has
4493 // different type operands (for example br), then they are all printed.
4494 bool PrintAllTypes = false;
4495 Type *TheType = Operand->getType();
4496
4497 // Select, Store, ShuffleVector, CmpXchg and AtomicRMW always print all
4498 // types.
4499 if (isa<SelectInst>(Val: I) || isa<StoreInst>(Val: I) || isa<ShuffleVectorInst>(Val: I) ||
4500 isa<ReturnInst>(Val: I) || isa<AtomicCmpXchgInst>(Val: I) ||
4501 isa<AtomicRMWInst>(Val: I)) {
4502 PrintAllTypes = true;
4503 } else {
4504 for (unsigned i = 1, E = I.getNumOperands(); i != E; ++i) {
4505 Operand = I.getOperand(i);
4506 // note that Operand shouldn't be null, but the test helps make dump()
4507 // more tolerant of malformed IR
4508 if (Operand && Operand->getType() != TheType) {
4509 PrintAllTypes = true; // We have differing types! Print them all!
4510 break;
4511 }
4512 }
4513 }
4514
4515 if (!PrintAllTypes) {
4516 Out << ' ';
4517 TypePrinter.print(Ty: TheType, OS&: Out);
4518 }
4519
4520 Out << ' ';
4521 for (unsigned i = 0, E = I.getNumOperands(); i != E; ++i) {
4522 if (i) Out << ", ";
4523 writeOperand(Operand: I.getOperand(i), PrintType: PrintAllTypes);
4524 }
4525 }
4526
4527 // Print atomic ordering/alignment for memory operations
4528 if (const LoadInst *LI = dyn_cast<LoadInst>(Val: &I)) {
4529 if (LI->isAtomic())
4530 writeAtomic(Context: LI->getContext(), Ordering: LI->getOrdering(), SSID: LI->getSyncScopeID());
4531 if (MaybeAlign A = LI->getAlign())
4532 Out << ", align " << A->value();
4533 } else if (const StoreInst *SI = dyn_cast<StoreInst>(Val: &I)) {
4534 if (SI->isAtomic())
4535 writeAtomic(Context: SI->getContext(), Ordering: SI->getOrdering(), SSID: SI->getSyncScopeID());
4536 if (MaybeAlign A = SI->getAlign())
4537 Out << ", align " << A->value();
4538 } else if (const AtomicCmpXchgInst *CXI = dyn_cast<AtomicCmpXchgInst>(Val: &I)) {
4539 writeAtomicCmpXchg(Context: CXI->getContext(), SuccessOrdering: CXI->getSuccessOrdering(),
4540 FailureOrdering: CXI->getFailureOrdering(), SSID: CXI->getSyncScopeID());
4541 Out << ", align " << CXI->getAlign().value();
4542 } else if (const AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(Val: &I)) {
4543 writeAtomic(Context: RMWI->getContext(), Ordering: RMWI->getOrdering(),
4544 SSID: RMWI->getSyncScopeID());
4545 Out << ", align " << RMWI->getAlign().value();
4546 } else if (const FenceInst *FI = dyn_cast<FenceInst>(Val: &I)) {
4547 writeAtomic(Context: FI->getContext(), Ordering: FI->getOrdering(), SSID: FI->getSyncScopeID());
4548 } else if (const ShuffleVectorInst *SVI = dyn_cast<ShuffleVectorInst>(Val: &I)) {
4549 PrintShuffleMask(Out, Ty: SVI->getType(), Mask: SVI->getShuffleMask());
4550 }
4551
4552 // Print Metadata info.
4553 SmallVector<std::pair<unsigned, MDNode *>, 4> InstMD;
4554 I.getAllMetadata(MDs&: InstMD);
4555 printMetadataAttachments(MDs: InstMD, Separator: ", ");
4556
4557 // Print a nice comment.
4558 printInfoComment(V: I);
4559}
4560
4561void AssemblyWriter::printDPMarker(const DPMarker &Marker) {
4562 // There's no formal representation of a DPMarker -- print purely as a
4563 // debugging aid.
4564 for (const DPValue &DPI2 : Marker.StoredDPValues) {
4565 printDPValue(DPI: DPI2);
4566 Out << "\n";
4567 }
4568
4569 Out << " DPMarker -> { ";
4570 printInstruction(I: *Marker.MarkedInstr);
4571 Out << " }";
4572 return;
4573}
4574
4575void AssemblyWriter::printDPValue(const DPValue &Value) {
4576 // There's no formal representation of a DPValue -- print purely as a
4577 // debugging aid.
4578 Out << " DPValue ";
4579
4580 switch (Value.getType()) {
4581 case DPValue::LocationType::Value:
4582 Out << "value";
4583 break;
4584 case DPValue::LocationType::Declare:
4585 Out << "declare";
4586 break;
4587 case DPValue::LocationType::Assign:
4588 Out << "assign";
4589 break;
4590 default:
4591 llvm_unreachable("Tried to print a DPValue with an invalid LocationType!");
4592 }
4593 Out << " { ";
4594 auto WriterCtx = getContext();
4595 WriteAsOperandInternal(Out, MD: Value.getRawLocation(), WriterCtx, FromValue: true);
4596 Out << ", ";
4597 WriteAsOperandInternal(Out, MD: Value.getVariable(), WriterCtx, FromValue: true);
4598 Out << ", ";
4599 WriteAsOperandInternal(Out, MD: Value.getExpression(), WriterCtx, FromValue: true);
4600 Out << ", ";
4601 if (Value.isDbgAssign()) {
4602 WriteAsOperandInternal(Out, MD: Value.getAssignID(), WriterCtx, FromValue: true);
4603 Out << ", ";
4604 WriteAsOperandInternal(Out, MD: Value.getRawAddress(), WriterCtx, FromValue: true);
4605 Out << ", ";
4606 WriteAsOperandInternal(Out, MD: Value.getAddressExpression(), WriterCtx, FromValue: true);
4607 Out << ", ";
4608 }
4609 WriteAsOperandInternal(Out, MD: Value.getDebugLoc().get(), WriterCtx, FromValue: true);
4610 Out << " marker @" << Value.getMarker();
4611 Out << " }";
4612}
4613
4614void AssemblyWriter::printMetadataAttachments(
4615 const SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs,
4616 StringRef Separator) {
4617 if (MDs.empty())
4618 return;
4619
4620 if (MDNames.empty())
4621 MDs[0].second->getContext().getMDKindNames(Result&: MDNames);
4622
4623 auto WriterCtx = getContext();
4624 for (const auto &I : MDs) {
4625 unsigned Kind = I.first;
4626 Out << Separator;
4627 if (Kind < MDNames.size()) {
4628 Out << "!";
4629 printMetadataIdentifier(Name: MDNames[Kind], Out);
4630 } else
4631 Out << "!<unknown kind #" << Kind << ">";
4632 Out << ' ';
4633 WriteAsOperandInternal(Out, MD: I.second, WriterCtx);
4634 }
4635}
4636
4637void AssemblyWriter::writeMDNode(unsigned Slot, const MDNode *Node) {
4638 Out << '!' << Slot << " = ";
4639 printMDNodeBody(MD: Node);
4640 Out << "\n";
4641}
4642
4643void AssemblyWriter::writeAllMDNodes() {
4644 SmallVector<const MDNode *, 16> Nodes;
4645 Nodes.resize(N: Machine.mdn_size());
4646 for (auto &I : llvm::make_range(x: Machine.mdn_begin(), y: Machine.mdn_end()))
4647 Nodes[I.second] = cast<MDNode>(Val: I.first);
4648
4649 for (unsigned i = 0, e = Nodes.size(); i != e; ++i) {
4650 writeMDNode(Slot: i, Node: Nodes[i]);
4651 }
4652}
4653
4654void AssemblyWriter::printMDNodeBody(const MDNode *Node) {
4655 auto WriterCtx = getContext();
4656 WriteMDNodeBodyInternal(Out, Node, Ctx&: WriterCtx);
4657}
4658
4659void AssemblyWriter::writeAttribute(const Attribute &Attr, bool InAttrGroup) {
4660 if (!Attr.isTypeAttribute()) {
4661 Out << Attr.getAsString(InAttrGrp: InAttrGroup);
4662 return;
4663 }
4664
4665 Out << Attribute::getNameFromAttrKind(AttrKind: Attr.getKindAsEnum());
4666 if (Type *Ty = Attr.getValueAsType()) {
4667 Out << '(';
4668 TypePrinter.print(Ty, OS&: Out);
4669 Out << ')';
4670 }
4671}
4672
4673void AssemblyWriter::writeAttributeSet(const AttributeSet &AttrSet,
4674 bool InAttrGroup) {
4675 bool FirstAttr = true;
4676 for (const auto &Attr : AttrSet) {
4677 if (!FirstAttr)
4678 Out << ' ';
4679 writeAttribute(Attr, InAttrGroup);
4680 FirstAttr = false;
4681 }
4682}
4683
4684void AssemblyWriter::writeAllAttributeGroups() {
4685 std::vector<std::pair<AttributeSet, unsigned>> asVec;
4686 asVec.resize(new_size: Machine.as_size());
4687
4688 for (auto &I : llvm::make_range(x: Machine.as_begin(), y: Machine.as_end()))
4689 asVec[I.second] = I;
4690
4691 for (const auto &I : asVec)
4692 Out << "attributes #" << I.second << " = { "
4693 << I.first.getAsString(InAttrGrp: true) << " }\n";
4694}
4695
4696void AssemblyWriter::printUseListOrder(const Value *V,
4697 const std::vector<unsigned> &Shuffle) {
4698 bool IsInFunction = Machine.getFunction();
4699 if (IsInFunction)
4700 Out << " ";
4701
4702 Out << "uselistorder";
4703 if (const BasicBlock *BB = IsInFunction ? nullptr : dyn_cast<BasicBlock>(Val: V)) {
4704 Out << "_bb ";
4705 writeOperand(Operand: BB->getParent(), PrintType: false);
4706 Out << ", ";
4707 writeOperand(Operand: BB, PrintType: false);
4708 } else {
4709 Out << " ";
4710 writeOperand(Operand: V, PrintType: true);
4711 }
4712 Out << ", { ";
4713
4714 assert(Shuffle.size() >= 2 && "Shuffle too small");
4715 Out << Shuffle[0];
4716 for (unsigned I = 1, E = Shuffle.size(); I != E; ++I)
4717 Out << ", " << Shuffle[I];
4718 Out << " }\n";
4719}
4720
4721void AssemblyWriter::printUseLists(const Function *F) {
4722 auto It = UseListOrders.find(Val: F);
4723 if (It == UseListOrders.end())
4724 return;
4725
4726 Out << "\n; uselistorder directives\n";
4727 for (const auto &Pair : It->second)
4728 printUseListOrder(V: Pair.first, Shuffle: Pair.second);
4729}
4730
4731//===----------------------------------------------------------------------===//
4732// External Interface declarations
4733//===----------------------------------------------------------------------===//
4734
4735void Function::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
4736 bool ShouldPreserveUseListOrder,
4737 bool IsForDebug) const {
4738 SlotTracker SlotTable(this->getParent());
4739 formatted_raw_ostream OS(ROS);
4740 AssemblyWriter W(OS, SlotTable, this->getParent(), AAW,
4741 IsForDebug,
4742 ShouldPreserveUseListOrder);
4743 W.printFunction(F: this);
4744}
4745
4746void BasicBlock::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
4747 bool ShouldPreserveUseListOrder,
4748 bool IsForDebug) const {
4749 SlotTracker SlotTable(this->getParent());
4750 formatted_raw_ostream OS(ROS);
4751 AssemblyWriter W(OS, SlotTable, this->getModule(), AAW,
4752 IsForDebug,
4753 ShouldPreserveUseListOrder);
4754 W.printBasicBlock(BB: this);
4755}
4756
4757void Module::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
4758 bool ShouldPreserveUseListOrder, bool IsForDebug) const {
4759 // RemoveDIs: always print with debug-info in intrinsic format.
4760 bool ConvertAfter = IsNewDbgInfoFormat;
4761 if (IsNewDbgInfoFormat)
4762 const_cast<Module *>(this)->convertFromNewDbgValues();
4763
4764 SlotTracker SlotTable(this);
4765 formatted_raw_ostream OS(ROS);
4766 AssemblyWriter W(OS, SlotTable, this, AAW, IsForDebug,
4767 ShouldPreserveUseListOrder);
4768 W.printModule(M: this);
4769
4770 if (ConvertAfter)
4771 const_cast<Module *>(this)->convertToNewDbgValues();
4772}
4773
4774void NamedMDNode::print(raw_ostream &ROS, bool IsForDebug) const {
4775 SlotTracker SlotTable(getParent());
4776 formatted_raw_ostream OS(ROS);
4777 AssemblyWriter W(OS, SlotTable, getParent(), nullptr, IsForDebug);
4778 W.printNamedMDNode(NMD: this);
4779}
4780
4781void NamedMDNode::print(raw_ostream &ROS, ModuleSlotTracker &MST,
4782 bool IsForDebug) const {
4783 std::optional<SlotTracker> LocalST;
4784 SlotTracker *SlotTable;
4785 if (auto *ST = MST.getMachine())
4786 SlotTable = ST;
4787 else {
4788 LocalST.emplace(args: getParent());
4789 SlotTable = &*LocalST;
4790 }
4791
4792 formatted_raw_ostream OS(ROS);
4793 AssemblyWriter W(OS, *SlotTable, getParent(), nullptr, IsForDebug);
4794 W.printNamedMDNode(NMD: this);
4795}
4796
4797void Comdat::print(raw_ostream &ROS, bool /*IsForDebug*/) const {
4798 PrintLLVMName(OS&: ROS, Name: getName(), Prefix: ComdatPrefix);
4799 ROS << " = comdat ";
4800
4801 switch (getSelectionKind()) {
4802 case Comdat::Any:
4803 ROS << "any";
4804 break;
4805 case Comdat::ExactMatch:
4806 ROS << "exactmatch";
4807 break;
4808 case Comdat::Largest:
4809 ROS << "largest";
4810 break;
4811 case Comdat::NoDeduplicate:
4812 ROS << "nodeduplicate";
4813 break;
4814 case Comdat::SameSize:
4815 ROS << "samesize";
4816 break;
4817 }
4818
4819 ROS << '\n';
4820}
4821
4822void Type::print(raw_ostream &OS, bool /*IsForDebug*/, bool NoDetails) const {
4823 TypePrinting TP;
4824 TP.print(Ty: const_cast<Type*>(this), OS);
4825
4826 if (NoDetails)
4827 return;
4828
4829 // If the type is a named struct type, print the body as well.
4830 if (StructType *STy = dyn_cast<StructType>(Val: const_cast<Type*>(this)))
4831 if (!STy->isLiteral()) {
4832 OS << " = type ";
4833 TP.printStructBody(STy, OS);
4834 }
4835}
4836
4837static bool isReferencingMDNode(const Instruction &I) {
4838 if (const auto *CI = dyn_cast<CallInst>(Val: &I))
4839 if (Function *F = CI->getCalledFunction())
4840 if (F->isIntrinsic())
4841 for (auto &Op : I.operands())
4842 if (auto *V = dyn_cast_or_null<MetadataAsValue>(Val: Op))
4843 if (isa<MDNode>(Val: V->getMetadata()))
4844 return true;
4845 return false;
4846}
4847
4848void DPMarker::print(raw_ostream &ROS, bool IsForDebug) const {
4849
4850 ModuleSlotTracker MST(getModuleFromDPI(Marker: this), true);
4851 print(ROS, MST, IsForDebug);
4852}
4853
4854void DPValue::print(raw_ostream &ROS, bool IsForDebug) const {
4855
4856 ModuleSlotTracker MST(getModuleFromDPI(DPV: this), true);
4857 print(ROS, MST, IsForDebug);
4858}
4859
4860void DPMarker::print(raw_ostream &ROS, ModuleSlotTracker &MST,
4861 bool IsForDebug) const {
4862 // There's no formal representation of a DPMarker -- print purely as a
4863 // debugging aid.
4864 formatted_raw_ostream OS(ROS);
4865 SlotTracker EmptySlotTable(static_cast<const Module *>(nullptr));
4866 SlotTracker &SlotTable =
4867 MST.getMachine() ? *MST.getMachine() : EmptySlotTable;
4868 auto incorporateFunction = [&](const Function *F) {
4869 if (F)
4870 MST.incorporateFunction(F: *F);
4871 };
4872 incorporateFunction(getParent() ? getParent()->getParent() : nullptr);
4873 AssemblyWriter W(OS, SlotTable, getModuleFromDPI(Marker: this), nullptr, IsForDebug);
4874 W.printDPMarker(Marker: *this);
4875}
4876
4877void DPValue::print(raw_ostream &ROS, ModuleSlotTracker &MST,
4878 bool IsForDebug) const {
4879 // There's no formal representation of a DPValue -- print purely as a
4880 // debugging aid.
4881 formatted_raw_ostream OS(ROS);
4882 SlotTracker EmptySlotTable(static_cast<const Module *>(nullptr));
4883 SlotTracker &SlotTable =
4884 MST.getMachine() ? *MST.getMachine() : EmptySlotTable;
4885 auto incorporateFunction = [&](const Function *F) {
4886 if (F)
4887 MST.incorporateFunction(F: *F);
4888 };
4889 incorporateFunction(Marker->getParent() ? Marker->getParent()->getParent()
4890 : nullptr);
4891 AssemblyWriter W(OS, SlotTable, getModuleFromDPI(DPV: this), nullptr, IsForDebug);
4892 W.printDPValue(Value: *this);
4893}
4894
4895void Value::print(raw_ostream &ROS, bool IsForDebug) const {
4896 bool ShouldInitializeAllMetadata = false;
4897 if (auto *I = dyn_cast<Instruction>(Val: this))
4898 ShouldInitializeAllMetadata = isReferencingMDNode(I: *I);
4899 else if (isa<Function>(Val: this) || isa<MetadataAsValue>(Val: this))
4900 ShouldInitializeAllMetadata = true;
4901
4902 ModuleSlotTracker MST(getModuleFromVal(V: this), ShouldInitializeAllMetadata);
4903 print(O&: ROS, MST, IsForDebug);
4904}
4905
4906void Value::print(raw_ostream &ROS, ModuleSlotTracker &MST,
4907 bool IsForDebug) const {
4908 formatted_raw_ostream OS(ROS);
4909 SlotTracker EmptySlotTable(static_cast<const Module *>(nullptr));
4910 SlotTracker &SlotTable =
4911 MST.getMachine() ? *MST.getMachine() : EmptySlotTable;
4912 auto incorporateFunction = [&](const Function *F) {
4913 if (F)
4914 MST.incorporateFunction(F: *F);
4915 };
4916
4917 if (const Instruction *I = dyn_cast<Instruction>(Val: this)) {
4918 incorporateFunction(I->getParent() ? I->getParent()->getParent() : nullptr);
4919 AssemblyWriter W(OS, SlotTable, getModuleFromVal(V: I), nullptr, IsForDebug);
4920 W.printInstruction(I: *I);
4921 } else if (const BasicBlock *BB = dyn_cast<BasicBlock>(Val: this)) {
4922 incorporateFunction(BB->getParent());
4923 AssemblyWriter W(OS, SlotTable, getModuleFromVal(V: BB), nullptr, IsForDebug);
4924 W.printBasicBlock(BB);
4925 } else if (const GlobalValue *GV = dyn_cast<GlobalValue>(Val: this)) {
4926 AssemblyWriter W(OS, SlotTable, GV->getParent(), nullptr, IsForDebug);
4927 if (const GlobalVariable *V = dyn_cast<GlobalVariable>(Val: GV))
4928 W.printGlobal(GV: V);
4929 else if (const Function *F = dyn_cast<Function>(Val: GV))
4930 W.printFunction(F);
4931 else if (const GlobalAlias *A = dyn_cast<GlobalAlias>(Val: GV))
4932 W.printAlias(GA: A);
4933 else if (const GlobalIFunc *I = dyn_cast<GlobalIFunc>(Val: GV))
4934 W.printIFunc(GI: I);
4935 else
4936 llvm_unreachable("Unknown GlobalValue to print out!");
4937 } else if (const MetadataAsValue *V = dyn_cast<MetadataAsValue>(Val: this)) {
4938 V->getMetadata()->print(OS&: ROS, MST, M: getModuleFromVal(V));
4939 } else if (const Constant *C = dyn_cast<Constant>(Val: this)) {
4940 TypePrinting TypePrinter;
4941 TypePrinter.print(Ty: C->getType(), OS);
4942 OS << ' ';
4943 AsmWriterContext WriterCtx(&TypePrinter, MST.getMachine());
4944 WriteConstantInternal(Out&: OS, CV: C, WriterCtx);
4945 } else if (isa<InlineAsm>(Val: this) || isa<Argument>(Val: this)) {
4946 this->printAsOperand(O&: OS, /* PrintType */ true, MST);
4947 } else {
4948 llvm_unreachable("Unknown value to print out!");
4949 }
4950}
4951
4952/// Print without a type, skipping the TypePrinting object.
4953///
4954/// \return \c true iff printing was successful.
4955static bool printWithoutType(const Value &V, raw_ostream &O,
4956 SlotTracker *Machine, const Module *M) {
4957 if (V.hasName() || isa<GlobalValue>(Val: V) ||
4958 (!isa<Constant>(Val: V) && !isa<MetadataAsValue>(Val: V))) {
4959 AsmWriterContext WriterCtx(nullptr, Machine, M);
4960 WriteAsOperandInternal(Out&: O, V: &V, WriterCtx);
4961 return true;
4962 }
4963 return false;
4964}
4965
4966static void printAsOperandImpl(const Value &V, raw_ostream &O, bool PrintType,
4967 ModuleSlotTracker &MST) {
4968 TypePrinting TypePrinter(MST.getModule());
4969 if (PrintType) {
4970 TypePrinter.print(Ty: V.getType(), OS&: O);
4971 O << ' ';
4972 }
4973
4974 AsmWriterContext WriterCtx(&TypePrinter, MST.getMachine(), MST.getModule());
4975 WriteAsOperandInternal(Out&: O, V: &V, WriterCtx);
4976}
4977
4978void Value::printAsOperand(raw_ostream &O, bool PrintType,
4979 const Module *M) const {
4980 if (!M)
4981 M = getModuleFromVal(V: this);
4982
4983 if (!PrintType)
4984 if (printWithoutType(V: *this, O, Machine: nullptr, M))
4985 return;
4986
4987 SlotTracker Machine(
4988 M, /* ShouldInitializeAllMetadata */ isa<MetadataAsValue>(Val: this));
4989 ModuleSlotTracker MST(Machine, M);
4990 printAsOperandImpl(V: *this, O, PrintType, MST);
4991}
4992
4993void Value::printAsOperand(raw_ostream &O, bool PrintType,
4994 ModuleSlotTracker &MST) const {
4995 if (!PrintType)
4996 if (printWithoutType(V: *this, O, Machine: MST.getMachine(), M: MST.getModule()))
4997 return;
4998
4999 printAsOperandImpl(V: *this, O, PrintType, MST);
5000}
5001
5002/// Recursive version of printMetadataImpl.
5003static void printMetadataImplRec(raw_ostream &ROS, const Metadata &MD,
5004 AsmWriterContext &WriterCtx) {
5005 formatted_raw_ostream OS(ROS);
5006 WriteAsOperandInternal(Out&: OS, MD: &MD, WriterCtx, /* FromValue */ true);
5007
5008 auto *N = dyn_cast<MDNode>(Val: &MD);
5009 if (!N || isa<DIExpression>(Val: MD))
5010 return;
5011
5012 OS << " = ";
5013 WriteMDNodeBodyInternal(Out&: OS, Node: N, Ctx&: WriterCtx);
5014}
5015
5016namespace {
5017struct MDTreeAsmWriterContext : public AsmWriterContext {
5018 unsigned Level;
5019 // {Level, Printed string}
5020 using EntryTy = std::pair<unsigned, std::string>;
5021 SmallVector<EntryTy, 4> Buffer;
5022
5023 // Used to break the cycle in case there is any.
5024 SmallPtrSet<const Metadata *, 4> Visited;
5025
5026 raw_ostream &MainOS;
5027
5028 MDTreeAsmWriterContext(TypePrinting *TP, SlotTracker *ST, const Module *M,
5029 raw_ostream &OS, const Metadata *InitMD)
5030 : AsmWriterContext(TP, ST, M), Level(0U), Visited({InitMD}), MainOS(OS) {}
5031
5032 void onWriteMetadataAsOperand(const Metadata *MD) override {
5033 if (!Visited.insert(Ptr: MD).second)
5034 return;
5035
5036 std::string Str;
5037 raw_string_ostream SS(Str);
5038 ++Level;
5039 // A placeholder entry to memorize the correct
5040 // position in buffer.
5041 Buffer.emplace_back(Args: std::make_pair(x&: Level, y: ""));
5042 unsigned InsertIdx = Buffer.size() - 1;
5043
5044 printMetadataImplRec(ROS&: SS, MD: *MD, WriterCtx&: *this);
5045 Buffer[InsertIdx].second = std::move(SS.str());
5046 --Level;
5047 }
5048
5049 ~MDTreeAsmWriterContext() {
5050 for (const auto &Entry : Buffer) {
5051 MainOS << "\n";
5052 unsigned NumIndent = Entry.first * 2U;
5053 MainOS.indent(NumSpaces: NumIndent) << Entry.second;
5054 }
5055 }
5056};
5057} // end anonymous namespace
5058
5059static void printMetadataImpl(raw_ostream &ROS, const Metadata &MD,
5060 ModuleSlotTracker &MST, const Module *M,
5061 bool OnlyAsOperand, bool PrintAsTree = false) {
5062 formatted_raw_ostream OS(ROS);
5063
5064 TypePrinting TypePrinter(M);
5065
5066 std::unique_ptr<AsmWriterContext> WriterCtx;
5067 if (PrintAsTree && !OnlyAsOperand)
5068 WriterCtx = std::make_unique<MDTreeAsmWriterContext>(
5069 args: &TypePrinter, args: MST.getMachine(), args&: M, args&: OS, args: &MD);
5070 else
5071 WriterCtx =
5072 std::make_unique<AsmWriterContext>(args: &TypePrinter, args: MST.getMachine(), args&: M);
5073
5074 WriteAsOperandInternal(Out&: OS, MD: &MD, WriterCtx&: *WriterCtx, /* FromValue */ true);
5075
5076 auto *N = dyn_cast<MDNode>(Val: &MD);
5077 if (OnlyAsOperand || !N || isa<DIExpression>(Val: MD))
5078 return;
5079
5080 OS << " = ";
5081 WriteMDNodeBodyInternal(Out&: OS, Node: N, Ctx&: *WriterCtx);
5082}
5083
5084void Metadata::printAsOperand(raw_ostream &OS, const Module *M) const {
5085 ModuleSlotTracker MST(M, isa<MDNode>(Val: this));
5086 printMetadataImpl(ROS&: OS, MD: *this, MST, M, /* OnlyAsOperand */ true);
5087}
5088
5089void Metadata::printAsOperand(raw_ostream &OS, ModuleSlotTracker &MST,
5090 const Module *M) const {
5091 printMetadataImpl(ROS&: OS, MD: *this, MST, M, /* OnlyAsOperand */ true);
5092}
5093
5094void Metadata::print(raw_ostream &OS, const Module *M,
5095 bool /*IsForDebug*/) const {
5096 ModuleSlotTracker MST(M, isa<MDNode>(Val: this));
5097 printMetadataImpl(ROS&: OS, MD: *this, MST, M, /* OnlyAsOperand */ false);
5098}
5099
5100void Metadata::print(raw_ostream &OS, ModuleSlotTracker &MST,
5101 const Module *M, bool /*IsForDebug*/) const {
5102 printMetadataImpl(ROS&: OS, MD: *this, MST, M, /* OnlyAsOperand */ false);
5103}
5104
5105void MDNode::printTree(raw_ostream &OS, const Module *M) const {
5106 ModuleSlotTracker MST(M, true);
5107 printMetadataImpl(ROS&: OS, MD: *this, MST, M, /* OnlyAsOperand */ false,
5108 /*PrintAsTree=*/true);
5109}
5110
5111void MDNode::printTree(raw_ostream &OS, ModuleSlotTracker &MST,
5112 const Module *M) const {
5113 printMetadataImpl(ROS&: OS, MD: *this, MST, M, /* OnlyAsOperand */ false,
5114 /*PrintAsTree=*/true);
5115}
5116
5117void ModuleSummaryIndex::print(raw_ostream &ROS, bool IsForDebug) const {
5118 SlotTracker SlotTable(this);
5119 formatted_raw_ostream OS(ROS);
5120 AssemblyWriter W(OS, SlotTable, this, IsForDebug);
5121 W.printModuleSummaryIndex();
5122}
5123
5124void ModuleSlotTracker::collectMDNodes(MachineMDNodeListType &L, unsigned LB,
5125 unsigned UB) const {
5126 SlotTracker *ST = MachineStorage.get();
5127 if (!ST)
5128 return;
5129
5130 for (auto &I : llvm::make_range(x: ST->mdn_begin(), y: ST->mdn_end()))
5131 if (I.second >= LB && I.second < UB)
5132 L.push_back(x: std::make_pair(x&: I.second, y&: I.first));
5133}
5134
5135#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
5136// Value::dump - allow easy printing of Values from the debugger.
5137LLVM_DUMP_METHOD
5138void Value::dump() const { print(ROS&: dbgs(), /*IsForDebug=*/true); dbgs() << '\n'; }
5139
5140// Value::dump - allow easy printing of Values from the debugger.
5141LLVM_DUMP_METHOD
5142void DPMarker::dump() const { print(ROS&: dbgs(), /*IsForDebug=*/true); dbgs() << '\n'; }
5143
5144// Value::dump - allow easy printing of Values from the debugger.
5145LLVM_DUMP_METHOD
5146void DPValue::dump() const { print(ROS&: dbgs(), /*IsForDebug=*/true); dbgs() << '\n'; }
5147
5148// Type::dump - allow easy printing of Types from the debugger.
5149LLVM_DUMP_METHOD
5150void Type::dump() const { print(OS&: dbgs(), /*IsForDebug=*/true); dbgs() << '\n'; }
5151
5152// Module::dump() - Allow printing of Modules from the debugger.
5153LLVM_DUMP_METHOD
5154void Module::dump() const {
5155 print(ROS&: dbgs(), AAW: nullptr,
5156 /*ShouldPreserveUseListOrder=*/false, /*IsForDebug=*/true);
5157}
5158
5159// Allow printing of Comdats from the debugger.
5160LLVM_DUMP_METHOD
5161void Comdat::dump() const { print(ROS&: dbgs(), /*IsForDebug=*/true); }
5162
5163// NamedMDNode::dump() - Allow printing of NamedMDNodes from the debugger.
5164LLVM_DUMP_METHOD
5165void NamedMDNode::dump() const { print(ROS&: dbgs(), /*IsForDebug=*/true); }
5166
5167LLVM_DUMP_METHOD
5168void Metadata::dump() const { dump(M: nullptr); }
5169
5170LLVM_DUMP_METHOD
5171void Metadata::dump(const Module *M) const {
5172 print(OS&: dbgs(), M, /*IsForDebug=*/true);
5173 dbgs() << '\n';
5174}
5175
5176LLVM_DUMP_METHOD
5177void MDNode::dumpTree() const { dumpTree(M: nullptr); }
5178
5179LLVM_DUMP_METHOD
5180void MDNode::dumpTree(const Module *M) const {
5181 printTree(OS&: dbgs(), M);
5182 dbgs() << '\n';
5183}
5184
5185// Allow printing of ModuleSummaryIndex from the debugger.
5186LLVM_DUMP_METHOD
5187void ModuleSummaryIndex::dump() const { print(ROS&: dbgs(), /*IsForDebug=*/true); }
5188#endif
5189

source code of llvm/lib/IR/AsmWriter.cpp