LLVM 24.0.0git
AsmWriter.cpp
Go to the documentation of this file.
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 "IROptions.h"
19#include "LLVMContextImpl.h"
20#include "llvm/ADT/APFloat.h"
21#include "llvm/ADT/APInt.h"
22#include "llvm/ADT/ArrayRef.h"
23#include "llvm/ADT/DenseMap.h"
24#include "llvm/ADT/STLExtras.h"
30#include "llvm/ADT/StringRef.h"
33#include "llvm/Config/llvm-config.h"
34#include "llvm/IR/Argument.h"
36#include "llvm/IR/Attributes.h"
37#include "llvm/IR/BasicBlock.h"
38#include "llvm/IR/CFG.h"
39#include "llvm/IR/CallingConv.h"
40#include "llvm/IR/Comdat.h"
41#include "llvm/IR/Constant.h"
42#include "llvm/IR/Constants.h"
46#include "llvm/IR/Function.h"
47#include "llvm/IR/GlobalAlias.h"
48#include "llvm/IR/GlobalIFunc.h"
50#include "llvm/IR/GlobalValue.h"
53#include "llvm/IR/InlineAsm.h"
54#include "llvm/IR/InstrTypes.h"
55#include "llvm/IR/Instruction.h"
58#include "llvm/IR/Intrinsics.h"
59#include "llvm/IR/LLVMContext.h"
60#include "llvm/IR/Metadata.h"
61#include "llvm/IR/Module.h"
64#include "llvm/IR/Operator.h"
65#include "llvm/IR/Type.h"
66#include "llvm/IR/TypeFinder.h"
68#include "llvm/IR/Use.h"
69#include "llvm/IR/User.h"
70#include "llvm/IR/Value.h"
74#include "llvm/Support/Debug.h"
79#include <cassert>
80#include <cctype>
81#include <cstddef>
82#include <cstdint>
83#include <iterator>
84#include <memory>
85#include <optional>
86#include <string>
87#include <tuple>
88#include <utility>
89#include <vector>
90
91using namespace llvm;
92
93// Make virtual table appear in this compilation unit.
95
96//===----------------------------------------------------------------------===//
97// Helper Functions
98//===----------------------------------------------------------------------===//
99
101
104
105/// Look for a value that might be wrapped as metadata, e.g. a value in a
106/// metadata operand. Returns the input value as-is if it is not wrapped.
107static const Value *skipMetadataWrapper(const Value *V) {
108 if (const auto *MAV = dyn_cast<MetadataAsValue>(V))
109 if (const auto *VAM = dyn_cast<ValueAsMetadata>(MAV->getMetadata()))
110 return VAM->getValue();
111 return V;
112}
113
114static void orderValue(const Value *V, OrderMap &OM) {
115 if (OM.lookup(V))
116 return;
117
118 if (const auto *C = dyn_cast<Constant>(V)) {
119 if (isa<ConstantData>(C))
120 return;
121
122 if (C->getNumOperands() && !isa<GlobalValue>(C))
123 for (const Value *Op : C->operands())
125 orderValue(Op, OM);
126 }
127
128 // Note: we cannot cache this lookup above, since inserting into the map
129 // changes the map's size, and thus affects the other IDs.
130 unsigned ID = OM.size() + 1;
131 OM[V] = ID;
132}
133
134static OrderMap orderModule(const Module *M) {
135 OrderMap OM;
136
137 auto OrderConstantValue = [&OM](const Value *V) {
139 orderValue(V, OM);
140 };
141
142 auto OrderConstantFromMetadata = [&](Metadata *MD) {
143 if (const auto *VAM = dyn_cast<ValueAsMetadata>(MD)) {
144 OrderConstantValue(VAM->getValue());
145 } else if (const auto *AL = dyn_cast<DIArgList>(MD)) {
146 for (const auto *VAM : AL->getArgs())
147 OrderConstantValue(VAM->getValue());
148 }
149 };
150
151 for (const GlobalVariable &G : M->globals()) {
152 if (G.hasInitializer())
153 if (!isa<GlobalValue>(G.getInitializer()))
154 orderValue(G.getInitializer(), OM);
155 orderValue(&G, OM);
156 }
157 for (const GlobalAlias &A : M->aliases()) {
158 if (!isa<GlobalValue>(A.getAliasee()))
159 orderValue(A.getAliasee(), OM);
160 orderValue(&A, OM);
161 }
162 for (const GlobalIFunc &I : M->ifuncs()) {
163 if (!isa<GlobalValue>(I.getResolver()))
164 orderValue(I.getResolver(), OM);
165 orderValue(&I, OM);
166 }
167 for (const Function &F : *M) {
168 for (const Use &U : F.operands())
169 if (!isa<GlobalValue>(U.get()))
170 orderValue(U.get(), OM);
171
172 orderValue(&F, OM);
173
174 if (F.isDeclaration())
175 continue;
176
177 for (const Argument &A : F.args())
178 orderValue(&A, OM);
179 for (const BasicBlock &BB : F) {
180 orderValue(&BB, OM);
181 for (const Instruction &I : BB) {
182 // Debug records can contain Value references, that can then contain
183 // Values disconnected from the rest of the Value hierachy, if wrapped
184 // in some kind of constant-expression. Find and order any Values that
185 // are wrapped in debug-info.
186 for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) {
187 OrderConstantFromMetadata(DVR.getRawLocation());
188 if (DVR.isDbgAssign())
189 OrderConstantFromMetadata(DVR.getRawAddress());
190 }
191
192 for (const Value *Op : I.operands()) {
194 if ((isa<Constant>(*Op) && !isa<GlobalValue>(*Op)) ||
196 orderValue(Op, OM);
197 }
198 orderValue(&I, OM);
199 }
200 }
201 }
202 return OM;
203}
204
205static std::vector<unsigned>
206predictValueUseListOrder(const Value *V, unsigned ID, const OrderMap &OM) {
207 // Predict use-list order for this one.
208 using Entry = std::pair<const Use *, unsigned>;
210 for (const Use &U : V->uses())
211 // Check if this user will be serialized.
212 if (OM.lookup(U.getUser()))
213 List.push_back(std::make_pair(&U, List.size()));
214
215 if (List.size() < 2)
216 // We may have lost some users.
217 return {};
218
219 // When referencing a value before its declaration, a temporary value is
220 // created, which will later be RAUWed with the actual value. This reverses
221 // the use list. This happens for all values apart from basic blocks.
222 bool GetsReversed = !isa<BasicBlock>(V);
223 if (auto *BA = dyn_cast<BlockAddress>(V))
224 ID = OM.lookup(BA->getBasicBlock());
225 llvm::sort(List, [&](const Entry &L, const Entry &R) {
226 const Use *LU = L.first;
227 const Use *RU = R.first;
228 if (LU == RU)
229 return false;
230
231 auto LID = OM.lookup(LU->getUser());
232 auto RID = OM.lookup(RU->getUser());
233
234 // If ID is 4, then expect: 7 6 5 1 2 3.
235 if (LID < RID) {
236 if (GetsReversed)
237 if (RID <= ID)
238 return true;
239 return false;
240 }
241 if (RID < LID) {
242 if (GetsReversed)
243 if (LID <= ID)
244 return false;
245 return true;
246 }
247
248 // LID and RID are equal, so we have different operands of the same user.
249 // Assume operands are added in order for all instructions.
250 if (GetsReversed)
251 if (LID <= ID)
252 return LU->getOperandNo() < RU->getOperandNo();
253 return LU->getOperandNo() > RU->getOperandNo();
254 });
255
257 // Order is already correct.
258 return {};
259
260 // Store the shuffle.
261 std::vector<unsigned> Shuffle(List.size());
262 for (size_t I = 0, E = List.size(); I != E; ++I)
263 Shuffle[I] = List[I].second;
264 return Shuffle;
265}
266
268 OrderMap OM = orderModule(M);
269 UseListOrderMap ULOM;
270 for (const auto &Pair : OM) {
271 const Value *V = Pair.first;
272 if (V->use_empty() || std::next(V->use_begin()) == V->use_end())
273 continue;
274
275 std::vector<unsigned> Shuffle =
276 predictValueUseListOrder(V, Pair.second, OM);
277 if (Shuffle.empty())
278 continue;
279
280 const Function *F = nullptr;
281 if (auto *I = dyn_cast<Instruction>(V))
282 F = I->getFunction();
283 if (auto *A = dyn_cast<Argument>(V))
284 F = A->getParent();
285 if (auto *BB = dyn_cast<BasicBlock>(V))
286 F = BB->getParent();
287 ULOM[F][V] = std::move(Shuffle);
288 }
289 return ULOM;
290}
291
292static const Module *getModuleFromVal(const Value *V) {
293 if (const auto *MA = dyn_cast<Argument>(V))
294 return MA->getParent() ? MA->getParent()->getParent() : nullptr;
295
296 if (const auto *BB = dyn_cast<BasicBlock>(V))
297 return BB->getParent() ? BB->getParent()->getParent() : nullptr;
298
299 if (const auto *I = dyn_cast<Instruction>(V)) {
300 const Function *M = I->getParent() ? I->getParent()->getParent() : nullptr;
301 return M ? M->getParent() : nullptr;
302 }
303
304 if (const auto *GV = dyn_cast<GlobalValue>(V))
305 return GV->getParent();
306
307 if (const auto *MAV = dyn_cast<MetadataAsValue>(V)) {
308 for (const User *U : MAV->users())
309 if (isa<Instruction>(U))
310 if (const Module *M = getModuleFromVal(U))
311 return M;
312 return nullptr;
313 }
314
315 return nullptr;
316}
317
318static const Module *getModuleFromDPI(const DbgMarker *Marker) {
319 const Function *M =
320 Marker->getParent() ? Marker->getParent()->getParent() : nullptr;
321 return M ? M->getParent() : nullptr;
322}
323
324static const Module *getModuleFromDPI(const DbgRecord *DR) {
325 return DR->getMarker() ? getModuleFromDPI(DR->getMarker()) : nullptr;
326}
327
328static void printCallingConv(unsigned cc, raw_ostream &Out) {
329 switch (cc) {
330 default: Out << "cc" << cc; break;
331 case CallingConv::Fast: Out << "fastcc"; break;
332 case CallingConv::Cold: Out << "coldcc"; break;
333 case CallingConv::AnyReg: Out << "anyregcc"; break;
334 case CallingConv::PreserveMost: Out << "preserve_mostcc"; break;
335 case CallingConv::PreserveAll: Out << "preserve_allcc"; break;
336 case CallingConv::PreserveNone: Out << "preserve_nonecc"; break;
337 case CallingConv::CXX_FAST_TLS: Out << "cxx_fast_tlscc"; break;
338 case CallingConv::GHC: Out << "ghccc"; break;
339 case CallingConv::Tail: Out << "tailcc"; break;
340 case CallingConv::GRAAL: Out << "graalcc"; break;
341 case CallingConv::CFGuard_Check: Out << "cfguard_checkcc"; break;
342 case CallingConv::X86_StdCall: Out << "x86_stdcallcc"; break;
343 case CallingConv::X86_FastCall: Out << "x86_fastcallcc"; break;
344 case CallingConv::X86_ThisCall: Out << "x86_thiscallcc"; break;
345 case CallingConv::X86_RegCall: Out << "x86_regcallcc"; break;
346 case CallingConv::X86_VectorCall:Out << "x86_vectorcallcc"; break;
347 case CallingConv::Intel_OCL_BI: Out << "intel_ocl_bicc"; break;
348 case CallingConv::ARM_APCS: Out << "arm_apcscc"; break;
349 case CallingConv::ARM_AAPCS: Out << "arm_aapcscc"; break;
350 case CallingConv::ARM_AAPCS_VFP: Out << "arm_aapcs_vfpcc"; break;
351 case CallingConv::AArch64_VectorCall: Out << "aarch64_vector_pcs"; break;
353 Out << "aarch64_sve_vector_pcs";
354 break;
356 Out << "aarch64_sme_preservemost_from_x0";
357 break;
359 Out << "aarch64_sme_preservemost_from_x1";
360 break;
362 Out << "aarch64_sme_preservemost_from_x2";
363 break;
364 case CallingConv::MSP430_INTR: Out << "msp430_intrcc"; break;
365 case CallingConv::AVR_INTR: Out << "avr_intrcc "; break;
366 case CallingConv::AVR_SIGNAL: Out << "avr_signalcc "; break;
367 case CallingConv::PTX_Kernel: Out << "ptx_kernel"; break;
368 case CallingConv::PTX_Device: Out << "ptx_device"; break;
369 case CallingConv::X86_64_SysV: Out << "x86_64_sysvcc"; break;
370 case CallingConv::Win64: Out << "win64cc"; break;
371 case CallingConv::SPIR_FUNC: Out << "spir_func"; break;
372 case CallingConv::SPIR_KERNEL: Out << "spir_kernel"; break;
373 case CallingConv::Swift: Out << "swiftcc"; break;
374 case CallingConv::SwiftTail: Out << "swifttailcc"; break;
375 case CallingConv::X86_INTR: Out << "x86_intrcc"; break;
377 Out << "hhvmcc";
378 break;
380 Out << "hhvm_ccc";
381 break;
382 case CallingConv::AMDGPU_VS: Out << "amdgpu_vs"; break;
383 case CallingConv::AMDGPU_LS: Out << "amdgpu_ls"; break;
384 case CallingConv::AMDGPU_HS: Out << "amdgpu_hs"; break;
385 case CallingConv::AMDGPU_ES: Out << "amdgpu_es"; break;
386 case CallingConv::AMDGPU_GS: Out << "amdgpu_gs"; break;
387 case CallingConv::AMDGPU_PS: Out << "amdgpu_ps"; break;
388 case CallingConv::AMDGPU_CS: Out << "amdgpu_cs"; break;
390 Out << "amdgpu_cs_chain";
391 break;
393 Out << "amdgpu_cs_chain_preserve";
394 break;
395 case CallingConv::AMDGPU_KERNEL: Out << "amdgpu_kernel"; break;
396 case CallingConv::AMDGPU_Gfx: Out << "amdgpu_gfx"; break;
398 Out << "amdgpu_gfx_whole_wave";
399 break;
400 case CallingConv::M68k_RTD: Out << "m68k_rtdcc"; break;
402 Out << "wasm_emscripten_invokecc";
403 break;
405 Out << "riscv_vector_cc";
406 break;
407#define CC_VLS_CASE(ABI_VLEN) \
408 case CallingConv::RISCV_VLSCall_##ABI_VLEN: \
409 Out << "riscv_vls_cc(" #ABI_VLEN ")"; \
410 break;
411 CC_VLS_CASE(32)
412 CC_VLS_CASE(64)
413 CC_VLS_CASE(128)
414 CC_VLS_CASE(256)
415 CC_VLS_CASE(512)
416 CC_VLS_CASE(1024)
417 CC_VLS_CASE(2048)
418 CC_VLS_CASE(4096)
419 CC_VLS_CASE(8192)
420 CC_VLS_CASE(16384)
421 CC_VLS_CASE(32768)
422 CC_VLS_CASE(65536)
423#undef CC_VLS_CASE
425 Out << "cheriot_compartmentcallcc";
426 break;
428 Out << "cheriot_compartmentcalleecc";
429 break;
431 Out << "cheriot_librarycallcc";
432 break;
433 }
434}
435
443
445 assert(!Name.empty() && "Cannot get empty name!");
446
447 // Scan the name to see if it needs quotes first.
448 bool NeedsQuotes = isdigit(static_cast<unsigned char>(Name[0]));
449 if (!NeedsQuotes) {
450 for (unsigned char C : Name) {
451 // By making this unsigned, the value passed in to isalnum will always be
452 // in the range 0-255. This is important when building with MSVC because
453 // its implementation will assert. This situation can arise when dealing
454 // with UTF-8 multibyte characters.
455 if (!isalnum(C) && C != '-' && C != '.' && C != '_') {
456 NeedsQuotes = true;
457 break;
458 }
459 }
460 }
461
462 // If we didn't need any quotes, just write out the name in one blast.
463 if (!NeedsQuotes) {
464 OS << Name;
465 return;
466 }
467
468 // Okay, we need quotes. Output the quotes and escape any scary characters as
469 // needed.
470 OS << '"';
471 printEscapedString(Name, OS);
472 OS << '"';
473}
474
475/// Turn the specified name into an 'LLVM name', which is either prefixed with %
476/// (if the string only contains simple characters) or is surrounded with ""'s
477/// (if it has special chars in it). Print it out.
478static void printLLVMName(raw_ostream &OS, StringRef Name, PrefixType Prefix) {
479 switch (Prefix) {
480 case NoPrefix:
481 break;
482 case GlobalPrefix:
483 OS << '@';
484 break;
485 case ComdatPrefix:
486 OS << '$';
487 break;
488 case LabelPrefix:
489 break;
490 case LocalPrefix:
491 OS << '%';
492 break;
493 }
495}
496
497/// Turn the specified name into an 'LLVM name', which is either prefixed with %
498/// (if the string only contains simple characters) or is surrounded with ""'s
499/// (if it has special chars in it). Print it out.
500static void printLLVMName(raw_ostream &OS, const Value *V) {
501 printLLVMName(OS, V->getName(),
503}
504
505static void printShuffleMask(raw_ostream &Out, Type *Ty, ArrayRef<int> Mask) {
506 Out << ", <";
508 Out << "vscale x ";
509 Out << Mask.size() << " x i32> ";
510 if (all_of(Mask, equal_to(0))) {
511 Out << "zeroinitializer";
512 } else if (all_of(Mask, equal_to(PoisonMaskElem))) {
513 Out << "poison";
514 } else {
515 Out << "<";
516 ListSeparator LS;
517 for (int Elt : Mask) {
518 Out << LS << "i32 ";
519 if (Elt == PoisonMaskElem)
520 Out << "poison";
521 else
522 Out << Elt;
523 }
524 Out << ">";
525 }
526}
527
528namespace {
529
530class TypePrinting {
531public:
532 TypePrinting(const Module *M = nullptr)
533 : M(M), TypesIncorporated(M == nullptr) {}
534
535 TypePrinting(const TypePrinting &) = delete;
536 TypePrinting &operator=(const TypePrinting &) = delete;
537
538 /// The named types that are used by the current module.
539 TypeFinder &getNamedTypes();
540
541 /// The numbered types, number to type mapping.
542 std::vector<StructType *> &getNumberedTypes();
543
544 bool empty();
545
546 void print(Type *Ty, raw_ostream &OS);
547
548 void printStructBody(StructType *Ty, raw_ostream &OS);
549
550private:
551 void incorporateTypes();
552
553 /// A module to process lazily.
554 const Module *M;
555 bool TypesIncorporated;
556
557 TypeFinder NamedTypes;
558
559 // The numbered types, along with their value.
560 DenseMap<StructType *, unsigned> Type2Number;
561
562 std::vector<StructType *> NumberedTypes;
563};
564
565} // end anonymous namespace
566
567TypeFinder &TypePrinting::getNamedTypes() {
568 incorporateTypes();
569 return NamedTypes;
570}
571
572std::vector<StructType *> &TypePrinting::getNumberedTypes() {
573 incorporateTypes();
574
575 // We know all the numbers that each type is used and we know that it is a
576 // dense assignment. Convert the map to an index table, if it's not done
577 // already (judging from the sizes):
578 if (NumberedTypes.size() == Type2Number.size())
579 return NumberedTypes;
580
581 NumberedTypes.resize(Type2Number.size());
582 for (const auto &P : Type2Number) {
583 assert(P.second < NumberedTypes.size() && "Didn't get a dense numbering?");
584 assert(!NumberedTypes[P.second] && "Didn't get a unique numbering?");
585 NumberedTypes[P.second] = P.first;
586 }
587 return NumberedTypes;
588}
589
590bool TypePrinting::empty() {
591 incorporateTypes();
592 return NamedTypes.empty() && Type2Number.empty();
593}
594
595void TypePrinting::incorporateTypes() {
596 if (TypesIncorporated)
597 return;
598
599 NamedTypes.run(*M, false);
600 TypesIncorporated = true;
601
602 // The list of struct types we got back includes all the struct types, split
603 // the unnamed ones out to a numbering and remove the anonymous structs.
604 unsigned NextNumber = 0;
605
606 std::vector<StructType *>::iterator NextToUse = NamedTypes.begin();
607 for (StructType *STy : NamedTypes) {
608 // Ignore anonymous types.
609 if (STy->isLiteral())
610 continue;
611
612 if (STy->getName().empty())
613 Type2Number[STy] = NextNumber++;
614 else
615 *NextToUse++ = STy;
616 }
617
618 NamedTypes.erase(NextToUse, NamedTypes.end());
619}
620
621static void printAddressSpace(const Module *M, unsigned AS, raw_ostream &OS,
622 StringRef Prefix = " ", StringRef Suffix = "",
623 bool ForcePrint = false) {
624 if (AS == 0 && !ForcePrint)
625 return;
626 OS << Prefix << "addrspace(";
627 StringRef ASName = M && getIROptions(M->getContext()).print_addrspace_name
628 ? M->getDataLayout().getAddressSpaceName(AS)
629 : "";
630 if (!ASName.empty())
631 OS << "\"" << ASName << "\"";
632 else
633 OS << AS;
634 OS << ")" << Suffix;
635}
636
637/// Write the specified type to the specified raw_ostream, making use of type
638/// names or up references to shorten the type name where possible.
639void TypePrinting::print(Type *Ty, raw_ostream &OS) {
640 switch (Ty->getTypeID()) {
641 case Type::VoidTyID: OS << "void"; return;
642 case Type::HalfTyID: OS << "half"; return;
643 case Type::BFloatTyID: OS << "bfloat"; return;
644 case Type::FloatTyID: OS << "float"; return;
645 case Type::DoubleTyID: OS << "double"; return;
646 case Type::X86_FP80TyID: OS << "x86_fp80"; return;
647 case Type::FP128TyID: OS << "fp128"; return;
648 case Type::PPC_FP128TyID: OS << "ppc_fp128"; return;
649 case Type::LabelTyID: OS << "label"; return;
650 case Type::MetadataTyID:
651 OS << "metadata";
652 return;
653 case Type::X86_AMXTyID: OS << "x86_amx"; return;
654 case Type::TokenTyID: OS << "token"; return;
655 case Type::ByteTyID:
656 OS << 'b' << Ty->getByteBitWidth();
657 return;
658 case Type::IntegerTyID:
659 OS << 'i' << cast<IntegerType>(Ty)->getBitWidth();
660 return;
661
662 case Type::FunctionTyID: {
663 FunctionType *FTy = cast<FunctionType>(Ty);
664 print(FTy->getReturnType(), OS);
665 OS << " (";
666 ListSeparator LS;
667 for (Type *Ty : FTy->params()) {
668 OS << LS;
669 print(Ty, OS);
670 }
671 if (FTy->isVarArg())
672 OS << LS << "...";
673 OS << ')';
674 return;
675 }
676 case Type::StructTyID: {
677 StructType *STy = cast<StructType>(Ty);
678
679 if (STy->isLiteral())
680 return printStructBody(STy, OS);
681
682 if (!STy->getName().empty())
683 return printLLVMName(OS, STy->getName(), LocalPrefix);
684
685 incorporateTypes();
686 const auto I = Type2Number.find(STy);
687 if (I != Type2Number.end())
688 OS << '%' << I->second;
689 else // Not enumerated, print the hex address.
690 OS << "%\"type " << STy << '\"';
691 return;
692 }
693 case Type::PointerTyID: {
695 OS << "ptr";
696 printAddressSpace(M, PTy->getAddressSpace(), OS);
697 return;
698 }
699 case Type::ArrayTyID: {
700 ArrayType *ATy = cast<ArrayType>(Ty);
701 OS << '[' << ATy->getNumElements() << " x ";
702 print(ATy->getElementType(), OS);
703 OS << ']';
704 return;
705 }
706 case Type::FixedVectorTyID:
707 case Type::ScalableVectorTyID: {
708 VectorType *PTy = cast<VectorType>(Ty);
709 ElementCount EC = PTy->getElementCount();
710 OS << "<";
711 if (EC.isScalable())
712 OS << "vscale x ";
713 OS << EC.getKnownMinValue() << " x ";
714 print(PTy->getElementType(), OS);
715 OS << '>';
716 return;
717 }
718 case Type::TypedPointerTyID: {
719 TypedPointerType *TPTy = cast<TypedPointerType>(Ty);
720 OS << "typedptr(" << *TPTy->getElementType() << ", "
721 << TPTy->getAddressSpace() << ")";
722 return;
723 }
724 case Type::TargetExtTyID:
725 TargetExtType *TETy = cast<TargetExtType>(Ty);
726 OS << "target(\"";
728 OS << "\"";
729 for (Type *Inner : TETy->type_params()) {
730 OS << ", ";
731 Inner->print(OS, /*IsForDebug=*/false, /*NoDetails=*/true);
732 }
733 for (unsigned IntParam : TETy->int_params())
734 OS << ", " << IntParam;
735 OS << ")";
736 return;
737 }
738 llvm_unreachable("Invalid TypeID");
739}
740
741void TypePrinting::printStructBody(StructType *STy, raw_ostream &OS) {
742 if (STy->isOpaque()) {
743 OS << "opaque";
744 return;
745 }
746
747 if (STy->isPacked())
748 OS << '<';
749
750 if (STy->getNumElements() == 0) {
751 OS << "{}";
752 } else {
753 OS << "{ ";
754 ListSeparator LS;
755 for (Type *Ty : STy->elements()) {
756 OS << LS;
757 print(Ty, OS);
758 }
759
760 OS << " }";
761 }
762 if (STy->isPacked())
763 OS << '>';
764}
765
767
768//===----------------------------------------------------------------------===//
769// SlotTracker Class: Enumerate slot numbers for unnamed values
770//===----------------------------------------------------------------------===//
771/// This class provides computation of slot numbers for LLVM Assembly writing.
772///
774public:
775 /// ValueMap - A mapping of Values to slot numbers.
777
778private:
779 /// TheModule - The module for which we are holding slot numbers.
780 const Module* TheModule;
781
782 /// TheFunction - The function for which we are holding slot numbers.
783 const Function* TheFunction = nullptr;
784 bool FunctionProcessed = false;
785 bool ShouldTrackMetadataDefinitions;
786
787 std::function<void(AbstractSlotTrackerStorage *, const Module *)>
788 ProcessModuleHookFn;
789 std::function<void(AbstractSlotTrackerStorage *, const Function *)>
790 ProcessFunctionHookFn;
791
792 /// The summary index for which we are holding slot numbers.
793 const ModuleSummaryIndex *TheIndex = nullptr;
794
795 /// mMap - The slot map for the module level data.
796 ValueMap mMap;
797 unsigned mNext = 0;
798
799 /// fMap - The slot map for the function level data.
800 ValueMap fMap;
801 unsigned fNext = 0;
802
803 /// mdnMap - Map for MDNodes.
805 /// asMap - The slot map for attribute sets.
807 unsigned asNext = 0;
808
809 /// ModulePathMap - The slot map for Module paths used in the summary index.
810 StringMap<unsigned> ModulePathMap;
811 unsigned ModulePathNext = 0;
812
813 /// GUIDMap - The slot map for GUIDs used in the summary index.
815 unsigned GUIDNext = 0;
816
817 /// TypeIdMap - The slot map for type ids used in the summary index.
818 StringMap<unsigned> TypeIdMap;
819 unsigned TypeIdNext = 0;
820
821 /// TypeIdCompatibleVtableMap - The slot map for type compatible vtable ids
822 /// used in the summary index.
823 StringMap<unsigned> TypeIdCompatibleVtableMap;
824 unsigned TypeIdCompatibleVtableNext = 0;
825
826public:
827 /// Construct from a module.
828 ///
829 explicit SlotTracker(const Module *M,
830 bool ShouldTrackMetadataDefinitions = false);
831
832 /// Construct from a function, starting out in incorp state.
833 ///
834 explicit SlotTracker(const Function *F);
835
836 /// Construct from a module summary index.
837 explicit SlotTracker(const ModuleSummaryIndex *Index);
838
839 SlotTracker(const SlotTracker &) = delete;
841
842 ~SlotTracker() override = default;
843
844 void setProcessHook(
845 std::function<void(AbstractSlotTrackerStorage *, const Module *)>);
846 void setProcessHook(
847 std::function<void(AbstractSlotTrackerStorage *, const Function *)>);
848
849 void createMetadataSlot(const MDNode *N) override;
850
851 /// Return the slot number of the specified value in it's type
852 /// plane. If something is not in the SlotTracker, return -1.
853 int getLocalSlot(const Value *V);
854 int getGlobalSlot(const GlobalValue *V);
855 int getMetadataSlot(const MDNode *N) override;
859 int getTypeIdSlot(StringRef Id);
861
862 /// If you'd like to deal with a function instead of just a module, use
863 /// this method to get its data into the SlotTracker.
865 TheFunction = F;
866 FunctionProcessed = false;
867 }
868
869 const Function *getFunction() const { return TheFunction; }
870
871 /// After calling incorporateFunction, use this method to remove the
872 /// most recently incorporated function from the SlotTracker. This
873 /// will reset the state of the machine back to just the module contents.
874 void purgeFunction();
875
876 /// MDNode map iterators.
878
879 mdn_iterator mdn_begin() { return mdnMap.begin(); }
880 mdn_iterator mdn_end() { return mdnMap.end(); }
881 unsigned mdn_size() const { return mdnMap.size(); }
882 bool mdn_empty() const { return mdnMap.empty(); }
883
884 /// AttributeSet map iterators.
886
887 as_iterator as_begin() { return asMap.begin(); }
888 as_iterator as_end() { return asMap.end(); }
889 unsigned as_size() const { return asMap.size(); }
890 bool as_empty() const { return asMap.empty(); }
891
892 /// GUID map iterators.
894
895 /// These functions do the actual initialization.
896 inline void initializeIfNeeded();
898
899 // Implementation Details
900private:
901 /// CreateModuleSlot - Insert the specified GlobalValue* into the slot table.
902 void CreateModuleSlot(const GlobalValue *V);
903
904 /// Record a metadata definition and the metadata nodes referenced by it.
905 void CreateMetadataSlot(const MDNode *N);
906
907 /// CreateFunctionSlot - Insert the specified Value* into the slot table.
908 void CreateFunctionSlot(const Value *V);
909
910 /// Insert the specified AttributeSet into the slot table.
911 void CreateAttributeSetSlot(AttributeSet AS);
912
913 inline void CreateModulePathSlot(StringRef Path);
914 void CreateGUIDSlot(GlobalValue::GUID GUID);
915 void CreateTypeIdSlot(StringRef Id);
916 void CreateTypeIdCompatibleVtableSlot(StringRef Id);
917
918 /// Add all of the module level global variables (and their initializers)
919 /// and function declarations, but not the contents of those functions.
920 void processModule();
921 // Returns number of allocated slots
922 int processIndex();
923
924 /// Add all of the functions arguments, basic blocks, and instructions.
925 void processFunction();
926};
927
929 const Function *F)
930 : M(M), F(F), Machine(&Machine) {}
931
933 : ShouldCreateStorage(M), M(M) {}
934
936
938 if (!ShouldCreateStorage)
939 return Machine;
940
941 ShouldCreateStorage = false;
942 MachineStorage = std::make_unique<SlotTracker>(M);
943 Machine = MachineStorage.get();
944 if (ProcessModuleHookFn)
945 Machine->setProcessHook(ProcessModuleHookFn);
946 if (ProcessFunctionHookFn)
947 Machine->setProcessHook(ProcessFunctionHookFn);
948 return Machine;
949}
950
952 // Using getMachine() may lazily create the slot tracker.
953 if (!getMachine())
954 return;
955
956 // Nothing to do if this is the right function already.
957 if (this->F == &F)
958 return;
959 if (this->F)
960 Machine->purgeFunction();
961 Machine->incorporateFunction(&F);
962 this->F = &F;
963}
964
966 assert(F && "No function incorporated");
967 return Machine->getLocalSlot(V);
968}
969
971 std::function<void(AbstractSlotTrackerStorage *, const Module *)> Fn) {
972 ProcessModuleHookFn = std::move(Fn);
973}
974
976 std::function<void(AbstractSlotTrackerStorage *, const Function *)> Fn) {
977 ProcessFunctionHookFn = std::move(Fn);
978}
979
981 if (const auto *FA = dyn_cast<Argument>(V))
982 return new SlotTracker(FA->getParent());
983
984 if (const auto *I = dyn_cast<Instruction>(V))
985 if (I->getParent())
986 return new SlotTracker(I->getParent()->getParent());
987
988 if (const auto *BB = dyn_cast<BasicBlock>(V))
989 return new SlotTracker(BB->getParent());
990
991 if (const auto *GV = dyn_cast<GlobalVariable>(V))
992 return new SlotTracker(GV->getParent());
993
994 if (const auto *GA = dyn_cast<GlobalAlias>(V))
995 return new SlotTracker(GA->getParent());
996
997 if (const auto *GIF = dyn_cast<GlobalIFunc>(V))
998 return new SlotTracker(GIF->getParent());
999
1000 if (const auto *Func = dyn_cast<Function>(V))
1001 return new SlotTracker(Func);
1002
1003 return nullptr;
1004}
1005
1006#if 0
1007#define ST_DEBUG(X) dbgs() << X
1008#else
1009#define ST_DEBUG(X)
1010#endif
1011
1012// Module level constructor. Causes the contents of the Module (sans functions)
1013// to be added to the slot table.
1014SlotTracker::SlotTracker(const Module *M, bool ShouldTrackMetadataDefinitions)
1015 : TheModule(M),
1016 ShouldTrackMetadataDefinitions(ShouldTrackMetadataDefinitions) {}
1017
1018// Function level constructor. Causes the contents of the Module and the one
1019// function provided to be added to the slot table.
1021 : TheModule(F ? F->getParent() : nullptr), TheFunction(F),
1022 ShouldTrackMetadataDefinitions(false) {}
1023
1025 : TheModule(nullptr), ShouldTrackMetadataDefinitions(false),
1026 TheIndex(Index) {}
1027
1029 if (TheModule) {
1030 processModule();
1031 TheModule = nullptr; ///< Prevent re-processing next time we're called.
1032 }
1033
1034 if (TheFunction && !FunctionProcessed)
1035 processFunction();
1036}
1037
1039 if (!TheIndex)
1040 return 0;
1041 int NumSlots = processIndex();
1042 TheIndex = nullptr; ///< Prevent re-processing next time we're called.
1043 return NumSlots;
1044}
1045
1046// Iterate through all the global variables, functions, and global
1047// variable initializers and create slots for them.
1048void SlotTracker::processModule() {
1049 ST_DEBUG("begin processModule!\n");
1050
1051 // Add all of the unnamed global variables to the value table.
1052 for (const GlobalVariable &Var : TheModule->globals()) {
1053 if (!Var.hasName())
1054 CreateModuleSlot(&Var);
1055 auto Attrs = Var.getAttributes();
1056 if (Attrs.hasAttributes())
1057 CreateAttributeSetSlot(Attrs);
1058 }
1059
1060 for (const GlobalAlias &A : TheModule->aliases()) {
1061 if (!A.hasName())
1062 CreateModuleSlot(&A);
1063 }
1064
1065 for (const GlobalIFunc &I : TheModule->ifuncs()) {
1066 if (!I.hasName())
1067 CreateModuleSlot(&I);
1068 }
1069
1070 for (const Function &F : *TheModule) {
1071 if (!F.hasName())
1072 // Add all the unnamed functions to the table.
1073 CreateModuleSlot(&F);
1074
1075 // Add all the function attributes to the table.
1076 // FIXME: Add attributes of other objects?
1077 AttributeSet FnAttrs = F.getAttributes().getFnAttrs();
1078 if (FnAttrs.hasAttributes())
1079 CreateAttributeSetSlot(FnAttrs);
1080 }
1081
1082 if (ProcessModuleHookFn)
1083 ProcessModuleHookFn(this, TheModule);
1084
1085 ST_DEBUG("end processModule!\n");
1086}
1087
1088// Process the arguments, basic blocks, and instructions of a function.
1089void SlotTracker::processFunction() {
1090 ST_DEBUG("begin processFunction!\n");
1091 fNext = 0;
1092
1093 // Add all the function arguments with no names.
1094 for(Function::const_arg_iterator AI = TheFunction->arg_begin(),
1095 AE = TheFunction->arg_end(); AI != AE; ++AI)
1096 if (!AI->hasName())
1097 CreateFunctionSlot(&*AI);
1098
1099 ST_DEBUG("Inserting Instructions:\n");
1100
1101 // Add all of the basic blocks and instructions with no names.
1102 for (auto &BB : *TheFunction) {
1103 if (!BB.hasName())
1104 CreateFunctionSlot(&BB);
1105
1106 for (auto &I : BB) {
1107 if (!I.getType()->isVoidTy() && !I.hasName())
1108 CreateFunctionSlot(&I);
1109
1110 // We allow direct calls to any llvm.foo function here, because the
1111 // target may not be linked into the optimizer.
1112 if (const auto *Call = dyn_cast<CallBase>(&I)) {
1113 // Add all the call attributes to the table.
1114 AttributeSet Attrs = Call->getAttributes().getFnAttrs();
1115 if (Attrs.hasAttributes())
1116 CreateAttributeSetSlot(Attrs);
1117 }
1118 }
1119 }
1120
1121 if (ProcessFunctionHookFn)
1122 ProcessFunctionHookFn(this, TheFunction);
1123
1124 FunctionProcessed = true;
1125
1126 ST_DEBUG("end processFunction!\n");
1127}
1128
1129// Iterate through all the GUID in the index and create slots for them.
1130int SlotTracker::processIndex() {
1131 ST_DEBUG("begin processIndex!\n");
1132 assert(TheIndex);
1133
1134 // The first block of slots are just the module ids, which start at 0 and are
1135 // assigned consecutively. Since the StringMap iteration order isn't
1136 // guaranteed, order by path string before assigning slots.
1137 std::vector<StringRef> ModulePaths;
1138 for (auto &[ModPath, _] : TheIndex->modulePaths())
1139 ModulePaths.push_back(ModPath);
1140 llvm::sort(ModulePaths);
1141 for (auto &ModPath : ModulePaths)
1142 CreateModulePathSlot(ModPath);
1143
1144 // Start numbering the GUIDs after the module ids.
1145 GUIDNext = ModulePathNext;
1146
1147 // Sort by GUID for deterministic slot assignment.
1148 for (const auto &GlobalList : TheIndex->sortedGlobalValueSummariesRange())
1149 CreateGUIDSlot(GlobalList.first);
1150
1151 // Start numbering the TypeIdCompatibleVtables after the GUIDs.
1152 TypeIdCompatibleVtableNext = GUIDNext;
1153 for (auto &TId : TheIndex->typeIdCompatibleVtableMap())
1154 CreateTypeIdCompatibleVtableSlot(TId.first);
1155
1156 // Start numbering the TypeIds after the TypeIdCompatibleVtables.
1157 TypeIdNext = TypeIdCompatibleVtableNext;
1158 for (const auto &TID : TheIndex->typeIds())
1159 CreateTypeIdSlot(TID.second.first);
1160
1161 ST_DEBUG("end processIndex!\n");
1162 return TypeIdNext;
1163}
1164
1165namespace {
1166class MetadataNodeVisitor {
1167 /// Visited MDNodes.
1168 SmallPtrSet<const MDNode *, 32> VisitedMDNodes;
1169 function_ref<void(const MDNode *)> Visit;
1170
1171 void visit(const MDNode *N) {
1172 if (isa<DIExpression>(N) || !VisitedMDNodes.insert(N).second)
1173 return;
1174
1175 Visit(N);
1176 for (const MDOperand &Op : N->operands())
1177 if (const auto *OpNode = dyn_cast_or_null<MDNode>(Op.get()))
1178 visit(OpNode);
1179 }
1180
1181 void visitGlobalObjectMetadata(const GlobalObject &GO) {
1183 GO.getAllMetadata(MDs);
1184 for (auto &MD : MDs)
1185 visit(MD.second);
1186 }
1187
1188 void visitDbgRecordMetadata(const DbgRecord &DR) {
1189 if (const auto *DVR = dyn_cast<const DbgVariableRecord>(&DR)) {
1190 if (auto *Empty = dyn_cast_if_present<MDNode>(DVR->getRawLocation()))
1191 visit(Empty);
1192 if (DVR->getRawVariable())
1193 visit(DVR->getRawVariable());
1194 if (DVR->isDbgAssign()) {
1195 if (auto *AssignID = DVR->getRawAssignID())
1196 visit(cast<MDNode>(AssignID));
1197 if (auto *Empty = dyn_cast_if_present<MDNode>(DVR->getRawAddress()))
1198 visit(Empty);
1199 }
1200 } else if (const auto *DLR = dyn_cast<const DbgLabelRecord>(&DR)) {
1201 visit(DLR->getRawLabel());
1202 } else {
1203 llvm_unreachable("unsupported DbgRecord kind");
1204 }
1205 if (DR.getDebugLoc())
1207 }
1208
1209 void visitInstructionMetadata(const Instruction &I) {
1210 if (const auto *CI = dyn_cast<CallInst>(&I))
1211 if (Function *F = CI->getCalledFunction())
1212 if (F->isIntrinsic())
1213 for (auto &Op : I.operands())
1215 if (auto *N = dyn_cast<MDNode>(V->getMetadata()))
1216 visit(N);
1217
1219 I.getAllMetadata(MDs);
1220 for (auto &MD : MDs)
1221 visit(MD.second);
1222 }
1223
1224 void visitFunctionMetadata(const Function &F) {
1225 visitGlobalObjectMetadata(F);
1226 for (const BasicBlock &BB : F)
1227 for (const Instruction &I : BB) {
1228 for (const DbgRecord &DR : I.getDbgRecordRange())
1229 visitDbgRecordMetadata(DR);
1230 visitInstructionMetadata(I);
1231 }
1232 }
1233
1234public:
1235 MetadataNodeVisitor(function_ref<void(const MDNode *)> Visit)
1236 : Visit(Visit) {}
1237
1238 void visitModuleMetadata(const Module &M) {
1239 for (const GlobalVariable &Var : M.globals())
1240 visitGlobalObjectMetadata(Var);
1241 for (const GlobalIFunc &I : M.ifuncs())
1242 visitGlobalObjectMetadata(I);
1243 for (const NamedMDNode &NMD : M.named_metadata())
1244 for (const MDNode *N : NMD.operands())
1245 visit(N);
1246 for (const Function &F : M)
1247 visitFunctionMetadata(F);
1248 }
1249
1250 void visitMetadata(ArrayRef<const MDNode *> Metadata) {
1251 for (const MDNode *N : Metadata)
1252 visit(N);
1253 }
1254
1255 bool contains(const MDNode *N) const { return VisitedMDNodes.contains(N); }
1256};
1257
1258class MetadataIDRenumberer {
1259 uint32_t NextID = 0;
1260
1261public:
1262 void run(const Module &M, ArrayRef<const MDNode *> AdditionalMetadata,
1263 ModuleSlotTracker::MachineMDNodeListType *AdditionalMetadataNodes =
1264 nullptr) {
1265 bool IsAdditionalMetadata = false;
1266 auto Renumber = [&](const MDNode *N) {
1267 N->getContext().pImpl->setMetadataPrintID(const_cast<MDNode *>(N),
1268 NextID++);
1269 if (IsAdditionalMetadata && AdditionalMetadataNodes)
1270 AdditionalMetadataNodes->emplace_back(
1271 N->getContext().pImpl->getMetadataPrintID(N), N);
1272 };
1273 MetadataNodeVisitor Visitor(Renumber);
1274
1275 Visitor.visitModuleMetadata(M);
1276
1277 IsAdditionalMetadata = true;
1278 Visitor.visitMetadata(AdditionalMetadata);
1279
1280 // Keep IDs unique for nodes outside the canonical output.
1281 SmallVector<MDNode *, 32> RemainingNodes;
1282 M.getContext().pImpl->getAllMetadataNodes(RemainingNodes);
1283 llvm::erase_if(RemainingNodes, [&](const MDNode *N) {
1284 return Visitor.contains(N) ||
1285 M.getContext().pImpl->getMetadataPrintID(N) >= NextID;
1286 });
1287 llvm::sort(RemainingNodes, [&](const MDNode *LHS, const MDNode *RHS) {
1288 return M.getContext().pImpl->getMetadataPrintID(LHS) <
1289 M.getContext().pImpl->getMetadataPrintID(RHS);
1290 });
1291 for (MDNode *N : RemainingNodes)
1292 M.getContext().pImpl->setMetadataPrintID(
1293 N, M.getContext().pImpl->allocateMetadataPrintID());
1294
1295 if (AdditionalMetadataNodes)
1296 llvm::sort(*AdditionalMetadataNodes);
1297 }
1298};
1299} // namespace
1300
1302 MetadataIDRenumberer().run(*this, {});
1303}
1304
1306 ArrayRef<const MDNode *> AdditionalMetadata,
1307 MachineMDNodeListType *AdditionalMetadataNodes) const {
1308 assert(M && "metadata renumbering requires a module");
1309 MetadataIDRenumberer().run(*M, AdditionalMetadata, AdditionalMetadataNodes);
1310}
1311
1313 ArrayRef<const MDNode *> AdditionalMetadata,
1314 MachineMDNodeListType &AdditionalMetadataNodes) const {
1315 assert(M && "metadata collection requires a module");
1316 bool IsAdditionalMetadata = false;
1317 auto Collect = [&](const MDNode *N) {
1318 if (IsAdditionalMetadata)
1319 AdditionalMetadataNodes.emplace_back(
1320 N->getContext().pImpl->getMetadataPrintID(N), N);
1321 };
1322 MetadataNodeVisitor Visitor(Collect);
1323 Visitor.visitModuleMetadata(*M);
1324 IsAdditionalMetadata = true;
1325 Visitor.visitMetadata(AdditionalMetadata);
1326 llvm::sort(AdditionalMetadataNodes);
1327}
1328
1329/// Clean up after incorporating a function. This is the only way to get out of
1330/// the function incorporation state that affects get*Slot/Create*Slot. Function
1331/// incorporation state is indicated by TheFunction != 0.
1333 ST_DEBUG("begin purgeFunction!\n");
1334 fMap.clear(); // Simply discard the function level map
1335 TheFunction = nullptr;
1336 FunctionProcessed = false;
1337 ST_DEBUG("end purgeFunction!\n");
1338}
1339
1340/// getGlobalSlot - Get the slot number of a global value.
1342 // Check for uninitialized state and do lazy initialization.
1344
1345 // Find the value in the module map
1346 ValueMap::iterator MI = mMap.find(V);
1347 return MI == mMap.end() ? -1 : (int)MI->second;
1348}
1349
1351 std::function<void(AbstractSlotTrackerStorage *, const Module *)> Fn) {
1352 ProcessModuleHookFn = std::move(Fn);
1353}
1354
1356 std::function<void(AbstractSlotTrackerStorage *, const Function *)> Fn) {
1357 ProcessFunctionHookFn = std::move(Fn);
1358}
1359
1360/// getMetadataSlot - Get the slot number of a MDNode.
1361void SlotTracker::createMetadataSlot(const MDNode *N) { CreateMetadataSlot(N); }
1362
1363/// getMetadataSlot - Get the slot number of a MDNode.
1365 // Check for uninitialized state and do lazy initialization.
1367
1368 if (isa<DIExpression>(N))
1369 return -1;
1370 if (ShouldTrackMetadataDefinitions)
1371 CreateMetadataSlot(N);
1372 return N->getContext().pImpl->getMetadataPrintID(N);
1373}
1374
1375/// getLocalSlot - Get the slot number for a value that is local to a function.
1377 assert(!isa<Constant>(V) && "Can't get a constant or global slot with this!");
1378
1379 // Check for uninitialized state and do lazy initialization.
1381
1382 ValueMap::iterator FI = fMap.find(V);
1383 return FI == fMap.end() ? -1 : (int)FI->second;
1384}
1385
1387 // Check for uninitialized state and do lazy initialization.
1389
1390 // Find the AttributeSet in the module map.
1391 as_iterator AI = asMap.find(AS);
1392 return AI == asMap.end() ? -1 : (int)AI->second;
1393}
1394
1396 // Check for uninitialized state and do lazy initialization.
1398
1399 // Find the Module path in the map
1400 auto I = ModulePathMap.find(Path);
1401 return I == ModulePathMap.end() ? -1 : (int)I->second;
1402}
1403
1405 // Check for uninitialized state and do lazy initialization.
1407
1408 // Find the GUID in the map
1409 guid_iterator I = GUIDMap.find(GUID);
1410 return I == GUIDMap.end() ? -1 : (int)I->second;
1411}
1412
1414 // Check for uninitialized state and do lazy initialization.
1416
1417 // Find the TypeId string in the map
1418 auto I = TypeIdMap.find(Id);
1419 return I == TypeIdMap.end() ? -1 : (int)I->second;
1420}
1421
1423 // Check for uninitialized state and do lazy initialization.
1425
1426 // Find the TypeIdCompatibleVtable string in the map
1427 auto I = TypeIdCompatibleVtableMap.find(Id);
1428 return I == TypeIdCompatibleVtableMap.end() ? -1 : (int)I->second;
1429}
1430
1431/// CreateModuleSlot - Insert the specified GlobalValue* into the slot table.
1432void SlotTracker::CreateModuleSlot(const GlobalValue *V) {
1433 assert(V && "Can't insert a null Value into SlotTracker!");
1434 assert(!V->getType()->isVoidTy() && "Doesn't need a slot!");
1435 assert(!V->hasName() && "Doesn't need a slot!");
1436
1437 unsigned DestSlot = mNext++;
1438 mMap[V] = DestSlot;
1439
1440 ST_DEBUG(" Inserting value [" << V->getType() << "] = " << V << " slot=" <<
1441 DestSlot << " [");
1442 // G = Global, F = Function, A = Alias, I = IFunc, o = other
1443 ST_DEBUG((isa<GlobalVariable>(V) ? 'G' :
1444 (isa<Function>(V) ? 'F' :
1445 (isa<GlobalAlias>(V) ? 'A' :
1446 (isa<GlobalIFunc>(V) ? 'I' : 'o')))) << "]\n");
1447}
1448
1449/// CreateSlot - Create a new slot for the specified value if it has no name.
1450void SlotTracker::CreateFunctionSlot(const Value *V) {
1451 assert(!V->getType()->isVoidTy() && !V->hasName() && "Doesn't need a slot!");
1452
1453 unsigned DestSlot = fNext++;
1454 fMap[V] = DestSlot;
1455
1456 // G = Global, F = Function, o = other
1457 ST_DEBUG(" Inserting value [" << V->getType() << "] = " << V << " slot=" <<
1458 DestSlot << " [o]\n");
1459}
1460
1461/// CreateModuleSlot - Insert the specified MDNode* into the slot table.
1462void SlotTracker::CreateMetadataSlot(const MDNode *N) {
1463 assert(N && "Can't insert a null Value into SlotTracker!");
1464
1465 if (isa<DIExpression>(N))
1466 return;
1467
1468 unsigned ID = N->getContext().pImpl->getMetadataPrintID(N);
1469 if (!mdnMap.try_emplace(N, ID).second)
1470 return;
1471
1472 for (const MDOperand &Op : N->operands())
1473 if (const auto *OpNode = dyn_cast_or_null<MDNode>(Op.get()))
1474 CreateMetadataSlot(OpNode);
1475}
1476
1477void SlotTracker::CreateAttributeSetSlot(AttributeSet AS) {
1478 assert(AS.hasAttributes() && "Doesn't need a slot!");
1479
1480 if (asMap.try_emplace(AS, asNext).second)
1481 ++asNext;
1482}
1483
1484/// Create a new slot for the specified Module
1485void SlotTracker::CreateModulePathSlot(StringRef Path) {
1486 ModulePathMap[Path] = ModulePathNext++;
1487}
1488
1489/// Create a new slot for the specified GUID
1490void SlotTracker::CreateGUIDSlot(GlobalValue::GUID GUID) {
1491 GUIDMap[GUID] = GUIDNext++;
1492}
1493
1494/// Create a new slot for the specified Id
1495void SlotTracker::CreateTypeIdSlot(StringRef Id) {
1496 TypeIdMap[Id] = TypeIdNext++;
1497}
1498
1499/// Create a new slot for the specified Id
1500void SlotTracker::CreateTypeIdCompatibleVtableSlot(StringRef Id) {
1501 TypeIdCompatibleVtableMap[Id] = TypeIdCompatibleVtableNext++;
1502}
1503
1504namespace {
1505/// Common instances used by most of the printer functions.
1506struct AsmWriterContext {
1507 TypePrinting *TypePrinter = nullptr;
1508 SlotTracker *Machine = nullptr;
1509 const Module *Context = nullptr;
1510 const ModuleSlotTracker *MST = nullptr;
1511
1512 AsmWriterContext(TypePrinting *TP, SlotTracker *ST, const Module *M = nullptr,
1513 const ModuleSlotTracker *MST = nullptr)
1514 : TypePrinter(TP), Machine(ST), Context(M), MST(MST) {}
1515
1516 static AsmWriterContext &getEmpty() {
1517 static AsmWriterContext EmptyCtx(nullptr, nullptr);
1518 return EmptyCtx;
1519 }
1520
1521 /// A callback that will be triggered when the underlying printer
1522 /// prints a Metadata as operand.
1523 virtual void onWriteMetadataAsOperand(const Metadata *) {}
1524
1525 virtual ~AsmWriterContext() = default;
1526};
1527} // end anonymous namespace
1528
1529//===----------------------------------------------------------------------===//
1530// AsmWriter Implementation
1531//===----------------------------------------------------------------------===//
1532
1533static void writeAsOperandInternal(raw_ostream &Out, const Value *V,
1534 AsmWriterContext &WriterCtx,
1535 bool PrintType = false);
1536
1537static void writeAsOperandInternal(raw_ostream &Out, const Metadata *MD,
1538 AsmWriterContext &WriterCtx,
1539 bool FromValue = false);
1540
1541static void writeOptimizationInfo(raw_ostream &Out, const User *U) {
1542 if (const auto *FPO = dyn_cast<const FPMathOperator>(U))
1543 Out << FPO->getFastMathFlags();
1544
1545 if (const auto *OBO = dyn_cast<OverflowingBinaryOperator>(U)) {
1546 if (OBO->hasNoUnsignedWrap())
1547 Out << " nuw";
1548 if (OBO->hasNoSignedWrap())
1549 Out << " nsw";
1550 } else if (const auto *Div = dyn_cast<PossiblyExactOperator>(U)) {
1551 if (Div->isExact())
1552 Out << " exact";
1553 } else if (const auto *PDI = dyn_cast<PossiblyDisjointInst>(U)) {
1554 if (PDI->isDisjoint())
1555 Out << " disjoint";
1556 } else if (const auto *GEP = dyn_cast<GEPOperator>(U)) {
1557 if (GEP->isInBounds())
1558 Out << " inbounds";
1559 else if (GEP->hasNoUnsignedSignedWrap())
1560 Out << " nusw";
1561 if (GEP->hasNoUnsignedWrap())
1562 Out << " nuw";
1563 if (auto InRange = GEP->getInRange()) {
1564 Out << " inrange(" << InRange->getLower() << ", " << InRange->getUpper()
1565 << ")";
1566 }
1567 } else if (const auto *NNI = dyn_cast<PossiblyNonNegInst>(U)) {
1568 if (NNI->hasNonNeg())
1569 Out << " nneg";
1570 } else if (const auto *TI = dyn_cast<TruncInst>(U)) {
1571 if (TI->hasNoUnsignedWrap())
1572 Out << " nuw";
1573 if (TI->hasNoSignedWrap())
1574 Out << " nsw";
1575 } else if (const auto *ICmp = dyn_cast<ICmpInst>(U)) {
1576 if (ICmp->hasSameSign())
1577 Out << " samesign";
1578 } else if (const auto *ASC = dyn_cast<AddrSpaceCastInst>(U)) {
1579 if (ASC->hasNonNull())
1580 Out << " nonnull";
1581 }
1582}
1583
1584static void WriteFullHexAPInt(raw_ostream &Out, const APInt &Val) {
1586 Val.toStringUnsigned(Bits, 16);
1587 unsigned NumDigits = std::max((Val.getBitWidth() + 3) / 4, 1U);
1588 Out << "0x";
1589 for (unsigned i = 0; i < NumDigits - Bits.size(); i++)
1590 Out << '0';
1591 Out << Bits;
1592}
1593
1594static void writeAPFloatInternal(raw_ostream &Out, const APFloat &APF) {
1595 bool ForceBitwiseOutput = false;
1596 if (&APF.getSemantics() == &APFloat::PPCDoubleDouble()) {
1597 // ppc_fp128 types are double-double. The special cases set the second
1598 // (high) double to +0.0, so if the high word is nonzero, force the use of
1599 // bitwise output.
1600 APInt HiWord = APF.bitcastToAPInt().lshr(64);
1601 ForceBitwiseOutput = !HiWord.isZero();
1602 }
1603
1604 if (!ForceBitwiseOutput) {
1605 // Check for special values in APFloat.
1606 if (APF.isInfinity()) {
1607 Out << (APF.isNegative() ? '-' : '+') << "inf";
1608 return;
1609 }
1610
1611 if (APF.isNaN()) {
1612 Out << (APF.isNegative() ? '-' : '+');
1613 APInt Payload = APF.getNaNPayload();
1614 // The quiet bit of a NaN is the highest bit of the payload, so the
1615 // preferred QNaN value happens to be the sign mask value.
1616 if (Payload.isSignMask()) {
1617 Out << "qnan";
1618 } else {
1619 if (APF.isSignaling())
1620 Out << 's';
1621 Out << "nan(";
1622 // Clear out the signaling/quiet bit of the payload for output.
1623 Payload.clearBit(Payload.getBitWidth() - 1);
1624 // Trim the string to exclude leading 0's.
1625 WriteFullHexAPInt(Out, Payload.trunc(Payload.getActiveBits()));
1626 Out << ')';
1627 }
1628 return;
1629 }
1630 }
1631
1632 // Try for a decimal string output. If the value is convertible back to the
1633 // same APFloat value, then we know that it is safe to use it. Otherwise, fall
1634 // back onto the hexadecimal format.
1635 SmallString<128> StrVal;
1636 APF.toString(StrVal, 6, 0, false);
1637 if (APFloat(APF.getSemantics(), StrVal) == APF) {
1638 Out << StrVal;
1639 return;
1640 }
1641
1642 // Fallback to the hexadecimal format representing the bit string exactly.
1643 Out << 'f';
1644 APInt API = APF.bitcastToAPInt();
1645 WriteFullHexAPInt(Out, API);
1646}
1647
1648static void writeConstantInternal(raw_ostream &Out, const Constant *CV,
1649 AsmWriterContext &WriterCtx) {
1650 if (const auto *CI = dyn_cast<ConstantInt>(CV)) {
1651 Type *Ty = CI->getType();
1652
1653 if (Ty->isVectorTy()) {
1654 Out << "splat (";
1655 WriterCtx.TypePrinter->print(Ty->getScalarType(), Out);
1656 Out << " ";
1657 }
1658
1659 if (Ty->getScalarType()->isIntegerTy(1))
1660 Out << (CI->getZExtValue() ? "true" : "false");
1661 else
1662 Out << CI->getValue();
1663
1664 if (Ty->isVectorTy())
1665 Out << ")";
1666
1667 return;
1668 }
1669
1670 if (const auto *CB = dyn_cast<ConstantByte>(CV)) {
1671 Type *Ty = CB->getType();
1672
1673 if (Ty->isVectorTy()) {
1674 Out << "splat (";
1675 WriterCtx.TypePrinter->print(Ty->getScalarType(), Out);
1676 Out << " ";
1677 }
1678
1679 Out << CB->getValue();
1680
1681 if (Ty->isVectorTy())
1682 Out << ")";
1683
1684 return;
1685 }
1686
1687 if (const auto *CFP = dyn_cast<ConstantFP>(CV)) {
1688 Type *Ty = CFP->getType();
1689
1690 if (Ty->isVectorTy()) {
1691 if (CFP->getValue().bitcastToAPInt().isZero()) {
1692 Out << "zeroinitializer";
1693 return;
1694 }
1695
1696 Out << "splat (";
1697 WriterCtx.TypePrinter->print(Ty->getScalarType(), Out);
1698 Out << " ";
1699 }
1700
1701 writeAPFloatInternal(Out, CFP->getValueAPF());
1702
1703 if (Ty->isVectorTy())
1704 Out << ")";
1705
1706 return;
1707 }
1708
1710 Out << "zeroinitializer";
1711 return;
1712 }
1713
1714 if (const auto *BA = dyn_cast<BlockAddress>(CV)) {
1715 Out << "blockaddress(";
1716 writeAsOperandInternal(Out, BA->getFunction(), WriterCtx);
1717 Out << ", ";
1718 writeAsOperandInternal(Out, BA->getBasicBlock(), WriterCtx);
1719 Out << ")";
1720 return;
1721 }
1722
1723 if (const auto *Equiv = dyn_cast<DSOLocalEquivalent>(CV)) {
1724 Out << "dso_local_equivalent ";
1725 writeAsOperandInternal(Out, Equiv->getGlobalValue(), WriterCtx);
1726 return;
1727 }
1728
1729 if (const auto *NC = dyn_cast<NoCFIValue>(CV)) {
1730 Out << "no_cfi ";
1731 writeAsOperandInternal(Out, NC->getGlobalValue(), WriterCtx);
1732 return;
1733 }
1734
1735 if (const auto *CPA = dyn_cast<ConstantPtrAuth>(CV)) {
1736 Out << "ptrauth (";
1737
1738 // ptrauth (ptr CST, i32 KEY[, i64 DISC[, ptr ADDRDISC[, ptr DS]?]?]?)
1739 unsigned NumOpsToWrite = 2;
1740 if (!CPA->getOperand(2)->isNullValue())
1741 NumOpsToWrite = 3;
1742 if (!isa<ConstantPointerNull>(CPA->getOperand(3)))
1743 NumOpsToWrite = 4;
1744 if (!isa<ConstantPointerNull>(CPA->getOperand(4)))
1745 NumOpsToWrite = 5;
1746
1747 ListSeparator LS;
1748 for (unsigned i = 0, e = NumOpsToWrite; i != e; ++i) {
1749 Out << LS;
1750 writeAsOperandInternal(Out, CPA->getOperand(i), WriterCtx,
1751 /*PrintType=*/true);
1752 }
1753 Out << ')';
1754 return;
1755 }
1756
1757 if (const auto *CA = dyn_cast<ConstantArray>(CV)) {
1758 Out << '[';
1759 ListSeparator LS;
1760 for (const Value *Op : CA->operands()) {
1761 Out << LS;
1762 writeAsOperandInternal(Out, Op, WriterCtx, /*PrintType=*/true);
1763 }
1764 Out << ']';
1765 return;
1766 }
1767
1768 if (const auto *CA = dyn_cast<ConstantDataArray>(CV)) {
1769 // As a special case, print the array as a string if it is an array of
1770 // i8 with ConstantInt values.
1771 if (CA->isString()) {
1772 Out << "c\"";
1773 printEscapedString(CA->getAsString(), Out);
1774 Out << '"';
1775 return;
1776 }
1777
1778 Out << '[';
1779 ListSeparator LS;
1780 for (uint64_t i = 0, e = CA->getNumElements(); i != e; ++i) {
1781 Out << LS;
1782 writeAsOperandInternal(Out, CA->getElementAsConstant(i), WriterCtx,
1783 /*PrintType=*/true);
1784 }
1785 Out << ']';
1786 return;
1787 }
1788
1789 if (const auto *CS = dyn_cast<ConstantStruct>(CV)) {
1790 if (CS->getType()->isPacked())
1791 Out << '<';
1792 Out << '{';
1793 if (CS->getNumOperands() != 0) {
1794 Out << ' ';
1795 ListSeparator LS;
1796 for (const Value *Op : CS->operands()) {
1797 Out << LS;
1798 writeAsOperandInternal(Out, Op, WriterCtx, /*PrintType=*/true);
1799 }
1800 Out << ' ';
1801 }
1802 Out << '}';
1803 if (CS->getType()->isPacked())
1804 Out << '>';
1805 return;
1806 }
1807
1809 auto *CVVTy = cast<FixedVectorType>(CV->getType());
1810
1811 // Use the same shorthand for splat vector (i.e. "splat(Ty val)") as is
1812 // permitted on IR input to reduce the output changes when enabling
1813 // UseConstant{Int,FP}ForFixedLengthSplat.
1814 // TODO: Remove this block when the UseConstant{Int,FP}ForFixedLengthSplat
1815 // options are removed.
1816 if (auto *SplatVal = CV->getSplatValue()) {
1817 if (isa<ConstantInt>(SplatVal) || isa<ConstantFP>(SplatVal) ||
1818 isa<ConstantByte>(SplatVal)) {
1819 Out << "splat (";
1820 writeAsOperandInternal(Out, SplatVal, WriterCtx, /*PrintType=*/true);
1821 Out << ')';
1822 return;
1823 }
1824 }
1825
1826 Out << '<';
1827 ListSeparator LS;
1828 for (unsigned i = 0, e = CVVTy->getNumElements(); i != e; ++i) {
1829 Out << LS;
1830 writeAsOperandInternal(Out, CV->getAggregateElement(i), WriterCtx,
1831 /*PrintType=*/true);
1832 }
1833 Out << '>';
1834 return;
1835 }
1836
1837 if (const auto *CPN = dyn_cast<ConstantPointerNull>(CV)) {
1838 if (auto *VT = dyn_cast<VectorType>(CPN->getType())) {
1839 Out << "splat (";
1841 ConstantPointerNull::get(VT->getElementType()),
1842 WriterCtx, /*PrintType=*/true);
1843 Out << ')';
1844 return;
1845 }
1846
1847 Out << "null";
1848 return;
1849 }
1850
1851 if (isa<ConstantTokenNone>(CV)) {
1852 Out << "none";
1853 return;
1854 }
1855
1856 if (isa<PoisonValue>(CV)) {
1857 Out << "poison";
1858 return;
1859 }
1860
1861 if (isa<UndefValue>(CV)) {
1862 Out << "undef";
1863 return;
1864 }
1865
1866 if (const auto *CE = dyn_cast<ConstantExpr>(CV)) {
1867 // Use the same shorthand for splat vector (i.e. "splat(Ty val)") as is
1868 // permitted on IR input to reduce the output changes when enabling
1869 // UseConstant{Int,FP}ForScalableSplat.
1870 // TODO: Remove this block when the UseConstant{Int,FP}ForScalableSplat
1871 // options are removed.
1872 if (CE->getOpcode() == Instruction::ShuffleVector) {
1873 if (auto *SplatVal = CE->getSplatValue()) {
1874 if (isa<ConstantInt>(SplatVal) || isa<ConstantFP>(SplatVal) ||
1875 isa<ConstantByte>(SplatVal)) {
1876 Out << "splat (";
1877 writeAsOperandInternal(Out, SplatVal, WriterCtx, /*PrintType=*/true);
1878 Out << ')';
1879 return;
1880 }
1881 }
1882 }
1883
1884 Out << CE->getOpcodeName();
1885 writeOptimizationInfo(Out, CE);
1886 Out << " (";
1887
1888 if (const auto *GEP = dyn_cast<GEPOperator>(CE)) {
1889 WriterCtx.TypePrinter->print(GEP->getSourceElementType(), Out);
1890 Out << ", ";
1891 }
1892
1893 ListSeparator LS;
1894 for (const Value *Op : CE->operands()) {
1895 Out << LS;
1896 writeAsOperandInternal(Out, Op, WriterCtx, /*PrintType=*/true);
1897 }
1898
1899 if (CE->isCast()) {
1900 Out << " to ";
1901 WriterCtx.TypePrinter->print(CE->getType(), Out);
1902 }
1903
1904 if (CE->getOpcode() == Instruction::ShuffleVector)
1905 printShuffleMask(Out, CE->getType(), CE->getShuffleMask());
1906
1907 Out << ')';
1908 return;
1909 }
1910
1911 Out << "<placeholder or erroneous Constant>";
1912}
1913
1914static void writeMDTuple(raw_ostream &Out, const MDTuple *Node,
1915 AsmWriterContext &WriterCtx) {
1916 Out << "!{";
1917 ListSeparator LS;
1918 for (const Metadata *MD : Node->operands()) {
1919 Out << LS;
1920 if (!MD) {
1921 Out << "null";
1922 } else if (auto *MDV = dyn_cast<ValueAsMetadata>(MD)) {
1923 Value *V = MDV->getValue();
1924 writeAsOperandInternal(Out, V, WriterCtx, /*PrintType=*/true);
1925 } else {
1926 writeAsOperandInternal(Out, MD, WriterCtx);
1927 WriterCtx.onWriteMetadataAsOperand(MD);
1928 }
1929 }
1930
1931 Out << "}";
1932}
1933
1934namespace {
1935
1936struct MDFieldPrinter {
1937 raw_ostream &Out;
1938 ListSeparator FS;
1939 AsmWriterContext &WriterCtx;
1940
1941 explicit MDFieldPrinter(raw_ostream &Out)
1942 : Out(Out), WriterCtx(AsmWriterContext::getEmpty()) {}
1943 MDFieldPrinter(raw_ostream &Out, AsmWriterContext &Ctx)
1944 : Out(Out), WriterCtx(Ctx) {}
1945
1946 void printTag(const DINode *N);
1947 void printMacinfoType(const DIMacroNode *N);
1948 void printChecksum(const DIFile::ChecksumInfo<StringRef> &N);
1949 void printString(StringRef Name, StringRef Value,
1950 bool ShouldSkipEmpty = true);
1951 void printMetadata(StringRef Name, const Metadata *MD,
1952 bool ShouldSkipNull = true);
1953 void printMetadataOrInt(StringRef Name, const Metadata *MD, bool IsUnsigned,
1954 bool ShouldSkipZero = true);
1955 template <class IntTy>
1956 void printInt(StringRef Name, IntTy Int, bool ShouldSkipZero = true);
1957 void printAPInt(StringRef Name, const APInt &Int, bool IsUnsigned,
1958 bool ShouldSkipZero);
1959 void printBool(StringRef Name, bool Value,
1960 std::optional<bool> Default = std::nullopt);
1961 void printDIFlags(StringRef Name, DINode::DIFlags Flags);
1962 void printDISPFlags(StringRef Name, DISubprogram::DISPFlags Flags);
1963 template <class IntTy, class Stringifier>
1964 void printDwarfEnum(StringRef Name, IntTy Value, Stringifier toString,
1965 bool ShouldSkipZero = true);
1966 void printEmissionKind(StringRef Name, DICompileUnit::DebugEmissionKind EK);
1967 void printNameTableKind(StringRef Name,
1969 void printFixedPointKind(StringRef Name, DIFixedPointType::FixedPointKind V);
1970};
1971
1972} // end anonymous namespace
1973
1974void MDFieldPrinter::printTag(const DINode *N) {
1975 Out << FS << "tag: ";
1976 auto Tag = dwarf::TagString(N->getTag());
1977 if (!Tag.empty())
1978 Out << Tag;
1979 else
1980 Out << N->getTag();
1981}
1982
1983void MDFieldPrinter::printMacinfoType(const DIMacroNode *N) {
1984 Out << FS << "type: ";
1985 auto Type = dwarf::MacinfoString(N->getMacinfoType());
1986 if (!Type.empty())
1987 Out << Type;
1988 else
1989 Out << N->getMacinfoType();
1990}
1991
1992void MDFieldPrinter::printChecksum(
1993 const DIFile::ChecksumInfo<StringRef> &Checksum) {
1994 Out << FS << "checksumkind: " << Checksum.getKindAsString();
1995 printString("checksum", Checksum.Value, /* ShouldSkipEmpty */ false);
1996}
1997
1998void MDFieldPrinter::printString(StringRef Name, StringRef Value,
1999 bool ShouldSkipEmpty) {
2000 if (ShouldSkipEmpty && Value.empty())
2001 return;
2002
2003 Out << FS << Name << ": \"";
2005 Out << "\"";
2006}
2007
2008static void writeMetadataAsOperand(raw_ostream &Out, const Metadata *MD,
2009 AsmWriterContext &WriterCtx) {
2010 if (!MD) {
2011 Out << "null";
2012 return;
2013 }
2014 writeAsOperandInternal(Out, MD, WriterCtx);
2015 WriterCtx.onWriteMetadataAsOperand(MD);
2016}
2017
2018void MDFieldPrinter::printMetadata(StringRef Name, const Metadata *MD,
2019 bool ShouldSkipNull) {
2020 if (ShouldSkipNull && !MD)
2021 return;
2022
2023 Out << FS << Name << ": ";
2024 writeMetadataAsOperand(Out, MD, WriterCtx);
2025}
2026
2027void MDFieldPrinter::printMetadataOrInt(StringRef Name, const Metadata *MD,
2028 bool IsUnsigned, bool ShouldSkipZero) {
2029 if (!MD)
2030 return;
2031
2032 if (auto *CI = dyn_cast<ConstantAsMetadata>(MD)) {
2033 auto *CV = cast<ConstantInt>(CI->getValue());
2034 if (IsUnsigned)
2035 printInt(Name, CV->getZExtValue(), ShouldSkipZero);
2036 else
2037 printInt(Name, CV->getSExtValue(), ShouldSkipZero);
2038 } else
2039 printMetadata(Name, MD);
2040}
2041
2042template <class IntTy>
2043void MDFieldPrinter::printInt(StringRef Name, IntTy Int, bool ShouldSkipZero) {
2044 if (ShouldSkipZero && !Int)
2045 return;
2046
2047 Out << FS << Name << ": " << Int;
2048}
2049
2050void MDFieldPrinter::printAPInt(StringRef Name, const APInt &Int,
2051 bool IsUnsigned, bool ShouldSkipZero) {
2052 if (ShouldSkipZero && Int.isZero())
2053 return;
2054
2055 Out << FS << Name << ": ";
2056 Int.print(Out, !IsUnsigned);
2057}
2058
2059void MDFieldPrinter::printBool(StringRef Name, bool Value,
2060 std::optional<bool> Default) {
2061 if (Default && Value == *Default)
2062 return;
2063 Out << FS << Name << ": " << (Value ? "true" : "false");
2064}
2065
2066void MDFieldPrinter::printDIFlags(StringRef Name, DINode::DIFlags Flags) {
2067 if (!Flags)
2068 return;
2069
2070 Out << FS << Name << ": ";
2071
2073 auto Extra = DINode::splitFlags(Flags, SplitFlags);
2074
2075 ListSeparator FlagsFS(" | ");
2076 for (auto F : SplitFlags) {
2077 auto StringF = DINode::getFlagString(F);
2078 assert(!StringF.empty() && "Expected valid flag");
2079 Out << FlagsFS << StringF;
2080 }
2081 if (Extra || SplitFlags.empty())
2082 Out << FlagsFS << Extra;
2083}
2084
2085void MDFieldPrinter::printDISPFlags(StringRef Name,
2087 // Always print this field, because no flags in the IR at all will be
2088 // interpreted as old-style isDefinition: true.
2089 Out << FS << Name << ": ";
2090
2091 if (!Flags) {
2092 Out << 0;
2093 return;
2094 }
2095
2097 auto Extra = DISubprogram::splitFlags(Flags, SplitFlags);
2098
2099 ListSeparator FlagsFS(" | ");
2100 for (auto F : SplitFlags) {
2101 auto StringF = DISubprogram::getFlagString(F);
2102 assert(!StringF.empty() && "Expected valid flag");
2103 Out << FlagsFS << StringF;
2104 }
2105 if (Extra || SplitFlags.empty())
2106 Out << FlagsFS << Extra;
2107}
2108
2109void MDFieldPrinter::printEmissionKind(StringRef Name,
2111 Out << FS << Name << ": " << DICompileUnit::emissionKindString(EK);
2112}
2113
2114void MDFieldPrinter::printNameTableKind(StringRef Name,
2117 return;
2118 Out << FS << Name << ": " << DICompileUnit::nameTableKindString(NTK);
2119}
2120
2121void MDFieldPrinter::printFixedPointKind(StringRef Name,
2124}
2125
2126template <class IntTy, class Stringifier>
2127void MDFieldPrinter::printDwarfEnum(StringRef Name, IntTy Value,
2128 Stringifier toString, bool ShouldSkipZero) {
2129 if (ShouldSkipZero && !Value)
2130 return;
2131
2132 Out << FS << Name << ": ";
2133 auto S = toString(Value);
2134 if (!S.empty())
2135 Out << S;
2136 else
2137 Out << Value;
2138}
2139
2141 AsmWriterContext &WriterCtx) {
2142 Out << "!GenericDINode(";
2143 MDFieldPrinter Printer(Out, WriterCtx);
2144 Printer.printTag(N);
2145 Printer.printString("header", N->getHeader());
2146 if (N->getNumDwarfOperands()) {
2147 Out << Printer.FS << "operands: {";
2148 ListSeparator IFS;
2149 for (auto &I : N->dwarf_operands()) {
2150 Out << IFS;
2151 writeMetadataAsOperand(Out, I, WriterCtx);
2152 }
2153 Out << "}";
2154 }
2155 Out << ")";
2156}
2157
2158static void writeDILocation(raw_ostream &Out, const DILocation *DL,
2159 AsmWriterContext &WriterCtx) {
2160 Out << "!DILocation(";
2161 MDFieldPrinter Printer(Out, WriterCtx);
2162 // Always output the line, since 0 is a relevant and important value for it.
2163 Printer.printInt("line", DL->getLine(), /* ShouldSkipZero */ false);
2164 Printer.printInt("column", DL->getColumn());
2165 Printer.printMetadata("scope", DL->getRawScope(), /* ShouldSkipNull */ false);
2166 Printer.printMetadata("inlinedAt", DL->getRawInlinedAt());
2167 Printer.printBool("isImplicitCode", DL->isImplicitCode(),
2168 /* Default */ false);
2169 Printer.printInt("atomGroup", DL->getAtomGroup());
2170 Printer.printInt<unsigned>("atomRank", DL->getAtomRank());
2171 Printer.printMetadata("irlayers", DL->getRawIRLayers());
2172 Out << ")";
2173}
2174
2175static void writeDILayerLoc(raw_ostream &Out, const DILayerLoc *N,
2176 AsmWriterContext &WriterCtx) {
2177 Out << "!DILayerLoc(";
2178 MDFieldPrinter Printer(Out, WriterCtx);
2179 Printer.printInt("line", N->getLine(), /* ShouldSkipZero */ false);
2180 Printer.printInt("column", N->getColumn());
2181 Printer.printMetadata("file", N->getRawFile(), /* ShouldSkipNull */ false);
2182 Printer.printString("kind", N->getKind(), /* ShouldSkipEmpty */ false);
2183 Out << ")";
2184}
2185
2187 AsmWriterContext &WriterCtx) {
2188 Out << "!DILayerLocList(";
2189 ListSeparator FS;
2190 for (const MDOperand &Op : N->operands()) {
2191 Out << FS;
2192 writeMetadataAsOperand(Out, Op, WriterCtx);
2193 }
2194 Out << ")";
2195}
2196
2197static void writeDIAssignID(raw_ostream &Out, const DIAssignID *DL,
2198 AsmWriterContext &WriterCtx) {
2199 Out << "!DIAssignID()";
2200 MDFieldPrinter Printer(Out, WriterCtx);
2201}
2202
2203static void writeDISubrange(raw_ostream &Out, const DISubrange *N,
2204 AsmWriterContext &WriterCtx) {
2205 Out << "!DISubrange(";
2206 MDFieldPrinter Printer(Out, WriterCtx);
2207
2208 Printer.printMetadataOrInt("count", N->getRawCountNode(),
2209 /* IsUnsigned */ false,
2210 /* ShouldSkipZero */ false);
2211
2212 // A lowerBound of constant 0 should not be skipped, since it is different
2213 // from an unspecified lower bound (= nullptr).
2214 Printer.printMetadataOrInt("lowerBound", N->getRawLowerBound(),
2215 /* IsUnsigned */ false,
2216 /* ShouldSkipZero */ false);
2217 Printer.printMetadataOrInt("upperBound", N->getRawUpperBound(),
2218 /* IsUnsigned */ false,
2219 /* ShouldSkipZero */ false);
2220 Printer.printMetadataOrInt("stride", N->getRawStride(),
2221 /* IsUnsigned */ false,
2222 /* ShouldSkipZero */ false);
2223
2224 Out << ")";
2225}
2226
2228 AsmWriterContext &WriterCtx) {
2229 Out << "!DIGenericSubrange(";
2230 MDFieldPrinter Printer(Out, WriterCtx);
2231
2232 auto GetConstant = [&](Metadata *Bound) -> std::optional<int64_t> {
2233 auto *BE = dyn_cast_or_null<DIExpression>(Bound);
2234 if (!BE)
2235 return std::nullopt;
2236 if (BE->isConstant() &&
2238 *BE->isConstant()) {
2239 return static_cast<int64_t>(BE->getElement(1));
2240 }
2241 return std::nullopt;
2242 };
2243
2244 auto *Count = N->getRawCountNode();
2245 if (auto ConstantCount = GetConstant(Count))
2246 Printer.printInt("count", *ConstantCount,
2247 /* ShouldSkipZero */ false);
2248 else
2249 Printer.printMetadata("count", Count, /*ShouldSkipNull */ true);
2250
2251 auto *LBound = N->getRawLowerBound();
2252 if (auto ConstantLBound = GetConstant(LBound))
2253 Printer.printInt("lowerBound", *ConstantLBound,
2254 /* ShouldSkipZero */ false);
2255 else
2256 Printer.printMetadata("lowerBound", LBound, /*ShouldSkipNull */ true);
2257
2258 auto *UBound = N->getRawUpperBound();
2259 if (auto ConstantUBound = GetConstant(UBound))
2260 Printer.printInt("upperBound", *ConstantUBound,
2261 /* ShouldSkipZero */ false);
2262 else
2263 Printer.printMetadata("upperBound", UBound, /*ShouldSkipNull */ true);
2264
2265 auto *Stride = N->getRawStride();
2266 if (auto ConstantStride = GetConstant(Stride))
2267 Printer.printInt("stride", *ConstantStride,
2268 /* ShouldSkipZero */ false);
2269 else
2270 Printer.printMetadata("stride", Stride, /*ShouldSkipNull */ true);
2271
2272 Out << ")";
2273}
2274
2276 AsmWriterContext &) {
2277 Out << "!DIEnumerator(";
2278 MDFieldPrinter Printer(Out);
2279 Printer.printString("name", N->getName(), /* ShouldSkipEmpty */ false);
2280 Printer.printAPInt("value", N->getValue(), N->isUnsigned(),
2281 /*ShouldSkipZero=*/false);
2282 if (N->isUnsigned())
2283 Printer.printBool("isUnsigned", true);
2284 Out << ")";
2285}
2286
2288 AsmWriterContext &WriterCtx) {
2289 Out << "!DIBasicType(";
2290 MDFieldPrinter Printer(Out, WriterCtx);
2291 if (N->getTag() != dwarf::DW_TAG_base_type)
2292 Printer.printTag(N);
2293 Printer.printString("name", N->getName());
2294 Printer.printMetadata("scope", N->getRawScope());
2295 Printer.printMetadata("file", N->getRawFile());
2296 Printer.printInt("line", N->getLine());
2297 Printer.printMetadataOrInt("size", N->getRawSizeInBits(), true);
2298 Printer.printInt("align", N->getAlignInBits());
2299 Printer.printInt("dataSize", N->getDataSizeInBits());
2300 Printer.printDwarfEnum("encoding", N->getEncoding(),
2302 Printer.printInt("num_extra_inhabitants", N->getNumExtraInhabitants());
2303 Printer.printDIFlags("flags", N->getFlags());
2304 Out << ")";
2305}
2306
2308 AsmWriterContext &WriterCtx) {
2309 Out << "!DIFixedPointType(";
2310 MDFieldPrinter Printer(Out, WriterCtx);
2311 if (N->getTag() != dwarf::DW_TAG_base_type)
2312 Printer.printTag(N);
2313 Printer.printString("name", N->getName());
2314 Printer.printMetadata("scope", N->getRawScope());
2315 Printer.printMetadata("file", N->getRawFile());
2316 Printer.printInt("line", N->getLine());
2317 Printer.printMetadataOrInt("size", N->getRawSizeInBits(), true);
2318 Printer.printInt("align", N->getAlignInBits());
2319 Printer.printDwarfEnum("encoding", N->getEncoding(),
2321 Printer.printDIFlags("flags", N->getFlags());
2322 Printer.printFixedPointKind("kind", N->getKind());
2323 if (N->isRational()) {
2324 bool IsUnsigned = !N->isSigned();
2325 Printer.printAPInt("numerator", N->getNumerator(), IsUnsigned, false);
2326 Printer.printAPInt("denominator", N->getDenominator(), IsUnsigned, false);
2327 } else {
2328 Printer.printInt("factor", N->getFactor());
2329 }
2330 Out << ")";
2331}
2332
2334 AsmWriterContext &WriterCtx) {
2335 Out << "!DIStringType(";
2336 MDFieldPrinter Printer(Out, WriterCtx);
2337 if (N->getTag() != dwarf::DW_TAG_string_type)
2338 Printer.printTag(N);
2339 Printer.printString("name", N->getName());
2340 Printer.printMetadata("stringLength", N->getRawStringLength());
2341 Printer.printMetadata("stringLengthExpression", N->getRawStringLengthExp());
2342 Printer.printMetadata("stringLocationExpression",
2343 N->getRawStringLocationExp());
2344 Printer.printMetadataOrInt("size", N->getRawSizeInBits(), true);
2345 Printer.printInt("align", N->getAlignInBits());
2346 Printer.printDwarfEnum("encoding", N->getEncoding(),
2348 Printer.printMetadata("charType", N->getRawCharType());
2349 Out << ")";
2350}
2351
2353 AsmWriterContext &WriterCtx) {
2354 Out << "!DIDerivedType(";
2355 MDFieldPrinter Printer(Out, WriterCtx);
2356 Printer.printTag(N);
2357 Printer.printString("name", N->getName());
2358 Printer.printMetadata("scope", N->getRawScope());
2359 Printer.printMetadata("file", N->getRawFile());
2360 Printer.printInt("line", N->getLine());
2361 Printer.printMetadata("baseType", N->getRawBaseType(),
2362 /* ShouldSkipNull */ false);
2363 Printer.printMetadataOrInt("size", N->getRawSizeInBits(), true);
2364 Printer.printInt("align", N->getAlignInBits());
2365 Printer.printMetadataOrInt("offset", N->getRawOffsetInBits(), true);
2366 Printer.printDIFlags("flags", N->getFlags());
2367 Printer.printMetadata("extraData", N->getRawExtraData());
2368 if (const auto &DWARFAddressSpace = N->getDWARFAddressSpace())
2369 Printer.printInt("dwarfAddressSpace", *DWARFAddressSpace,
2370 /* ShouldSkipZero */ false);
2371 Printer.printMetadata("annotations", N->getRawAnnotations());
2372 if (auto PtrAuthData = N->getPtrAuthData()) {
2373 Printer.printInt("ptrAuthKey", PtrAuthData->key());
2374 Printer.printBool("ptrAuthIsAddressDiscriminated",
2375 PtrAuthData->isAddressDiscriminated());
2376 Printer.printInt("ptrAuthExtraDiscriminator",
2377 PtrAuthData->extraDiscriminator());
2378 Printer.printBool("ptrAuthIsaPointer", PtrAuthData->isaPointer());
2379 Printer.printBool("ptrAuthAuthenticatesNullValues",
2380 PtrAuthData->authenticatesNullValues());
2381 }
2382 Out << ")";
2383}
2384
2386 AsmWriterContext &WriterCtx) {
2387 Out << "!DISubrangeType(";
2388 MDFieldPrinter Printer(Out, WriterCtx);
2389 Printer.printString("name", N->getName());
2390 Printer.printMetadata("scope", N->getRawScope());
2391 Printer.printMetadata("file", N->getRawFile());
2392 Printer.printInt("line", N->getLine());
2393 Printer.printMetadataOrInt("size", N->getRawSizeInBits(), true);
2394 Printer.printInt("align", N->getAlignInBits());
2395 Printer.printDIFlags("flags", N->getFlags());
2396 Printer.printMetadata("baseType", N->getRawBaseType(),
2397 /* ShouldSkipNull */ false);
2398 Printer.printMetadata("lowerBound", N->getRawLowerBound());
2399 Printer.printMetadata("upperBound", N->getRawUpperBound());
2400 Printer.printMetadata("stride", N->getRawStride());
2401 Printer.printMetadata("bias", N->getRawBias());
2402 Out << ")";
2403}
2404
2406 AsmWriterContext &WriterCtx) {
2407 Out << "!DICompositeType(";
2408 MDFieldPrinter Printer(Out, WriterCtx);
2409 Printer.printTag(N);
2410 Printer.printString("name", N->getName());
2411 Printer.printMetadata("scope", N->getRawScope());
2412 Printer.printMetadata("file", N->getRawFile());
2413 Printer.printInt("line", N->getLine());
2414 Printer.printMetadata("baseType", N->getRawBaseType());
2415 Printer.printMetadataOrInt("size", N->getRawSizeInBits(), true);
2416 Printer.printInt("align", N->getAlignInBits());
2417 Printer.printMetadataOrInt("offset", N->getRawOffsetInBits(), true);
2418 Printer.printInt("num_extra_inhabitants", N->getNumExtraInhabitants());
2419 Printer.printDIFlags("flags", N->getFlags());
2420 Printer.printMetadata("elements", N->getRawElements());
2421 Printer.printDwarfEnum("runtimeLang", N->getRuntimeLang(),
2423 Printer.printMetadata("vtableHolder", N->getRawVTableHolder());
2424 Printer.printMetadata("templateParams", N->getRawTemplateParams());
2425 Printer.printString("identifier", N->getIdentifier());
2426 Printer.printMetadata("discriminator", N->getRawDiscriminator());
2427 Printer.printMetadata("dataLocation", N->getRawDataLocation());
2428 Printer.printMetadata("associated", N->getRawAssociated());
2429 Printer.printMetadata("allocated", N->getRawAllocated());
2430 if (auto *RankConst = N->getRankConst())
2431 Printer.printInt("rank", RankConst->getSExtValue(),
2432 /* ShouldSkipZero */ false);
2433 else
2434 Printer.printMetadata("rank", N->getRawRank(), /*ShouldSkipNull */ true);
2435 Printer.printMetadata("annotations", N->getRawAnnotations());
2436 if (auto *Specification = N->getRawSpecification())
2437 Printer.printMetadata("specification", Specification);
2438
2439 if (auto EnumKind = N->getEnumKind())
2440 Printer.printDwarfEnum("enumKind", *EnumKind, dwarf::EnumKindString,
2441 /*ShouldSkipZero=*/false);
2442
2443 Printer.printMetadata("bitStride", N->getRawBitStride());
2444 Out << ")";
2445}
2446
2448 AsmWriterContext &WriterCtx) {
2449 Out << "!DISubroutineType(";
2450 MDFieldPrinter Printer(Out, WriterCtx);
2451 Printer.printDIFlags("flags", N->getFlags());
2452 Printer.printDwarfEnum("cc", N->getCC(), dwarf::ConventionString);
2453 Printer.printMetadata("types", N->getRawTypeArray(),
2454 /* ShouldSkipNull */ false);
2455 Out << ")";
2456}
2457
2458static void writeDIFile(raw_ostream &Out, const DIFile *N, AsmWriterContext &) {
2459 Out << "!DIFile(";
2460 MDFieldPrinter Printer(Out);
2461 Printer.printString("filename", N->getFilename(),
2462 /* ShouldSkipEmpty */ false);
2463 Printer.printString("directory", N->getDirectory(),
2464 /* ShouldSkipEmpty */ false);
2465 // Print all values for checksum together, or not at all.
2466 if (N->getChecksum())
2467 Printer.printChecksum(*N->getChecksum());
2468 if (N->getSource())
2469 Printer.printString("source", *N->getSource(),
2470 /* ShouldSkipEmpty */ false);
2471 Out << ")";
2472}
2473
2475 AsmWriterContext &WriterCtx) {
2476 Out << "!DICompileUnit(";
2477 MDFieldPrinter Printer(Out, WriterCtx);
2478
2479 DISourceLanguageName Lang = N->getSourceLanguage();
2480
2481 if (Lang.hasVersionedName()) {
2482 Printer.printDwarfEnum(
2483 "sourceLanguageName",
2484 static_cast<llvm::dwarf::SourceLanguageName>(Lang.getName()),
2486 /* ShouldSkipZero */ false);
2487
2488 Printer.printInt("sourceLanguageVersion", Lang.getVersion(),
2489 /*ShouldSkipZero=*/true);
2490 } else {
2491 Printer.printDwarfEnum("language", Lang.getName(), dwarf::LanguageString,
2492 /* ShouldSkipZero */ false);
2493 }
2494
2495 Printer.printMetadata("file", N->getRawFile(), /* ShouldSkipNull */ false);
2496 Printer.printString("producer", N->getProducer());
2497 Printer.printBool("isOptimized", N->isOptimized());
2498 Printer.printString("flags", N->getFlags());
2499 Printer.printInt("runtimeVersion", N->getRuntimeVersion(),
2500 /* ShouldSkipZero */ false);
2501 Printer.printString("splitDebugFilename", N->getSplitDebugFilename());
2502 Printer.printEmissionKind("emissionKind", N->getEmissionKind());
2503 Printer.printMetadata("enums", N->getRawEnumTypes());
2504 Printer.printMetadata("retainedTypes", N->getRawRetainedTypes());
2505 Printer.printMetadata("globals", N->getRawGlobalVariables());
2506 Printer.printMetadata("imports", N->getRawImportedEntities());
2507 Printer.printMetadata("macros", N->getRawMacros());
2508 Printer.printInt("dwoId", N->getDWOId());
2509 Printer.printBool("splitDebugInlining", N->getSplitDebugInlining(), true);
2510 Printer.printBool("debugInfoForProfiling", N->getDebugInfoForProfiling(),
2511 false);
2512 Printer.printNameTableKind("nameTableKind", N->getNameTableKind());
2513 Printer.printBool("rangesBaseAddress", N->getRangesBaseAddress(), false);
2514 Printer.printString("sysroot", N->getSysRoot());
2515 Printer.printString("sdk", N->getSDK());
2516 Printer.printDwarfEnum("dialect", Lang.getDialect(),
2518 Out << ")";
2519}
2520
2522 AsmWriterContext &WriterCtx) {
2523 Out << "!DISubprogram(";
2524 MDFieldPrinter Printer(Out, WriterCtx);
2525 Printer.printString("name", N->getName());
2526 Printer.printString("linkageName", N->getLinkageName());
2527 Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
2528 Printer.printMetadata("file", N->getRawFile());
2529 Printer.printInt("line", N->getLine());
2530 Printer.printMetadata("type", N->getRawType());
2531 Printer.printInt("scopeLine", N->getScopeLine());
2532 Printer.printMetadata("containingType", N->getRawContainingType());
2533 if (N->getVirtuality() != dwarf::DW_VIRTUALITY_none ||
2534 N->getVirtualIndex() != 0)
2535 Printer.printInt("virtualIndex", N->getVirtualIndex(), false);
2536 Printer.printInt("thisAdjustment", N->getThisAdjustment());
2537 Printer.printDIFlags("flags", N->getFlags());
2538 Printer.printDISPFlags("spFlags", N->getSPFlags());
2539 Printer.printMetadata("unit", N->getRawUnit());
2540 Printer.printMetadata("templateParams", N->getRawTemplateParams());
2541 Printer.printMetadata("declaration", N->getRawDeclaration());
2542 Printer.printMetadata("retainedNodes", N->getRawRetainedNodes());
2543 Printer.printMetadata("thrownTypes", N->getRawThrownTypes());
2544 Printer.printMetadata("annotations", N->getRawAnnotations());
2545 Printer.printString("targetFuncName", N->getTargetFuncName());
2546 Printer.printBool("keyInstructions", N->getKeyInstructionsEnabled(), false);
2547 Out << ")";
2548}
2549
2551 AsmWriterContext &WriterCtx) {
2552 Out << "!DILexicalBlock(";
2553 MDFieldPrinter Printer(Out, WriterCtx);
2554 Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
2555 Printer.printMetadata("file", N->getRawFile());
2556 Printer.printInt("line", N->getLine());
2557 Printer.printInt("column", N->getColumn());
2558 Out << ")";
2559}
2560
2562 const DILexicalBlockFile *N,
2563 AsmWriterContext &WriterCtx) {
2564 Out << "!DILexicalBlockFile(";
2565 MDFieldPrinter Printer(Out, WriterCtx);
2566 Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
2567 Printer.printMetadata("file", N->getRawFile());
2568 Printer.printInt("discriminator", N->getDiscriminator(),
2569 /* ShouldSkipZero */ false);
2570 Out << ")";
2571}
2572
2574 AsmWriterContext &WriterCtx) {
2575 Out << "!DINamespace(";
2576 MDFieldPrinter Printer(Out, WriterCtx);
2577 Printer.printString("name", N->getName());
2578 Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
2579 Printer.printBool("exportSymbols", N->getExportSymbols(), false);
2580 Out << ")";
2581}
2582
2584 AsmWriterContext &WriterCtx) {
2585 Out << "!DICommonBlock(";
2586 MDFieldPrinter Printer(Out, WriterCtx);
2587 Printer.printMetadata("scope", N->getRawScope(), false);
2588 Printer.printMetadata("declaration", N->getRawDecl(), false);
2589 Printer.printString("name", N->getName());
2590 Printer.printMetadata("file", N->getRawFile());
2591 Printer.printInt("line", N->getLineNo());
2592 Out << ")";
2593}
2594
2595static void writeDIMacro(raw_ostream &Out, const DIMacro *N,
2596 AsmWriterContext &WriterCtx) {
2597 Out << "!DIMacro(";
2598 MDFieldPrinter Printer(Out, WriterCtx);
2599 Printer.printMacinfoType(N);
2600 Printer.printInt("line", N->getLine());
2601 Printer.printString("name", N->getName());
2602 Printer.printString("value", N->getValue());
2603 Out << ")";
2604}
2605
2607 AsmWriterContext &WriterCtx) {
2608 Out << "!DIMacroFile(";
2609 MDFieldPrinter Printer(Out, WriterCtx);
2610 Printer.printInt("line", N->getLine());
2611 Printer.printMetadata("file", N->getRawFile(), /* ShouldSkipNull */ false);
2612 Printer.printMetadata("nodes", N->getRawElements());
2613 Out << ")";
2614}
2615
2616static void writeDIModule(raw_ostream &Out, const DIModule *N,
2617 AsmWriterContext &WriterCtx) {
2618 Out << "!DIModule(";
2619 MDFieldPrinter Printer(Out, WriterCtx);
2620 Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
2621 Printer.printString("name", N->getName());
2622 Printer.printString("configMacros", N->getConfigurationMacros());
2623 Printer.printString("includePath", N->getIncludePath());
2624 Printer.printString("apinotes", N->getAPINotesFile());
2625 Printer.printMetadata("file", N->getRawFile());
2626 Printer.printInt("line", N->getLineNo());
2627 Printer.printBool("isDecl", N->getIsDecl(), /* Default */ false);
2628 Out << ")";
2629}
2630
2633 AsmWriterContext &WriterCtx) {
2634 Out << "!DITemplateTypeParameter(";
2635 MDFieldPrinter Printer(Out, WriterCtx);
2636 Printer.printString("name", N->getName());
2637 Printer.printMetadata("type", N->getRawType(), /* ShouldSkipNull */ false);
2638 Printer.printBool("defaulted", N->isDefault(), /* Default= */ false);
2639 Out << ")";
2640}
2641
2644 AsmWriterContext &WriterCtx) {
2645 Out << "!DITemplateValueParameter(";
2646 MDFieldPrinter Printer(Out, WriterCtx);
2647 if (N->getTag() != dwarf::DW_TAG_template_value_parameter)
2648 Printer.printTag(N);
2649 Printer.printString("name", N->getName());
2650 Printer.printMetadata("type", N->getRawType());
2651 Printer.printBool("defaulted", N->isDefault(), /* Default= */ false);
2652 Printer.printMetadata("value", N->getValue(), /* ShouldSkipNull */ false);
2653 Out << ")";
2654}
2655
2657 AsmWriterContext &WriterCtx) {
2658 Out << "!DIGlobalVariable(";
2659 MDFieldPrinter Printer(Out, WriterCtx);
2660 Printer.printString("name", N->getName());
2661 Printer.printString("linkageName", N->getLinkageName());
2662 Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
2663 Printer.printMetadata("file", N->getRawFile());
2664 Printer.printInt("line", N->getLine());
2665 Printer.printMetadata("type", N->getRawType());
2666 Printer.printBool("isLocal", N->isLocalToUnit());
2667 Printer.printBool("isDefinition", N->isDefinition());
2668 Printer.printMetadata("declaration", N->getRawStaticDataMemberDeclaration());
2669 Printer.printMetadata("templateParams", N->getRawTemplateParams());
2670 Printer.printInt("align", N->getAlignInBits());
2671 Printer.printMetadata("annotations", N->getRawAnnotations());
2672 Out << ")";
2673}
2674
2676 AsmWriterContext &WriterCtx) {
2677 Out << "!DILocalVariable(";
2678 MDFieldPrinter Printer(Out, WriterCtx);
2679 Printer.printString("name", N->getName());
2680 Printer.printInt("arg", N->getArg());
2681 Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
2682 Printer.printMetadata("file", N->getRawFile());
2683 Printer.printInt("line", N->getLine());
2684 Printer.printMetadata("type", N->getRawType());
2685 Printer.printDIFlags("flags", N->getFlags());
2686 Printer.printInt("align", N->getAlignInBits());
2687 Printer.printMetadata("annotations", N->getRawAnnotations());
2688 Out << ")";
2689}
2690
2691static void writeDILabel(raw_ostream &Out, const DILabel *N,
2692 AsmWriterContext &WriterCtx) {
2693 Out << "!DILabel(";
2694 MDFieldPrinter Printer(Out, WriterCtx);
2695 Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
2696 Printer.printString("name", N->getName());
2697 Printer.printMetadata("file", N->getRawFile());
2698 Printer.printInt("line", N->getLine(), /* ShouldSkipZero */ false);
2699 Printer.printInt("column", N->getColumn());
2700 Printer.printBool("isArtificial", N->isArtificial(), false);
2701 if (N->getCoroSuspendIdx())
2702 Printer.printInt("coroSuspendIdx", *N->getCoroSuspendIdx(),
2703 /* ShouldSkipZero */ false);
2704 Out << ")";
2705}
2706
2708 AsmWriterContext &WriterCtx) {
2709 Out << "!DIExpression(";
2710 ListSeparator FS;
2711 if (N->isValid()) {
2712 for (const DIExpression::ExprOperand &Op : N->expr_ops()) {
2713 auto OpStr = dwarf::OperationEncodingString(Op.getOp());
2714 assert(!OpStr.empty() && "Expected valid opcode");
2715
2716 Out << FS << OpStr;
2717 if (auto Convert = dyn_cast<DIExpression::ConvertOp>(Op)) {
2718 Out << FS << Convert.getBitSize();
2719 Out << FS << dwarf::AttributeEncodingString(Convert.getEncoding());
2720 } else {
2721 for (unsigned A = 0, AE = Op.getNumArgs(); A != AE; ++A)
2722 Out << FS << Op.getArg(A);
2723 }
2724 }
2725 } else {
2726 for (const auto &I : N->getElements())
2727 Out << FS << I;
2728 }
2729 Out << ")";
2730}
2731
2732static void writeDIArgList(raw_ostream &Out, const DIArgList *N,
2733 AsmWriterContext &WriterCtx,
2734 bool FromValue = false) {
2735 assert(FromValue &&
2736 "Unexpected DIArgList metadata outside of value argument");
2737 Out << "!DIArgList(";
2738 ListSeparator FS;
2739 MDFieldPrinter Printer(Out, WriterCtx);
2740 for (const Metadata *Arg : N->getArgs()) {
2741 Out << FS;
2742 writeAsOperandInternal(Out, Arg, WriterCtx, true);
2743 }
2744 Out << ")";
2745}
2746
2749 AsmWriterContext &WriterCtx) {
2750 Out << "!DIGlobalVariableExpression(";
2751 MDFieldPrinter Printer(Out, WriterCtx);
2752 Printer.printMetadata("var", N->getVariable());
2753 Printer.printMetadata("expr", N->getExpression());
2754 Out << ")";
2755}
2756
2758 AsmWriterContext &WriterCtx) {
2759 Out << "!DIObjCProperty(";
2760 MDFieldPrinter Printer(Out, WriterCtx);
2761 Printer.printString("name", N->getName());
2762 Printer.printMetadata("file", N->getRawFile());
2763 Printer.printInt("line", N->getLine());
2764 Printer.printString("setter", N->getSetterName());
2765 Printer.printString("getter", N->getGetterName());
2766 Printer.printInt("attributes", N->getAttributes());
2767 Printer.printMetadata("type", N->getRawType());
2768 Out << ")";
2769}
2770
2771static void writeDIProperty(raw_ostream &Out, const DIProperty *N,
2772 AsmWriterContext &WriterCtx) {
2773 Out << "!DIProperty(";
2774 MDFieldPrinter Printer(Out, WriterCtx);
2775 Printer.printString("name", N->getName());
2776 Printer.printMetadata("file", N->getRawFile());
2777 Printer.printInt("line", N->getLine());
2778 Printer.printMetadata("type", N->getRawType());
2779 Printer.printMetadata("backing_storage", N->getRawBackingStorage());
2780 Out << ")";
2781}
2782
2784 AsmWriterContext &WriterCtx) {
2785 Out << "!DIImportedEntity(";
2786 MDFieldPrinter Printer(Out, WriterCtx);
2787 Printer.printTag(N);
2788 Printer.printString("name", N->getName());
2789 Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
2790 Printer.printMetadata("entity", N->getRawEntity());
2791 Printer.printMetadata("file", N->getRawFile());
2792 Printer.printInt("line", N->getLine());
2793 Printer.printMetadata("elements", N->getRawElements());
2794 Out << ")";
2795}
2796
2798 AsmWriterContext &Ctx) {
2799 if (Node->isDistinct())
2800 Out << "distinct ";
2801 else if (Node->isTemporary())
2802 Out << "<temporary!> "; // Handle broken code.
2803
2804 switch (Node->getMetadataID()) {
2805 default:
2806 llvm_unreachable("Expected uniquable MDNode");
2807#define HANDLE_MDNODE_LEAF(CLASS) \
2808 case Metadata::CLASS##Kind: \
2809 write##CLASS(Out, cast<CLASS>(Node), Ctx); \
2810 break;
2811#include "llvm/IR/Metadata.def"
2812 }
2813}
2814
2815// Full implementation of printing a Value as an operand with support for
2816// TypePrinting, etc.
2818 AsmWriterContext &WriterCtx,
2819 bool PrintType) {
2820 if (PrintType) {
2821 WriterCtx.TypePrinter->print(V->getType(), Out);
2822 Out << ' ';
2823 }
2824
2825 if (V->hasName()) {
2826 printLLVMName(Out, V);
2827 return;
2828 }
2829
2830 const auto *CV = dyn_cast<Constant>(V);
2831 if (CV && !isa<GlobalValue>(CV)) {
2832 assert(WriterCtx.TypePrinter && "Constants require TypePrinting!");
2833 writeConstantInternal(Out, CV, WriterCtx);
2834 return;
2835 }
2836
2837 if (const auto *IA = dyn_cast<InlineAsm>(V)) {
2838 Out << "asm ";
2839 if (IA->hasSideEffects())
2840 Out << "sideeffect ";
2841 if (IA->isAlignStack())
2842 Out << "alignstack ";
2843 // We don't emit the AD_ATT dialect as it's the assumed default.
2844 if (IA->getDialect() == InlineAsm::AD_Intel)
2845 Out << "inteldialect ";
2846 if (IA->canThrow())
2847 Out << "unwind ";
2848 Out << '"';
2849 printEscapedString(IA->getAsmString(), Out);
2850 Out << "\", \"";
2851 printEscapedString(IA->getConstraintString(), Out);
2852 Out << '"';
2853 return;
2854 }
2855
2856 if (auto *MD = dyn_cast<MetadataAsValue>(V)) {
2857 writeAsOperandInternal(Out, MD->getMetadata(), WriterCtx,
2858 /* FromValue */ true);
2859 return;
2860 }
2861
2862 char Prefix = '%';
2863 int Slot;
2864 auto *Machine = WriterCtx.Machine;
2865 // If we have a SlotTracker, use it.
2866 if (Machine) {
2867 if (const auto *GV = dyn_cast<GlobalValue>(V)) {
2868 Slot = Machine->getGlobalSlot(GV);
2869 Prefix = '@';
2870 } else {
2871 Slot = Machine->getLocalSlot(V);
2872
2873 // If the local value didn't succeed, then we may be referring to a value
2874 // from a different function. Translate it, as this can happen when using
2875 // address of blocks.
2876 if (Slot == -1)
2877 if ((Machine = createSlotTracker(V))) {
2878 Slot = Machine->getLocalSlot(V);
2879 delete Machine;
2880 }
2881 }
2882 } else if ((Machine = createSlotTracker(V))) {
2883 // Otherwise, create one to get the # and then destroy it.
2884 if (const auto *GV = dyn_cast<GlobalValue>(V)) {
2885 Slot = Machine->getGlobalSlot(GV);
2886 Prefix = '@';
2887 } else {
2888 Slot = Machine->getLocalSlot(V);
2889 }
2890 delete Machine;
2891 Machine = nullptr;
2892 } else {
2893 Slot = -1;
2894 }
2895
2896 if (Slot != -1)
2897 Out << Prefix << Slot;
2898 else
2899 Out << "<badref>";
2900}
2901
2902static void writeAsOperandInternal(raw_ostream &Out, const Metadata *MD,
2903 AsmWriterContext &WriterCtx,
2904 bool FromValue) {
2905 // Write DIExpressions and DIArgLists inline when used as a value. Improves
2906 // readability of debug info intrinsics.
2907 if (const auto *Expr = dyn_cast<DIExpression>(MD)) {
2908 writeDIExpression(Out, Expr, WriterCtx);
2909 return;
2910 }
2911 if (const auto *ArgList = dyn_cast<DIArgList>(MD)) {
2912 writeDIArgList(Out, ArgList, WriterCtx, FromValue);
2913 return;
2914 }
2915
2916 if (const auto *N = dyn_cast<MDNode>(MD)) {
2917 if (const auto *Loc = dyn_cast<DILocation>(N);
2918 Loc && WriterCtx.MST &&
2919 WriterCtx.MST->shouldPrintDebugLocationInline(Loc)) {
2920 writeDILocation(Out, Loc, WriterCtx);
2921 return;
2922 }
2923
2924 std::unique_ptr<SlotTracker> MachineStorage;
2925 SaveAndRestore SARMachine(WriterCtx.Machine);
2926 if (!WriterCtx.Machine) {
2927 MachineStorage = std::make_unique<SlotTracker>(WriterCtx.Context);
2928 WriterCtx.Machine = MachineStorage.get();
2929 }
2930 int Slot = WriterCtx.Machine->getMetadataSlot(N);
2931 if (Slot == -1) {
2932 if (const auto *Loc = dyn_cast<DILocation>(N)) {
2933 writeDILocation(Out, Loc, WriterCtx);
2934 return;
2935 }
2936 // Give the pointer value instead of "badref", since this comes up all
2937 // the time when debugging.
2938 Out << "<" << N << ">";
2939 } else
2940 Out << '!' << Slot;
2941 return;
2942 }
2943
2944 if (const auto *MDS = dyn_cast<MDString>(MD)) {
2945 Out << "!\"";
2946 printEscapedString(MDS->getString(), Out);
2947 Out << '"';
2948 return;
2949 }
2950
2951 auto *V = cast<ValueAsMetadata>(MD);
2952 assert(WriterCtx.TypePrinter && "TypePrinter required for metadata values");
2953 assert((FromValue || !isa<LocalAsMetadata>(V)) &&
2954 "Unexpected function-local metadata outside of value argument");
2955
2956 writeAsOperandInternal(Out, V->getValue(), WriterCtx, /*PrintType=*/true);
2957}
2958
2959namespace {
2960
2961class AssemblyWriter {
2962 const IROptions &Opts;
2963 formatted_raw_ostream &Out;
2964 const Module *TheModule = nullptr;
2965 const ModuleSummaryIndex *TheIndex = nullptr;
2966 std::unique_ptr<SlotTracker> SlotTrackerStorage;
2967 SlotTracker &Machine;
2968 TypePrinting TypePrinter;
2969 AssemblyAnnotationWriter *AnnotationWriter = nullptr;
2970 bool IsForDebug;
2971 bool ShouldPreserveUseListOrder;
2972 UseListOrderMap UseListOrders;
2974 /// Synchronization scope names registered with LLVMContext.
2976 DenseMap<const GlobalValueSummary *, GlobalValue::GUID> SummaryToGUIDMap;
2977
2978public:
2979 /// Construct an AssemblyWriter with an external SlotTracker
2980 AssemblyWriter(const IROptions &Opts, formatted_raw_ostream &o,
2981 SlotTracker &Mac, const Module *M,
2982 AssemblyAnnotationWriter *AAW, bool IsForDebug,
2983 bool ShouldPreserveUseListOrder = false);
2984
2985 AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
2986 const ModuleSummaryIndex *Index, bool IsForDebug);
2987
2988 AsmWriterContext getContext() {
2989 return AsmWriterContext(&TypePrinter, &Machine, TheModule);
2990 }
2991
2992 void printMDNodeBody(const MDNode *MD);
2993 void printNamedMDNode(const NamedMDNode *NMD);
2994
2995 void printModule(const Module *M);
2996
2997 void writeOperand(const Value *Op, bool PrintType);
2998 void writeParamOperand(const Value *Operand, AttributeSet Attrs);
2999 void writeOperandBundles(const CallBase *Call);
3000 void writeSyncScope(const LLVMContext &Context,
3001 SyncScope::ID SSID);
3002 void writeAtomic(const LLVMContext &Context,
3003 AtomicOrdering Ordering,
3004 SyncScope::ID SSID);
3005 void writeAtomicCmpXchg(const LLVMContext &Context,
3006 AtomicOrdering SuccessOrdering,
3007 AtomicOrdering FailureOrdering,
3008 SyncScope::ID SSID);
3009
3010 void writeAllMDNodes();
3011 void writeMDNode(unsigned Slot, const MDNode *Node);
3012 void writeAttribute(const Attribute &Attr, bool InAttrGroup = false);
3013 void writeAttributeSet(const AttributeSet &AttrSet, bool InAttrGroup = false);
3014 void writeAllAttributeGroups();
3015
3016 void printTypeIdentities();
3017 void printGlobal(const GlobalVariable *GV);
3018 void printAlias(const GlobalAlias *GA);
3019 void printIFunc(const GlobalIFunc *GI);
3020 void printComdat(const Comdat *C);
3021 void printFunction(const Function *F);
3022 void printArgument(const Argument *FA, AttributeSet Attrs);
3023 void printBasicBlock(const BasicBlock *BB);
3024 void printInstructionLine(const Instruction &I);
3025 void printInstruction(const Instruction &I);
3026 void printDbgMarker(const DbgMarker &DPI);
3027 void printDbgVariableRecord(const DbgVariableRecord &DVR);
3028 void printDbgLabelRecord(const DbgLabelRecord &DLR);
3029 void printDbgRecord(const DbgRecord &DR);
3030 void printDbgRecordLine(const DbgRecord &DR);
3031
3032 void printUseListOrder(const Value *V, ArrayRef<unsigned> Shuffle);
3033 void printUseLists(const Function *F);
3034
3035 void printModuleSummaryIndex();
3036 void printSummaryInfo(unsigned Slot, const ValueInfo &VI);
3037 void printSummary(const GlobalValueSummary &Summary);
3038 void printAliasSummary(const AliasSummary *AS);
3039 void printGlobalVarSummary(const GlobalVarSummary *GS);
3040 void printFunctionSummary(const FunctionSummary *FS);
3041 void printTypeIdSummary(const TypeIdSummary &TIS);
3042 void printTypeIdCompatibleVtableSummary(const TypeIdCompatibleVtableInfo &TI);
3043 void printTypeTestResolution(const TypeTestResolution &TTRes);
3044 void printArgs(ArrayRef<uint64_t> Args);
3045 void printWPDRes(const WholeProgramDevirtResolution &WPDRes);
3046 void printTypeIdInfo(const FunctionSummary::TypeIdInfo &TIDInfo);
3047 void printVFuncId(const FunctionSummary::VFuncId VFId);
3048 void printNonConstVCalls(ArrayRef<FunctionSummary::VFuncId> VCallList,
3049 const char *Tag);
3050 void printConstVCalls(ArrayRef<FunctionSummary::ConstVCall> VCallList,
3051 const char *Tag);
3052
3053private:
3054 /// Print out metadata attachments.
3055 void printMetadataAttachments(
3056 const SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs,
3057 StringRef Separator);
3058
3059 // printInfoComment - Print a little comment after the instruction indicating
3060 // which slot it occupies.
3061 void printInfoComment(const Value &V, bool isMaterializable = false);
3062
3063 // printGCRelocateComment - print comment after call to the gc.relocate
3064 // intrinsic indicating base and derived pointer names.
3065 void printGCRelocateComment(const GCRelocateInst &Relocate);
3066};
3067
3068} // end anonymous namespace
3069
3070// The options of what has no LLVMContext: a summary index or a detached debug
3071// record.
3072constexpr IROptions DefaultOptions;
3073
3074static const IROptions &getOptions(const Module *M) {
3075 return M ? getIROptions(M->getContext()) : DefaultOptions;
3076}
3077
3078AssemblyWriter::AssemblyWriter(const IROptions &Opts, formatted_raw_ostream &o,
3079 SlotTracker &Mac, const Module *M,
3080 AssemblyAnnotationWriter *AAW, bool IsForDebug,
3081 bool ShouldPreserveUseListOrder)
3082 : Opts(Opts), Out(o), TheModule(M), Machine(Mac), TypePrinter(M),
3083 AnnotationWriter(AAW), IsForDebug(IsForDebug),
3084 ShouldPreserveUseListOrder(
3085 valueOr(Opts.preserve_ll_uselistorder, ShouldPreserveUseListOrder)) {}
3086
3087AssemblyWriter::AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
3088 const ModuleSummaryIndex *Index, bool IsForDebug)
3089 : Opts(DefaultOptions), Out(o), TheIndex(Index), Machine(Mac),
3090 TypePrinter(/*Module=*/nullptr), IsForDebug(IsForDebug),
3091 ShouldPreserveUseListOrder(false) {}
3092
3093void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType) {
3094 if (!Operand) {
3095 Out << "<null operand!>";
3096 return;
3097 }
3098 auto WriteCtx = getContext();
3099 writeAsOperandInternal(Out, Operand, WriteCtx, PrintType);
3100}
3101
3102void AssemblyWriter::writeSyncScope(const LLVMContext &Context,
3103 SyncScope::ID SSID) {
3104 switch (SSID) {
3105 case SyncScope::System: {
3106 break;
3107 }
3108 default: {
3109 if (SSNs.empty())
3110 Context.getSyncScopeNames(SSNs);
3111
3112 Out << " syncscope(\"";
3113 printEscapedString(SSNs[SSID], Out);
3114 Out << "\")";
3115 break;
3116 }
3117 }
3118}
3119
3120void AssemblyWriter::writeAtomic(const LLVMContext &Context,
3121 AtomicOrdering Ordering,
3122 SyncScope::ID SSID) {
3123 if (Ordering == AtomicOrdering::NotAtomic)
3124 return;
3125
3126 writeSyncScope(Context, SSID);
3127 Out << " " << toIRString(Ordering);
3128}
3129
3130void AssemblyWriter::writeAtomicCmpXchg(const LLVMContext &Context,
3131 AtomicOrdering SuccessOrdering,
3132 AtomicOrdering FailureOrdering,
3133 SyncScope::ID SSID) {
3134 assert(SuccessOrdering != AtomicOrdering::NotAtomic &&
3135 FailureOrdering != AtomicOrdering::NotAtomic);
3136
3137 writeSyncScope(Context, SSID);
3138 Out << " " << toIRString(SuccessOrdering);
3139 Out << " " << toIRString(FailureOrdering);
3140}
3141
3142void AssemblyWriter::writeParamOperand(const Value *Operand,
3143 AttributeSet Attrs) {
3144 if (!Operand) {
3145 Out << "<null operand!>";
3146 return;
3147 }
3148
3149 // Print the type
3150 TypePrinter.print(Operand->getType(), Out);
3151 // Print parameter attributes list
3152 if (Attrs.hasAttributes()) {
3153 Out << ' ';
3154 writeAttributeSet(Attrs);
3155 }
3156 Out << ' ';
3157 // Print the operand
3158 auto WriterCtx = getContext();
3159 writeAsOperandInternal(Out, Operand, WriterCtx);
3160}
3161
3162void AssemblyWriter::writeOperandBundles(const CallBase *Call) {
3163 if (!Call->hasOperandBundles())
3164 return;
3165
3166 Out << " [ ";
3167
3168 ListSeparator LS;
3169 for (unsigned i = 0, e = Call->getNumOperandBundles(); i != e; ++i) {
3170 OperandBundleUse BU = Call->getOperandBundleAt(i);
3171
3172 Out << LS << '"';
3173 printEscapedString(BU.getTagName(), Out);
3174 Out << '"';
3175
3176 Out << '(';
3177
3178 ListSeparator InnerLS;
3179 auto WriterCtx = getContext();
3180 for (const auto &Input : BU.Inputs) {
3181 Out << InnerLS;
3182 if (Input == nullptr)
3183 Out << "<null operand bundle!>";
3184 else
3185 writeAsOperandInternal(Out, Input, WriterCtx, /*PrintType=*/true);
3186 }
3187
3188 Out << ')';
3189 }
3190
3191 Out << " ]";
3192}
3193
3194void AssemblyWriter::printModule(const Module *M) {
3195 Machine.initializeIfNeeded();
3196
3197 if (ShouldPreserveUseListOrder)
3198 UseListOrders = predictUseListOrder(M);
3199
3200 if (!M->getModuleIdentifier().empty() &&
3201 // Don't print the ID if it will start a new line (which would
3202 // require a comment char before it).
3203 M->getModuleIdentifier().find('\n') == std::string::npos)
3204 Out << "; ModuleID = '" << M->getModuleIdentifier() << "'\n";
3205
3206 if (!M->getSourceFileName().empty()) {
3207 Out << "source_filename = \"";
3208 printEscapedString(M->getSourceFileName(), Out);
3209 Out << "\"\n";
3210 }
3211
3212 const std::string &DL = M->getDataLayoutStr();
3213 if (!DL.empty())
3214 Out << "target datalayout = \"" << DL << "\"\n";
3215 if (!M->getTargetTriple().empty())
3216 Out << "target triple = \"" << M->getTargetTriple().str() << "\"\n";
3217
3218 if (M->hasModuleInlineAsm()) {
3219 Out << '\n';
3220
3221 for (const Module::GlobalAsmFragment &Frag : M->getModuleInlineAsm()) {
3222 Out << "module asm";
3224 Frag.Props.getAsStrings();
3225 if (!Props.empty()) {
3226 ListSeparator LS;
3227 Out << "(";
3228 for (auto [Key, Value] : Props) {
3229 Out << LS;
3230 Out << Key << ": \"";
3232 Out << "\"";
3233 }
3234 Out << ")";
3235 }
3236 Out << "\n";
3237 // Split the string into lines, to make it easier to read the .ll file.
3238 StringRef Asm = Frag.Asm;
3239 do {
3240 StringRef Front;
3241 std::tie(Front, Asm) = Asm.split('\n');
3242
3243 // We found a newline, print the portion of the asm string from the
3244 // last newline up to this newline.
3245 Out << " \"";
3246 printEscapedString(Front, Out);
3247 Out << "\"\n";
3248 } while (!Asm.empty());
3249 }
3250 }
3251
3252 printTypeIdentities();
3253
3254 {
3255 // Output each used comdat at its first global object.
3256 SmallPtrSet<const Comdat *, 8> PrintedComdats;
3257 for (const GlobalObject &GO : M->global_objects()) {
3258 const Comdat *C = GO.getComdat();
3259 if (!C || !PrintedComdats.insert(C).second)
3260 continue;
3261 Out << '\n';
3262 printComdat(C);
3263 }
3264 }
3265
3266 // Output all globals.
3267 if (!M->global_empty()) Out << '\n';
3268 for (const GlobalVariable &GV : M->globals()) {
3269 printGlobal(&GV); Out << '\n';
3270 }
3271
3272 // Output all aliases.
3273 if (!M->alias_empty()) Out << "\n";
3274 for (const GlobalAlias &GA : M->aliases())
3275 printAlias(&GA);
3276
3277 // Output all ifuncs.
3278 if (!M->ifunc_empty()) Out << "\n";
3279 for (const GlobalIFunc &GI : M->ifuncs())
3280 printIFunc(&GI);
3281
3282 // Output all of the functions.
3283 for (const Function &F : *M) {
3284 Out << '\n';
3285 printFunction(&F);
3286 }
3287
3288 // Output global use-lists.
3289 printUseLists(nullptr);
3290
3291 // Output all attribute groups.
3292 if (!Machine.as_empty()) {
3293 Out << '\n';
3294 writeAllAttributeGroups();
3295 }
3296
3297 // Output named metadata.
3298 if (!M->named_metadata_empty()) Out << '\n';
3299
3300 for (const NamedMDNode &Node : M->named_metadata())
3301 printNamedMDNode(&Node);
3302
3303 // Output metadata.
3304 if (!Machine.mdn_empty()) {
3305 Out << '\n';
3306 writeAllMDNodes();
3307 }
3308}
3309
3310void AssemblyWriter::printModuleSummaryIndex() {
3311 assert(TheIndex);
3312 int NumSlots = Machine.initializeIndexIfNeeded();
3313
3314 Out << "\n";
3315
3316 // Print module path entries. To print in order, add paths to a vector
3317 // indexed by module slot.
3318 std::vector<std::pair<std::string, ModuleHash>> moduleVec;
3319 std::string RegularLTOModuleName =
3321 moduleVec.resize(TheIndex->modulePaths().size());
3322 for (auto &[ModPath, ModHash] : TheIndex->modulePaths())
3323 moduleVec[Machine.getModulePathSlot(ModPath)] = std::make_pair(
3324 // An empty module path is a special entry for a regular LTO module
3325 // created during the thin link.
3326 ModPath.empty() ? RegularLTOModuleName : std::string(ModPath), ModHash);
3327
3328 unsigned i = 0;
3329 for (auto &ModPair : moduleVec) {
3330 Out << "^" << i++ << " = module: (";
3331 Out << "path: \"";
3332 printEscapedString(ModPair.first, Out);
3333 Out << "\", hash: (";
3334 ListSeparator FS;
3335 for (auto Hash : ModPair.second)
3336 Out << FS << Hash;
3337 Out << "))\n";
3338 }
3339
3340 // FIXME: Change AliasSummary to hold a ValueInfo instead of summary pointer
3341 // for aliasee (then update BitcodeWriter.cpp and remove get/setAliaseeGUID).
3342 // Sort by GUID for deterministic output matching slot assignment order.
3343 auto SortedGVS = TheIndex->sortedGlobalValueSummariesRange();
3344
3345 for (const auto &GlobalList : SortedGVS) {
3346 auto GUID = GlobalList.first;
3347 for (auto &Summary : GlobalList.second.getSummaryList())
3348 SummaryToGUIDMap[Summary.get()] = GUID;
3349 }
3350
3351 // Print the global value summary entries.
3352 for (const auto &GlobalList : SortedGVS) {
3353 auto GUID = GlobalList.first;
3354 auto VI = TheIndex->getValueInfo(GlobalList);
3355 printSummaryInfo(Machine.getGUIDSlot(GUID), VI);
3356 }
3357
3358 // Print the TypeIdMap entries.
3359 for (const auto &TID : TheIndex->typeIds()) {
3360 Out << "^" << Machine.getTypeIdSlot(TID.second.first)
3361 << " = typeid: (name: \"";
3362 printEscapedString(TID.second.first, Out);
3363 Out << "\"";
3364 printTypeIdSummary(TID.second.second);
3365 Out << ") ; guid = " << TID.first << "\n";
3366 }
3367
3368 // Print the TypeIdCompatibleVtableMap entries.
3369 for (auto &TId : TheIndex->typeIdCompatibleVtableMap()) {
3371 Out << "^" << Machine.getTypeIdCompatibleVtableSlot(TId.first)
3372 << " = typeidCompatibleVTable: (name: \"";
3373 printEscapedString(TId.first, Out);
3374 Out << "\"";
3375 printTypeIdCompatibleVtableSummary(TId.second);
3376 Out << ") ; guid = " << GUID << "\n";
3377 }
3378
3379 // Print the CFI function entries (the names of the functions with jump
3380 // table entries, with the GUIDs that ThinLTO uses for them).
3381 auto PrintCfiFunctions = [&](const CfiFunctionIndex &CfiIndex,
3382 StringRef EntryName) {
3383 if (CfiIndex.empty())
3384 return;
3385 Out << "^" << NumSlots++ << " = " << EntryName << ": (";
3386 ListSeparator FS;
3387 for (const auto &[Name, GUID] : CfiIndex.getSortedSymbols()) {
3388 Out << FS << "(guid: " << GUID << ", name: \"";
3389 printEscapedString(Name, Out);
3390 Out << "\")";
3391 }
3392 Out << ")\n";
3393 };
3394 PrintCfiFunctions(TheIndex->cfiFunctionDefs(), "cfiFunctionDefs");
3395 PrintCfiFunctions(TheIndex->cfiFunctionDecls(), "cfiFunctionDecls");
3396
3397 // Don't emit flags when it's not really needed (value is zero by default).
3398 if (TheIndex->getFlags()) {
3399 Out << "^" << NumSlots << " = flags: " << TheIndex->getFlags() << "\n";
3400 ++NumSlots;
3401 }
3402
3403 Out << "^" << NumSlots << " = blockcount: " << TheIndex->getBlockCount()
3404 << "\n";
3405}
3406
3407static const char *
3409 switch (K) {
3411 return "indir";
3413 return "singleImpl";
3415 return "branchFunnel";
3416 }
3417 llvm_unreachable("invalid WholeProgramDevirtResolution kind");
3418}
3419
3422 switch (K) {
3424 return "indir";
3426 return "uniformRetVal";
3428 return "uniqueRetVal";
3430 return "virtualConstProp";
3431 }
3432 llvm_unreachable("invalid WholeProgramDevirtResolution::ByArg kind");
3433}
3434
3436 switch (K) {
3438 return "unknown";
3440 return "unsat";
3442 return "byteArray";
3444 return "inline";
3446 return "single";
3448 return "allOnes";
3449 }
3450 llvm_unreachable("invalid TypeTestResolution kind");
3451}
3452
3453void AssemblyWriter::printTypeTestResolution(const TypeTestResolution &TTRes) {
3454 Out << "typeTestRes: (kind: " << getTTResKindName(TTRes.TheKind)
3455 << ", sizeM1BitWidth: " << TTRes.SizeM1BitWidth;
3456
3457 // The following fields are only used if the target does not support the use
3458 // of absolute symbols to store constants. Print only if non-zero.
3459 if (TTRes.AlignLog2)
3460 Out << ", alignLog2: " << TTRes.AlignLog2;
3461 if (TTRes.SizeM1)
3462 Out << ", sizeM1: " << TTRes.SizeM1;
3463 if (TTRes.BitMask)
3464 // BitMask is uint8_t which causes it to print the corresponding char.
3465 Out << ", bitMask: " << (unsigned)TTRes.BitMask;
3466 if (TTRes.InlineBits)
3467 Out << ", inlineBits: " << TTRes.InlineBits;
3468
3469 Out << ")";
3470}
3471
3472void AssemblyWriter::printTypeIdSummary(const TypeIdSummary &TIS) {
3473 Out << ", summary: (";
3474 printTypeTestResolution(TIS.TTRes);
3475 if (!TIS.WPDRes.empty()) {
3476 Out << ", wpdResolutions: (";
3477 ListSeparator FS;
3478 for (auto &WPDRes : TIS.WPDRes) {
3479 Out << FS;
3480 Out << "(offset: " << WPDRes.first << ", ";
3481 printWPDRes(WPDRes.second);
3482 Out << ")";
3483 }
3484 Out << ")";
3485 }
3486 Out << ")";
3487}
3488
3489void AssemblyWriter::printTypeIdCompatibleVtableSummary(
3490 const TypeIdCompatibleVtableInfo &TI) {
3491 Out << ", summary: (";
3492 ListSeparator FS;
3493 for (auto &P : TI) {
3494 Out << FS;
3495 Out << "(offset: " << P.AddressPointOffset << ", ";
3496 Out << "^" << Machine.getGUIDSlot(P.VTableVI.getGUID());
3497 Out << ")";
3498 }
3499 Out << ")";
3500}
3501
3502void AssemblyWriter::printArgs(ArrayRef<uint64_t> Args) {
3503 Out << "args: (" << llvm::interleaved(Args) << ')';
3504}
3505
3506void AssemblyWriter::printWPDRes(const WholeProgramDevirtResolution &WPDRes) {
3507 Out << "wpdRes: (kind: ";
3509
3511 Out << ", singleImplName: \"";
3513 Out << "\"";
3514 }
3515
3516 if (!WPDRes.ResByArg.empty()) {
3517 Out << ", resByArg: (";
3518 ListSeparator FS;
3519 for (auto &ResByArg : WPDRes.ResByArg) {
3520 Out << FS;
3521 printArgs(ResByArg.first);
3522 Out << ", byArg: (kind: ";
3523 Out << getWholeProgDevirtResByArgKindName(ResByArg.second.TheKind);
3524 if (ResByArg.second.TheKind ==
3526 ResByArg.second.TheKind ==
3528 Out << ", info: " << ResByArg.second.Info;
3529
3530 // The following fields are only used if the target does not support the
3531 // use of absolute symbols to store constants. Print only if non-zero.
3532 if (ResByArg.second.Byte || ResByArg.second.Bit)
3533 Out << ", byte: " << ResByArg.second.Byte
3534 << ", bit: " << ResByArg.second.Bit;
3535
3536 Out << ")";
3537 }
3538 Out << ")";
3539 }
3540 Out << ")";
3541}
3542
3544 switch (SK) {
3546 return "alias";
3548 return "function";
3550 return "variable";
3551 }
3552 llvm_unreachable("invalid summary kind");
3553}
3554
3555void AssemblyWriter::printAliasSummary(const AliasSummary *AS) {
3556 Out << ", aliasee: ";
3557 // The indexes emitted for distributed backends may not include the
3558 // aliasee summary (only if it is being imported directly). Handle
3559 // that case by just emitting "null" as the aliasee.
3560 if (AS->hasAliasee())
3561 Out << "^" << Machine.getGUIDSlot(SummaryToGUIDMap[&AS->getAliasee()]);
3562 else
3563 Out << "null";
3564}
3565
3566void AssemblyWriter::printGlobalVarSummary(const GlobalVarSummary *GS) {
3567 auto VTableFuncs = GS->vTableFuncs();
3568 Out << ", varFlags: (readonly: " << GS->VarFlags.MaybeReadOnly << ", "
3569 << "writeonly: " << GS->VarFlags.MaybeWriteOnly << ", "
3570 << "constant: " << GS->VarFlags.Constant;
3571 if (!VTableFuncs.empty())
3572 Out << ", "
3573 << "vcall_visibility: " << GS->VarFlags.VCallVisibility;
3574 Out << ")";
3575
3576 if (!VTableFuncs.empty()) {
3577 Out << ", vTableFuncs: (";
3578 ListSeparator FS;
3579 for (auto &P : VTableFuncs) {
3580 Out << FS;
3581 Out << "(virtFunc: ^" << Machine.getGUIDSlot(P.FuncVI.getGUID())
3582 << ", offset: " << P.VTableOffset;
3583 Out << ")";
3584 }
3585 Out << ")";
3586 }
3587}
3588
3590 switch (LT) {
3592 return "external";
3594 return "private";
3596 return "internal";
3598 return "linkonce";
3600 return "linkonce_odr";
3602 return "weak";
3604 return "weak_odr";
3606 return "common";
3608 return "appending";
3610 return "extern_weak";
3612 return "available_externally";
3613 }
3614 llvm_unreachable("invalid linkage");
3615}
3616
3617// When printing the linkage types in IR where the ExternalLinkage is
3618// not printed, and other linkage types are expected to be printed with
3619// a space after the name.
3622 return "";
3623 return getLinkageName(LT) + " ";
3624}
3625
3627 switch (Vis) {
3629 return "default";
3631 return "hidden";
3633 return "protected";
3634 }
3635 llvm_unreachable("invalid visibility");
3636}
3637
3639 switch (IK) {
3641 return "definition";
3643 return "declaration";
3644 }
3645 llvm_unreachable("invalid import kind");
3646}
3647
3648void AssemblyWriter::printFunctionSummary(const FunctionSummary *FS) {
3649 Out << ", insts: " << FS->instCount();
3650 if (FS->fflags().anyFlagSet())
3651 Out << ", " << FS->fflags();
3652
3653 if (!FS->calls().empty()) {
3654 Out << ", calls: (";
3655 ListSeparator IFS;
3656 for (auto &Call : FS->calls()) {
3657 Out << IFS;
3658 Out << "(callee: ^" << Machine.getGUIDSlot(Call.first.getGUID());
3659 if (Call.second.getHotness() != CalleeInfo::HotnessType::Unknown)
3660 Out << ", hotness: " << getHotnessName(Call.second.getHotness());
3661 // Follow the convention of emitting flags as a boolean value, but only
3662 // emit if true to avoid unnecessary verbosity and test churn.
3663 if (Call.second.HasTailCall)
3664 Out << ", tail: 1";
3665 if (Call.second.HasIndirectCall)
3666 Out << ", indirect: 1";
3667 Out << ")";
3668 }
3669 Out << ")";
3670 }
3671
3672 if (const auto *TIdInfo = FS->getTypeIdInfo())
3673 printTypeIdInfo(*TIdInfo);
3674
3675 // The AllocationType identifiers capture the profiled context behavior
3676 // reaching a specific static allocation site (possibly cloned).
3677 auto AllocTypeName = [](uint8_t Type) -> const char * {
3678 switch (Type) {
3679 case (uint8_t)AllocationType::None:
3680 return "none";
3681 case (uint8_t)AllocationType::NotCold:
3682 return "notcold";
3683 case (uint8_t)AllocationType::Cold:
3684 return "cold";
3685 case (uint8_t)AllocationType::Hot:
3686 return "hot";
3687 case (uint8_t)AllocationType::NotCold | (uint8_t)AllocationType::Cold:
3688 // The contexts reaching the allocation could not be disambiguated.
3689 return "ambiguous";
3690 }
3691 llvm_unreachable("Unexpected alloc type");
3692 };
3693
3694 if (!FS->allocs().empty()) {
3695 Out << ", allocs: (";
3696 ListSeparator AFS;
3697 for (auto &AI : FS->allocs()) {
3698 Out << AFS;
3699 Out << "(versions: (";
3700 ListSeparator VFS;
3701 for (auto V : AI.Versions) {
3702 Out << VFS;
3703 Out << AllocTypeName(V);
3704 }
3705 Out << "), memProf: (";
3706 ListSeparator MIBFS;
3707 for (auto &MIB : AI.MIBs) {
3708 Out << MIBFS;
3709 Out << "(type: " << AllocTypeName((uint8_t)MIB.AllocType);
3710 Out << ", stackIds: (";
3711 ListSeparator SIDFS;
3712 for (auto Id : MIB.StackIdIndices) {
3713 Out << SIDFS;
3714 Out << TheIndex->getStackIdAtIndex(Id);
3715 }
3716 Out << "))";
3717 }
3718 Out << "))";
3719 }
3720 Out << ")";
3721 }
3722
3723 if (!FS->callsites().empty()) {
3724 Out << ", callsites: (";
3725 ListSeparator SNFS;
3726 for (auto &CI : FS->callsites()) {
3727 Out << SNFS;
3728 if (CI.Callee)
3729 Out << "(callee: ^" << Machine.getGUIDSlot(CI.Callee.getGUID());
3730 else
3731 Out << "(callee: null";
3732 Out << ", clones: (";
3733 ListSeparator VFS;
3734 for (auto V : CI.Clones) {
3735 Out << VFS;
3736 Out << V;
3737 }
3738 Out << "), stackIds: (";
3739 ListSeparator SIDFS;
3740 for (auto Id : CI.StackIdIndices) {
3741 Out << SIDFS;
3742 Out << TheIndex->getStackIdAtIndex(Id);
3743 }
3744 Out << "))";
3745 }
3746 Out << ")";
3747 }
3748
3749 auto PrintRange = [&](const ConstantRange &Range) {
3750 Out << "[" << Range.getSignedMin() << ", " << Range.getSignedMax() << "]";
3751 };
3752
3753 if (!FS->paramAccesses().empty()) {
3754 Out << ", params: (";
3755 ListSeparator IFS;
3756 for (auto &PS : FS->paramAccesses()) {
3757 Out << IFS;
3758 Out << "(param: " << PS.ParamNo;
3759 Out << ", offset: ";
3760 PrintRange(PS.Use);
3761 if (!PS.Calls.empty()) {
3762 Out << ", calls: (";
3763 ListSeparator IFS;
3764 for (auto &Call : PS.Calls) {
3765 Out << IFS;
3766 Out << "(callee: ^" << Machine.getGUIDSlot(Call.Callee.getGUID());
3767 Out << ", param: " << Call.ParamNo;
3768 Out << ", offset: ";
3769 PrintRange(Call.Offsets);
3770 Out << ")";
3771 }
3772 Out << ")";
3773 }
3774 Out << ")";
3775 }
3776 Out << ")";
3777 }
3778}
3779
3780void AssemblyWriter::printTypeIdInfo(
3781 const FunctionSummary::TypeIdInfo &TIDInfo) {
3782 Out << ", typeIdInfo: (";
3783 ListSeparator TIDFS;
3784 if (!TIDInfo.TypeTests.empty()) {
3785 Out << TIDFS;
3786 Out << "typeTests: (";
3787 ListSeparator FS;
3788 for (auto &GUID : TIDInfo.TypeTests) {
3789 auto TidIter = TheIndex->typeIds().equal_range(GUID);
3790 if (TidIter.first == TidIter.second) {
3791 Out << FS;
3792 Out << GUID;
3793 continue;
3794 }
3795 // Print all type id that correspond to this GUID.
3796 for (const auto &[GUID, TypeIdPair] : make_range(TidIter)) {
3797 Out << FS;
3798 auto Slot = Machine.getTypeIdSlot(TypeIdPair.first);
3799 assert(Slot != -1);
3800 Out << "^" << Slot;
3801 }
3802 }
3803 Out << ")";
3804 }
3805 if (!TIDInfo.TypeTestAssumeVCalls.empty()) {
3806 Out << TIDFS;
3807 printNonConstVCalls(TIDInfo.TypeTestAssumeVCalls, "typeTestAssumeVCalls");
3808 }
3809 if (!TIDInfo.TypeCheckedLoadVCalls.empty()) {
3810 Out << TIDFS;
3811 printNonConstVCalls(TIDInfo.TypeCheckedLoadVCalls, "typeCheckedLoadVCalls");
3812 }
3813 if (!TIDInfo.TypeTestAssumeConstVCalls.empty()) {
3814 Out << TIDFS;
3815 printConstVCalls(TIDInfo.TypeTestAssumeConstVCalls,
3816 "typeTestAssumeConstVCalls");
3817 }
3818 if (!TIDInfo.TypeCheckedLoadConstVCalls.empty()) {
3819 Out << TIDFS;
3820 printConstVCalls(TIDInfo.TypeCheckedLoadConstVCalls,
3821 "typeCheckedLoadConstVCalls");
3822 }
3823 Out << ")";
3824}
3825
3826void AssemblyWriter::printVFuncId(const FunctionSummary::VFuncId VFId) {
3827 auto TidIter = TheIndex->typeIds().equal_range(VFId.GUID);
3828 if (TidIter.first == TidIter.second) {
3829 Out << "vFuncId: (";
3830 Out << "guid: " << VFId.GUID;
3831 Out << ", offset: " << VFId.Offset;
3832 Out << ")";
3833 return;
3834 }
3835 // Print all type id that correspond to this GUID.
3836 ListSeparator FS;
3837 for (const auto &[GUID, TypeIdPair] : make_range(TidIter)) {
3838 Out << FS;
3839 Out << "vFuncId: (";
3840 auto Slot = Machine.getTypeIdSlot(TypeIdPair.first);
3841 assert(Slot != -1);
3842 Out << "^" << Slot;
3843 Out << ", offset: " << VFId.Offset;
3844 Out << ")";
3845 }
3846}
3847
3848void AssemblyWriter::printNonConstVCalls(
3849 ArrayRef<FunctionSummary::VFuncId> VCallList, const char *Tag) {
3850 Out << Tag << ": (";
3851 ListSeparator FS;
3852 for (auto &VFuncId : VCallList) {
3853 Out << FS;
3854 printVFuncId(VFuncId);
3855 }
3856 Out << ")";
3857}
3858
3859void AssemblyWriter::printConstVCalls(
3860 ArrayRef<FunctionSummary::ConstVCall> VCallList, const char *Tag) {
3861 Out << Tag << ": (";
3862 ListSeparator FS;
3863 for (auto &ConstVCall : VCallList) {
3864 Out << FS;
3865 Out << "(";
3866 printVFuncId(ConstVCall.VFunc);
3867 if (!ConstVCall.Args.empty()) {
3868 Out << ", ";
3869 printArgs(ConstVCall.Args);
3870 }
3871 Out << ")";
3872 }
3873 Out << ")";
3874}
3875
3876void AssemblyWriter::printSummary(const GlobalValueSummary &Summary) {
3877 GlobalValueSummary::GVFlags GVFlags = Summary.flags();
3879 Out << getSummaryKindName(Summary.getSummaryKind()) << ": ";
3880 Out << "(module: ^" << Machine.getModulePathSlot(Summary.modulePath())
3881 << ", flags: (";
3882 Out << "linkage: " << getLinkageName(LT);
3883 Out << ", visibility: "
3885 Out << ", notEligibleToImport: " << GVFlags.NotEligibleToImport;
3886 Out << ", live: " << GVFlags.Live;
3887 Out << ", dsoLocal: " << GVFlags.DSOLocal;
3888 Out << ", canAutoHide: " << GVFlags.CanAutoHide;
3889 Out << ", importType: "
3891 Out << ", noRenameOnPromotion: " << GVFlags.NoRenameOnPromotion;
3892 Out << ")";
3893
3894 if (Summary.getSummaryKind() == GlobalValueSummary::AliasKind)
3895 printAliasSummary(cast<AliasSummary>(&Summary));
3896 else if (Summary.getSummaryKind() == GlobalValueSummary::FunctionKind)
3897 printFunctionSummary(cast<FunctionSummary>(&Summary));
3898 else
3899 printGlobalVarSummary(cast<GlobalVarSummary>(&Summary));
3900
3901 auto RefList = Summary.refs();
3902 if (!RefList.empty()) {
3903 Out << ", refs: (";
3904 ListSeparator FS;
3905 for (auto &Ref : RefList) {
3906 Out << FS;
3907 if (Ref.isReadOnly())
3908 Out << "readonly ";
3909 else if (Ref.isWriteOnly())
3910 Out << "writeonly ";
3911 Out << "^" << Machine.getGUIDSlot(Ref.getGUID());
3912 }
3913 Out << ")";
3914 }
3915
3916 Out << ")";
3917}
3918
3919void AssemblyWriter::printSummaryInfo(unsigned Slot, const ValueInfo &VI) {
3920 Out << "^" << Slot << " = gv: (";
3921 if (VI.hasName() && !VI.name().empty()) {
3922 Out << "name: \"";
3923 printEscapedString(VI.name(), Out);
3924 Out << "\"";
3925 } else {
3926 Out << "guid: " << VI.getGUID();
3927 }
3928 if (!VI.getSummaryList().empty()) {
3929 Out << ", summaries: (";
3930 ListSeparator FS;
3931 for (auto &Summary : VI.getSummaryList()) {
3932 Out << FS;
3933 printSummary(*Summary);
3934 }
3935 Out << ")";
3936 }
3937 Out << ")";
3938 if (VI.hasName() && !VI.name().empty())
3939 Out << " ; guid = " << VI.getGUID();
3940 Out << "\n";
3941}
3942
3944 formatted_raw_ostream &Out) {
3945 if (Name.empty()) {
3946 Out << "<empty name> ";
3947 } else {
3948 unsigned char FirstC = static_cast<unsigned char>(Name[0]);
3949 if (isalpha(FirstC) || FirstC == '-' || FirstC == '$' || FirstC == '.' ||
3950 FirstC == '_')
3951 Out << FirstC;
3952 else
3953 Out << '\\' << hexdigit(FirstC >> 4) << hexdigit(FirstC & 0x0F);
3954 for (unsigned i = 1, e = Name.size(); i != e; ++i) {
3955 unsigned char C = Name[i];
3956 if (isalnum(C) || C == '-' || C == '$' || C == '.' || C == '_')
3957 Out << C;
3958 else
3959 Out << '\\' << hexdigit(C >> 4) << hexdigit(C & 0x0F);
3960 }
3961 }
3962}
3963
3964void AssemblyWriter::printNamedMDNode(const NamedMDNode *NMD) {
3965 Out << '!';
3966 printMetadataIdentifier(NMD->getName(), Out);
3967 Out << " = !{";
3968 ListSeparator LS;
3969 for (const MDNode *Op : NMD->operands()) {
3970 Out << LS;
3971 // Write DIExpressions inline.
3972 // FIXME: Ban DIExpressions in NamedMDNodes, they will serve no purpose.
3973 if (auto *Expr = dyn_cast<DIExpression>(Op)) {
3974 writeDIExpression(Out, Expr, AsmWriterContext::getEmpty());
3975 continue;
3976 }
3977
3978 int Slot = Machine.getMetadataSlot(Op);
3979 if (Slot == -1)
3980 Out << "<badref>";
3981 else
3982 Out << '!' << Slot;
3983 }
3984 Out << "}\n";
3985}
3986
3988 formatted_raw_ostream &Out) {
3989 switch (Vis) {
3991 case GlobalValue::HiddenVisibility: Out << "hidden "; break;
3992 case GlobalValue::ProtectedVisibility: Out << "protected "; break;
3993 }
3994}
3995
3996static void printDSOLocation(const GlobalValue &GV,
3997 formatted_raw_ostream &Out) {
3998 if (GV.isDSOLocal() && !GV.isImplicitDSOLocal())
3999 Out << "dso_local ";
4000}
4001
4003 formatted_raw_ostream &Out) {
4004 switch (SCT) {
4006 case GlobalValue::DLLImportStorageClass: Out << "dllimport "; break;
4007 case GlobalValue::DLLExportStorageClass: Out << "dllexport "; break;
4008 }
4009}
4010
4012 formatted_raw_ostream &Out) {
4013 switch (TLM) {
4015 break;
4017 Out << "thread_local ";
4018 break;
4020 Out << "thread_local(localdynamic) ";
4021 break;
4023 Out << "thread_local(initialexec) ";
4024 break;
4026 Out << "thread_local(localexec) ";
4027 break;
4028 }
4029}
4030
4032 switch (UA) {
4034 return "";
4036 return "local_unnamed_addr";
4038 return "unnamed_addr";
4039 }
4040 llvm_unreachable("Unknown UnnamedAddr");
4041}
4042
4044 const GlobalObject &GO) {
4045 const Comdat *C = GO.getComdat();
4046 if (!C)
4047 return;
4048
4049 if (isa<GlobalVariable>(GO))
4050 Out << ',';
4051 Out << " comdat";
4052
4053 if (GO.getName() == C->getName())
4054 return;
4055
4056 Out << '(';
4057 printLLVMName(Out, C->getName(), ComdatPrefix);
4058 Out << ')';
4059}
4060
4061void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
4062 if (GV->isMaterializable())
4063 Out << "; Materializable\n";
4064
4065 AsmWriterContext WriterCtx(&TypePrinter, &Machine, GV->getParent());
4066 writeAsOperandInternal(Out, GV, WriterCtx);
4067 Out << " = ";
4068
4069 if (!GV->hasInitializer() && GV->hasExternalLinkage())
4070 Out << "external ";
4071
4072 Out << getLinkageNameWithSpace(GV->getLinkage());
4073 printDSOLocation(*GV, Out);
4074 printVisibility(GV->getVisibility(), Out);
4077 StringRef UA = getUnnamedAddrEncoding(GV->getUnnamedAddr());
4078 if (!UA.empty())
4079 Out << UA << ' ';
4080
4082 /*Prefix=*/"", /*Suffix=*/" ");
4083 if (GV->isExternallyInitialized()) Out << "externally_initialized ";
4084 Out << (GV->isConstant() ? "constant " : "global ");
4085 TypePrinter.print(GV->getValueType(), Out);
4086
4087 if (GV->hasInitializer()) {
4088 Out << ' ';
4089 writeOperand(GV->getInitializer(), false);
4090 }
4091
4092 if (GV->hasSection()) {
4093 Out << ", section \"";
4094 printEscapedString(GV->getSection(), Out);
4095 Out << '"';
4096 }
4097 if (GV->hasPartition()) {
4098 Out << ", partition \"";
4099 printEscapedString(GV->getPartition(), Out);
4100 Out << '"';
4101 }
4102 if (auto CM = GV->getCodeModel()) {
4103 Out << ", code_model \"";
4104 switch (*CM) {
4105 case CodeModel::Tiny:
4106 Out << "tiny";
4107 break;
4108 case CodeModel::Small:
4109 Out << "small";
4110 break;
4111 case CodeModel::Kernel:
4112 Out << "kernel";
4113 break;
4114 case CodeModel::Medium:
4115 Out << "medium";
4116 break;
4117 case CodeModel::Large:
4118 Out << "large";
4119 break;
4120 }
4121 Out << '"';
4122 }
4123
4124 using SanitizerMetadata = llvm::GlobalValue::SanitizerMetadata;
4125 if (GV->hasSanitizerMetadata()) {
4127 if (MD.NoAddress)
4128 Out << ", no_sanitize_address";
4129 if (MD.NoHWAddress)
4130 Out << ", no_sanitize_hwaddress";
4131 if (MD.Memtag)
4132 Out << ", sanitize_memtag";
4133 if (MD.IsDynInit)
4134 Out << ", sanitize_address_dyninit";
4135 }
4136
4137 maybePrintComdat(Out, *GV);
4138 if (MaybeAlign A = GV->getAlign())
4139 Out << ", align " << A->value();
4140
4142 GV->getAllMetadata(MDs);
4143 printMetadataAttachments(MDs, ", ");
4144
4145 auto Attrs = GV->getAttributes();
4146 if (Attrs.hasAttributes())
4147 Out << " #" << Machine.getAttributeGroupSlot(Attrs);
4148
4149 printInfoComment(*GV, GV->isMaterializable());
4150}
4151
4152void AssemblyWriter::printAlias(const GlobalAlias *GA) {
4153 if (GA->isMaterializable())
4154 Out << "; Materializable\n";
4155
4156 AsmWriterContext WriterCtx(&TypePrinter, &Machine, GA->getParent());
4157 writeAsOperandInternal(Out, GA, WriterCtx);
4158 Out << " = ";
4159
4160 Out << getLinkageNameWithSpace(GA->getLinkage());
4161 printDSOLocation(*GA, Out);
4162 printVisibility(GA->getVisibility(), Out);
4165 StringRef UA = getUnnamedAddrEncoding(GA->getUnnamedAddr());
4166 if (!UA.empty())
4167 Out << UA << ' ';
4168
4169 Out << "alias ";
4170
4171 TypePrinter.print(GA->getValueType(), Out);
4172 Out << ", ";
4173
4174 if (const Constant *Aliasee = GA->getAliasee()) {
4175 writeOperand(Aliasee, !isa<ConstantExpr>(Aliasee));
4176 } else {
4177 TypePrinter.print(GA->getType(), Out);
4178 Out << " <<NULL ALIASEE>>";
4179 }
4180
4181 if (GA->hasPartition()) {
4182 Out << ", partition \"";
4183 printEscapedString(GA->getPartition(), Out);
4184 Out << '"';
4185 }
4186
4187 printInfoComment(*GA, GA->isMaterializable());
4188 Out << '\n';
4189}
4190
4191void AssemblyWriter::printIFunc(const GlobalIFunc *GI) {
4192 if (GI->isMaterializable())
4193 Out << "; Materializable\n";
4194
4195 AsmWriterContext WriterCtx(&TypePrinter, &Machine, GI->getParent());
4196 writeAsOperandInternal(Out, GI, WriterCtx);
4197 Out << " = ";
4198
4199 Out << getLinkageNameWithSpace(GI->getLinkage());
4200 printDSOLocation(*GI, Out);
4201 printVisibility(GI->getVisibility(), Out);
4202
4203 Out << "ifunc ";
4204
4205 TypePrinter.print(GI->getValueType(), Out);
4206 Out << ", ";
4207
4208 if (const Constant *Resolver = GI->getResolver()) {
4209 writeOperand(Resolver, !isa<ConstantExpr>(Resolver));
4210 } else {
4211 TypePrinter.print(GI->getType(), Out);
4212 Out << " <<NULL RESOLVER>>";
4213 }
4214
4215 if (GI->hasPartition()) {
4216 Out << ", partition \"";
4217 printEscapedString(GI->getPartition(), Out);
4218 Out << '"';
4219 }
4221 GI->getAllMetadata(MDs);
4222 if (!MDs.empty()) {
4223 printMetadataAttachments(MDs, ", ");
4224 }
4225
4226 printInfoComment(*GI, GI->isMaterializable());
4227 Out << '\n';
4228}
4229
4230void AssemblyWriter::printComdat(const Comdat *C) {
4231 C->print(Out);
4232}
4233
4234void AssemblyWriter::printTypeIdentities() {
4235 if (TypePrinter.empty())
4236 return;
4237
4238 Out << '\n';
4239
4240 // Emit all numbered types.
4241 auto &NumberedTypes = TypePrinter.getNumberedTypes();
4242 for (unsigned I = 0, E = NumberedTypes.size(); I != E; ++I) {
4243 Out << '%' << I << " = type ";
4244
4245 // Make sure we print out at least one level of the type structure, so
4246 // that we do not get %2 = type %2
4247 TypePrinter.printStructBody(NumberedTypes[I], Out);
4248 Out << '\n';
4249 }
4250
4251 auto &NamedTypes = TypePrinter.getNamedTypes();
4252 for (StructType *NamedType : NamedTypes) {
4253 printLLVMName(Out, NamedType->getName(), LocalPrefix);
4254 Out << " = type ";
4255
4256 // Make sure we print out at least one level of the type structure, so
4257 // that we do not get %FILE = type %FILE
4258 TypePrinter.printStructBody(NamedType, Out);
4259 Out << '\n';
4260 }
4261}
4262
4263/// printFunction - Print all aspects of a function.
4264void AssemblyWriter::printFunction(const Function *F) {
4265 if (F->isMaterializable())
4266 Out << "; Materializable\n";
4267 else if (AnnotationWriter)
4268 AnnotationWriter->emitFunctionAnnot(F, Out);
4269
4270 const AttributeList &Attrs = F->getAttributes();
4271 if (Attrs.hasFnAttrs()) {
4272 AttributeSet AS = Attrs.getFnAttrs();
4273 std::string AttrStr;
4274
4275 for (const Attribute &Attr : AS) {
4276 if (!Attr.isStringAttribute()) {
4277 if (!AttrStr.empty()) AttrStr += ' ';
4278 AttrStr += Attr.getAsString();
4279 }
4280 }
4281
4282 if (!AttrStr.empty())
4283 Out << "; Function Attrs: " << AttrStr << '\n';
4284 }
4285
4286 if (F->isIntrinsic() && F->getIntrinsicID() == Intrinsic::not_intrinsic)
4287 Out << "; Unknown intrinsic\n";
4288
4289 Machine.incorporateFunction(F);
4290
4291 if (F->isDeclaration()) {
4292 Out << "declare";
4294 F->getAllMetadata(MDs);
4295 printMetadataAttachments(MDs, " ");
4296 Out << ' ';
4297 } else
4298 Out << "define ";
4299
4300 Out << getLinkageNameWithSpace(F->getLinkage());
4301 printDSOLocation(*F, Out);
4302 printVisibility(F->getVisibility(), Out);
4303 printDLLStorageClass(F->getDLLStorageClass(), Out);
4304
4305 // Print the calling convention.
4306 if (F->getCallingConv() != CallingConv::C) {
4307 printCallingConv(F->getCallingConv(), Out);
4308 Out << " ";
4309 }
4310
4311 FunctionType *FT = F->getFunctionType();
4312 if (Attrs.hasRetAttrs())
4313 Out << Attrs.getAsString(AttributeList::ReturnIndex) << ' ';
4314 TypePrinter.print(F->getReturnType(), Out);
4315 AsmWriterContext WriterCtx(&TypePrinter, &Machine, F->getParent());
4316 Out << ' ';
4317 writeAsOperandInternal(Out, F, WriterCtx);
4318 Out << '(';
4319
4320 // Loop over the arguments, printing them...
4321 if (F->isDeclaration() && !IsForDebug) {
4322 // We're only interested in the type here - don't print argument names.
4323 ListSeparator LS;
4324 for (unsigned I = 0, E = FT->getNumParams(); I != E; ++I) {
4325 Out << LS;
4326 // Output type.
4327 TypePrinter.print(FT->getParamType(I), Out);
4328
4329 AttributeSet ArgAttrs = Attrs.getParamAttrs(I);
4330 if (ArgAttrs.hasAttributes()) {
4331 Out << ' ';
4332 writeAttributeSet(ArgAttrs);
4333 }
4334 }
4335 } else {
4336 // The arguments are meaningful here, print them in detail.
4337 ListSeparator LS;
4338 for (const Argument &Arg : F->args()) {
4339 Out << LS;
4340 printArgument(&Arg, Attrs.getParamAttrs(Arg.getArgNo()));
4341 }
4342 }
4343
4344 // Finish printing arguments...
4345 if (FT->isVarArg()) {
4346 if (FT->getNumParams()) Out << ", ";
4347 Out << "..."; // Output varargs portion of signature!
4348 }
4349 Out << ')';
4350 StringRef UA = getUnnamedAddrEncoding(F->getUnnamedAddr());
4351 if (!UA.empty())
4352 Out << ' ' << UA;
4353 // We print the function address space if it is non-zero or if we are writing
4354 // a module with a non-zero program address space or if there is no valid
4355 // Module* so that the file can be parsed without the datalayout string.
4356 const Module *Mod = F->getParent();
4357 bool ForcePrintAddressSpace =
4358 !Mod || Mod->getDataLayout().getProgramAddressSpace() != 0;
4359 printAddressSpace(Mod, F->getAddressSpace(), Out, /*Prefix=*/" ",
4360 /*Suffix=*/"", ForcePrintAddressSpace);
4361 if (Attrs.hasFnAttrs())
4362 Out << " #" << Machine.getAttributeGroupSlot(Attrs.getFnAttrs());
4363 if (F->hasSection()) {
4364 Out << " section \"";
4365 printEscapedString(F->getSection(), Out);
4366 Out << '"';
4367 }
4368 if (F->hasPartition()) {
4369 Out << " partition \"";
4370 printEscapedString(F->getPartition(), Out);
4371 Out << '"';
4372 }
4373 maybePrintComdat(Out, *F);
4374 if (MaybeAlign A = F->getAlign())
4375 Out << " align " << A->value();
4376 if (MaybeAlign A = F->getPreferredAlignment())
4377 Out << " prefalign(" << A->value() << ')';
4378 if (F->hasGC())
4379 Out << " gc \"" << F->getGC() << '"';
4380 if (F->hasPrefixData()) {
4381 Out << " prefix ";
4382 writeOperand(F->getPrefixData(), true);
4383 }
4384 if (F->hasPrologueData()) {
4385 Out << " prologue ";
4386 writeOperand(F->getPrologueData(), true);
4387 }
4388 if (F->hasPersonalityFn()) {
4389 Out << " personality ";
4390 writeOperand(F->getPersonalityFn(), /*PrintType=*/true);
4391 }
4392
4393 if (Opts.print_prof_data) {
4394 if (auto *MDProf = F->getMetadata(LLVMContext::MD_prof)) {
4395 Out << " ";
4396 MDProf->print(Out, TheModule, /*IsForDebug=*/true);
4397 }
4398 }
4399
4400 if (F->isDeclaration()) {
4401 Out << '\n';
4402 } else {
4404 F->getAllMetadata(MDs);
4405 printMetadataAttachments(MDs, " ");
4406
4407 Out << " {";
4408 // Output all of the function's basic blocks.
4409 for (const BasicBlock &BB : *F)
4410 printBasicBlock(&BB);
4411
4412 // Output the function's use-lists.
4413 printUseLists(F);
4414
4415 Out << "}\n";
4416 }
4417
4418 Machine.purgeFunction();
4419}
4420
4421/// printArgument - This member is called for every argument that is passed into
4422/// the function. Simply print it out
4423void AssemblyWriter::printArgument(const Argument *Arg, AttributeSet Attrs) {
4424 // Output type...
4425 TypePrinter.print(Arg->getType(), Out);
4426
4427 // Output parameter attributes list
4428 if (Attrs.hasAttributes()) {
4429 Out << ' ';
4430 writeAttributeSet(Attrs);
4431 }
4432
4433 // Output name, if available...
4434 if (Arg->hasName()) {
4435 Out << ' ';
4436 printLLVMName(Out, Arg);
4437 } else {
4438 int Slot = Machine.getLocalSlot(Arg);
4439 assert(Slot != -1 && "expect argument in function here");
4440 Out << " %" << Slot;
4441 }
4442}
4443
4444/// printBasicBlock - This member is called for each basic block in a method.
4445void AssemblyWriter::printBasicBlock(const BasicBlock *BB) {
4446 bool IsEntryBlock = BB->getParent() && BB->isEntryBlock();
4447 if (BB->hasName()) { // Print out the label if it exists...
4448 Out << "\n";
4449 printLLVMName(Out, BB->getName(), LabelPrefix);
4450 Out << ':';
4451 } else if (!IsEntryBlock) {
4452 Out << "\n";
4453 int Slot = Machine.getLocalSlot(BB);
4454 if (Slot != -1)
4455 Out << Slot << ":";
4456 else
4457 Out << "<badref>:";
4458 }
4459
4460 if (!IsEntryBlock) {
4461 // Output predecessors for the block.
4462 Out.PadToColumn(50);
4463 Out << ";";
4464 if (pred_empty(BB)) {
4465 Out << " No predecessors!";
4466 } else {
4467 Out << " preds = ";
4468 ListSeparator LS;
4469 for (const BasicBlock *Pred : predecessors(BB)) {
4470 Out << LS;
4471 writeOperand(Pred, false);
4472 }
4473 }
4474 }
4475
4476 Out << "\n";
4477
4478 if (AnnotationWriter) AnnotationWriter->emitBasicBlockStartAnnot(BB, Out);
4479
4480 // Output all of the instructions in the basic block...
4481 for (const Instruction &I : *BB) {
4482 for (const DbgRecord &DR : I.getDbgRecordRange())
4483 printDbgRecordLine(DR);
4484 printInstructionLine(I);
4485 }
4486
4487 if (AnnotationWriter) AnnotationWriter->emitBasicBlockEndAnnot(BB, Out);
4488}
4489
4490/// printInstructionLine - Print an instruction and a newline character.
4491void AssemblyWriter::printInstructionLine(const Instruction &I) {
4492 printInstruction(I);
4493 Out << '\n';
4494}
4495
4496/// printGCRelocateComment - print comment after call to the gc.relocate
4497/// intrinsic indicating base and derived pointer names.
4498void AssemblyWriter::printGCRelocateComment(const GCRelocateInst &Relocate) {
4499 Out << " ; (";
4500 if (Value *BasePtr = Relocate.getBasePtr())
4501 writeOperand(BasePtr, false);
4502 else
4503 Out << "invalid";
4504 Out << ", ";
4505 if (Value *DerivedPtr = Relocate.getDerivedPtr())
4506 writeOperand(DerivedPtr, false);
4507 else
4508 Out << "invalid";
4509 Out << ")";
4510}
4511
4512/// printInfoComment - Print a little comment after the instruction indicating
4513/// which slot it occupies.
4514void AssemblyWriter::printInfoComment(const Value &V, bool isMaterializable) {
4515 if (const auto *Relocate = dyn_cast<GCRelocateInst>(&V))
4516 printGCRelocateComment(*Relocate);
4517
4518 if (AnnotationWriter && !isMaterializable)
4519 AnnotationWriter->printInfoComment(V, Out);
4520
4521 if (Opts.print_inst_debug_locs) {
4522 if (auto *I = dyn_cast<Instruction>(&V)) {
4523 if (I->getDebugLoc()) {
4524 Out << " ; ";
4525 I->getDebugLoc().print(Out);
4526 }
4527 }
4528 }
4529 if (Opts.print_prof_data) {
4530 if (auto *I = dyn_cast<Instruction>(&V)) {
4531 if (auto *MD = I->getMetadata(LLVMContext::MD_prof)) {
4532 Out << " ; ";
4533 MD->print(Out, TheModule, /*IsForDebug=*/true);
4534 }
4535 }
4536 }
4537
4538 if (Opts.print_inst_addrs)
4539 Out << " ; " << &V;
4540}
4541
4542static void maybePrintCallAddrSpace(const Value *Operand, const Instruction *I,
4543 raw_ostream &Out) {
4544 if (Operand == nullptr) {
4545 Out << " <cannot get addrspace!>";
4546 return;
4547 }
4548
4549 // We print the address space of the call if it is non-zero.
4550 // We also print it if it is zero but not equal to the program address space
4551 // or if we can't find a valid Module* to make it possible to parse
4552 // the resulting file even without a datalayout string.
4553 unsigned CallAddrSpace = Operand->getType()->getPointerAddressSpace();
4554 const Module *Mod = getModuleFromVal(I);
4555 bool ForcePrintAddrSpace =
4556 !Mod || Mod->getDataLayout().getProgramAddressSpace() != 0;
4557 printAddressSpace(Mod, CallAddrSpace, Out, /*Prefix=*/" ", /*Suffix=*/"",
4558 ForcePrintAddrSpace);
4559}
4560
4561// This member is called for each Instruction in a function..
4562void AssemblyWriter::printInstruction(const Instruction &I) {
4563 if (AnnotationWriter) AnnotationWriter->emitInstructionAnnot(&I, Out);
4564
4565 // Print out indentation for an instruction.
4566 Out << " ";
4567
4568 // Print out name if it exists...
4569 if (I.hasName()) {
4570 printLLVMName(Out, &I);
4571 Out << " = ";
4572 } else if (!I.getType()->isVoidTy()) {
4573 // Print out the def slot taken.
4574 int SlotNum = Machine.getLocalSlot(&I);
4575 if (SlotNum == -1)
4576 Out << "<badref> = ";
4577 else
4578 Out << '%' << SlotNum << " = ";
4579 }
4580
4581 if (const auto *CI = dyn_cast<CallInst>(&I)) {
4582 if (CI->isMustTailCall())
4583 Out << "musttail ";
4584 else if (CI->isTailCall())
4585 Out << "tail ";
4586 else if (CI->isNoTailCall())
4587 Out << "notail ";
4588 }
4589
4590 // Print out the opcode...
4591 Out << I.getOpcodeName();
4592
4593 // If this is an atomic load or store, print out the atomic marker.
4594 if ((isa<LoadInst>(I) && cast<LoadInst>(I).isAtomic()) ||
4596 Out << " atomic";
4597
4599 Out << " weak";
4600
4601 // If this is a volatile operation, print out the volatile marker.
4602 if ((isa<LoadInst>(I) && cast<LoadInst>(I).isVolatile()) ||
4603 (isa<StoreInst>(I) && cast<StoreInst>(I).isVolatile()) ||
4604 (isa<AtomicCmpXchgInst>(I) && cast<AtomicCmpXchgInst>(I).isVolatile()) ||
4605 (isa<AtomicRMWInst>(I) && cast<AtomicRMWInst>(I).isVolatile()))
4606 Out << " volatile";
4607
4608 // Print the elementwise marker for atomic loads and stores.
4611 Out << " elementwise";
4612
4613 // Print out optimization information.
4614 writeOptimizationInfo(Out, &I);
4615
4616 // Print out the compare instruction predicates
4617 if (const auto *CI = dyn_cast<CmpInst>(&I))
4618 Out << ' ' << CI->getPredicate();
4619
4620 // Print out the atomicrmw operation
4621 if (const auto *RMWI = dyn_cast<AtomicRMWInst>(&I)) {
4622 if (RMWI->isElementwise())
4623 Out << " elementwise";
4624 Out << ' ' << AtomicRMWInst::getOperationName(RMWI->getOperation());
4625 }
4626
4627 // Print out the type of the operands...
4628 const Value *Operand = I.getNumOperands() ? I.getOperand(0) : nullptr;
4629
4630 // Special case conditional branches to swizzle the condition out to the front
4631 if (const auto *BI = dyn_cast<CondBrInst>(&I)) {
4632 Out << ' ';
4633 writeOperand(BI->getCondition(), true);
4634 Out << ", ";
4635 writeOperand(BI->getSuccessor(0), true);
4636 Out << ", ";
4637 writeOperand(BI->getSuccessor(1), true);
4638 } else if (isa<SwitchInst>(I)) {
4639 const SwitchInst& SI(cast<SwitchInst>(I));
4640 // Special case switch instruction to get formatting nice and correct.
4641 Out << ' ';
4642 writeOperand(SI.getCondition(), true);
4643 Out << ", ";
4644 writeOperand(SI.getDefaultDest(), true);
4645 Out << " [";
4646 for (auto Case : SI.cases()) {
4647 Out << "\n ";
4648 writeOperand(Case.getCaseValue(), true);
4649 Out << ", ";
4650 writeOperand(Case.getCaseSuccessor(), true);
4651 }
4652 Out << "\n ]";
4653 } else if (isa<IndirectBrInst>(I)) {
4654 // Special case indirectbr instruction to get formatting nice and correct.
4655 Out << ' ';
4656 writeOperand(Operand, true);
4657 Out << ", [";
4658
4659 ListSeparator LS;
4660 for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i) {
4661 Out << LS;
4662 writeOperand(I.getOperand(i), true);
4663 }
4664 Out << ']';
4665 } else if (const auto *PN = dyn_cast<PHINode>(&I)) {
4666 Out << ' ';
4667 TypePrinter.print(I.getType(), Out);
4668 Out << ' ';
4669
4670 ListSeparator LS;
4671 for (const auto &[V, Block] :
4672 zip_equal(PN->incoming_values(), PN->blocks())) {
4673 Out << LS << "[ ";
4674 writeOperand(V, false);
4675 Out << ", ";
4676 writeOperand(Block, false);
4677 Out << " ]";
4678 }
4679 } else if (const auto *EVI = dyn_cast<ExtractValueInst>(&I)) {
4680 Out << ' ';
4681 writeOperand(I.getOperand(0), true);
4682 Out << ", ";
4683 Out << llvm::interleaved(EVI->indices());
4684 } else if (const auto *IVI = dyn_cast<InsertValueInst>(&I)) {
4685 Out << ' ';
4686 writeOperand(I.getOperand(0), true); Out << ", ";
4687 writeOperand(I.getOperand(1), true);
4688 Out << ", ";
4689 Out << llvm::interleaved(IVI->indices());
4690 } else if (const auto *LPI = dyn_cast<LandingPadInst>(&I)) {
4691 Out << ' ';
4692 TypePrinter.print(I.getType(), Out);
4693 if (LPI->isCleanup() || LPI->getNumClauses() != 0)
4694 Out << '\n';
4695
4696 if (LPI->isCleanup())
4697 Out << " cleanup";
4698
4699 for (unsigned i = 0, e = LPI->getNumClauses(); i != e; ++i) {
4700 if (i != 0 || LPI->isCleanup()) Out << "\n";
4701 if (LPI->isCatch(i))
4702 Out << " catch ";
4703 else
4704 Out << " filter ";
4705
4706 writeOperand(LPI->getClause(i), true);
4707 }
4708 } else if (const auto *CatchSwitch = dyn_cast<CatchSwitchInst>(&I)) {
4709 Out << " within ";
4710 writeOperand(CatchSwitch->getParentPad(), /*PrintType=*/false);
4711 Out << " [";
4712 ListSeparator LS;
4713 for (const BasicBlock *PadBB : CatchSwitch->handlers()) {
4714 Out << LS;
4715 writeOperand(PadBB, /*PrintType=*/true);
4716 }
4717 Out << "] unwind ";
4718 if (const BasicBlock *UnwindDest = CatchSwitch->getUnwindDest())
4719 writeOperand(UnwindDest, /*PrintType=*/true);
4720 else
4721 Out << "to caller";
4722 } else if (const auto *FPI = dyn_cast<FuncletPadInst>(&I)) {
4723 Out << " within ";
4724 writeOperand(FPI->getParentPad(), /*PrintType=*/false);
4725 Out << " [";
4726 ListSeparator LS;
4727 for (const Value *Op : FPI->arg_operands()) {
4728 Out << LS;
4729 writeOperand(Op, /*PrintType=*/true);
4730 }
4731 Out << ']';
4732 } else if (isa<ReturnInst>(I) && !Operand) {
4733 Out << " void";
4734 } else if (const auto *CRI = dyn_cast<CatchReturnInst>(&I)) {
4735 Out << " from ";
4736 writeOperand(CRI->getOperand(0), /*PrintType=*/false);
4737
4738 Out << " to ";
4739 writeOperand(CRI->getOperand(1), /*PrintType=*/true);
4740 } else if (const auto *CRI = dyn_cast<CleanupReturnInst>(&I)) {
4741 Out << " from ";
4742 writeOperand(CRI->getOperand(0), /*PrintType=*/false);
4743
4744 Out << " unwind ";
4745 if (CRI->hasUnwindDest())
4746 writeOperand(CRI->getOperand(1), /*PrintType=*/true);
4747 else
4748 Out << "to caller";
4749 } else if (const auto *CI = dyn_cast<CallInst>(&I)) {
4750 // Print the calling convention being used.
4751 if (CI->getCallingConv() != CallingConv::C) {
4752 Out << " ";
4753 printCallingConv(CI->getCallingConv(), Out);
4754 }
4755
4756 Operand = CI->getCalledOperand();
4757 FunctionType *FTy = CI->getFunctionType();
4758 Type *RetTy = FTy->getReturnType();
4759 const AttributeList &PAL = CI->getAttributes();
4760
4761 if (PAL.hasRetAttrs())
4762 Out << ' ' << PAL.getAsString(AttributeList::ReturnIndex);
4763
4764 // Only print addrspace(N) if necessary:
4765 maybePrintCallAddrSpace(Operand, &I, Out);
4766
4767 // If possible, print out the short form of the call instruction. We can
4768 // only do this if the first argument is a pointer to a nonvararg function,
4769 // and if the return type is not a pointer to a function.
4770 Out << ' ';
4771 TypePrinter.print(FTy->isVarArg() ? FTy : RetTy, Out);
4772 Out << ' ';
4773 writeOperand(Operand, false);
4774 Out << '(';
4775 bool HasPrettyPrintedArgs =
4776 isa<IntrinsicInst>(CI) &&
4777 Intrinsic::hasPrettyPrintedArgs(CI->getIntrinsicID());
4778
4779 ListSeparator LS;
4780 Function *CalledFunc = CI->getCalledFunction();
4781 auto PrintArgComment = [&](unsigned ArgNo) {
4782 const auto *ConstArg = dyn_cast<Constant>(CI->getArgOperand(ArgNo));
4783 if (!ConstArg || !CalledFunc)
4784 return;
4785 std::string ArgComment;
4786 raw_string_ostream ArgCommentStream(ArgComment);
4787 Intrinsic::ID IID = CalledFunc->getIntrinsicID();
4788 Intrinsic::printImmArg(IID, ArgNo, ArgCommentStream, ConstArg);
4789 if (ArgComment.empty())
4790 return;
4791 Out << "/* " << ArgComment << " */ ";
4792 };
4793 if (HasPrettyPrintedArgs) {
4794 for (unsigned ArgNo = 0, NumArgs = CI->arg_size(); ArgNo < NumArgs;
4795 ++ArgNo) {
4796 Out << LS;
4797 PrintArgComment(ArgNo);
4798 writeParamOperand(CI->getArgOperand(ArgNo), PAL.getParamAttrs(ArgNo));
4799 }
4800 } else {
4801 for (unsigned ArgNo = 0, NumArgs = CI->arg_size(); ArgNo < NumArgs;
4802 ++ArgNo) {
4803 Out << LS;
4804 writeParamOperand(CI->getArgOperand(ArgNo), PAL.getParamAttrs(ArgNo));
4805 }
4806 }
4807 // Emit an ellipsis if this is a musttail call in a vararg function. This
4808 // is only to aid readability, musttail calls forward varargs by default.
4809 if (CI->isMustTailCall() && CI->getParent() &&
4810 CI->getParent()->getParent() &&
4811 CI->getParent()->getParent()->isVarArg()) {
4812 if (CI->arg_size() > 0)
4813 Out << ", ";
4814 Out << "...";
4815 }
4816
4817 Out << ')';
4818 if (PAL.hasFnAttrs())
4819 Out << " #" << Machine.getAttributeGroupSlot(PAL.getFnAttrs());
4820
4821 writeOperandBundles(CI);
4822 } else if (const auto *II = dyn_cast<InvokeInst>(&I)) {
4823 Operand = II->getCalledOperand();
4824 FunctionType *FTy = II->getFunctionType();
4825 Type *RetTy = FTy->getReturnType();
4826 const AttributeList &PAL = II->getAttributes();
4827
4828 // Print the calling convention being used.
4829 if (II->getCallingConv() != CallingConv::C) {
4830 Out << " ";
4831 printCallingConv(II->getCallingConv(), Out);
4832 }
4833
4834 if (PAL.hasRetAttrs())
4835 Out << ' ' << PAL.getAsString(AttributeList::ReturnIndex);
4836
4837 // Only print addrspace(N) if necessary:
4838 maybePrintCallAddrSpace(Operand, &I, Out);
4839
4840 // If possible, print out the short form of the invoke instruction. We can
4841 // only do this if the first argument is a pointer to a nonvararg function,
4842 // and if the return type is not a pointer to a function.
4843 //
4844 Out << ' ';
4845 TypePrinter.print(FTy->isVarArg() ? FTy : RetTy, Out);
4846 Out << ' ';
4847 writeOperand(Operand, false);
4848 Out << '(';
4849 ListSeparator LS;
4850 for (unsigned op = 0, Eop = II->arg_size(); op < Eop; ++op) {
4851 Out << LS;
4852 writeParamOperand(II->getArgOperand(op), PAL.getParamAttrs(op));
4853 }
4854
4855 Out << ')';
4856 if (PAL.hasFnAttrs())
4857 Out << " #" << Machine.getAttributeGroupSlot(PAL.getFnAttrs());
4858
4859 writeOperandBundles(II);
4860
4861 Out << "\n to ";
4862 writeOperand(II->getNormalDest(), true);
4863 Out << " unwind ";
4864 writeOperand(II->getUnwindDest(), true);
4865 } else if (const auto *CBI = dyn_cast<CallBrInst>(&I)) {
4866 Operand = CBI->getCalledOperand();
4867 FunctionType *FTy = CBI->getFunctionType();
4868 Type *RetTy = FTy->getReturnType();
4869 const AttributeList &PAL = CBI->getAttributes();
4870
4871 // Print the calling convention being used.
4872 if (CBI->getCallingConv() != CallingConv::C) {
4873 Out << " ";
4874 printCallingConv(CBI->getCallingConv(), Out);
4875 }
4876
4877 if (PAL.hasRetAttrs())
4878 Out << ' ' << PAL.getAsString(AttributeList::ReturnIndex);
4879
4880 // If possible, print out the short form of the callbr instruction. We can
4881 // only do this if the first argument is a pointer to a nonvararg function,
4882 // and if the return type is not a pointer to a function.
4883 //
4884 Out << ' ';
4885 TypePrinter.print(FTy->isVarArg() ? FTy : RetTy, Out);
4886 Out << ' ';
4887 writeOperand(Operand, false);
4888 Out << '(';
4889 ListSeparator ArgLS;
4890 for (unsigned op = 0, Eop = CBI->arg_size(); op < Eop; ++op) {
4891 Out << ArgLS;
4892 writeParamOperand(CBI->getArgOperand(op), PAL.getParamAttrs(op));
4893 }
4894
4895 Out << ')';
4896 if (PAL.hasFnAttrs())
4897 Out << " #" << Machine.getAttributeGroupSlot(PAL.getFnAttrs());
4898
4899 writeOperandBundles(CBI);
4900
4901 Out << "\n to ";
4902 writeOperand(CBI->getDefaultDest(), true);
4903 Out << " [";
4904 ListSeparator DestLS;
4905 for (const BasicBlock *Dest : CBI->getIndirectDests()) {
4906 Out << DestLS;
4907 writeOperand(Dest, true);
4908 }
4909 Out << ']';
4910 } else if (const auto *AI = dyn_cast<AllocaInst>(&I)) {
4911 Out << ' ';
4912 if (AI->isUsedWithInAlloca())
4913 Out << "inalloca ";
4914 if (AI->isSwiftError())
4915 Out << "swifterror ";
4916 TypePrinter.print(AI->getAllocatedType(), Out);
4917
4918 // Explicitly write the array size if the code is broken, if it's an array
4919 // allocation, or if the type is not canonical for scalar allocations. The
4920 // latter case prevents the type from mutating when round-tripping through
4921 // assembly.
4922 if (!AI->getArraySize() || AI->isArrayAllocation() ||
4923 !AI->getArraySize()->getType()->isIntegerTy(32)) {
4924 Out << ", ";
4925 writeOperand(AI->getArraySize(), true);
4926 }
4927 if (MaybeAlign A = AI->getAlign()) {
4928 Out << ", align " << A->value();
4929 }
4930
4931 printAddressSpace(AI->getModule(), AI->getAddressSpace(), Out,
4932 /*Prefix=*/", ");
4933 } else if (isa<CastInst>(I)) {
4934 if (Operand) {
4935 Out << ' ';
4936 writeOperand(Operand, true); // Work with broken code
4937 }
4938 Out << " to ";
4939 TypePrinter.print(I.getType(), Out);
4940 } else if (isa<VAArgInst>(I)) {
4941 if (Operand) {
4942 Out << ' ';
4943 writeOperand(Operand, true); // Work with broken code
4944 }
4945 Out << ", ";
4946 TypePrinter.print(I.getType(), Out);
4947 } else if (Operand) { // Print the normal way.
4948 if (const auto *GEP = dyn_cast<GetElementPtrInst>(&I)) {
4949 Out << ' ';
4950 TypePrinter.print(GEP->getSourceElementType(), Out);
4951 Out << ',';
4952 } else if (isa<BitExtractInst>(I) || isa<LoadInst>(I)) {
4953 Out << ' ';
4954 TypePrinter.print(I.getType(), Out);
4955 Out << ',';
4956 }
4957
4958 // PrintAllTypes - Instructions who have operands of all the same type
4959 // omit the type from all but the first operand. If the instruction has
4960 // different type operands (for example br), then they are all printed.
4961 bool PrintAllTypes = false;
4962 Type *TheType = Operand->getType();
4963
4964 // Select, Store, ShuffleVector, CmpXchg and AtomicRMW always print all
4965 // types.
4969 PrintAllTypes = true;
4970 } else {
4971 for (unsigned i = 1, E = I.getNumOperands(); i != E; ++i) {
4972 Operand = I.getOperand(i);
4973 // note that Operand shouldn't be null, but the test helps make dump()
4974 // more tolerant of malformed IR
4975 if (Operand && Operand->getType() != TheType) {
4976 PrintAllTypes = true; // We have differing types! Print them all!
4977 break;
4978 }
4979 }
4980 }
4981
4982 if (!PrintAllTypes) {
4983 Out << ' ';
4984 TypePrinter.print(TheType, Out);
4985 }
4986
4987 Out << ' ';
4988 ListSeparator LS;
4989 for (const Value *Op : I.operands()) {
4990 Out << LS;
4991 writeOperand(Op, PrintAllTypes);
4992 }
4993 }
4994
4995 // Print atomic ordering/alignment for memory operations
4996 if (const auto *LI = dyn_cast<LoadInst>(&I)) {
4997 if (LI->isAtomic())
4998 writeAtomic(LI->getContext(), LI->getOrdering(), LI->getSyncScopeID());
4999 if (MaybeAlign A = LI->getAlign())
5000 Out << ", align " << A->value();
5001 } else if (const auto *SI = dyn_cast<StoreInst>(&I)) {
5002 if (SI->isAtomic())
5003 writeAtomic(SI->getContext(), SI->getOrdering(), SI->getSyncScopeID());
5004 if (MaybeAlign A = SI->getAlign())
5005 Out << ", align " << A->value();
5006 } else if (const auto *CXI = dyn_cast<AtomicCmpXchgInst>(&I)) {
5007 writeAtomicCmpXchg(CXI->getContext(), CXI->getSuccessOrdering(),
5008 CXI->getFailureOrdering(), CXI->getSyncScopeID());
5009 Out << ", align " << CXI->getAlign().value();
5010 } else if (const auto *RMWI = dyn_cast<AtomicRMWInst>(&I)) {
5011 writeAtomic(RMWI->getContext(), RMWI->getOrdering(),
5012 RMWI->getSyncScopeID());
5013 Out << ", align " << RMWI->getAlign().value();
5014 } else if (const auto *FI = dyn_cast<FenceInst>(&I)) {
5015 writeAtomic(FI->getContext(), FI->getOrdering(), FI->getSyncScopeID());
5016 } else if (const auto *SVI = dyn_cast<ShuffleVectorInst>(&I)) {
5017 printShuffleMask(Out, SVI->getType(), SVI->getShuffleMask());
5018 }
5019
5020 // Print Metadata info.
5022 I.getAllMetadata(InstMD);
5023 printMetadataAttachments(InstMD, ", ");
5024
5025 // Print a nice comment.
5026 printInfoComment(I);
5027}
5028
5029void AssemblyWriter::printDbgMarker(const DbgMarker &Marker) {
5030 // There's no formal representation of a DbgMarker -- print purely as a
5031 // debugging aid.
5032 for (const DbgRecord &DPR : Marker.StoredDbgRecords) {
5033 printDbgRecord(DPR);
5034 Out << "\n";
5035 }
5036
5037 Out << " DbgMarker -> { ";
5038 printInstruction(*Marker.MarkedInstr);
5039 Out << " }";
5040}
5041
5042void AssemblyWriter::printDbgRecord(const DbgRecord &DR) {
5043 if (auto *DVR = dyn_cast<DbgVariableRecord>(&DR))
5044 printDbgVariableRecord(*DVR);
5045 else if (auto *DLR = dyn_cast<DbgLabelRecord>(&DR))
5046 printDbgLabelRecord(*DLR);
5047 else
5048 llvm_unreachable("Unexpected DbgRecord kind");
5049}
5050
5051void AssemblyWriter::printDbgVariableRecord(const DbgVariableRecord &DVR) {
5052 auto WriterCtx = getContext();
5053 Out << "#dbg_";
5054 switch (DVR.getType()) {
5055 case DbgVariableRecord::LocationType::Value:
5056 Out << "value";
5057 break;
5058 case DbgVariableRecord::LocationType::Declare:
5059 Out << "declare";
5060 break;
5061 case DbgVariableRecord::LocationType::DeclareValue:
5062 Out << "declare_value";
5063 break;
5064 case DbgVariableRecord::LocationType::Assign:
5065 Out << "assign";
5066 break;
5067 default:
5069 "Tried to print a DbgVariableRecord with an invalid LocationType!");
5070 }
5071
5072 auto PrintOrNull = [&](Metadata *M) {
5073 if (!M)
5074 Out << "(null)";
5075 else
5076 writeAsOperandInternal(Out, M, WriterCtx, true);
5077 };
5078
5079 Out << "(";
5080 PrintOrNull(DVR.getRawLocation());
5081 Out << ", ";
5082 PrintOrNull(DVR.getRawVariable());
5083 Out << ", ";
5084 PrintOrNull(DVR.getRawExpression());
5085 Out << ", ";
5086 if (DVR.isDbgAssign()) {
5087 PrintOrNull(DVR.getRawAssignID());
5088 Out << ", ";
5089 PrintOrNull(DVR.getRawAddress());
5090 Out << ", ";
5091 PrintOrNull(DVR.getRawAddressExpression());
5092 Out << ", ";
5093 }
5094 PrintOrNull(DVR.getDebugLoc().getAsMDNode());
5095 Out << ")";
5096}
5097
5098/// printDbgRecordLine - Print a DbgRecord with indentation and a newline
5099/// character.
5100void AssemblyWriter::printDbgRecordLine(const DbgRecord &DR) {
5101 // Print lengthier indentation to bring out-of-line with instructions.
5102 Out << " ";
5103 printDbgRecord(DR);
5104 Out << '\n';
5105}
5106
5107void AssemblyWriter::printDbgLabelRecord(const DbgLabelRecord &Label) {
5108 auto WriterCtx = getContext();
5109 Out << "#dbg_label(";
5110 writeAsOperandInternal(Out, Label.getRawLabel(), WriterCtx, true);
5111 Out << ", ";
5112 writeAsOperandInternal(Out, Label.getDebugLoc(), WriterCtx, true);
5113 Out << ")";
5114}
5115
5116void AssemblyWriter::printMetadataAttachments(
5117 const SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs,
5118 StringRef Separator) {
5119 if (MDs.empty())
5120 return;
5121
5122 if (MDNames.empty())
5123 MDs[0].second->getContext().getMDKindNames(MDNames);
5124
5125 auto WriterCtx = getContext();
5126 for (const auto &I : MDs) {
5127 unsigned Kind = I.first;
5128 Out << Separator;
5129 if (Kind < MDNames.size()) {
5130 Out << "!";
5131 printMetadataIdentifier(MDNames[Kind], Out);
5132 } else
5133 Out << "!<unknown kind #" << Kind << ">";
5134 Out << ' ';
5135 writeAsOperandInternal(Out, I.second, WriterCtx);
5136 }
5137}
5138
5139void AssemblyWriter::writeMDNode(unsigned Slot, const MDNode *Node) {
5140 if (AnnotationWriter)
5141 AnnotationWriter->emitMDNodeAnnot(Node, Out);
5142
5143 Out << '!' << Slot << " = ";
5144 printMDNodeBody(Node);
5145 Out << "\n";
5146}
5147
5148void AssemblyWriter::writeAllMDNodes() {
5150 Nodes.reserve(Machine.mdn_size());
5151 for (auto &I : llvm::make_range(Machine.mdn_begin(), Machine.mdn_end()))
5152 Nodes.emplace_back(I.second, cast<MDNode>(I.first));
5153 llvm::sort(Nodes);
5154
5155 for (auto [Slot, Node] : Nodes)
5156 writeMDNode(Slot, Node);
5157}
5158
5159void AssemblyWriter::printMDNodeBody(const MDNode *Node) {
5160 auto WriterCtx = getContext();
5161 writeMDNodeBodyInternal(Out, Node, WriterCtx);
5162}
5163
5164void AssemblyWriter::writeAttribute(const Attribute &Attr, bool InAttrGroup) {
5165 if (!Attr.isTypeAttribute()) {
5166 Out << Attr.getAsString(InAttrGroup);
5167 return;
5168 }
5169
5170 Out << Attribute::getNameFromAttrKind(Attr.getKindAsEnum());
5171 if (Type *Ty = Attr.getValueAsType()) {
5172 Out << '(';
5173 TypePrinter.print(Ty, Out);
5174 Out << ')';
5175 }
5176}
5177
5178void AssemblyWriter::writeAttributeSet(const AttributeSet &AttrSet,
5179 bool InAttrGroup) {
5180 ListSeparator LS(" ");
5181 for (const auto &Attr : AttrSet) {
5182 Out << LS;
5183 writeAttribute(Attr, InAttrGroup);
5184 }
5185}
5186
5187void AssemblyWriter::writeAllAttributeGroups() {
5188 std::vector<std::pair<AttributeSet, unsigned>> asVec;
5189 asVec.resize(Machine.as_size());
5190
5191 for (auto &I : llvm::make_range(Machine.as_begin(), Machine.as_end()))
5192 asVec[I.second] = I;
5193
5194 for (const auto &I : asVec)
5195 Out << "attributes #" << I.second << " = { "
5196 << I.first.getAsString(true) << " }\n";
5197}
5198
5199void AssemblyWriter::printUseListOrder(const Value *V,
5200 ArrayRef<unsigned> Shuffle) {
5201 if (Machine.getFunction())
5202 Out << " ";
5203
5204 Out << "uselistorder ";
5205 writeOperand(V, true);
5206
5207 assert(Shuffle.size() >= 2 && "Shuffle too small");
5208 Out << ", { " << llvm::interleaved(Shuffle) << " }\n";
5209}
5210
5211void AssemblyWriter::printUseLists(const Function *F) {
5212 auto It = UseListOrders.find(F);
5213 if (It == UseListOrders.end())
5214 return;
5215
5216 Out << "\n; uselistorder directives\n";
5217 for (const auto &Pair : It->second)
5218 printUseListOrder(Pair.first, Pair.second);
5219}
5220
5221//===----------------------------------------------------------------------===//
5222// External Interface declarations
5223//===----------------------------------------------------------------------===//
5224
5226 bool ShouldPreserveUseListOrder, bool IsForDebug) const {
5227 SlotTracker SlotTable(this);
5228 formatted_raw_ostream OS(ROS);
5229 AssemblyWriter W(getIROptions(getContext()), OS, SlotTable, this->getParent(),
5230 AAW, IsForDebug, ShouldPreserveUseListOrder);
5231 W.printFunction(this);
5232}
5233
5235 bool ShouldPreserveUseListOrder,
5236 bool IsForDebug) const {
5237 SlotTracker SlotTable(this->getParent());
5238 formatted_raw_ostream OS(ROS);
5239 AssemblyWriter W(getIROptions(getContext()), OS, SlotTable, this->getModule(),
5240 AAW, IsForDebug, ShouldPreserveUseListOrder);
5241 W.printBasicBlock(this);
5242}
5243
5245 bool ShouldPreserveUseListOrder, bool IsForDebug) const {
5246 SlotTracker SlotTable(this, /*ShouldTrackMetadataDefinitions=*/true);
5247 formatted_raw_ostream OS(ROS);
5248 AssemblyWriter W(getIROptions(getContext()), OS, SlotTable, this, AAW,
5249 IsForDebug, ShouldPreserveUseListOrder);
5250 W.printModule(this);
5251}
5252
5253void NamedMDNode::print(raw_ostream &ROS, bool IsForDebug) const {
5254 SlotTracker SlotTable(getParent());
5255 formatted_raw_ostream OS(ROS);
5256 AssemblyWriter W(getOptions(getParent()), OS, SlotTable, getParent(), nullptr,
5257 IsForDebug);
5258 W.printNamedMDNode(this);
5259}
5260
5262 bool IsForDebug) const {
5263 std::optional<SlotTracker> LocalST;
5264 SlotTracker *SlotTable;
5265 if (auto *ST = MST.getMachine())
5266 SlotTable = ST;
5267 else {
5268 LocalST.emplace(getParent());
5269 SlotTable = &*LocalST;
5270 }
5271
5272 formatted_raw_ostream OS(ROS);
5273 AssemblyWriter W(getOptions(getParent()), OS, *SlotTable, getParent(),
5274 nullptr, IsForDebug);
5275 W.printNamedMDNode(this);
5276}
5277
5278void Comdat::print(raw_ostream &ROS, bool /*IsForDebug*/) const {
5280 ROS << " = comdat ";
5281
5282 switch (getSelectionKind()) {
5283 case Comdat::Any:
5284 ROS << "any";
5285 break;
5286 case Comdat::ExactMatch:
5287 ROS << "exactmatch";
5288 break;
5289 case Comdat::Largest:
5290 ROS << "largest";
5291 break;
5293 ROS << "nodeduplicate";
5294 break;
5295 case Comdat::SameSize:
5296 ROS << "samesize";
5297 break;
5298 }
5299
5300 ROS << '\n';
5301}
5302
5303void Type::print(raw_ostream &OS, bool /*IsForDebug*/, bool NoDetails) const {
5304 TypePrinting TP;
5305 TP.print(const_cast<Type*>(this), OS);
5306
5307 if (NoDetails)
5308 return;
5309
5310 // If the type is a named struct type, print the body as well.
5311 if (auto *STy = dyn_cast<StructType>(const_cast<Type *>(this)))
5312 if (!STy->isLiteral()) {
5313 OS << " = type ";
5314 TP.printStructBody(STy, OS);
5315 }
5316}
5317
5318void DbgMarker::print(raw_ostream &ROS, bool IsForDebug) const {
5319
5321 print(ROS, MST, IsForDebug);
5322}
5323
5324void DbgVariableRecord::print(raw_ostream &ROS, bool IsForDebug) const {
5325
5327 print(ROS, MST, IsForDebug);
5328}
5329
5331 bool IsForDebug) const {
5332 formatted_raw_ostream OS(ROS);
5333 SlotTracker EmptySlotTable(static_cast<const Module *>(nullptr));
5334 SlotTracker &SlotTable =
5335 MST.getMachine() ? *MST.getMachine() : EmptySlotTable;
5336 const Function *F = getParent() ? getParent()->getParent() : nullptr;
5337 if (F)
5338 MST.incorporateFunction(*F);
5339 const Module *M = getModuleFromDPI(this);
5340 AssemblyWriter W(getOptions(M), OS, SlotTable, M, nullptr, IsForDebug);
5341 W.printDbgMarker(*this);
5342}
5343
5344void DbgLabelRecord::print(raw_ostream &ROS, bool IsForDebug) const {
5345
5347 print(ROS, MST, IsForDebug);
5348}
5349
5351 bool IsForDebug) const {
5352 formatted_raw_ostream OS(ROS);
5353 SlotTracker EmptySlotTable(static_cast<const Module *>(nullptr));
5354 SlotTracker &SlotTable =
5355 MST.getMachine() ? *MST.getMachine() : EmptySlotTable;
5356 const Function *F = Marker && Marker->getParent()
5357 ? Marker->getParent()->getParent()
5358 : nullptr;
5359 if (F)
5360 MST.incorporateFunction(*F);
5361 const Module *M = getModuleFromDPI(this);
5362 AssemblyWriter W(getOptions(M), OS, SlotTable, M, nullptr, IsForDebug);
5363 W.printDbgVariableRecord(*this);
5364}
5365
5367 bool IsForDebug) const {
5368 formatted_raw_ostream OS(ROS);
5369 SlotTracker EmptySlotTable(static_cast<const Module *>(nullptr));
5370 SlotTracker &SlotTable =
5371 MST.getMachine() ? *MST.getMachine() : EmptySlotTable;
5372 const Function *F =
5373 Marker->getParent() ? Marker->getParent()->getParent() : nullptr;
5374 if (F)
5375 MST.incorporateFunction(*F);
5376
5377 const Module *M = getModuleFromDPI(this);
5378 AssemblyWriter W(getOptions(M), OS, SlotTable, M, nullptr, IsForDebug);
5379 W.printDbgLabelRecord(*this);
5380}
5381
5382void Value::print(raw_ostream &ROS, bool IsForDebug) const {
5383 if (const auto *F = dyn_cast<Function>(this)) {
5384 F->print(ROS, nullptr, /*ShouldPreserveUseListOrder=*/false, IsForDebug);
5385 return;
5386 }
5387 if (const auto *BB = dyn_cast<BasicBlock>(this)) {
5388 BB->print(ROS, nullptr, /*ShouldPreserveUseListOrder=*/false, IsForDebug);
5389 return;
5390 }
5391
5393 print(ROS, MST, IsForDebug);
5394}
5395
5397 bool IsForDebug) const {
5398 formatted_raw_ostream OS(ROS);
5399 SlotTracker EmptySlotTable(static_cast<const Module *>(nullptr));
5400 SlotTracker &SlotTable =
5401 MST.getMachine() ? *MST.getMachine() : EmptySlotTable;
5402 auto IncorporateFunction = [&](const Function *F) {
5403 if (F)
5404 MST.incorporateFunction(*F);
5405 };
5406
5407 if (const auto *I = dyn_cast<Instruction>(this)) {
5408 IncorporateFunction(I->getParent() ? I->getParent()->getParent() : nullptr);
5409 AssemblyWriter W(getIROptions(getContext()), OS, SlotTable,
5410 getModuleFromVal(I), nullptr, IsForDebug);
5411 W.printInstruction(*I);
5412 } else if (const auto *BB = dyn_cast<BasicBlock>(this)) {
5413 IncorporateFunction(BB->getParent());
5414 AssemblyWriter W(getIROptions(getContext()), OS, SlotTable,
5415 getModuleFromVal(BB), nullptr, IsForDebug);
5416 W.printBasicBlock(BB);
5417 } else if (const auto *GV = dyn_cast<GlobalValue>(this)) {
5418 AssemblyWriter W(getIROptions(getContext()), OS, SlotTable, GV->getParent(),
5419 nullptr, IsForDebug);
5420 if (const auto *V = dyn_cast<GlobalVariable>(GV))
5421 W.printGlobal(V);
5422 else if (const auto *F = dyn_cast<Function>(GV))
5423 W.printFunction(F);
5424 else if (const auto *A = dyn_cast<GlobalAlias>(GV))
5425 W.printAlias(A);
5426 else if (const auto *I = dyn_cast<GlobalIFunc>(GV))
5427 W.printIFunc(I);
5428 else
5429 llvm_unreachable("Unknown GlobalValue to print out!");
5430 } else if (const auto *V = dyn_cast<MetadataAsValue>(this)) {
5431 V->getMetadata()->print(ROS, MST, getModuleFromVal(V));
5432 } else if (const auto *C = dyn_cast<Constant>(this)) {
5433 TypePrinting TypePrinter;
5434 TypePrinter.print(C->getType(), OS);
5435 OS << ' ';
5436 AsmWriterContext WriterCtx(&TypePrinter, MST.getMachine());
5437 writeConstantInternal(OS, C, WriterCtx);
5438 } else if (isa<InlineAsm>(this) || isa<Argument>(this)) {
5439 this->printAsOperand(OS, /* PrintType */ true, MST);
5440 } else {
5441 llvm_unreachable("Unknown value to print out!");
5442 }
5443}
5444
5445/// Print without a type, skipping the TypePrinting object.
5446///
5447/// \return \c true iff printing was successful.
5448static bool printWithoutType(const Value &V, raw_ostream &O,
5449 SlotTracker *Machine, const Module *M) {
5450 if (V.hasName() || isa<GlobalValue>(V) ||
5452 AsmWriterContext WriterCtx(nullptr, Machine, M);
5453 writeAsOperandInternal(O, &V, WriterCtx);
5454 return true;
5455 }
5456 return false;
5457}
5458
5459static void printAsOperandImpl(const Value &V, raw_ostream &O, bool PrintType,
5460 ModuleSlotTracker &MST) {
5461 TypePrinting TypePrinter(MST.getModule());
5462 AsmWriterContext WriterCtx(&TypePrinter, MST.getMachine(), MST.getModule());
5463 writeAsOperandInternal(O, &V, WriterCtx, PrintType);
5464}
5465
5466void Value::printAsOperand(raw_ostream &O, bool PrintType,
5467 const Module *M) const {
5468 if (!M)
5469 M = getModuleFromVal(this);
5470
5471 if (!PrintType)
5472 if (printWithoutType(*this, O, nullptr, M))
5473 return;
5474
5476 ModuleSlotTracker MST(Machine, M);
5477 printAsOperandImpl(*this, O, PrintType, MST);
5478}
5479
5480void Value::printAsOperand(raw_ostream &O, bool PrintType,
5481 ModuleSlotTracker &MST) const {
5482 if (!PrintType)
5483 if (printWithoutType(*this, O, MST.getMachine(), MST.getModule()))
5484 return;
5485
5486 printAsOperandImpl(*this, O, PrintType, MST);
5487}
5488
5489/// Recursive version of printMetadataImpl.
5490static void printMetadataImplRec(raw_ostream &ROS, const Metadata &MD,
5491 AsmWriterContext &WriterCtx) {
5492 formatted_raw_ostream OS(ROS);
5493 writeAsOperandInternal(OS, &MD, WriterCtx, /* FromValue */ true);
5494
5495 auto *N = dyn_cast<MDNode>(&MD);
5496 if (!N || isa<DIExpression>(MD))
5497 return;
5498
5499 OS << " = ";
5500 writeMDNodeBodyInternal(OS, N, WriterCtx);
5501}
5502
5503namespace {
5504struct MDTreeAsmWriterContext : public AsmWriterContext {
5505 unsigned Level;
5506 // {Level, Printed string}
5507 using EntryTy = std::pair<unsigned, std::string>;
5509
5510 // Used to break the cycle in case there is any.
5511 SmallPtrSet<const Metadata *, 4> Visited;
5512
5513 raw_ostream &MainOS;
5514
5515 MDTreeAsmWriterContext(TypePrinting *TP, SlotTracker *ST, const Module *M,
5516 const ModuleSlotTracker *MST, raw_ostream &OS,
5517 const Metadata *InitMD)
5518 : AsmWriterContext(TP, ST, M, MST), Level(0U), Visited({InitMD}),
5519 MainOS(OS) {}
5520
5521 void onWriteMetadataAsOperand(const Metadata *MD) override {
5522 if (!Visited.insert(MD).second)
5523 return;
5524
5525 std::string Str;
5526 raw_string_ostream SS(Str);
5527 ++Level;
5528 // A placeholder entry to memorize the correct
5529 // position in buffer.
5530 Buffer.emplace_back(std::make_pair(Level, ""));
5531 unsigned InsertIdx = Buffer.size() - 1;
5532
5533 printMetadataImplRec(SS, *MD, *this);
5534 Buffer[InsertIdx].second = std::move(SS.str());
5535 --Level;
5536 }
5537
5538 ~MDTreeAsmWriterContext() override {
5539 for (const auto &Entry : Buffer) {
5540 MainOS << "\n";
5541 unsigned NumIndent = Entry.first * 2U;
5542 MainOS.indent(NumIndent) << Entry.second;
5543 }
5544 }
5545};
5546} // end anonymous namespace
5547
5548static void printMetadataImpl(raw_ostream &ROS, const Metadata &MD,
5549 ModuleSlotTracker &MST, const Module *M,
5550 bool OnlyAsOperand, bool PrintAsTree = false) {
5551 formatted_raw_ostream OS(ROS);
5552
5553 TypePrinting TypePrinter(M);
5554
5555 std::unique_ptr<AsmWriterContext> WriterCtx;
5556 if (PrintAsTree && !OnlyAsOperand)
5557 WriterCtx = std::make_unique<MDTreeAsmWriterContext>(
5558 &TypePrinter, MST.getMachine(), M, &MST, OS, &MD);
5559 else
5560 WriterCtx = std::make_unique<AsmWriterContext>(&TypePrinter,
5561 MST.getMachine(), M, &MST);
5562
5563 writeAsOperandInternal(OS, &MD, *WriterCtx, /* FromValue */ true);
5564
5565 auto *N = dyn_cast<MDNode>(&MD);
5566 if (OnlyAsOperand || !N || isa<DIExpression>(MD))
5567 return;
5568
5569 OS << " = ";
5570 writeMDNodeBodyInternal(OS, N, *WriterCtx);
5571}
5572
5574 ModuleSlotTracker MST(M);
5575 printMetadataImpl(OS, *this, MST, M, /* OnlyAsOperand */ true);
5576}
5577
5579 const Module *M) const {
5580 printMetadataImpl(OS, *this, MST, M, /* OnlyAsOperand */ true);
5581}
5582
5584 bool /*IsForDebug*/) const {
5585 ModuleSlotTracker MST(M);
5586 printMetadataImpl(OS, *this, MST, M, /* OnlyAsOperand */ false);
5587}
5588
5590 const Module *M, bool /*IsForDebug*/) const {
5591 printMetadataImpl(OS, *this, MST, M, /* OnlyAsOperand */ false);
5592}
5593
5594void MDNode::printTree(raw_ostream &OS, const Module *M) const {
5595 ModuleSlotTracker MST(M);
5596 printMetadataImpl(OS, *this, MST, M, /* OnlyAsOperand */ false,
5597 /*PrintAsTree=*/true);
5598}
5599
5601 const Module *M) const {
5602 printMetadataImpl(OS, *this, MST, M, /* OnlyAsOperand */ false,
5603 /*PrintAsTree=*/true);
5604}
5605
5606void ModuleSummaryIndex::print(raw_ostream &ROS, bool IsForDebug) const {
5607 SlotTracker SlotTable(this);
5608 formatted_raw_ostream OS(ROS);
5609 AssemblyWriter W(OS, SlotTable, this, IsForDebug);
5610 W.printModuleSummaryIndex();
5611}
5612
5614 SlotTracker *ST = MachineStorage.get();
5615 if (!ST)
5616 return;
5617
5618 for (auto &I : llvm::make_range(ST->mdn_begin(), ST->mdn_end()))
5619 L.push_back(std::make_pair(I.second, I.first));
5620}
5621
5622#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
5623// Value::dump - allow easy printing of Values from the debugger.
5625void Value::dump() const { print(dbgs(), /*IsForDebug=*/true); dbgs() << '\n'; }
5626
5627// Value::dump - allow easy printing of Values from the debugger.
5629void DbgMarker::dump() const {
5630 print(dbgs(), /*IsForDebug=*/true);
5631 dbgs() << '\n';
5632}
5633
5634// Value::dump - allow easy printing of Values from the debugger.
5636void DbgRecord::dump() const { print(dbgs(), /*IsForDebug=*/true); dbgs() << '\n'; }
5637
5638// Type::dump - allow easy printing of Types from the debugger.
5640void Type::dump() const { print(dbgs(), /*IsForDebug=*/true); dbgs() << '\n'; }
5641
5642// Module::dump() - Allow printing of Modules from the debugger.
5644void Module::dump() const {
5645 print(dbgs(), nullptr,
5646 /*ShouldPreserveUseListOrder=*/false, /*IsForDebug=*/true);
5647}
5648
5649// Allow printing of Comdats from the debugger.
5651void Comdat::dump() const { print(dbgs(), /*IsForDebug=*/true); }
5652
5653// NamedMDNode::dump() - Allow printing of NamedMDNodes from the debugger.
5655void NamedMDNode::dump() const { print(dbgs(), /*IsForDebug=*/true); }
5656
5658void Metadata::dump() const { dump(nullptr); }
5659
5661void Metadata::dump(const Module *M) const {
5662 print(dbgs(), M, /*IsForDebug=*/true);
5663 dbgs() << '\n';
5664}
5665
5667void MDNode::dumpTree() const { dumpTree(nullptr); }
5668
5670void MDNode::dumpTree(const Module *M) const {
5671 printTree(dbgs(), M);
5672 dbgs() << '\n';
5673}
5674
5675// Allow printing of ModuleSummaryIndex from the debugger.
5677void ModuleSummaryIndex::dump() const { print(dbgs(), /*IsForDebug=*/true); }
5678#endif
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
amdgpu next use AMDGPU Next Use Analysis Printer
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static void writeDIMacro(raw_ostream &Out, const DIMacro *N, AsmWriterContext &WriterCtx)
static void writeMetadataAsOperand(raw_ostream &Out, const Metadata *MD, AsmWriterContext &WriterCtx)
static void writeDIGlobalVariableExpression(raw_ostream &Out, const DIGlobalVariableExpression *N, AsmWriterContext &WriterCtx)
static void writeDICompositeType(raw_ostream &Out, const DICompositeType *N, AsmWriterContext &WriterCtx)
static void writeDIFixedPointType(raw_ostream &Out, const DIFixedPointType *N, AsmWriterContext &WriterCtx)
static void printDSOLocation(const GlobalValue &GV, formatted_raw_ostream &Out)
static const char * getWholeProgDevirtResKindName(WholeProgramDevirtResolution::Kind K)
static void writeDISubrangeType(raw_ostream &Out, const DISubrangeType *N, AsmWriterContext &WriterCtx)
static void WriteFullHexAPInt(raw_ostream &Out, const APInt &Val)
static void writeAPFloatInternal(raw_ostream &Out, const APFloat &APF)
static void printMetadataImpl(raw_ostream &ROS, const Metadata &MD, ModuleSlotTracker &MST, const Module *M, bool OnlyAsOperand, bool PrintAsTree=false)
static void writeDIStringType(raw_ostream &Out, const DIStringType *N, AsmWriterContext &WriterCtx)
static std::string getLinkageNameWithSpace(GlobalValue::LinkageTypes LT)
static std::vector< unsigned > predictValueUseListOrder(const Value *V, unsigned ID, const OrderMap &OM)
static void writeDILayerLocList(raw_ostream &Out, const DILayerLocList *N, AsmWriterContext &WriterCtx)
static void writeDIGlobalVariable(raw_ostream &Out, const DIGlobalVariable *N, AsmWriterContext &WriterCtx)
static void orderValue(const Value *V, OrderMap &OM)
static void writeDIBasicType(raw_ostream &Out, const DIBasicType *N, AsmWriterContext &WriterCtx)
static StringRef getUnnamedAddrEncoding(GlobalVariable::UnnamedAddr UA)
static const char * getWholeProgDevirtResByArgKindName(WholeProgramDevirtResolution::ByArg::Kind K)
static void writeDILayerLoc(raw_ostream &Out, const DILayerLoc *N, AsmWriterContext &WriterCtx)
static void writeMDNodeBodyInternal(raw_ostream &Out, const MDNode *Node, AsmWriterContext &Ctx)
static void writeDIModule(raw_ostream &Out, const DIModule *N, AsmWriterContext &WriterCtx)
static void writeDIFile(raw_ostream &Out, const DIFile *N, AsmWriterContext &)
static void writeDISubroutineType(raw_ostream &Out, const DISubroutineType *N, AsmWriterContext &WriterCtx)
static void writeOptimizationInfo(raw_ostream &Out, const User *U)
#define CC_VLS_CASE(ABI_VLEN)
static void writeDILabel(raw_ostream &Out, const DILabel *N, AsmWriterContext &WriterCtx)
static void writeDIDerivedType(raw_ostream &Out, const DIDerivedType *N, AsmWriterContext &WriterCtx)
static void printMetadataIdentifier(StringRef Name, formatted_raw_ostream &Out)
static void printShuffleMask(raw_ostream &Out, Type *Ty, ArrayRef< int > Mask)
static void writeDIImportedEntity(raw_ostream &Out, const DIImportedEntity *N, AsmWriterContext &WriterCtx)
static const Module * getModuleFromDPI(const DbgMarker *Marker)
static void printAsOperandImpl(const Value &V, raw_ostream &O, bool PrintType, ModuleSlotTracker &MST)
static void writeDIObjCProperty(raw_ostream &Out, const DIObjCProperty *N, AsmWriterContext &WriterCtx)
static void writeDISubprogram(raw_ostream &Out, const DISubprogram *N, AsmWriterContext &WriterCtx)
static const char * getSummaryKindName(GlobalValueSummary::SummaryKind SK)
static OrderMap orderModule(const Module *M)
static const char * getVisibilityName(GlobalValue::VisibilityTypes Vis)
static void printCallingConv(unsigned cc, raw_ostream &Out)
static void printAddressSpace(const Module *M, unsigned AS, raw_ostream &OS, StringRef Prefix=" ", StringRef Suffix="", bool ForcePrint=false)
static void printMetadataImplRec(raw_ostream &ROS, const Metadata &MD, AsmWriterContext &WriterCtx)
Recursive version of printMetadataImpl.
static SlotTracker * createSlotTracker(const Value *V)
static void writeDILocation(raw_ostream &Out, const DILocation *DL, AsmWriterContext &WriterCtx)
static void writeDINamespace(raw_ostream &Out, const DINamespace *N, AsmWriterContext &WriterCtx)
DenseMap< const Function *, MapVector< const Value *, std::vector< unsigned > > > UseListOrderMap
static void writeDICommonBlock(raw_ostream &Out, const DICommonBlock *N, AsmWriterContext &WriterCtx)
static UseListOrderMap predictUseListOrder(const Module *M)
static void printThreadLocalModel(GlobalVariable::ThreadLocalMode TLM, formatted_raw_ostream &Out)
static std::string getLinkageName(GlobalValue::LinkageTypes LT)
static void writeGenericDINode(raw_ostream &Out, const GenericDINode *N, AsmWriterContext &WriterCtx)
static void writeDILocalVariable(raw_ostream &Out, const DILocalVariable *N, AsmWriterContext &WriterCtx)
static const char * getTTResKindName(TypeTestResolution::Kind K)
static void writeDITemplateTypeParameter(raw_ostream &Out, const DITemplateTypeParameter *N, AsmWriterContext &WriterCtx)
static const char * getImportTypeName(GlobalValueSummary::ImportKind IK)
static void writeDICompileUnit(raw_ostream &Out, const DICompileUnit *N, AsmWriterContext &WriterCtx)
static const IROptions & getOptions(const Module *M)
static const Module * getModuleFromVal(const Value *V)
static void printLLVMName(raw_ostream &OS, StringRef Name, PrefixType Prefix)
Turn the specified name into an 'LLVM name', which is either prefixed with % (if the string only cont...
static void maybePrintCallAddrSpace(const Value *Operand, const Instruction *I, raw_ostream &Out)
static void writeDIGenericSubrange(raw_ostream &Out, const DIGenericSubrange *N, AsmWriterContext &WriterCtx)
static void writeDISubrange(raw_ostream &Out, const DISubrange *N, AsmWriterContext &WriterCtx)
static void writeDIProperty(raw_ostream &Out, const DIProperty *N, AsmWriterContext &WriterCtx)
static void writeDILexicalBlockFile(raw_ostream &Out, const DILexicalBlockFile *N, AsmWriterContext &WriterCtx)
static void writeConstantInternal(raw_ostream &Out, const Constant *CV, AsmWriterContext &WriterCtx)
static void writeDIEnumerator(raw_ostream &Out, const DIEnumerator *N, AsmWriterContext &)
static void writeAsOperandInternal(raw_ostream &Out, const Value *V, AsmWriterContext &WriterCtx, bool PrintType=false)
static void printVisibility(GlobalValue::VisibilityTypes Vis, formatted_raw_ostream &Out)
constexpr IROptions DefaultOptions
static void writeMDTuple(raw_ostream &Out, const MDTuple *Node, AsmWriterContext &WriterCtx)
static void writeDIExpression(raw_ostream &Out, const DIExpression *N, AsmWriterContext &WriterCtx)
static void writeDIAssignID(raw_ostream &Out, const DIAssignID *DL, AsmWriterContext &WriterCtx)
static void writeDILexicalBlock(raw_ostream &Out, const DILexicalBlock *N, AsmWriterContext &WriterCtx)
PrefixType
@ GlobalPrefix
@ LabelPrefix
@ LocalPrefix
@ NoPrefix
@ ComdatPrefix
static void maybePrintComdat(formatted_raw_ostream &Out, const GlobalObject &GO)
static void printDLLStorageClass(GlobalValue::DLLStorageClassTypes SCT, formatted_raw_ostream &Out)
static bool printWithoutType(const Value &V, raw_ostream &O, SlotTracker *Machine, const Module *M)
Print without a type, skipping the TypePrinting object.
#define ST_DEBUG(X)
static void writeDIArgList(raw_ostream &Out, const DIArgList *N, AsmWriterContext &WriterCtx, bool FromValue=false)
static void writeDITemplateValueParameter(raw_ostream &Out, const DITemplateValueParameter *N, AsmWriterContext &WriterCtx)
static const Value * skipMetadataWrapper(const Value *V)
Look for a value that might be wrapped as metadata, e.g.
static void writeDIMacroFile(raw_ostream &Out, const DIMacroFile *N, AsmWriterContext &WriterCtx)
Atomic ordering constants.
This file contains the simple types necessary to represent the attributes associated with functions a...
static const Function * getParent(const Value *V)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition Compiler.h:690
This file contains the declarations for the subclasses of Constant, which represent the different fla...
dxil translate DXIL Translate Metadata
This file defines the DenseMap class.
@ Default
This file contains constants used for implementing Dwarf debug support.
This file contains the declaration of the GlobalIFunc class, which represents a single indirect funct...
GlobalValue::SanitizerMetadata SanitizerMetadata
Definition Globals.cpp:317
#define op(i)
Hexagon Common GEP
#define _
IRTranslator LLVM IR MI
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
This file contains an interface for creating legacy passes to print out IR in various granularities.
Module.h This file contains the declarations for the Module class.
This defines the Use class.
static bool isAtomic(MachineBasicBlock::iterator I)
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define G(x, y, z)
Definition MD5.cpp:55
Machine Check Debug Module
This file contains the declarations for metadata subclasses.
static bool InRange(int64_t Value, unsigned short Shift, int LBound, int HBound)
ModuleSummaryIndex.h This file contains the declarations the classes that hold the module index and s...
static bool processModule(Module &M, NVPTXTargetMachine &TM)
static bool processFunction(Function &F, NVPTXTargetMachine &TM)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
#define P(N)
Function const char TargetMachine * Machine
if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod
static StringRef getName(Value *V)
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static void visit(BasicBlock &Start, std::function< bool(BasicBlock *)> op)
This file contains some templates that are useful if you are working with the STL at all.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition Value.cpp:479
This file provides utility classes that use RAII to save and restore values.
This file defines the SmallPtrSet class.
This file defines the SmallString class.
This file defines the SmallVector class.
This file contains some functions that are useful when dealing with strings.
LocallyHashedType DenseMapInfo< LocallyHashedType >::Empty
static UseListOrderStack predictUseListOrder(const Module &M)
Value * RHS
Value * LHS
static const fltSemantics & PPCDoubleDouble()
Definition APFloat.h:310
bool isNegative() const
Definition APFloat.h:1583
void toString(SmallVectorImpl< char > &Str, unsigned FormatPrecision=0, unsigned FormatMaxPadding=3, bool TruncateZero=true) const
Definition APFloat.h:1620
const fltSemantics & getSemantics() const
Definition APFloat.h:1591
bool isNaN() const
Definition APFloat.h:1581
bool isSignaling() const
Definition APFloat.h:1585
APInt bitcastToAPInt() const
Definition APFloat.h:1475
APInt getNaNPayload() const
If the value is a NaN value, return an integer containing the payload of this value.
Definition APFloat.h:1609
bool isInfinity() const
Definition APFloat.h:1580
Class for arbitrary precision integers.
Definition APInt.h:78
void clearBit(unsigned BitPosition)
Set a given bit to 0.
Definition APInt.h:1426
unsigned getActiveBits() const
Compute the number of active bits in the value.
Definition APInt.h:1532
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
Definition APInt.cpp:970
void toStringUnsigned(SmallVectorImpl< char > &Str, unsigned Radix=10) const
Considers the APInt to be unsigned and converts it into a string in the radix given.
Definition APInt.h:1711
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
Definition APInt.h:376
bool isSignMask() const
Check if the APInt's value is returned by getSignMask.
Definition APInt.h:462
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition APInt.h:1508
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
Definition APInt.h:853
Abstract interface of slot tracker storage.
const GlobalValueSummary & getAliasee() const
This class represents an incoming formal argument to a Function.
Definition Argument.h:32
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
virtual void emitMDNodeAnnot(const MDNode *, formatted_raw_ostream &)
emitMDNodeAnnot - This may be implemented to emit a string right before a metadata node is emitted.
virtual void emitBasicBlockStartAnnot(const BasicBlock *, formatted_raw_ostream &)
emitBasicBlockStartAnnot - This may be implemented to emit a string right after the basic block label...
virtual void emitBasicBlockEndAnnot(const BasicBlock *, formatted_raw_ostream &)
emitBasicBlockEndAnnot - This may be implemented to emit a string right after the basic block.
virtual void emitFunctionAnnot(const Function *, formatted_raw_ostream &)
emitFunctionAnnot - This may be implemented to emit a string right before the start of a function.
virtual void emitInstructionAnnot(const Instruction *, formatted_raw_ostream &)
emitInstructionAnnot - This may be implemented to emit a string right before an instruction is emitte...
virtual void printInfoComment(const Value &, formatted_raw_ostream &)
printInfoComment - This may be implemented to emit a comment to the right of an instruction or global...
static LLVM_ABI StringRef getOperationName(BinOp Op)
This class holds the attributes for a particular argument, parameter, function, or return value.
Definition Attributes.h:448
bool hasAttributes() const
Return true if attributes exists in this set.
Definition Attributes.h:529
LLVM_ABI std::string getAsString(bool InAttrGrp=false) const
The Attribute is converted to a string of equivalent mnemonic.
LLVM_ABI Attribute::AttrKind getKindAsEnum() const
Return the attribute's kind as an enum (Attribute::AttrKind).
LLVM_ABI bool isTypeAttribute() const
Return true if the attribute is a type attribute.
LLVM_ABI Type * getValueAsType() const
Return the attribute's value as a Type.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
const Function * getParent() const
Return the enclosing method, or null if none.
Definition BasicBlock.h:213
LLVM_ABI void print(raw_ostream &OS, AssemblyAnnotationWriter *AAW=nullptr, bool ShouldPreserveUseListOrder=false, bool IsForDebug=false) const
Print the basic block to an output stream with an optional AssemblyAnnotationWriter.
LLVM_ABI bool isEntryBlock() const
Return true if this is the entry block of the containing function.
LLVM_ABI const Module * getModule() const
Return the module owning the function this basic block belongs to, or nullptr if the function does no...
OperandBundleUse getOperandBundleAt(unsigned Index) const
Return the operand bundle at a specific index.
unsigned getNumOperandBundles() const
Return the number of operand bundles associated with this User.
AttributeList getAttributes() const
Return the attributes for this call.
bool hasOperandBundles() const
Return true if this User has any operand bundles.
std::vector< std::pair< StringRef, GlobalValue::GUID > > getSortedSymbols() const
API used for serialization, e.g. YAML.
LLVM_ABI void print(raw_ostream &OS, bool IsForDebug=false) const
LLVM_ABI void dump() const
@ Largest
The linker will choose the largest COMDAT.
Definition Comdat.h:39
@ SameSize
The data referenced by the COMDAT must be the same size.
Definition Comdat.h:41
@ Any
The linker may choose any COMDAT.
Definition Comdat.h:37
@ NoDeduplicate
No deduplication is performed.
Definition Comdat.h:40
@ ExactMatch
The data referenced by the COMDAT must be the same.
Definition Comdat.h:38
SelectionKind getSelectionKind() const
Definition Comdat.h:47
static LLVM_ABI ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
LLVM_ABI APInt getSignedMin() const
Return the smallest signed value contained in the ConstantRange.
LLVM_ABI APInt getSignedMax() const
Return the largest signed value contained in the ConstantRange.
This is an important base class in LLVM.
Definition Constant.h:44
LLVM_ABI Constant * getSplatValue(bool AllowPoison=false) const
If all elements of the vector constant have the same value, return that value.
LLVM_ABI Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
List of ValueAsMetadata, to be used as an argument to a dbg.value intrinsic.
Basic type, like 'int' or 'float'.
Debug common block.
static LLVM_ABI const char * nameTableKindString(DebugNameTableKind PK)
static LLVM_ABI const char * emissionKindString(DebugEmissionKind EK)
Enumeration value.
A lightweight wrapper around an expression operand.
DWARF expression.
static LLVM_ABI const char * fixedPointKindString(FixedPointKind)
A pair of DIGlobalVariable and DIExpression.
An imported module (C++ using directive or similar).
A sequence of DILayerLoc entries.
A single intermediate-IR layer location.
Debug lexical block.
Macro Info DWARF-like metadata node.
Represents a module in the programming language, for example, a Clang module, or a Fortran module.
Debug lexical block.
Tagged DWARF-like metadata node.
static LLVM_ABI DIFlags splitFlags(DIFlags Flags, SmallVectorImpl< DIFlags > &SplitFlags)
Split up a flags bitfield.
static LLVM_ABI StringRef getFlagString(DIFlags Flag)
DIFlags
Debug info flags.
A property of a class or structure.
Wrapper structure that holds source language identity metadata that includes language name,...
uint32_t getVersion() const
Returns language version. Only valid for versioned language names.
uint16_t getName() const
Returns a versioned or unversioned language name.
String type, Fortran CHARACTER(n)
Subprogram description. Uses SubclassData1.
static LLVM_ABI DISPFlags splitFlags(DISPFlags Flags, SmallVectorImpl< DISPFlags > &SplitFlags)
Split up a flags bitfield for easier printing.
static LLVM_ABI StringRef getFlagString(DISPFlags Flag)
DISPFlags
Debug info subprogram flags.
Array subrange.
Type array for a subprogram.
LLVM_ABI void print(raw_ostream &O, bool IsForDebug=false) const
Per-instruction record of debug-info.
LLVM_ABI void dump() const
Instruction * MarkedInstr
Link back to the Instruction that owns this marker.
LLVM_ABI void print(raw_ostream &O, bool IsForDebug=false) const
Implement operator<< on DbgMarker.
LLVM_ABI const BasicBlock * getParent() const
simple_ilist< DbgRecord > StoredDbgRecords
List of DbgRecords, the non-instruction equivalent of llvm.dbg.
Base class for non-instruction debug metadata records that have positions within IR.
DebugLoc getDebugLoc() const
LLVM_ABI void dump() const
DbgMarker * Marker
Marker that this DbgRecord is linked into.
Record of a variable value-assignment, aka a non instruction representation of the dbg....
LLVM_ABI void print(raw_ostream &O, bool IsForDebug=false) const
Metadata * getRawLocation() const
Returns the metadata operand for the first location description.
LLVM_ABI MDNode * getAsMDNode() const
Return this as a bar MDNode.
Definition DebugLoc.cpp:81
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT > iterator
Definition DenseMap.h:678
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
Definition Function.h:247
void print(raw_ostream &OS, AssemblyAnnotationWriter *AAW=nullptr, bool ShouldPreserveUseListOrder=false, bool IsForDebug=false) const
Print the function to an output stream with an optional AssemblyAnnotationWriter.
const Function & getFunction() const
Definition Function.h:167
const Argument * const_arg_iterator
Definition Function.h:74
LLVM_ABI Value * getBasePtr() const
LLVM_ABI Value * getDerivedPtr() const
Generic tagged DWARF-like metadata node.
const Constant * getAliasee() const
Definition GlobalAlias.h:87
const Constant * getResolver() const
Definition GlobalIFunc.h:73
StringRef getSection() const
Get the custom section of this global if it has one.
LLVM_ABI void getAllMetadata(SmallVectorImpl< std::pair< unsigned, MDNode * > > &MDs) const
Appends all metadata attached to this value to MDs, sorting by KindID.
const Comdat * getComdat() const
bool hasSection() const
Check if this global has a custom object file section.
SummaryKind
Sububclass discriminator (for dyn_cast<> et al.)
bool hasPartition() const
static LLVM_ABI GUID getGUIDAssumingExternalLinkage(StringRef GlobalName)
Return a 64-bit global unique ID constructed from the name of a global symbol.
Definition Globals.cpp:80
LLVM_ABI const SanitizerMetadata & getSanitizerMetadata() const
Definition Globals.cpp:318
bool hasExternalLinkage() const
bool isDSOLocal() const
VisibilityTypes getVisibility() const
bool isImplicitDSOLocal() const
LinkageTypes getLinkage() const
uint64_t GUID
Declare a type to represent a global unique identifier for a global value.
ThreadLocalMode getThreadLocalMode() const
DLLStorageClassTypes
Storage classes of global values for PE targets.
Definition GlobalValue.h:74
@ DLLExportStorageClass
Function to be accessible from DLL.
Definition GlobalValue.h:77
@ DLLImportStorageClass
Function to be imported from DLL.
Definition GlobalValue.h:76
bool hasSanitizerMetadata() const
LLVM_ABI StringRef getPartition() const
Definition Globals.cpp:295
Module * getParent()
Get the module that this global value is contained inside of...
PointerType * getType() const
Global values are always pointers.
VisibilityTypes
An enumeration for the kinds of visibility of global values.
Definition GlobalValue.h:67
@ DefaultVisibility
The GV is visible.
Definition GlobalValue.h:68
@ HiddenVisibility
The GV is hidden.
Definition GlobalValue.h:69
@ ProtectedVisibility
The GV is protected.
Definition GlobalValue.h:70
LLVM_ABI bool isMaterializable() const
If this function's Module is being lazily streamed in functions from disk or some other source,...
Definition Globals.cpp:47
UnnamedAddr getUnnamedAddr() const
LinkageTypes
An enumeration for the kinds of linkage for global values.
Definition GlobalValue.h:52
@ PrivateLinkage
Like Internal, but omit from symbol table.
Definition GlobalValue.h:61
@ CommonLinkage
Tentative definitions.
Definition GlobalValue.h:63
@ InternalLinkage
Rename collisions when linking (static functions).
Definition GlobalValue.h:60
@ LinkOnceAnyLinkage
Keep one copy of function when linking (inline)
Definition GlobalValue.h:55
@ WeakODRLinkage
Same, but only replaced by something equivalent.
Definition GlobalValue.h:58
@ ExternalLinkage
Externally visible function.
Definition GlobalValue.h:53
@ WeakAnyLinkage
Keep one copy of named function when linking (weak)
Definition GlobalValue.h:57
@ AppendingLinkage
Special purpose, only applies to global arrays.
Definition GlobalValue.h:59
@ AvailableExternallyLinkage
Available for inspection, not emission.
Definition GlobalValue.h:54
@ ExternalWeakLinkage
ExternalWeak linkage description.
Definition GlobalValue.h:62
@ LinkOnceODRLinkage
Same, but only replaced by something equivalent.
Definition GlobalValue.h:56
DLLStorageClassTypes getDLLStorageClass() const
Type * getValueType() const
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
bool isExternallyInitialized() const
bool hasInitializer() const
Definitions have initializers, declarations don't.
AttributeSet getAttributes() const
Return the attribute set for this global.
std::optional< CodeModel::Model > getCodeModel() const
Get the custom code model of this global if it has one.
MaybeAlign getAlign() const
Returns the alignment of the given variable.
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
A helper class to return the specified delimiter string after the first invocation of operator String...
Metadata node.
Definition Metadata.h:1081
LLVM_ABI void printTree(raw_ostream &OS, const Module *M=nullptr) const
Print in tree shape.
LLVM_ABI void dumpTree() const
User-friendly dump in tree shape.
Tracking metadata reference owned by Metadata.
Definition Metadata.h:902
Tuple of metadata.
Definition Metadata.h:1496
This class implements a map that also provides access to all stored values in a deterministic order.
Definition MapVector.h:39
Root of the metadata hierarchy.
Definition Metadata.h:64
LLVM_ABI void print(raw_ostream &OS, const Module *M=nullptr, bool IsForDebug=false) const
Print.
LLVM_ABI void printAsOperand(raw_ostream &OS, const Module *M=nullptr) const
Print as operand.
LLVM_ABI void dump() const
User-friendly dump.
Manage lifetime of a slot tracker for printing IR.
const Module * getModule() const
ModuleSlotTracker(SlotTracker &Machine, const Module *M, const Function *F=nullptr)
Wrap a preinitialized SlotTracker.
void renumberMetadataForAssembly(ArrayRef< const MDNode * > AdditionalMetadata, MachineMDNodeListType *AdditionalMetadataNodes=nullptr) const
Renumber module metadata and then additional metadata for canonical assembly output.
void collectMDNodes(MachineMDNodeListType &L) const
void setProcessHook(std::function< void(AbstractSlotTrackerStorage *, const Module *)>)
virtual ~ModuleSlotTracker()
Destructor to clean up storage.
void collectAdditionalMetadata(ArrayRef< const MDNode * > AdditionalMetadata, MachineMDNodeListType &AdditionalMetadataNodes) const
Collect metadata reachable from AdditionalMetadata but not from the module.
int getLocalSlot(const Value *V)
Return the slot number of the specified local value.
virtual bool shouldPrintDebugLocationInline(const DILocation *) const
Return whether a debug location should be printed inline instead of by ID.
SlotTracker * getMachine()
Lazily creates a slot tracker.
SmallVector< std::pair< unsigned, const MDNode * >, 0 > MachineMDNodeListType
void incorporateFunction(const Function &F)
Incorporate the given function.
Class to hold module path string table and global value map, and encapsulate methods for operating on...
const TypeIdSummaryMapTy & typeIds() const
CfiFunctionIndex & cfiFunctionDecls()
ValueInfo getValueInfo(const GlobalValueSummaryMapTy::value_type &R) const
Return a ValueInfo for the index value_type (convenient when iterating index).
static constexpr const char * getRegularLTOModuleName()
const auto & typeIdCompatibleVtableMap() const
const StringMap< ModuleHash > & modulePaths() const
Table of modules, containing module hash and id.
LLVM_ABI void dump() const
Dump to stderr (for debugging).
GlobalValueSummaryMapTy::SortedEntriesRange sortedGlobalValueSummariesRange() const
uint64_t getStackIdAtIndex(unsigned Index) const
LLVM_ABI void print(raw_ostream &OS, bool IsForDebug=false) const
Print to an output stream.
CfiFunctionIndex & cfiFunctionDefs()
LLVM_ABI uint64_t getFlags() const
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
void renumberMetadataForAssembly()
Renumber the IDs stored in metadata nodes into canonical assembly order.
iterator_range< alias_iterator > aliases()
Definition Module.h:861
iterator_range< global_iterator > globals()
Definition Module.h:810
void print(raw_ostream &OS, AssemblyAnnotationWriter *AAW, bool ShouldPreserveUseListOrder=false, bool IsForDebug=false) const
Print the module to an output stream with an optional AssemblyAnnotationWriter.
void dump() const
Dump the module to stderr (for debugging).
LLVM_ABI void dump() const
LLVM_ABI StringRef getName() const
LLVM_ABI void print(raw_ostream &ROS, bool IsForDebug=false) const
iterator_range< op_iterator > operands()
Definition Metadata.h:1893
unsigned getAddressSpace() const
Return the address space of the Pointer type.
This class provides computation of slot numbers for LLVM Assembly writing.
DenseMap< const Value *, unsigned > ValueMap
ValueMap - A mapping of Values to slot numbers.
bool mdn_empty() const
int getMetadataSlot(const MDNode *N) override
getMetadataSlot - Get the slot number of a MDNode.
~SlotTracker() override=default
int getTypeIdCompatibleVtableSlot(StringRef Id)
int getModulePathSlot(StringRef Path)
bool as_empty() const
unsigned mdn_size() const
SlotTracker(const SlotTracker &)=delete
void purgeFunction()
After calling incorporateFunction, use this method to remove the most recently incorporated function ...
mdn_iterator mdn_end()
int getTypeIdSlot(StringRef Id)
void initializeIfNeeded()
These functions do the actual initialization.
int getGlobalSlot(const GlobalValue *V)
getGlobalSlot - Get the slot number of a global value.
as_iterator as_begin()
SlotTracker(const Module *M, bool ShouldTrackMetadataDefinitions=false)
Construct from a module.
const Function * getFunction() const
DenseMap< GlobalValue::GUID, unsigned >::iterator guid_iterator
GUID map iterators.
void incorporateFunction(const Function *F)
If you'd like to deal with a function instead of just a module, use this method to get its data into ...
int getLocalSlot(const Value *V)
Return the slot number of the specified value in it's type plane.
int getAttributeGroupSlot(AttributeSet AS)
void setProcessHook(std::function< void(AbstractSlotTrackerStorage *, const Module *)>)
void createMetadataSlot(const MDNode *N) override
getMetadataSlot - Get the slot number of a MDNode.
DenseMap< const MDNode *, unsigned >::iterator mdn_iterator
MDNode map iterators.
as_iterator as_end()
unsigned as_size() const
SlotTracker & operator=(const SlotTracker &)=delete
int getGUIDSlot(GlobalValue::GUID GUID)
mdn_iterator mdn_begin()
int initializeIndexIfNeeded()
DenseMap< AttributeSet, unsigned >::iterator as_iterator
AttributeSet map iterators.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:28
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
unsigned size() const
Definition StringMap.h:104
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition StringMap.h:129
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
ArrayRef< Type * > elements() const
bool isPacked() const
unsigned getNumElements() const
Random access to the elements.
bool isLiteral() const
Return true if this type is uniqued by structural equivalence, false if it is a struct definition.
bool isOpaque() const
Return true if this is a type with an identity that has no body specified yet.
LLVM_ABI StringRef getName() const
Return the name for this struct type if it has an identity.
Definition Type.cpp:736
ArrayRef< Type * > type_params() const
Return the type parameters for this particular target extension type.
ArrayRef< unsigned > int_params() const
Return the integer parameters for this particular target extension type.
TypeFinder - Walk over a module, identifying all of the types that are used by the module.
Definition TypeFinder.h:31
LLVM_ABI void run(const Module &M, bool onlyNamed)
iterator begin()
Definition TypeFinder.h:51
bool empty() const
Definition TypeFinder.h:57
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
LLVM_ABI StringRef getTargetExtName() const
Type(LLVMContext &C, TypeID tid)
Definition Type.h:95
LLVM_ABI void dump() const
LLVM_ABI void print(raw_ostream &O, bool IsForDebug=false, bool NoDetails=false) const
Print the current type.
LLVM_ABI unsigned getByteBitWidth() const
TypeID getTypeID() const
Return the type id for the type.
Definition Type.h:138
Type * getElementType() const
unsigned getAddressSpace() const
Return the address space of the Pointer type.
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
LLVM_ABI void print(raw_ostream &O, bool IsForDebug=false) const
Implement operator<< on Value.
LLVM_ABI void getAllMetadata(SmallVectorImpl< std::pair< unsigned, MDNode * > > &MDs) const
Appends all metadata attached to this value to MDs, sorting by KindID.
iterator_range< user_iterator > users()
Definition Value.h:428
LLVM_ABI void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const
Print the name of this Value out to the specified raw_ostream.
bool hasName() const
Definition Value.h:263
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:314
LLVM_ABI void dump() const
Support for debugging, callable in GDB: V->dump()
formatted_raw_ostream - A raw_ostream that wraps another one and keeps track of line and column posit...
formatted_raw_ostream & PadToColumn(unsigned NewCol)
PadToColumn - Align the output to some column number.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
CallInst * Call
LLVM_ABI StringRef LanguageDialectString(unsigned LanguageDialect)
Definition Dwarf.cpp:623
LLVM_ABI StringRef SourceLanguageNameString(SourceLanguageName Lang)
Definition Dwarf.cpp:603
LLVM_ABI StringRef EnumKindString(unsigned EnumKind)
Definition Dwarf.cpp:394
LLVM_ABI StringRef LanguageString(unsigned Language)
Definition Dwarf.cpp:413
LLVM_ABI StringRef AttributeEncodingString(unsigned Encoding)
Definition Dwarf.cpp:264
LLVM_ABI StringRef ConventionString(unsigned Convention)
Definition Dwarf.cpp:659
LLVM_ABI StringRef MacinfoString(unsigned Encoding)
Definition Dwarf.cpp:723
LLVM_ABI StringRef OperationEncodingString(unsigned Encoding)
Definition Dwarf.cpp:138
LLVM_ABI StringRef TagString(unsigned Tag)
Definition Dwarf.cpp:21
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
This file contains the declaration of the Comdat class, which represents a single COMDAT in LLVM.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
@ Entry
Definition COFF.h:862
@ AArch64_VectorCall
Used between AArch64 Advanced SIMD functions.
@ X86_64_SysV
The C convention as specified in the x86-64 supplement to the System V ABI, used on most non-Windows ...
@ RISCV_VectorCall
Calling convention used for RISC-V V-extension.
@ AMDGPU_CS
Used for Mesa/AMDPAL compute shaders.
@ AMDGPU_VS
Used for Mesa vertex shaders, or AMDPAL last shader stage before rasterization (vertex shader if tess...
@ AVR_SIGNAL
Used for AVR signal routines.
@ Swift
Calling convention for Swift.
Definition CallingConv.h:69
@ AMDGPU_KERNEL
Used for AMDGPU code object kernels.
@ AArch64_SVE_VectorCall
Used between AArch64 SVE functions.
@ ARM_APCS
ARM Procedure Calling Standard (obsolete, but still used on some targets).
@ CHERIoT_CompartmentCall
Calling convention used for CHERIoT when crossing a protection boundary.
@ CFGuard_Check
Special calling convention on Windows for calling the Control Guard Check ICall funtion.
Definition CallingConv.h:82
@ AVR_INTR
Used for AVR interrupt routines.
@ PreserveMost
Used for runtime calls that preserves most registers.
Definition CallingConv.h:63
@ AnyReg
OBSOLETED - Used for stack based JavaScript calls.
Definition CallingConv.h:60
@ AMDGPU_Gfx
Used for AMD graphics targets.
@ DUMMY_HHVM
Placeholders for HHVM calling conventions (deprecated, removed).
@ AMDGPU_CS_ChainPreserve
Used on AMDGPUs to give the middle-end more control over argument placement.
@ AMDGPU_HS
Used for Mesa/AMDPAL hull shaders (= tessellation control shaders).
@ ARM_AAPCS
ARM Architecture Procedure Calling Standard calling convention (aka EABI).
@ CHERIoT_CompartmentCallee
Calling convention used for the callee of CHERIoT_CompartmentCall.
@ AMDGPU_GS
Used for Mesa/AMDPAL geometry shaders.
@ AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2
Preserve X2-X15, X19-X29, SP, Z0-Z31, P0-P15.
@ CHERIoT_LibraryCall
Calling convention used for CHERIoT for cross-library calls to a stateless compartment.
@ CXX_FAST_TLS
Used for access functions.
Definition CallingConv.h:72
@ X86_INTR
x86 hardware interrupt context.
@ AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0
Preserve X0-X13, X19-X29, SP, Z0-Z31, P0-P15.
@ WASM_EmscriptenInvoke
For emscripten __invoke_* functions.
@ AMDGPU_CS_Chain
Used on AMDGPUs to give the middle-end more control over argument placement.
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
Definition CallingConv.h:50
@ AMDGPU_PS
Used for Mesa/AMDPAL pixel shaders.
@ Cold
Attempts to make code in the caller as efficient as possible under the assumption that the call is no...
Definition CallingConv.h:47
@ AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1
Preserve X1-X15, X19-X29, SP, Z0-Z31, P0-P15.
@ X86_ThisCall
Similar to X86_StdCall.
@ PTX_Device
Call to a PTX device function.
@ SPIR_KERNEL
Used for SPIR kernel functions.
@ PreserveAll
Used for runtime calls that preserves (almost) all registers.
Definition CallingConv.h:66
@ X86_StdCall
stdcall is mostly used by the Win32 API.
Definition CallingConv.h:99
@ SPIR_FUNC
Used for SPIR non-kernel device functions.
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition CallingConv.h:41
@ MSP430_INTR
Used for MSP430 interrupt routines.
@ X86_VectorCall
MSVC calling convention that passes vectors and vector aggregates in SSE registers.
@ Intel_OCL_BI
Used for Intel OpenCL built-ins.
@ PreserveNone
Used for runtime calls that preserves none general registers.
Definition CallingConv.h:90
@ AMDGPU_ES
Used for AMDPAL shader stage before geometry shader if geometry is in use.
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
Definition CallingConv.h:76
@ Win64
The C convention as implemented on Windows/x86-64 and AArch64.
@ PTX_Kernel
Call to a PTX kernel. Passes all arguments in parameter space.
@ SwiftTail
This follows the Swift calling convention in how arguments are passed but guarantees tail calls will ...
Definition CallingConv.h:87
@ GRAAL
Used by GraalVM. Two additional registers are reserved.
@ AMDGPU_LS
Used for AMDPAL vertex shader if tessellation is in use.
@ ARM_AAPCS_VFP
Same as ARM_AAPCS, but uses hard floating point ABI.
@ X86_RegCall
Register calling convention used for parameters transfer optimization.
@ M68k_RTD
Used for M68k rtd-based CC (similar to X86's stdcall).
@ X86_FastCall
'fast' analog of X86_StdCall.
LLVM_ABI void printImmArg(ID IID, unsigned ArgIdx, raw_ostream &OS, const Constant *ImmArgVal)
Print the argument info for the arguments with ArgInfo.
LLVM_ABI bool hasPrettyPrintedArgs(ID id)
Returns true if the intrinsic has pretty printed immediate arguments.
@ System
Synchronized with respect to all concurrently executing threads.
Definition LLVMContext.h:66
SourceLanguageName
Definition Dwarf.h:229
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
bool empty() const
Definition BasicBlock.h:101
bool isElementwise(const VPValue *V)
Return true if V is elementwise, i.e. none of the lanes are permuted.
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1755
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
detail::zippy< detail::zip_first, T, U, Args... > zip_equal(T &&t, U &&u, Args &&...args)
zip iterator that assumes that all iteratees have the same length.
Definition STLExtras.h:856
InterleavedRange< Range > interleaved(const Range &R, StringRef Separator=", ", StringRef Prefix="", StringRef Suffix="")
Output range R as a sequence of interleaved elements.
const char * getHotnessName(CalleeInfo::HotnessType HT)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
Definition Casting.h:732
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
LLVM_ABI void printEscapedString(StringRef Name, raw_ostream &Out)
Print each character of the specified string, escaping it if it is not printable or if it is an escap...
constexpr auto equal_to(T &&Arg)
Functor variant of std::equal_to that can be used as a UnaryPredicate in functional algorithms like a...
Definition STLExtras.h:2189
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
const char * toIRString(AtomicOrdering ao)
String used by LLVM IR to represent atomic ordering.
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1652
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
char hexdigit(unsigned X, bool LowerCase=false)
hexdigit - Return the hexadecimal character for the given number X (which should be less than 16).
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
Definition STLExtras.h:1986
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
constexpr int PoisonMaskElem
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ Ref
The access may reference the value stored in memory.
Definition ModRef.h:32
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
const IROptions & getIROptions(const LLVMContext &C)
Definition IROptions.h:27
LLVM_ABI Printable printBasicBlock(const BasicBlock *BB)
Print BasicBlock BB as an operand or print "<nullptr>" if BB is a nullptr.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
Definition STLExtras.h:2208
auto predecessors(const MachineBasicBlock *BB)
constexpr bool valueOr(BoolOrDefault X, bool Default)
bool pred_empty(const BasicBlock *BB)
Definition CFG.h:107
std::vector< TypeIdOffsetVtableInfo > TypeIdCompatibleVtableInfo
List of vtable definitions decorated by a particular type identifier, and their corresponding offsets...
static auto filterDbgVars(iterator_range< simple_ilist< DbgRecord >::iterator > R)
Filter the DbgRecord range to DbgVariableRecord types only and downcast.
LLVM_ABI void printLLVMNameWithoutPrefix(raw_ostream &OS, StringRef Name)
Print out a name of an LLVM value without any prefixes.
#define N
#define NC
Definition regutils.h:42
A single checksum, represented by a Kind and a Value (a string).
T Value
The string value of the checksum.
StringRef getKindAsString() const
std::vector< ConstVCall > TypeCheckedLoadConstVCalls
std::vector< VFuncId > TypeCheckedLoadVCalls
std::vector< ConstVCall > TypeTestAssumeConstVCalls
List of virtual calls made by this function using (respectively) llvm.assume(llvm....
std::vector< GlobalValue::GUID > TypeTests
List of type identifiers used by this function in llvm.type.test intrinsics referenced by something o...
std::vector< VFuncId > TypeTestAssumeVCalls
List of virtual calls made by this function using (respectively) llvm.assume(llvm....
unsigned NoRenameOnPromotion
This field is written by the ThinLTO prelink stage to decide whether a particular static global value...
unsigned DSOLocal
Indicates that the linker resolved the symbol to a definition from within the same linkage unit.
unsigned CanAutoHide
In the per-module summary, indicates that the global value is linkonce_odr and global unnamed addr (s...
unsigned ImportType
This field is written by the ThinLTO indexing step to postlink combined summary.
unsigned NotEligibleToImport
Indicate if the global value cannot be imported (e.g.
unsigned Linkage
The linkage type of the associated global value.
unsigned Visibility
Indicates the visibility.
unsigned Live
In per-module summary, indicate that the global value must be considered a live root for index-based ...
StringRef getTagName() const
Return the tag of this operand bundle as a string.
ArrayRef< Use > Inputs
A utility class that uses RAII to save and restore the value of a variable.
std::map< uint64_t, WholeProgramDevirtResolution > WPDRes
Mapping from byte offset to whole-program devirt resolution for that (typeid, byte offset) pair.
TypeTestResolution TTRes
Kind
Specifies which kind of type check we should emit for this byte array.
@ Unknown
Unknown (analysis not performed, don't lower)
@ Single
Single element (last example in "Short Inline Bit Vectors")
@ Inline
Inlined bit vector ("Short Inline Bit Vectors")
@ Unsat
Unsatisfiable type (i.e. no global has this type metadata)
@ AllOnes
All-ones bit vector ("Eliminating Bit Vector Checks for All-Ones Bit Vectors")
@ ByteArray
Test a byte array (first example)
unsigned SizeM1BitWidth
Range of size-1 expressed as a bit width.
enum llvm::TypeTestResolution::Kind TheKind
@ UniformRetVal
Uniform return value optimization.
@ VirtualConstProp
Virtual constant propagation.
@ UniqueRetVal
Unique return value optimization.
@ Indir
Just do a regular virtual call.
enum llvm::WholeProgramDevirtResolution::Kind TheKind
std::map< std::vector< uint64_t >, ByArg > ResByArg
Resolutions for calls with all constant integer arguments (excluding the first argument,...
@ SingleImpl
Single implementation devirtualization.
@ Indir
Just do a regular virtual call.
@ BranchFunnel
When retpoline mitigation is enabled, use a branch funnel that is defined in the merged module.
Function object to check whether the second component of a container supported by std::get (like std:...
Definition STLExtras.h:1464