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