xref: /netbsd-src/external/apache2/llvm/dist/llvm/lib/IR/AsmWriter.cpp (revision 82d56013d7b633d116a93943de88e08335357a7c)
17330f729Sjoerg //===- AsmWriter.cpp - Printing LLVM as an assembly file ------------------===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg // This library implements `print` family of functions in classes like
107330f729Sjoerg // Module, Function, Value, etc. In-memory representation of those classes is
117330f729Sjoerg // converted to IR strings.
127330f729Sjoerg //
137330f729Sjoerg // Note that these routines must be extremely tolerant of various errors in the
147330f729Sjoerg // LLVM code, because it can be used for debugging transformations.
157330f729Sjoerg //
167330f729Sjoerg //===----------------------------------------------------------------------===//
177330f729Sjoerg 
187330f729Sjoerg #include "llvm/ADT/APFloat.h"
197330f729Sjoerg #include "llvm/ADT/APInt.h"
207330f729Sjoerg #include "llvm/ADT/ArrayRef.h"
217330f729Sjoerg #include "llvm/ADT/DenseMap.h"
227330f729Sjoerg #include "llvm/ADT/None.h"
237330f729Sjoerg #include "llvm/ADT/Optional.h"
247330f729Sjoerg #include "llvm/ADT/STLExtras.h"
257330f729Sjoerg #include "llvm/ADT/SetVector.h"
267330f729Sjoerg #include "llvm/ADT/SmallString.h"
277330f729Sjoerg #include "llvm/ADT/SmallVector.h"
287330f729Sjoerg #include "llvm/ADT/StringExtras.h"
297330f729Sjoerg #include "llvm/ADT/StringRef.h"
307330f729Sjoerg #include "llvm/ADT/iterator_range.h"
317330f729Sjoerg #include "llvm/BinaryFormat/Dwarf.h"
327330f729Sjoerg #include "llvm/Config/llvm-config.h"
337330f729Sjoerg #include "llvm/IR/Argument.h"
347330f729Sjoerg #include "llvm/IR/AssemblyAnnotationWriter.h"
357330f729Sjoerg #include "llvm/IR/Attributes.h"
367330f729Sjoerg #include "llvm/IR/BasicBlock.h"
377330f729Sjoerg #include "llvm/IR/CFG.h"
387330f729Sjoerg #include "llvm/IR/CallingConv.h"
397330f729Sjoerg #include "llvm/IR/Comdat.h"
407330f729Sjoerg #include "llvm/IR/Constant.h"
417330f729Sjoerg #include "llvm/IR/Constants.h"
427330f729Sjoerg #include "llvm/IR/DebugInfoMetadata.h"
437330f729Sjoerg #include "llvm/IR/DerivedTypes.h"
447330f729Sjoerg #include "llvm/IR/Function.h"
457330f729Sjoerg #include "llvm/IR/GlobalAlias.h"
467330f729Sjoerg #include "llvm/IR/GlobalIFunc.h"
477330f729Sjoerg #include "llvm/IR/GlobalIndirectSymbol.h"
487330f729Sjoerg #include "llvm/IR/GlobalObject.h"
497330f729Sjoerg #include "llvm/IR/GlobalValue.h"
507330f729Sjoerg #include "llvm/IR/GlobalVariable.h"
517330f729Sjoerg #include "llvm/IR/IRPrintingPasses.h"
527330f729Sjoerg #include "llvm/IR/InlineAsm.h"
537330f729Sjoerg #include "llvm/IR/InstrTypes.h"
547330f729Sjoerg #include "llvm/IR/Instruction.h"
557330f729Sjoerg #include "llvm/IR/Instructions.h"
56*82d56013Sjoerg #include "llvm/IR/IntrinsicInst.h"
577330f729Sjoerg #include "llvm/IR/LLVMContext.h"
587330f729Sjoerg #include "llvm/IR/Metadata.h"
597330f729Sjoerg #include "llvm/IR/Module.h"
607330f729Sjoerg #include "llvm/IR/ModuleSlotTracker.h"
617330f729Sjoerg #include "llvm/IR/ModuleSummaryIndex.h"
627330f729Sjoerg #include "llvm/IR/Operator.h"
637330f729Sjoerg #include "llvm/IR/Type.h"
647330f729Sjoerg #include "llvm/IR/TypeFinder.h"
657330f729Sjoerg #include "llvm/IR/Use.h"
667330f729Sjoerg #include "llvm/IR/UseListOrder.h"
677330f729Sjoerg #include "llvm/IR/User.h"
687330f729Sjoerg #include "llvm/IR/Value.h"
697330f729Sjoerg #include "llvm/Support/AtomicOrdering.h"
707330f729Sjoerg #include "llvm/Support/Casting.h"
717330f729Sjoerg #include "llvm/Support/Compiler.h"
727330f729Sjoerg #include "llvm/Support/Debug.h"
737330f729Sjoerg #include "llvm/Support/ErrorHandling.h"
747330f729Sjoerg #include "llvm/Support/Format.h"
757330f729Sjoerg #include "llvm/Support/FormattedStream.h"
767330f729Sjoerg #include "llvm/Support/raw_ostream.h"
777330f729Sjoerg #include <algorithm>
787330f729Sjoerg #include <cassert>
797330f729Sjoerg #include <cctype>
807330f729Sjoerg #include <cstddef>
817330f729Sjoerg #include <cstdint>
827330f729Sjoerg #include <iterator>
837330f729Sjoerg #include <memory>
847330f729Sjoerg #include <string>
857330f729Sjoerg #include <tuple>
867330f729Sjoerg #include <utility>
877330f729Sjoerg #include <vector>
887330f729Sjoerg 
897330f729Sjoerg using namespace llvm;
907330f729Sjoerg 
917330f729Sjoerg // Make virtual table appear in this compilation unit.
927330f729Sjoerg AssemblyAnnotationWriter::~AssemblyAnnotationWriter() = default;
937330f729Sjoerg 
947330f729Sjoerg //===----------------------------------------------------------------------===//
957330f729Sjoerg // Helper Functions
967330f729Sjoerg //===----------------------------------------------------------------------===//
977330f729Sjoerg 
987330f729Sjoerg namespace {
997330f729Sjoerg 
1007330f729Sjoerg struct OrderMap {
1017330f729Sjoerg   DenseMap<const Value *, std::pair<unsigned, bool>> IDs;
1027330f729Sjoerg 
size__anonf93afd230111::OrderMap1037330f729Sjoerg   unsigned size() const { return IDs.size(); }
operator []__anonf93afd230111::OrderMap1047330f729Sjoerg   std::pair<unsigned, bool> &operator[](const Value *V) { return IDs[V]; }
1057330f729Sjoerg 
lookup__anonf93afd230111::OrderMap1067330f729Sjoerg   std::pair<unsigned, bool> lookup(const Value *V) const {
1077330f729Sjoerg     return IDs.lookup(V);
1087330f729Sjoerg   }
1097330f729Sjoerg 
index__anonf93afd230111::OrderMap1107330f729Sjoerg   void index(const Value *V) {
1117330f729Sjoerg     // Explicitly sequence get-size and insert-value operations to avoid UB.
1127330f729Sjoerg     unsigned ID = IDs.size() + 1;
1137330f729Sjoerg     IDs[V].first = ID;
1147330f729Sjoerg   }
1157330f729Sjoerg };
1167330f729Sjoerg 
1177330f729Sjoerg } // end anonymous namespace
1187330f729Sjoerg 
119*82d56013Sjoerg /// Look for a value that might be wrapped as metadata, e.g. a value in a
120*82d56013Sjoerg /// metadata operand. Returns the input value as-is if it is not wrapped.
skipMetadataWrapper(const Value * V)121*82d56013Sjoerg static const Value *skipMetadataWrapper(const Value *V) {
122*82d56013Sjoerg   if (const auto *MAV = dyn_cast<MetadataAsValue>(V))
123*82d56013Sjoerg     if (const auto *VAM = dyn_cast<ValueAsMetadata>(MAV->getMetadata()))
124*82d56013Sjoerg       return VAM->getValue();
125*82d56013Sjoerg   return V;
126*82d56013Sjoerg }
127*82d56013Sjoerg 
orderValue(const Value * V,OrderMap & OM)1287330f729Sjoerg static void orderValue(const Value *V, OrderMap &OM) {
1297330f729Sjoerg   if (OM.lookup(V).first)
1307330f729Sjoerg     return;
1317330f729Sjoerg 
1327330f729Sjoerg   if (const Constant *C = dyn_cast<Constant>(V))
1337330f729Sjoerg     if (C->getNumOperands() && !isa<GlobalValue>(C))
1347330f729Sjoerg       for (const Value *Op : C->operands())
1357330f729Sjoerg         if (!isa<BasicBlock>(Op) && !isa<GlobalValue>(Op))
1367330f729Sjoerg           orderValue(Op, OM);
1377330f729Sjoerg 
1387330f729Sjoerg   // Note: we cannot cache this lookup above, since inserting into the map
1397330f729Sjoerg   // changes the map's size, and thus affects the other IDs.
1407330f729Sjoerg   OM.index(V);
1417330f729Sjoerg }
1427330f729Sjoerg 
orderModule(const Module * M)1437330f729Sjoerg static OrderMap orderModule(const Module *M) {
1447330f729Sjoerg   OrderMap OM;
1457330f729Sjoerg 
1467330f729Sjoerg   for (const GlobalVariable &G : M->globals()) {
1477330f729Sjoerg     if (G.hasInitializer())
1487330f729Sjoerg       if (!isa<GlobalValue>(G.getInitializer()))
1497330f729Sjoerg         orderValue(G.getInitializer(), OM);
1507330f729Sjoerg     orderValue(&G, OM);
1517330f729Sjoerg   }
1527330f729Sjoerg   for (const GlobalAlias &A : M->aliases()) {
1537330f729Sjoerg     if (!isa<GlobalValue>(A.getAliasee()))
1547330f729Sjoerg       orderValue(A.getAliasee(), OM);
1557330f729Sjoerg     orderValue(&A, OM);
1567330f729Sjoerg   }
1577330f729Sjoerg   for (const GlobalIFunc &I : M->ifuncs()) {
1587330f729Sjoerg     if (!isa<GlobalValue>(I.getResolver()))
1597330f729Sjoerg       orderValue(I.getResolver(), OM);
1607330f729Sjoerg     orderValue(&I, OM);
1617330f729Sjoerg   }
1627330f729Sjoerg   for (const Function &F : *M) {
1637330f729Sjoerg     for (const Use &U : F.operands())
1647330f729Sjoerg       if (!isa<GlobalValue>(U.get()))
1657330f729Sjoerg         orderValue(U.get(), OM);
1667330f729Sjoerg 
1677330f729Sjoerg     orderValue(&F, OM);
1687330f729Sjoerg 
1697330f729Sjoerg     if (F.isDeclaration())
1707330f729Sjoerg       continue;
1717330f729Sjoerg 
1727330f729Sjoerg     for (const Argument &A : F.args())
1737330f729Sjoerg       orderValue(&A, OM);
1747330f729Sjoerg     for (const BasicBlock &BB : F) {
1757330f729Sjoerg       orderValue(&BB, OM);
1767330f729Sjoerg       for (const Instruction &I : BB) {
177*82d56013Sjoerg         for (const Value *Op : I.operands()) {
178*82d56013Sjoerg           Op = skipMetadataWrapper(Op);
1797330f729Sjoerg           if ((isa<Constant>(*Op) && !isa<GlobalValue>(*Op)) ||
1807330f729Sjoerg               isa<InlineAsm>(*Op))
1817330f729Sjoerg             orderValue(Op, OM);
182*82d56013Sjoerg         }
1837330f729Sjoerg         orderValue(&I, OM);
1847330f729Sjoerg       }
1857330f729Sjoerg     }
1867330f729Sjoerg   }
1877330f729Sjoerg   return OM;
1887330f729Sjoerg }
1897330f729Sjoerg 
predictValueUseListOrderImpl(const Value * V,const Function * F,unsigned ID,const OrderMap & OM,UseListOrderStack & Stack)1907330f729Sjoerg static void predictValueUseListOrderImpl(const Value *V, const Function *F,
1917330f729Sjoerg                                          unsigned ID, const OrderMap &OM,
1927330f729Sjoerg                                          UseListOrderStack &Stack) {
1937330f729Sjoerg   // Predict use-list order for this one.
1947330f729Sjoerg   using Entry = std::pair<const Use *, unsigned>;
1957330f729Sjoerg   SmallVector<Entry, 64> List;
1967330f729Sjoerg   for (const Use &U : V->uses())
1977330f729Sjoerg     // Check if this user will be serialized.
1987330f729Sjoerg     if (OM.lookup(U.getUser()).first)
1997330f729Sjoerg       List.push_back(std::make_pair(&U, List.size()));
2007330f729Sjoerg 
2017330f729Sjoerg   if (List.size() < 2)
2027330f729Sjoerg     // We may have lost some users.
2037330f729Sjoerg     return;
2047330f729Sjoerg 
2057330f729Sjoerg   bool GetsReversed =
2067330f729Sjoerg       !isa<GlobalVariable>(V) && !isa<Function>(V) && !isa<BasicBlock>(V);
2077330f729Sjoerg   if (auto *BA = dyn_cast<BlockAddress>(V))
2087330f729Sjoerg     ID = OM.lookup(BA->getBasicBlock()).first;
2097330f729Sjoerg   llvm::sort(List, [&](const Entry &L, const Entry &R) {
2107330f729Sjoerg     const Use *LU = L.first;
2117330f729Sjoerg     const Use *RU = R.first;
2127330f729Sjoerg     if (LU == RU)
2137330f729Sjoerg       return false;
2147330f729Sjoerg 
2157330f729Sjoerg     auto LID = OM.lookup(LU->getUser()).first;
2167330f729Sjoerg     auto RID = OM.lookup(RU->getUser()).first;
2177330f729Sjoerg 
2187330f729Sjoerg     // If ID is 4, then expect: 7 6 5 1 2 3.
2197330f729Sjoerg     if (LID < RID) {
2207330f729Sjoerg       if (GetsReversed)
2217330f729Sjoerg         if (RID <= ID)
2227330f729Sjoerg           return true;
2237330f729Sjoerg       return false;
2247330f729Sjoerg     }
2257330f729Sjoerg     if (RID < LID) {
2267330f729Sjoerg       if (GetsReversed)
2277330f729Sjoerg         if (LID <= ID)
2287330f729Sjoerg           return false;
2297330f729Sjoerg       return true;
2307330f729Sjoerg     }
2317330f729Sjoerg 
2327330f729Sjoerg     // LID and RID are equal, so we have different operands of the same user.
2337330f729Sjoerg     // Assume operands are added in order for all instructions.
2347330f729Sjoerg     if (GetsReversed)
2357330f729Sjoerg       if (LID <= ID)
2367330f729Sjoerg         return LU->getOperandNo() < RU->getOperandNo();
2377330f729Sjoerg     return LU->getOperandNo() > RU->getOperandNo();
2387330f729Sjoerg   });
2397330f729Sjoerg 
240*82d56013Sjoerg   if (llvm::is_sorted(List, [](const Entry &L, const Entry &R) {
241*82d56013Sjoerg         return L.second < R.second;
242*82d56013Sjoerg       }))
2437330f729Sjoerg     // Order is already correct.
2447330f729Sjoerg     return;
2457330f729Sjoerg 
2467330f729Sjoerg   // Store the shuffle.
2477330f729Sjoerg   Stack.emplace_back(V, F, List.size());
2487330f729Sjoerg   assert(List.size() == Stack.back().Shuffle.size() && "Wrong size");
2497330f729Sjoerg   for (size_t I = 0, E = List.size(); I != E; ++I)
2507330f729Sjoerg     Stack.back().Shuffle[I] = List[I].second;
2517330f729Sjoerg }
2527330f729Sjoerg 
predictValueUseListOrder(const Value * V,const Function * F,OrderMap & OM,UseListOrderStack & Stack)2537330f729Sjoerg static void predictValueUseListOrder(const Value *V, const Function *F,
2547330f729Sjoerg                                      OrderMap &OM, UseListOrderStack &Stack) {
2557330f729Sjoerg   auto &IDPair = OM[V];
2567330f729Sjoerg   assert(IDPair.first && "Unmapped value");
2577330f729Sjoerg   if (IDPair.second)
2587330f729Sjoerg     // Already predicted.
2597330f729Sjoerg     return;
2607330f729Sjoerg 
2617330f729Sjoerg   // Do the actual prediction.
2627330f729Sjoerg   IDPair.second = true;
2637330f729Sjoerg   if (!V->use_empty() && std::next(V->use_begin()) != V->use_end())
2647330f729Sjoerg     predictValueUseListOrderImpl(V, F, IDPair.first, OM, Stack);
2657330f729Sjoerg 
2667330f729Sjoerg   // Recursive descent into constants.
2677330f729Sjoerg   if (const Constant *C = dyn_cast<Constant>(V))
2687330f729Sjoerg     if (C->getNumOperands()) // Visit GlobalValues.
2697330f729Sjoerg       for (const Value *Op : C->operands())
2707330f729Sjoerg         if (isa<Constant>(Op)) // Visit GlobalValues.
2717330f729Sjoerg           predictValueUseListOrder(Op, F, OM, Stack);
2727330f729Sjoerg }
2737330f729Sjoerg 
predictUseListOrder(const Module * M)2747330f729Sjoerg static UseListOrderStack predictUseListOrder(const Module *M) {
2757330f729Sjoerg   OrderMap OM = orderModule(M);
2767330f729Sjoerg 
2777330f729Sjoerg   // Use-list orders need to be serialized after all the users have been added
2787330f729Sjoerg   // to a value, or else the shuffles will be incomplete.  Store them per
2797330f729Sjoerg   // function in a stack.
2807330f729Sjoerg   //
2817330f729Sjoerg   // Aside from function order, the order of values doesn't matter much here.
2827330f729Sjoerg   UseListOrderStack Stack;
2837330f729Sjoerg 
2847330f729Sjoerg   // We want to visit the functions backward now so we can list function-local
2857330f729Sjoerg   // constants in the last Function they're used in.  Module-level constants
2867330f729Sjoerg   // have already been visited above.
2877330f729Sjoerg   for (const Function &F : make_range(M->rbegin(), M->rend())) {
2887330f729Sjoerg     if (F.isDeclaration())
2897330f729Sjoerg       continue;
2907330f729Sjoerg     for (const BasicBlock &BB : F)
2917330f729Sjoerg       predictValueUseListOrder(&BB, &F, OM, Stack);
2927330f729Sjoerg     for (const Argument &A : F.args())
2937330f729Sjoerg       predictValueUseListOrder(&A, &F, OM, Stack);
2947330f729Sjoerg     for (const BasicBlock &BB : F)
2957330f729Sjoerg       for (const Instruction &I : BB)
296*82d56013Sjoerg         for (const Value *Op : I.operands()) {
297*82d56013Sjoerg           Op = skipMetadataWrapper(Op);
2987330f729Sjoerg           if (isa<Constant>(*Op) || isa<InlineAsm>(*Op)) // Visit GlobalValues.
2997330f729Sjoerg             predictValueUseListOrder(Op, &F, OM, Stack);
300*82d56013Sjoerg         }
3017330f729Sjoerg     for (const BasicBlock &BB : F)
3027330f729Sjoerg       for (const Instruction &I : BB)
3037330f729Sjoerg         predictValueUseListOrder(&I, &F, OM, Stack);
3047330f729Sjoerg   }
3057330f729Sjoerg 
3067330f729Sjoerg   // Visit globals last.
3077330f729Sjoerg   for (const GlobalVariable &G : M->globals())
3087330f729Sjoerg     predictValueUseListOrder(&G, nullptr, OM, Stack);
3097330f729Sjoerg   for (const Function &F : *M)
3107330f729Sjoerg     predictValueUseListOrder(&F, nullptr, OM, Stack);
3117330f729Sjoerg   for (const GlobalAlias &A : M->aliases())
3127330f729Sjoerg     predictValueUseListOrder(&A, nullptr, OM, Stack);
3137330f729Sjoerg   for (const GlobalIFunc &I : M->ifuncs())
3147330f729Sjoerg     predictValueUseListOrder(&I, nullptr, OM, Stack);
3157330f729Sjoerg   for (const GlobalVariable &G : M->globals())
3167330f729Sjoerg     if (G.hasInitializer())
3177330f729Sjoerg       predictValueUseListOrder(G.getInitializer(), nullptr, OM, Stack);
3187330f729Sjoerg   for (const GlobalAlias &A : M->aliases())
3197330f729Sjoerg     predictValueUseListOrder(A.getAliasee(), nullptr, OM, Stack);
3207330f729Sjoerg   for (const GlobalIFunc &I : M->ifuncs())
3217330f729Sjoerg     predictValueUseListOrder(I.getResolver(), nullptr, OM, Stack);
3227330f729Sjoerg   for (const Function &F : *M)
3237330f729Sjoerg     for (const Use &U : F.operands())
3247330f729Sjoerg       predictValueUseListOrder(U.get(), nullptr, OM, Stack);
3257330f729Sjoerg 
3267330f729Sjoerg   return Stack;
3277330f729Sjoerg }
3287330f729Sjoerg 
getModuleFromVal(const Value * V)3297330f729Sjoerg static const Module *getModuleFromVal(const Value *V) {
3307330f729Sjoerg   if (const Argument *MA = dyn_cast<Argument>(V))
3317330f729Sjoerg     return MA->getParent() ? MA->getParent()->getParent() : nullptr;
3327330f729Sjoerg 
3337330f729Sjoerg   if (const BasicBlock *BB = dyn_cast<BasicBlock>(V))
3347330f729Sjoerg     return BB->getParent() ? BB->getParent()->getParent() : nullptr;
3357330f729Sjoerg 
3367330f729Sjoerg   if (const Instruction *I = dyn_cast<Instruction>(V)) {
3377330f729Sjoerg     const Function *M = I->getParent() ? I->getParent()->getParent() : nullptr;
3387330f729Sjoerg     return M ? M->getParent() : nullptr;
3397330f729Sjoerg   }
3407330f729Sjoerg 
3417330f729Sjoerg   if (const GlobalValue *GV = dyn_cast<GlobalValue>(V))
3427330f729Sjoerg     return GV->getParent();
3437330f729Sjoerg 
3447330f729Sjoerg   if (const auto *MAV = dyn_cast<MetadataAsValue>(V)) {
3457330f729Sjoerg     for (const User *U : MAV->users())
3467330f729Sjoerg       if (isa<Instruction>(U))
3477330f729Sjoerg         if (const Module *M = getModuleFromVal(U))
3487330f729Sjoerg           return M;
3497330f729Sjoerg     return nullptr;
3507330f729Sjoerg   }
3517330f729Sjoerg 
3527330f729Sjoerg   return nullptr;
3537330f729Sjoerg }
3547330f729Sjoerg 
PrintCallingConv(unsigned cc,raw_ostream & Out)3557330f729Sjoerg static void PrintCallingConv(unsigned cc, raw_ostream &Out) {
3567330f729Sjoerg   switch (cc) {
3577330f729Sjoerg   default:                         Out << "cc" << cc; break;
3587330f729Sjoerg   case CallingConv::Fast:          Out << "fastcc"; break;
3597330f729Sjoerg   case CallingConv::Cold:          Out << "coldcc"; break;
3607330f729Sjoerg   case CallingConv::WebKit_JS:     Out << "webkit_jscc"; break;
3617330f729Sjoerg   case CallingConv::AnyReg:        Out << "anyregcc"; break;
3627330f729Sjoerg   case CallingConv::PreserveMost:  Out << "preserve_mostcc"; break;
3637330f729Sjoerg   case CallingConv::PreserveAll:   Out << "preserve_allcc"; break;
3647330f729Sjoerg   case CallingConv::CXX_FAST_TLS:  Out << "cxx_fast_tlscc"; break;
3657330f729Sjoerg   case CallingConv::GHC:           Out << "ghccc"; break;
3667330f729Sjoerg   case CallingConv::Tail:          Out << "tailcc"; break;
3677330f729Sjoerg   case CallingConv::CFGuard_Check: Out << "cfguard_checkcc"; break;
3687330f729Sjoerg   case CallingConv::X86_StdCall:   Out << "x86_stdcallcc"; break;
3697330f729Sjoerg   case CallingConv::X86_FastCall:  Out << "x86_fastcallcc"; break;
3707330f729Sjoerg   case CallingConv::X86_ThisCall:  Out << "x86_thiscallcc"; break;
3717330f729Sjoerg   case CallingConv::X86_RegCall:   Out << "x86_regcallcc"; break;
3727330f729Sjoerg   case CallingConv::X86_VectorCall:Out << "x86_vectorcallcc"; break;
3737330f729Sjoerg   case CallingConv::Intel_OCL_BI:  Out << "intel_ocl_bicc"; break;
3747330f729Sjoerg   case CallingConv::ARM_APCS:      Out << "arm_apcscc"; break;
3757330f729Sjoerg   case CallingConv::ARM_AAPCS:     Out << "arm_aapcscc"; break;
3767330f729Sjoerg   case CallingConv::ARM_AAPCS_VFP: Out << "arm_aapcs_vfpcc"; break;
3777330f729Sjoerg   case CallingConv::AArch64_VectorCall: Out << "aarch64_vector_pcs"; break;
378*82d56013Sjoerg   case CallingConv::AArch64_SVE_VectorCall:
379*82d56013Sjoerg     Out << "aarch64_sve_vector_pcs";
380*82d56013Sjoerg     break;
3817330f729Sjoerg   case CallingConv::MSP430_INTR:   Out << "msp430_intrcc"; break;
3827330f729Sjoerg   case CallingConv::AVR_INTR:      Out << "avr_intrcc "; break;
3837330f729Sjoerg   case CallingConv::AVR_SIGNAL:    Out << "avr_signalcc "; break;
3847330f729Sjoerg   case CallingConv::PTX_Kernel:    Out << "ptx_kernel"; break;
3857330f729Sjoerg   case CallingConv::PTX_Device:    Out << "ptx_device"; break;
3867330f729Sjoerg   case CallingConv::X86_64_SysV:   Out << "x86_64_sysvcc"; break;
3877330f729Sjoerg   case CallingConv::Win64:         Out << "win64cc"; break;
3887330f729Sjoerg   case CallingConv::SPIR_FUNC:     Out << "spir_func"; break;
3897330f729Sjoerg   case CallingConv::SPIR_KERNEL:   Out << "spir_kernel"; break;
3907330f729Sjoerg   case CallingConv::Swift:         Out << "swiftcc"; break;
391*82d56013Sjoerg   case CallingConv::SwiftTail:     Out << "swifttailcc"; break;
3927330f729Sjoerg   case CallingConv::X86_INTR:      Out << "x86_intrcc"; break;
3937330f729Sjoerg   case CallingConv::HHVM:          Out << "hhvmcc"; break;
3947330f729Sjoerg   case CallingConv::HHVM_C:        Out << "hhvm_ccc"; break;
3957330f729Sjoerg   case CallingConv::AMDGPU_VS:     Out << "amdgpu_vs"; break;
3967330f729Sjoerg   case CallingConv::AMDGPU_LS:     Out << "amdgpu_ls"; break;
3977330f729Sjoerg   case CallingConv::AMDGPU_HS:     Out << "amdgpu_hs"; break;
3987330f729Sjoerg   case CallingConv::AMDGPU_ES:     Out << "amdgpu_es"; break;
3997330f729Sjoerg   case CallingConv::AMDGPU_GS:     Out << "amdgpu_gs"; break;
4007330f729Sjoerg   case CallingConv::AMDGPU_PS:     Out << "amdgpu_ps"; break;
4017330f729Sjoerg   case CallingConv::AMDGPU_CS:     Out << "amdgpu_cs"; break;
4027330f729Sjoerg   case CallingConv::AMDGPU_KERNEL: Out << "amdgpu_kernel"; break;
403*82d56013Sjoerg   case CallingConv::AMDGPU_Gfx:    Out << "amdgpu_gfx"; break;
4047330f729Sjoerg   }
4057330f729Sjoerg }
4067330f729Sjoerg 
4077330f729Sjoerg enum PrefixType {
4087330f729Sjoerg   GlobalPrefix,
4097330f729Sjoerg   ComdatPrefix,
4107330f729Sjoerg   LabelPrefix,
4117330f729Sjoerg   LocalPrefix,
4127330f729Sjoerg   NoPrefix
4137330f729Sjoerg };
4147330f729Sjoerg 
printLLVMNameWithoutPrefix(raw_ostream & OS,StringRef Name)4157330f729Sjoerg void llvm::printLLVMNameWithoutPrefix(raw_ostream &OS, StringRef Name) {
4167330f729Sjoerg   assert(!Name.empty() && "Cannot get empty name!");
4177330f729Sjoerg 
4187330f729Sjoerg   // Scan the name to see if it needs quotes first.
4197330f729Sjoerg   bool NeedsQuotes = isdigit(static_cast<unsigned char>(Name[0]));
4207330f729Sjoerg   if (!NeedsQuotes) {
4217330f729Sjoerg     for (unsigned i = 0, e = Name.size(); i != e; ++i) {
4227330f729Sjoerg       // By making this unsigned, the value passed in to isalnum will always be
4237330f729Sjoerg       // in the range 0-255.  This is important when building with MSVC because
4247330f729Sjoerg       // its implementation will assert.  This situation can arise when dealing
4257330f729Sjoerg       // with UTF-8 multibyte characters.
4267330f729Sjoerg       unsigned char C = Name[i];
4277330f729Sjoerg       if (!isalnum(static_cast<unsigned char>(C)) && C != '-' && C != '.' &&
4287330f729Sjoerg           C != '_') {
4297330f729Sjoerg         NeedsQuotes = true;
4307330f729Sjoerg         break;
4317330f729Sjoerg       }
4327330f729Sjoerg     }
4337330f729Sjoerg   }
4347330f729Sjoerg 
4357330f729Sjoerg   // If we didn't need any quotes, just write out the name in one blast.
4367330f729Sjoerg   if (!NeedsQuotes) {
4377330f729Sjoerg     OS << Name;
4387330f729Sjoerg     return;
4397330f729Sjoerg   }
4407330f729Sjoerg 
4417330f729Sjoerg   // Okay, we need quotes.  Output the quotes and escape any scary characters as
4427330f729Sjoerg   // needed.
4437330f729Sjoerg   OS << '"';
4447330f729Sjoerg   printEscapedString(Name, OS);
4457330f729Sjoerg   OS << '"';
4467330f729Sjoerg }
4477330f729Sjoerg 
4487330f729Sjoerg /// Turn the specified name into an 'LLVM name', which is either prefixed with %
4497330f729Sjoerg /// (if the string only contains simple characters) or is surrounded with ""'s
4507330f729Sjoerg /// (if it has special chars in it). Print it out.
PrintLLVMName(raw_ostream & OS,StringRef Name,PrefixType Prefix)4517330f729Sjoerg static void PrintLLVMName(raw_ostream &OS, StringRef Name, PrefixType Prefix) {
4527330f729Sjoerg   switch (Prefix) {
4537330f729Sjoerg   case NoPrefix:
4547330f729Sjoerg     break;
4557330f729Sjoerg   case GlobalPrefix:
4567330f729Sjoerg     OS << '@';
4577330f729Sjoerg     break;
4587330f729Sjoerg   case ComdatPrefix:
4597330f729Sjoerg     OS << '$';
4607330f729Sjoerg     break;
4617330f729Sjoerg   case LabelPrefix:
4627330f729Sjoerg     break;
4637330f729Sjoerg   case LocalPrefix:
4647330f729Sjoerg     OS << '%';
4657330f729Sjoerg     break;
4667330f729Sjoerg   }
4677330f729Sjoerg   printLLVMNameWithoutPrefix(OS, Name);
4687330f729Sjoerg }
4697330f729Sjoerg 
4707330f729Sjoerg /// Turn the specified name into an 'LLVM name', which is either prefixed with %
4717330f729Sjoerg /// (if the string only contains simple characters) or is surrounded with ""'s
4727330f729Sjoerg /// (if it has special chars in it). Print it out.
PrintLLVMName(raw_ostream & OS,const Value * V)4737330f729Sjoerg static void PrintLLVMName(raw_ostream &OS, const Value *V) {
4747330f729Sjoerg   PrintLLVMName(OS, V->getName(),
4757330f729Sjoerg                 isa<GlobalValue>(V) ? GlobalPrefix : LocalPrefix);
4767330f729Sjoerg }
4777330f729Sjoerg 
PrintShuffleMask(raw_ostream & Out,Type * Ty,ArrayRef<int> Mask)478*82d56013Sjoerg static void PrintShuffleMask(raw_ostream &Out, Type *Ty, ArrayRef<int> Mask) {
479*82d56013Sjoerg   Out << ", <";
480*82d56013Sjoerg   if (isa<ScalableVectorType>(Ty))
481*82d56013Sjoerg     Out << "vscale x ";
482*82d56013Sjoerg   Out << Mask.size() << " x i32> ";
483*82d56013Sjoerg   bool FirstElt = true;
484*82d56013Sjoerg   if (all_of(Mask, [](int Elt) { return Elt == 0; })) {
485*82d56013Sjoerg     Out << "zeroinitializer";
486*82d56013Sjoerg   } else if (all_of(Mask, [](int Elt) { return Elt == UndefMaskElem; })) {
487*82d56013Sjoerg     Out << "undef";
488*82d56013Sjoerg   } else {
489*82d56013Sjoerg     Out << "<";
490*82d56013Sjoerg     for (int Elt : Mask) {
491*82d56013Sjoerg       if (FirstElt)
492*82d56013Sjoerg         FirstElt = false;
493*82d56013Sjoerg       else
494*82d56013Sjoerg         Out << ", ";
495*82d56013Sjoerg       Out << "i32 ";
496*82d56013Sjoerg       if (Elt == UndefMaskElem)
497*82d56013Sjoerg         Out << "undef";
498*82d56013Sjoerg       else
499*82d56013Sjoerg         Out << Elt;
500*82d56013Sjoerg     }
501*82d56013Sjoerg     Out << ">";
502*82d56013Sjoerg   }
503*82d56013Sjoerg }
504*82d56013Sjoerg 
5057330f729Sjoerg namespace {
5067330f729Sjoerg 
5077330f729Sjoerg class TypePrinting {
5087330f729Sjoerg public:
TypePrinting(const Module * M=nullptr)5097330f729Sjoerg   TypePrinting(const Module *M = nullptr) : DeferredM(M) {}
5107330f729Sjoerg 
5117330f729Sjoerg   TypePrinting(const TypePrinting &) = delete;
5127330f729Sjoerg   TypePrinting &operator=(const TypePrinting &) = delete;
5137330f729Sjoerg 
5147330f729Sjoerg   /// The named types that are used by the current module.
5157330f729Sjoerg   TypeFinder &getNamedTypes();
5167330f729Sjoerg 
5177330f729Sjoerg   /// The numbered types, number to type mapping.
5187330f729Sjoerg   std::vector<StructType *> &getNumberedTypes();
5197330f729Sjoerg 
5207330f729Sjoerg   bool empty();
5217330f729Sjoerg 
5227330f729Sjoerg   void print(Type *Ty, raw_ostream &OS);
5237330f729Sjoerg 
5247330f729Sjoerg   void printStructBody(StructType *Ty, raw_ostream &OS);
5257330f729Sjoerg 
5267330f729Sjoerg private:
5277330f729Sjoerg   void incorporateTypes();
5287330f729Sjoerg 
5297330f729Sjoerg   /// A module to process lazily when needed. Set to nullptr as soon as used.
5307330f729Sjoerg   const Module *DeferredM;
5317330f729Sjoerg 
5327330f729Sjoerg   TypeFinder NamedTypes;
5337330f729Sjoerg 
5347330f729Sjoerg   // The numbered types, along with their value.
5357330f729Sjoerg   DenseMap<StructType *, unsigned> Type2Number;
5367330f729Sjoerg 
5377330f729Sjoerg   std::vector<StructType *> NumberedTypes;
5387330f729Sjoerg };
5397330f729Sjoerg 
5407330f729Sjoerg } // end anonymous namespace
5417330f729Sjoerg 
getNamedTypes()5427330f729Sjoerg TypeFinder &TypePrinting::getNamedTypes() {
5437330f729Sjoerg   incorporateTypes();
5447330f729Sjoerg   return NamedTypes;
5457330f729Sjoerg }
5467330f729Sjoerg 
getNumberedTypes()5477330f729Sjoerg std::vector<StructType *> &TypePrinting::getNumberedTypes() {
5487330f729Sjoerg   incorporateTypes();
5497330f729Sjoerg 
5507330f729Sjoerg   // We know all the numbers that each type is used and we know that it is a
5517330f729Sjoerg   // dense assignment. Convert the map to an index table, if it's not done
5527330f729Sjoerg   // already (judging from the sizes):
5537330f729Sjoerg   if (NumberedTypes.size() == Type2Number.size())
5547330f729Sjoerg     return NumberedTypes;
5557330f729Sjoerg 
5567330f729Sjoerg   NumberedTypes.resize(Type2Number.size());
5577330f729Sjoerg   for (const auto &P : Type2Number) {
5587330f729Sjoerg     assert(P.second < NumberedTypes.size() && "Didn't get a dense numbering?");
5597330f729Sjoerg     assert(!NumberedTypes[P.second] && "Didn't get a unique numbering?");
5607330f729Sjoerg     NumberedTypes[P.second] = P.first;
5617330f729Sjoerg   }
5627330f729Sjoerg   return NumberedTypes;
5637330f729Sjoerg }
5647330f729Sjoerg 
empty()5657330f729Sjoerg bool TypePrinting::empty() {
5667330f729Sjoerg   incorporateTypes();
5677330f729Sjoerg   return NamedTypes.empty() && Type2Number.empty();
5687330f729Sjoerg }
5697330f729Sjoerg 
incorporateTypes()5707330f729Sjoerg void TypePrinting::incorporateTypes() {
5717330f729Sjoerg   if (!DeferredM)
5727330f729Sjoerg     return;
5737330f729Sjoerg 
5747330f729Sjoerg   NamedTypes.run(*DeferredM, false);
5757330f729Sjoerg   DeferredM = nullptr;
5767330f729Sjoerg 
5777330f729Sjoerg   // The list of struct types we got back includes all the struct types, split
5787330f729Sjoerg   // the unnamed ones out to a numbering and remove the anonymous structs.
5797330f729Sjoerg   unsigned NextNumber = 0;
5807330f729Sjoerg 
5817330f729Sjoerg   std::vector<StructType*>::iterator NextToUse = NamedTypes.begin(), I, E;
5827330f729Sjoerg   for (I = NamedTypes.begin(), E = NamedTypes.end(); I != E; ++I) {
5837330f729Sjoerg     StructType *STy = *I;
5847330f729Sjoerg 
5857330f729Sjoerg     // Ignore anonymous types.
5867330f729Sjoerg     if (STy->isLiteral())
5877330f729Sjoerg       continue;
5887330f729Sjoerg 
5897330f729Sjoerg     if (STy->getName().empty())
5907330f729Sjoerg       Type2Number[STy] = NextNumber++;
5917330f729Sjoerg     else
5927330f729Sjoerg       *NextToUse++ = STy;
5937330f729Sjoerg   }
5947330f729Sjoerg 
5957330f729Sjoerg   NamedTypes.erase(NextToUse, NamedTypes.end());
5967330f729Sjoerg }
5977330f729Sjoerg 
5987330f729Sjoerg /// Write the specified type to the specified raw_ostream, making use of type
5997330f729Sjoerg /// names or up references to shorten the type name where possible.
print(Type * Ty,raw_ostream & OS)6007330f729Sjoerg void TypePrinting::print(Type *Ty, raw_ostream &OS) {
6017330f729Sjoerg   switch (Ty->getTypeID()) {
6027330f729Sjoerg   case Type::VoidTyID:      OS << "void"; return;
6037330f729Sjoerg   case Type::HalfTyID:      OS << "half"; return;
604*82d56013Sjoerg   case Type::BFloatTyID:    OS << "bfloat"; return;
6057330f729Sjoerg   case Type::FloatTyID:     OS << "float"; return;
6067330f729Sjoerg   case Type::DoubleTyID:    OS << "double"; return;
6077330f729Sjoerg   case Type::X86_FP80TyID:  OS << "x86_fp80"; return;
6087330f729Sjoerg   case Type::FP128TyID:     OS << "fp128"; return;
6097330f729Sjoerg   case Type::PPC_FP128TyID: OS << "ppc_fp128"; return;
6107330f729Sjoerg   case Type::LabelTyID:     OS << "label"; return;
6117330f729Sjoerg   case Type::MetadataTyID:  OS << "metadata"; return;
6127330f729Sjoerg   case Type::X86_MMXTyID:   OS << "x86_mmx"; return;
613*82d56013Sjoerg   case Type::X86_AMXTyID:   OS << "x86_amx"; return;
6147330f729Sjoerg   case Type::TokenTyID:     OS << "token"; return;
6157330f729Sjoerg   case Type::IntegerTyID:
6167330f729Sjoerg     OS << 'i' << cast<IntegerType>(Ty)->getBitWidth();
6177330f729Sjoerg     return;
6187330f729Sjoerg 
6197330f729Sjoerg   case Type::FunctionTyID: {
6207330f729Sjoerg     FunctionType *FTy = cast<FunctionType>(Ty);
6217330f729Sjoerg     print(FTy->getReturnType(), OS);
6227330f729Sjoerg     OS << " (";
6237330f729Sjoerg     for (FunctionType::param_iterator I = FTy->param_begin(),
6247330f729Sjoerg          E = FTy->param_end(); I != E; ++I) {
6257330f729Sjoerg       if (I != FTy->param_begin())
6267330f729Sjoerg         OS << ", ";
6277330f729Sjoerg       print(*I, OS);
6287330f729Sjoerg     }
6297330f729Sjoerg     if (FTy->isVarArg()) {
6307330f729Sjoerg       if (FTy->getNumParams()) OS << ", ";
6317330f729Sjoerg       OS << "...";
6327330f729Sjoerg     }
6337330f729Sjoerg     OS << ')';
6347330f729Sjoerg     return;
6357330f729Sjoerg   }
6367330f729Sjoerg   case Type::StructTyID: {
6377330f729Sjoerg     StructType *STy = cast<StructType>(Ty);
6387330f729Sjoerg 
6397330f729Sjoerg     if (STy->isLiteral())
6407330f729Sjoerg       return printStructBody(STy, OS);
6417330f729Sjoerg 
6427330f729Sjoerg     if (!STy->getName().empty())
6437330f729Sjoerg       return PrintLLVMName(OS, STy->getName(), LocalPrefix);
6447330f729Sjoerg 
6457330f729Sjoerg     incorporateTypes();
6467330f729Sjoerg     const auto I = Type2Number.find(STy);
6477330f729Sjoerg     if (I != Type2Number.end())
6487330f729Sjoerg       OS << '%' << I->second;
6497330f729Sjoerg     else  // Not enumerated, print the hex address.
6507330f729Sjoerg       OS << "%\"type " << STy << '\"';
6517330f729Sjoerg     return;
6527330f729Sjoerg   }
6537330f729Sjoerg   case Type::PointerTyID: {
6547330f729Sjoerg     PointerType *PTy = cast<PointerType>(Ty);
655*82d56013Sjoerg     if (PTy->isOpaque()) {
656*82d56013Sjoerg       OS << "ptr";
657*82d56013Sjoerg       if (unsigned AddressSpace = PTy->getAddressSpace())
658*82d56013Sjoerg         OS << " addrspace(" << AddressSpace << ')';
659*82d56013Sjoerg       return;
660*82d56013Sjoerg     }
6617330f729Sjoerg     print(PTy->getElementType(), OS);
6627330f729Sjoerg     if (unsigned AddressSpace = PTy->getAddressSpace())
6637330f729Sjoerg       OS << " addrspace(" << AddressSpace << ')';
6647330f729Sjoerg     OS << '*';
6657330f729Sjoerg     return;
6667330f729Sjoerg   }
6677330f729Sjoerg   case Type::ArrayTyID: {
6687330f729Sjoerg     ArrayType *ATy = cast<ArrayType>(Ty);
6697330f729Sjoerg     OS << '[' << ATy->getNumElements() << " x ";
6707330f729Sjoerg     print(ATy->getElementType(), OS);
6717330f729Sjoerg     OS << ']';
6727330f729Sjoerg     return;
6737330f729Sjoerg   }
674*82d56013Sjoerg   case Type::FixedVectorTyID:
675*82d56013Sjoerg   case Type::ScalableVectorTyID: {
6767330f729Sjoerg     VectorType *PTy = cast<VectorType>(Ty);
677*82d56013Sjoerg     ElementCount EC = PTy->getElementCount();
6787330f729Sjoerg     OS << "<";
679*82d56013Sjoerg     if (EC.isScalable())
6807330f729Sjoerg       OS << "vscale x ";
681*82d56013Sjoerg     OS << EC.getKnownMinValue() << " x ";
6827330f729Sjoerg     print(PTy->getElementType(), OS);
6837330f729Sjoerg     OS << '>';
6847330f729Sjoerg     return;
6857330f729Sjoerg   }
6867330f729Sjoerg   }
6877330f729Sjoerg   llvm_unreachable("Invalid TypeID");
6887330f729Sjoerg }
6897330f729Sjoerg 
printStructBody(StructType * STy,raw_ostream & OS)6907330f729Sjoerg void TypePrinting::printStructBody(StructType *STy, raw_ostream &OS) {
6917330f729Sjoerg   if (STy->isOpaque()) {
6927330f729Sjoerg     OS << "opaque";
6937330f729Sjoerg     return;
6947330f729Sjoerg   }
6957330f729Sjoerg 
6967330f729Sjoerg   if (STy->isPacked())
6977330f729Sjoerg     OS << '<';
6987330f729Sjoerg 
6997330f729Sjoerg   if (STy->getNumElements() == 0) {
7007330f729Sjoerg     OS << "{}";
7017330f729Sjoerg   } else {
7027330f729Sjoerg     StructType::element_iterator I = STy->element_begin();
7037330f729Sjoerg     OS << "{ ";
7047330f729Sjoerg     print(*I++, OS);
7057330f729Sjoerg     for (StructType::element_iterator E = STy->element_end(); I != E; ++I) {
7067330f729Sjoerg       OS << ", ";
7077330f729Sjoerg       print(*I, OS);
7087330f729Sjoerg     }
7097330f729Sjoerg 
7107330f729Sjoerg     OS << " }";
7117330f729Sjoerg   }
7127330f729Sjoerg   if (STy->isPacked())
7137330f729Sjoerg     OS << '>';
7147330f729Sjoerg }
7157330f729Sjoerg 
7167330f729Sjoerg namespace llvm {
7177330f729Sjoerg 
7187330f729Sjoerg //===----------------------------------------------------------------------===//
7197330f729Sjoerg // SlotTracker Class: Enumerate slot numbers for unnamed values
7207330f729Sjoerg //===----------------------------------------------------------------------===//
7217330f729Sjoerg /// This class provides computation of slot numbers for LLVM Assembly writing.
7227330f729Sjoerg ///
7237330f729Sjoerg class SlotTracker {
7247330f729Sjoerg public:
7257330f729Sjoerg   /// ValueMap - A mapping of Values to slot numbers.
7267330f729Sjoerg   using ValueMap = DenseMap<const Value *, unsigned>;
7277330f729Sjoerg 
7287330f729Sjoerg private:
7297330f729Sjoerg   /// TheModule - The module for which we are holding slot numbers.
7307330f729Sjoerg   const Module* TheModule;
7317330f729Sjoerg 
7327330f729Sjoerg   /// TheFunction - The function for which we are holding slot numbers.
7337330f729Sjoerg   const Function* TheFunction = nullptr;
7347330f729Sjoerg   bool FunctionProcessed = false;
7357330f729Sjoerg   bool ShouldInitializeAllMetadata;
7367330f729Sjoerg 
7377330f729Sjoerg   /// The summary index for which we are holding slot numbers.
7387330f729Sjoerg   const ModuleSummaryIndex *TheIndex = nullptr;
7397330f729Sjoerg 
7407330f729Sjoerg   /// mMap - The slot map for the module level data.
7417330f729Sjoerg   ValueMap mMap;
7427330f729Sjoerg   unsigned mNext = 0;
7437330f729Sjoerg 
7447330f729Sjoerg   /// fMap - The slot map for the function level data.
7457330f729Sjoerg   ValueMap fMap;
7467330f729Sjoerg   unsigned fNext = 0;
7477330f729Sjoerg 
7487330f729Sjoerg   /// mdnMap - Map for MDNodes.
7497330f729Sjoerg   DenseMap<const MDNode*, unsigned> mdnMap;
7507330f729Sjoerg   unsigned mdnNext = 0;
7517330f729Sjoerg 
7527330f729Sjoerg   /// asMap - The slot map for attribute sets.
7537330f729Sjoerg   DenseMap<AttributeSet, unsigned> asMap;
7547330f729Sjoerg   unsigned asNext = 0;
7557330f729Sjoerg 
7567330f729Sjoerg   /// ModulePathMap - The slot map for Module paths used in the summary index.
7577330f729Sjoerg   StringMap<unsigned> ModulePathMap;
7587330f729Sjoerg   unsigned ModulePathNext = 0;
7597330f729Sjoerg 
7607330f729Sjoerg   /// GUIDMap - The slot map for GUIDs used in the summary index.
7617330f729Sjoerg   DenseMap<GlobalValue::GUID, unsigned> GUIDMap;
7627330f729Sjoerg   unsigned GUIDNext = 0;
7637330f729Sjoerg 
7647330f729Sjoerg   /// TypeIdMap - The slot map for type ids used in the summary index.
7657330f729Sjoerg   StringMap<unsigned> TypeIdMap;
7667330f729Sjoerg   unsigned TypeIdNext = 0;
7677330f729Sjoerg 
7687330f729Sjoerg public:
7697330f729Sjoerg   /// Construct from a module.
7707330f729Sjoerg   ///
7717330f729Sjoerg   /// If \c ShouldInitializeAllMetadata, initializes all metadata in all
7727330f729Sjoerg   /// functions, giving correct numbering for metadata referenced only from
7737330f729Sjoerg   /// within a function (even if no functions have been initialized).
7747330f729Sjoerg   explicit SlotTracker(const Module *M,
7757330f729Sjoerg                        bool ShouldInitializeAllMetadata = false);
7767330f729Sjoerg 
7777330f729Sjoerg   /// Construct from a function, starting out in incorp state.
7787330f729Sjoerg   ///
7797330f729Sjoerg   /// If \c ShouldInitializeAllMetadata, initializes all metadata in all
7807330f729Sjoerg   /// functions, giving correct numbering for metadata referenced only from
7817330f729Sjoerg   /// within a function (even if no functions have been initialized).
7827330f729Sjoerg   explicit SlotTracker(const Function *F,
7837330f729Sjoerg                        bool ShouldInitializeAllMetadata = false);
7847330f729Sjoerg 
7857330f729Sjoerg   /// Construct from a module summary index.
7867330f729Sjoerg   explicit SlotTracker(const ModuleSummaryIndex *Index);
7877330f729Sjoerg 
7887330f729Sjoerg   SlotTracker(const SlotTracker &) = delete;
7897330f729Sjoerg   SlotTracker &operator=(const SlotTracker &) = delete;
7907330f729Sjoerg 
7917330f729Sjoerg   /// Return the slot number of the specified value in it's type
7927330f729Sjoerg   /// plane.  If something is not in the SlotTracker, return -1.
7937330f729Sjoerg   int getLocalSlot(const Value *V);
7947330f729Sjoerg   int getGlobalSlot(const GlobalValue *V);
7957330f729Sjoerg   int getMetadataSlot(const MDNode *N);
7967330f729Sjoerg   int getAttributeGroupSlot(AttributeSet AS);
7977330f729Sjoerg   int getModulePathSlot(StringRef Path);
7987330f729Sjoerg   int getGUIDSlot(GlobalValue::GUID GUID);
7997330f729Sjoerg   int getTypeIdSlot(StringRef Id);
8007330f729Sjoerg 
8017330f729Sjoerg   /// If you'd like to deal with a function instead of just a module, use
8027330f729Sjoerg   /// this method to get its data into the SlotTracker.
incorporateFunction(const Function * F)8037330f729Sjoerg   void incorporateFunction(const Function *F) {
8047330f729Sjoerg     TheFunction = F;
8057330f729Sjoerg     FunctionProcessed = false;
8067330f729Sjoerg   }
8077330f729Sjoerg 
getFunction() const8087330f729Sjoerg   const Function *getFunction() const { return TheFunction; }
8097330f729Sjoerg 
8107330f729Sjoerg   /// After calling incorporateFunction, use this method to remove the
8117330f729Sjoerg   /// most recently incorporated function from the SlotTracker. This
8127330f729Sjoerg   /// will reset the state of the machine back to just the module contents.
8137330f729Sjoerg   void purgeFunction();
8147330f729Sjoerg 
8157330f729Sjoerg   /// MDNode map iterators.
8167330f729Sjoerg   using mdn_iterator = DenseMap<const MDNode*, unsigned>::iterator;
8177330f729Sjoerg 
mdn_begin()8187330f729Sjoerg   mdn_iterator mdn_begin() { return mdnMap.begin(); }
mdn_end()8197330f729Sjoerg   mdn_iterator mdn_end() { return mdnMap.end(); }
mdn_size() const8207330f729Sjoerg   unsigned mdn_size() const { return mdnMap.size(); }
mdn_empty() const8217330f729Sjoerg   bool mdn_empty() const { return mdnMap.empty(); }
8227330f729Sjoerg 
8237330f729Sjoerg   /// AttributeSet map iterators.
8247330f729Sjoerg   using as_iterator = DenseMap<AttributeSet, unsigned>::iterator;
8257330f729Sjoerg 
as_begin()8267330f729Sjoerg   as_iterator as_begin()   { return asMap.begin(); }
as_end()8277330f729Sjoerg   as_iterator as_end()     { return asMap.end(); }
as_size() const8287330f729Sjoerg   unsigned as_size() const { return asMap.size(); }
as_empty() const8297330f729Sjoerg   bool as_empty() const    { return asMap.empty(); }
8307330f729Sjoerg 
8317330f729Sjoerg   /// GUID map iterators.
8327330f729Sjoerg   using guid_iterator = DenseMap<GlobalValue::GUID, unsigned>::iterator;
8337330f729Sjoerg 
8347330f729Sjoerg   /// These functions do the actual initialization.
8357330f729Sjoerg   inline void initializeIfNeeded();
836*82d56013Sjoerg   int initializeIndexIfNeeded();
8377330f729Sjoerg 
8387330f729Sjoerg   // Implementation Details
8397330f729Sjoerg private:
8407330f729Sjoerg   /// CreateModuleSlot - Insert the specified GlobalValue* into the slot table.
8417330f729Sjoerg   void CreateModuleSlot(const GlobalValue *V);
8427330f729Sjoerg 
8437330f729Sjoerg   /// CreateMetadataSlot - Insert the specified MDNode* into the slot table.
8447330f729Sjoerg   void CreateMetadataSlot(const MDNode *N);
8457330f729Sjoerg 
8467330f729Sjoerg   /// CreateFunctionSlot - Insert the specified Value* into the slot table.
8477330f729Sjoerg   void CreateFunctionSlot(const Value *V);
8487330f729Sjoerg 
8497330f729Sjoerg   /// Insert the specified AttributeSet into the slot table.
8507330f729Sjoerg   void CreateAttributeSetSlot(AttributeSet AS);
8517330f729Sjoerg 
8527330f729Sjoerg   inline void CreateModulePathSlot(StringRef Path);
8537330f729Sjoerg   void CreateGUIDSlot(GlobalValue::GUID GUID);
8547330f729Sjoerg   void CreateTypeIdSlot(StringRef Id);
8557330f729Sjoerg 
8567330f729Sjoerg   /// Add all of the module level global variables (and their initializers)
8577330f729Sjoerg   /// and function declarations, but not the contents of those functions.
8587330f729Sjoerg   void processModule();
859*82d56013Sjoerg   // Returns number of allocated slots
860*82d56013Sjoerg   int processIndex();
8617330f729Sjoerg 
8627330f729Sjoerg   /// Add all of the functions arguments, basic blocks, and instructions.
8637330f729Sjoerg   void processFunction();
8647330f729Sjoerg 
8657330f729Sjoerg   /// Add the metadata directly attached to a GlobalObject.
8667330f729Sjoerg   void processGlobalObjectMetadata(const GlobalObject &GO);
8677330f729Sjoerg 
8687330f729Sjoerg   /// Add all of the metadata from a function.
8697330f729Sjoerg   void processFunctionMetadata(const Function &F);
8707330f729Sjoerg 
8717330f729Sjoerg   /// Add all of the metadata from an instruction.
8727330f729Sjoerg   void processInstructionMetadata(const Instruction &I);
8737330f729Sjoerg };
8747330f729Sjoerg 
8757330f729Sjoerg } // end namespace llvm
8767330f729Sjoerg 
ModuleSlotTracker(SlotTracker & Machine,const Module * M,const Function * F)8777330f729Sjoerg ModuleSlotTracker::ModuleSlotTracker(SlotTracker &Machine, const Module *M,
8787330f729Sjoerg                                      const Function *F)
8797330f729Sjoerg     : M(M), F(F), Machine(&Machine) {}
8807330f729Sjoerg 
ModuleSlotTracker(const Module * M,bool ShouldInitializeAllMetadata)8817330f729Sjoerg ModuleSlotTracker::ModuleSlotTracker(const Module *M,
8827330f729Sjoerg                                      bool ShouldInitializeAllMetadata)
8837330f729Sjoerg     : ShouldCreateStorage(M),
8847330f729Sjoerg       ShouldInitializeAllMetadata(ShouldInitializeAllMetadata), M(M) {}
8857330f729Sjoerg 
8867330f729Sjoerg ModuleSlotTracker::~ModuleSlotTracker() = default;
8877330f729Sjoerg 
getMachine()8887330f729Sjoerg SlotTracker *ModuleSlotTracker::getMachine() {
8897330f729Sjoerg   if (!ShouldCreateStorage)
8907330f729Sjoerg     return Machine;
8917330f729Sjoerg 
8927330f729Sjoerg   ShouldCreateStorage = false;
8937330f729Sjoerg   MachineStorage =
8947330f729Sjoerg       std::make_unique<SlotTracker>(M, ShouldInitializeAllMetadata);
8957330f729Sjoerg   Machine = MachineStorage.get();
8967330f729Sjoerg   return Machine;
8977330f729Sjoerg }
8987330f729Sjoerg 
incorporateFunction(const Function & F)8997330f729Sjoerg void ModuleSlotTracker::incorporateFunction(const Function &F) {
9007330f729Sjoerg   // Using getMachine() may lazily create the slot tracker.
9017330f729Sjoerg   if (!getMachine())
9027330f729Sjoerg     return;
9037330f729Sjoerg 
9047330f729Sjoerg   // Nothing to do if this is the right function already.
9057330f729Sjoerg   if (this->F == &F)
9067330f729Sjoerg     return;
9077330f729Sjoerg   if (this->F)
9087330f729Sjoerg     Machine->purgeFunction();
9097330f729Sjoerg   Machine->incorporateFunction(&F);
9107330f729Sjoerg   this->F = &F;
9117330f729Sjoerg }
9127330f729Sjoerg 
getLocalSlot(const Value * V)9137330f729Sjoerg int ModuleSlotTracker::getLocalSlot(const Value *V) {
9147330f729Sjoerg   assert(F && "No function incorporated");
9157330f729Sjoerg   return Machine->getLocalSlot(V);
9167330f729Sjoerg }
9177330f729Sjoerg 
createSlotTracker(const Value * V)9187330f729Sjoerg static SlotTracker *createSlotTracker(const Value *V) {
9197330f729Sjoerg   if (const Argument *FA = dyn_cast<Argument>(V))
9207330f729Sjoerg     return new SlotTracker(FA->getParent());
9217330f729Sjoerg 
9227330f729Sjoerg   if (const Instruction *I = dyn_cast<Instruction>(V))
9237330f729Sjoerg     if (I->getParent())
9247330f729Sjoerg       return new SlotTracker(I->getParent()->getParent());
9257330f729Sjoerg 
9267330f729Sjoerg   if (const BasicBlock *BB = dyn_cast<BasicBlock>(V))
9277330f729Sjoerg     return new SlotTracker(BB->getParent());
9287330f729Sjoerg 
9297330f729Sjoerg   if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V))
9307330f729Sjoerg     return new SlotTracker(GV->getParent());
9317330f729Sjoerg 
9327330f729Sjoerg   if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(V))
9337330f729Sjoerg     return new SlotTracker(GA->getParent());
9347330f729Sjoerg 
9357330f729Sjoerg   if (const GlobalIFunc *GIF = dyn_cast<GlobalIFunc>(V))
9367330f729Sjoerg     return new SlotTracker(GIF->getParent());
9377330f729Sjoerg 
9387330f729Sjoerg   if (const Function *Func = dyn_cast<Function>(V))
9397330f729Sjoerg     return new SlotTracker(Func);
9407330f729Sjoerg 
9417330f729Sjoerg   return nullptr;
9427330f729Sjoerg }
9437330f729Sjoerg 
9447330f729Sjoerg #if 0
9457330f729Sjoerg #define ST_DEBUG(X) dbgs() << X
9467330f729Sjoerg #else
9477330f729Sjoerg #define ST_DEBUG(X)
9487330f729Sjoerg #endif
9497330f729Sjoerg 
9507330f729Sjoerg // Module level constructor. Causes the contents of the Module (sans functions)
9517330f729Sjoerg // to be added to the slot table.
SlotTracker(const Module * M,bool ShouldInitializeAllMetadata)9527330f729Sjoerg SlotTracker::SlotTracker(const Module *M, bool ShouldInitializeAllMetadata)
9537330f729Sjoerg     : TheModule(M), ShouldInitializeAllMetadata(ShouldInitializeAllMetadata) {}
9547330f729Sjoerg 
9557330f729Sjoerg // Function level constructor. Causes the contents of the Module and the one
9567330f729Sjoerg // function provided to be added to the slot table.
SlotTracker(const Function * F,bool ShouldInitializeAllMetadata)9577330f729Sjoerg SlotTracker::SlotTracker(const Function *F, bool ShouldInitializeAllMetadata)
9587330f729Sjoerg     : TheModule(F ? F->getParent() : nullptr), TheFunction(F),
9597330f729Sjoerg       ShouldInitializeAllMetadata(ShouldInitializeAllMetadata) {}
9607330f729Sjoerg 
SlotTracker(const ModuleSummaryIndex * Index)9617330f729Sjoerg SlotTracker::SlotTracker(const ModuleSummaryIndex *Index)
9627330f729Sjoerg     : TheModule(nullptr), ShouldInitializeAllMetadata(false), TheIndex(Index) {}
9637330f729Sjoerg 
initializeIfNeeded()9647330f729Sjoerg inline void SlotTracker::initializeIfNeeded() {
9657330f729Sjoerg   if (TheModule) {
9667330f729Sjoerg     processModule();
9677330f729Sjoerg     TheModule = nullptr; ///< Prevent re-processing next time we're called.
9687330f729Sjoerg   }
9697330f729Sjoerg 
9707330f729Sjoerg   if (TheFunction && !FunctionProcessed)
9717330f729Sjoerg     processFunction();
9727330f729Sjoerg }
9737330f729Sjoerg 
initializeIndexIfNeeded()974*82d56013Sjoerg int SlotTracker::initializeIndexIfNeeded() {
9757330f729Sjoerg   if (!TheIndex)
976*82d56013Sjoerg     return 0;
977*82d56013Sjoerg   int NumSlots = processIndex();
9787330f729Sjoerg   TheIndex = nullptr; ///< Prevent re-processing next time we're called.
979*82d56013Sjoerg   return NumSlots;
9807330f729Sjoerg }
9817330f729Sjoerg 
9827330f729Sjoerg // Iterate through all the global variables, functions, and global
9837330f729Sjoerg // variable initializers and create slots for them.
processModule()9847330f729Sjoerg void SlotTracker::processModule() {
9857330f729Sjoerg   ST_DEBUG("begin processModule!\n");
9867330f729Sjoerg 
9877330f729Sjoerg   // Add all of the unnamed global variables to the value table.
9887330f729Sjoerg   for (const GlobalVariable &Var : TheModule->globals()) {
9897330f729Sjoerg     if (!Var.hasName())
9907330f729Sjoerg       CreateModuleSlot(&Var);
9917330f729Sjoerg     processGlobalObjectMetadata(Var);
9927330f729Sjoerg     auto Attrs = Var.getAttributes();
9937330f729Sjoerg     if (Attrs.hasAttributes())
9947330f729Sjoerg       CreateAttributeSetSlot(Attrs);
9957330f729Sjoerg   }
9967330f729Sjoerg 
9977330f729Sjoerg   for (const GlobalAlias &A : TheModule->aliases()) {
9987330f729Sjoerg     if (!A.hasName())
9997330f729Sjoerg       CreateModuleSlot(&A);
10007330f729Sjoerg   }
10017330f729Sjoerg 
10027330f729Sjoerg   for (const GlobalIFunc &I : TheModule->ifuncs()) {
10037330f729Sjoerg     if (!I.hasName())
10047330f729Sjoerg       CreateModuleSlot(&I);
10057330f729Sjoerg   }
10067330f729Sjoerg 
10077330f729Sjoerg   // Add metadata used by named metadata.
10087330f729Sjoerg   for (const NamedMDNode &NMD : TheModule->named_metadata()) {
10097330f729Sjoerg     for (unsigned i = 0, e = NMD.getNumOperands(); i != e; ++i)
10107330f729Sjoerg       CreateMetadataSlot(NMD.getOperand(i));
10117330f729Sjoerg   }
10127330f729Sjoerg 
10137330f729Sjoerg   for (const Function &F : *TheModule) {
10147330f729Sjoerg     if (!F.hasName())
10157330f729Sjoerg       // Add all the unnamed functions to the table.
10167330f729Sjoerg       CreateModuleSlot(&F);
10177330f729Sjoerg 
10187330f729Sjoerg     if (ShouldInitializeAllMetadata)
10197330f729Sjoerg       processFunctionMetadata(F);
10207330f729Sjoerg 
10217330f729Sjoerg     // Add all the function attributes to the table.
10227330f729Sjoerg     // FIXME: Add attributes of other objects?
10237330f729Sjoerg     AttributeSet FnAttrs = F.getAttributes().getFnAttributes();
10247330f729Sjoerg     if (FnAttrs.hasAttributes())
10257330f729Sjoerg       CreateAttributeSetSlot(FnAttrs);
10267330f729Sjoerg   }
10277330f729Sjoerg 
10287330f729Sjoerg   ST_DEBUG("end processModule!\n");
10297330f729Sjoerg }
10307330f729Sjoerg 
10317330f729Sjoerg // Process the arguments, basic blocks, and instructions  of a function.
processFunction()10327330f729Sjoerg void SlotTracker::processFunction() {
10337330f729Sjoerg   ST_DEBUG("begin processFunction!\n");
10347330f729Sjoerg   fNext = 0;
10357330f729Sjoerg 
10367330f729Sjoerg   // Process function metadata if it wasn't hit at the module-level.
10377330f729Sjoerg   if (!ShouldInitializeAllMetadata)
10387330f729Sjoerg     processFunctionMetadata(*TheFunction);
10397330f729Sjoerg 
10407330f729Sjoerg   // Add all the function arguments with no names.
10417330f729Sjoerg   for(Function::const_arg_iterator AI = TheFunction->arg_begin(),
10427330f729Sjoerg       AE = TheFunction->arg_end(); AI != AE; ++AI)
10437330f729Sjoerg     if (!AI->hasName())
10447330f729Sjoerg       CreateFunctionSlot(&*AI);
10457330f729Sjoerg 
10467330f729Sjoerg   ST_DEBUG("Inserting Instructions:\n");
10477330f729Sjoerg 
10487330f729Sjoerg   // Add all of the basic blocks and instructions with no names.
10497330f729Sjoerg   for (auto &BB : *TheFunction) {
10507330f729Sjoerg     if (!BB.hasName())
10517330f729Sjoerg       CreateFunctionSlot(&BB);
10527330f729Sjoerg 
10537330f729Sjoerg     for (auto &I : BB) {
10547330f729Sjoerg       if (!I.getType()->isVoidTy() && !I.hasName())
10557330f729Sjoerg         CreateFunctionSlot(&I);
10567330f729Sjoerg 
10577330f729Sjoerg       // We allow direct calls to any llvm.foo function here, because the
10587330f729Sjoerg       // target may not be linked into the optimizer.
10597330f729Sjoerg       if (const auto *Call = dyn_cast<CallBase>(&I)) {
10607330f729Sjoerg         // Add all the call attributes to the table.
10617330f729Sjoerg         AttributeSet Attrs = Call->getAttributes().getFnAttributes();
10627330f729Sjoerg         if (Attrs.hasAttributes())
10637330f729Sjoerg           CreateAttributeSetSlot(Attrs);
10647330f729Sjoerg       }
10657330f729Sjoerg     }
10667330f729Sjoerg   }
10677330f729Sjoerg 
10687330f729Sjoerg   FunctionProcessed = true;
10697330f729Sjoerg 
10707330f729Sjoerg   ST_DEBUG("end processFunction!\n");
10717330f729Sjoerg }
10727330f729Sjoerg 
10737330f729Sjoerg // Iterate through all the GUID in the index and create slots for them.
processIndex()1074*82d56013Sjoerg int SlotTracker::processIndex() {
10757330f729Sjoerg   ST_DEBUG("begin processIndex!\n");
10767330f729Sjoerg   assert(TheIndex);
10777330f729Sjoerg 
10787330f729Sjoerg   // The first block of slots are just the module ids, which start at 0 and are
10797330f729Sjoerg   // assigned consecutively. Since the StringMap iteration order isn't
10807330f729Sjoerg   // guaranteed, use a std::map to order by module ID before assigning slots.
10817330f729Sjoerg   std::map<uint64_t, StringRef> ModuleIdToPathMap;
10827330f729Sjoerg   for (auto &ModPath : TheIndex->modulePaths())
10837330f729Sjoerg     ModuleIdToPathMap[ModPath.second.first] = ModPath.first();
10847330f729Sjoerg   for (auto &ModPair : ModuleIdToPathMap)
10857330f729Sjoerg     CreateModulePathSlot(ModPair.second);
10867330f729Sjoerg 
10877330f729Sjoerg   // Start numbering the GUIDs after the module ids.
10887330f729Sjoerg   GUIDNext = ModulePathNext;
10897330f729Sjoerg 
10907330f729Sjoerg   for (auto &GlobalList : *TheIndex)
10917330f729Sjoerg     CreateGUIDSlot(GlobalList.first);
10927330f729Sjoerg 
10937330f729Sjoerg   for (auto &TId : TheIndex->typeIdCompatibleVtableMap())
10947330f729Sjoerg     CreateGUIDSlot(GlobalValue::getGUID(TId.first));
10957330f729Sjoerg 
1096*82d56013Sjoerg   // Start numbering the TypeIds after the GUIDs.
1097*82d56013Sjoerg   TypeIdNext = GUIDNext;
1098*82d56013Sjoerg   for (const auto &TID : TheIndex->typeIds())
1099*82d56013Sjoerg     CreateTypeIdSlot(TID.second.first);
1100*82d56013Sjoerg 
11017330f729Sjoerg   ST_DEBUG("end processIndex!\n");
1102*82d56013Sjoerg   return TypeIdNext;
11037330f729Sjoerg }
11047330f729Sjoerg 
processGlobalObjectMetadata(const GlobalObject & GO)11057330f729Sjoerg void SlotTracker::processGlobalObjectMetadata(const GlobalObject &GO) {
11067330f729Sjoerg   SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
11077330f729Sjoerg   GO.getAllMetadata(MDs);
11087330f729Sjoerg   for (auto &MD : MDs)
11097330f729Sjoerg     CreateMetadataSlot(MD.second);
11107330f729Sjoerg }
11117330f729Sjoerg 
processFunctionMetadata(const Function & F)11127330f729Sjoerg void SlotTracker::processFunctionMetadata(const Function &F) {
11137330f729Sjoerg   processGlobalObjectMetadata(F);
11147330f729Sjoerg   for (auto &BB : F) {
11157330f729Sjoerg     for (auto &I : BB)
11167330f729Sjoerg       processInstructionMetadata(I);
11177330f729Sjoerg   }
11187330f729Sjoerg }
11197330f729Sjoerg 
processInstructionMetadata(const Instruction & I)11207330f729Sjoerg void SlotTracker::processInstructionMetadata(const Instruction &I) {
11217330f729Sjoerg   // Process metadata used directly by intrinsics.
11227330f729Sjoerg   if (const CallInst *CI = dyn_cast<CallInst>(&I))
11237330f729Sjoerg     if (Function *F = CI->getCalledFunction())
11247330f729Sjoerg       if (F->isIntrinsic())
11257330f729Sjoerg         for (auto &Op : I.operands())
11267330f729Sjoerg           if (auto *V = dyn_cast_or_null<MetadataAsValue>(Op))
11277330f729Sjoerg             if (MDNode *N = dyn_cast<MDNode>(V->getMetadata()))
11287330f729Sjoerg               CreateMetadataSlot(N);
11297330f729Sjoerg 
11307330f729Sjoerg   // Process metadata attached to this instruction.
11317330f729Sjoerg   SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
11327330f729Sjoerg   I.getAllMetadata(MDs);
11337330f729Sjoerg   for (auto &MD : MDs)
11347330f729Sjoerg     CreateMetadataSlot(MD.second);
11357330f729Sjoerg }
11367330f729Sjoerg 
11377330f729Sjoerg /// Clean up after incorporating a function. This is the only way to get out of
11387330f729Sjoerg /// the function incorporation state that affects get*Slot/Create*Slot. Function
11397330f729Sjoerg /// incorporation state is indicated by TheFunction != 0.
purgeFunction()11407330f729Sjoerg void SlotTracker::purgeFunction() {
11417330f729Sjoerg   ST_DEBUG("begin purgeFunction!\n");
11427330f729Sjoerg   fMap.clear(); // Simply discard the function level map
11437330f729Sjoerg   TheFunction = nullptr;
11447330f729Sjoerg   FunctionProcessed = false;
11457330f729Sjoerg   ST_DEBUG("end purgeFunction!\n");
11467330f729Sjoerg }
11477330f729Sjoerg 
11487330f729Sjoerg /// getGlobalSlot - Get the slot number of a global value.
getGlobalSlot(const GlobalValue * V)11497330f729Sjoerg int SlotTracker::getGlobalSlot(const GlobalValue *V) {
11507330f729Sjoerg   // Check for uninitialized state and do lazy initialization.
11517330f729Sjoerg   initializeIfNeeded();
11527330f729Sjoerg 
11537330f729Sjoerg   // Find the value in the module map
11547330f729Sjoerg   ValueMap::iterator MI = mMap.find(V);
11557330f729Sjoerg   return MI == mMap.end() ? -1 : (int)MI->second;
11567330f729Sjoerg }
11577330f729Sjoerg 
11587330f729Sjoerg /// getMetadataSlot - Get the slot number of a MDNode.
getMetadataSlot(const MDNode * N)11597330f729Sjoerg int SlotTracker::getMetadataSlot(const MDNode *N) {
11607330f729Sjoerg   // Check for uninitialized state and do lazy initialization.
11617330f729Sjoerg   initializeIfNeeded();
11627330f729Sjoerg 
11637330f729Sjoerg   // Find the MDNode in the module map
11647330f729Sjoerg   mdn_iterator MI = mdnMap.find(N);
11657330f729Sjoerg   return MI == mdnMap.end() ? -1 : (int)MI->second;
11667330f729Sjoerg }
11677330f729Sjoerg 
11687330f729Sjoerg /// getLocalSlot - Get the slot number for a value that is local to a function.
getLocalSlot(const Value * V)11697330f729Sjoerg int SlotTracker::getLocalSlot(const Value *V) {
11707330f729Sjoerg   assert(!isa<Constant>(V) && "Can't get a constant or global slot with this!");
11717330f729Sjoerg 
11727330f729Sjoerg   // Check for uninitialized state and do lazy initialization.
11737330f729Sjoerg   initializeIfNeeded();
11747330f729Sjoerg 
11757330f729Sjoerg   ValueMap::iterator FI = fMap.find(V);
11767330f729Sjoerg   return FI == fMap.end() ? -1 : (int)FI->second;
11777330f729Sjoerg }
11787330f729Sjoerg 
getAttributeGroupSlot(AttributeSet AS)11797330f729Sjoerg int SlotTracker::getAttributeGroupSlot(AttributeSet AS) {
11807330f729Sjoerg   // Check for uninitialized state and do lazy initialization.
11817330f729Sjoerg   initializeIfNeeded();
11827330f729Sjoerg 
11837330f729Sjoerg   // Find the AttributeSet in the module map.
11847330f729Sjoerg   as_iterator AI = asMap.find(AS);
11857330f729Sjoerg   return AI == asMap.end() ? -1 : (int)AI->second;
11867330f729Sjoerg }
11877330f729Sjoerg 
getModulePathSlot(StringRef Path)11887330f729Sjoerg int SlotTracker::getModulePathSlot(StringRef Path) {
11897330f729Sjoerg   // Check for uninitialized state and do lazy initialization.
11907330f729Sjoerg   initializeIndexIfNeeded();
11917330f729Sjoerg 
11927330f729Sjoerg   // Find the Module path in the map
11937330f729Sjoerg   auto I = ModulePathMap.find(Path);
11947330f729Sjoerg   return I == ModulePathMap.end() ? -1 : (int)I->second;
11957330f729Sjoerg }
11967330f729Sjoerg 
getGUIDSlot(GlobalValue::GUID GUID)11977330f729Sjoerg int SlotTracker::getGUIDSlot(GlobalValue::GUID GUID) {
11987330f729Sjoerg   // Check for uninitialized state and do lazy initialization.
11997330f729Sjoerg   initializeIndexIfNeeded();
12007330f729Sjoerg 
12017330f729Sjoerg   // Find the GUID in the map
12027330f729Sjoerg   guid_iterator I = GUIDMap.find(GUID);
12037330f729Sjoerg   return I == GUIDMap.end() ? -1 : (int)I->second;
12047330f729Sjoerg }
12057330f729Sjoerg 
getTypeIdSlot(StringRef Id)12067330f729Sjoerg int SlotTracker::getTypeIdSlot(StringRef Id) {
12077330f729Sjoerg   // Check for uninitialized state and do lazy initialization.
12087330f729Sjoerg   initializeIndexIfNeeded();
12097330f729Sjoerg 
12107330f729Sjoerg   // Find the TypeId string in the map
12117330f729Sjoerg   auto I = TypeIdMap.find(Id);
12127330f729Sjoerg   return I == TypeIdMap.end() ? -1 : (int)I->second;
12137330f729Sjoerg }
12147330f729Sjoerg 
12157330f729Sjoerg /// CreateModuleSlot - Insert the specified GlobalValue* into the slot table.
CreateModuleSlot(const GlobalValue * V)12167330f729Sjoerg void SlotTracker::CreateModuleSlot(const GlobalValue *V) {
12177330f729Sjoerg   assert(V && "Can't insert a null Value into SlotTracker!");
12187330f729Sjoerg   assert(!V->getType()->isVoidTy() && "Doesn't need a slot!");
12197330f729Sjoerg   assert(!V->hasName() && "Doesn't need a slot!");
12207330f729Sjoerg 
12217330f729Sjoerg   unsigned DestSlot = mNext++;
12227330f729Sjoerg   mMap[V] = DestSlot;
12237330f729Sjoerg 
12247330f729Sjoerg   ST_DEBUG("  Inserting value [" << V->getType() << "] = " << V << " slot=" <<
12257330f729Sjoerg            DestSlot << " [");
12267330f729Sjoerg   // G = Global, F = Function, A = Alias, I = IFunc, o = other
12277330f729Sjoerg   ST_DEBUG((isa<GlobalVariable>(V) ? 'G' :
12287330f729Sjoerg             (isa<Function>(V) ? 'F' :
12297330f729Sjoerg              (isa<GlobalAlias>(V) ? 'A' :
12307330f729Sjoerg               (isa<GlobalIFunc>(V) ? 'I' : 'o')))) << "]\n");
12317330f729Sjoerg }
12327330f729Sjoerg 
12337330f729Sjoerg /// CreateSlot - Create a new slot for the specified value if it has no name.
CreateFunctionSlot(const Value * V)12347330f729Sjoerg void SlotTracker::CreateFunctionSlot(const Value *V) {
12357330f729Sjoerg   assert(!V->getType()->isVoidTy() && !V->hasName() && "Doesn't need a slot!");
12367330f729Sjoerg 
12377330f729Sjoerg   unsigned DestSlot = fNext++;
12387330f729Sjoerg   fMap[V] = DestSlot;
12397330f729Sjoerg 
12407330f729Sjoerg   // G = Global, F = Function, o = other
12417330f729Sjoerg   ST_DEBUG("  Inserting value [" << V->getType() << "] = " << V << " slot=" <<
12427330f729Sjoerg            DestSlot << " [o]\n");
12437330f729Sjoerg }
12447330f729Sjoerg 
12457330f729Sjoerg /// CreateModuleSlot - Insert the specified MDNode* into the slot table.
CreateMetadataSlot(const MDNode * N)12467330f729Sjoerg void SlotTracker::CreateMetadataSlot(const MDNode *N) {
12477330f729Sjoerg   assert(N && "Can't insert a null Value into SlotTracker!");
12487330f729Sjoerg 
1249*82d56013Sjoerg   // Don't make slots for DIExpressions or DIArgLists. We just print them inline
1250*82d56013Sjoerg   // everywhere.
1251*82d56013Sjoerg   if (isa<DIExpression>(N) || isa<DIArgList>(N))
12527330f729Sjoerg     return;
12537330f729Sjoerg 
12547330f729Sjoerg   unsigned DestSlot = mdnNext;
12557330f729Sjoerg   if (!mdnMap.insert(std::make_pair(N, DestSlot)).second)
12567330f729Sjoerg     return;
12577330f729Sjoerg   ++mdnNext;
12587330f729Sjoerg 
12597330f729Sjoerg   // Recursively add any MDNodes referenced by operands.
12607330f729Sjoerg   for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
12617330f729Sjoerg     if (const MDNode *Op = dyn_cast_or_null<MDNode>(N->getOperand(i)))
12627330f729Sjoerg       CreateMetadataSlot(Op);
12637330f729Sjoerg }
12647330f729Sjoerg 
CreateAttributeSetSlot(AttributeSet AS)12657330f729Sjoerg void SlotTracker::CreateAttributeSetSlot(AttributeSet AS) {
12667330f729Sjoerg   assert(AS.hasAttributes() && "Doesn't need a slot!");
12677330f729Sjoerg 
12687330f729Sjoerg   as_iterator I = asMap.find(AS);
12697330f729Sjoerg   if (I != asMap.end())
12707330f729Sjoerg     return;
12717330f729Sjoerg 
12727330f729Sjoerg   unsigned DestSlot = asNext++;
12737330f729Sjoerg   asMap[AS] = DestSlot;
12747330f729Sjoerg }
12757330f729Sjoerg 
12767330f729Sjoerg /// Create a new slot for the specified Module
CreateModulePathSlot(StringRef Path)12777330f729Sjoerg void SlotTracker::CreateModulePathSlot(StringRef Path) {
12787330f729Sjoerg   ModulePathMap[Path] = ModulePathNext++;
12797330f729Sjoerg }
12807330f729Sjoerg 
12817330f729Sjoerg /// Create a new slot for the specified GUID
CreateGUIDSlot(GlobalValue::GUID GUID)12827330f729Sjoerg void SlotTracker::CreateGUIDSlot(GlobalValue::GUID GUID) {
12837330f729Sjoerg   GUIDMap[GUID] = GUIDNext++;
12847330f729Sjoerg }
12857330f729Sjoerg 
12867330f729Sjoerg /// Create a new slot for the specified Id
CreateTypeIdSlot(StringRef Id)12877330f729Sjoerg void SlotTracker::CreateTypeIdSlot(StringRef Id) {
12887330f729Sjoerg   TypeIdMap[Id] = TypeIdNext++;
12897330f729Sjoerg }
12907330f729Sjoerg 
12917330f729Sjoerg //===----------------------------------------------------------------------===//
12927330f729Sjoerg // AsmWriter Implementation
12937330f729Sjoerg //===----------------------------------------------------------------------===//
12947330f729Sjoerg 
12957330f729Sjoerg static void WriteAsOperandInternal(raw_ostream &Out, const Value *V,
12967330f729Sjoerg                                    TypePrinting *TypePrinter,
12977330f729Sjoerg                                    SlotTracker *Machine,
12987330f729Sjoerg                                    const Module *Context);
12997330f729Sjoerg 
13007330f729Sjoerg static void WriteAsOperandInternal(raw_ostream &Out, const Metadata *MD,
13017330f729Sjoerg                                    TypePrinting *TypePrinter,
13027330f729Sjoerg                                    SlotTracker *Machine, const Module *Context,
13037330f729Sjoerg                                    bool FromValue = false);
13047330f729Sjoerg 
WriteOptimizationInfo(raw_ostream & Out,const User * U)13057330f729Sjoerg static void WriteOptimizationInfo(raw_ostream &Out, const User *U) {
13067330f729Sjoerg   if (const FPMathOperator *FPO = dyn_cast<const FPMathOperator>(U)) {
13077330f729Sjoerg     // 'Fast' is an abbreviation for all fast-math-flags.
13087330f729Sjoerg     if (FPO->isFast())
13097330f729Sjoerg       Out << " fast";
13107330f729Sjoerg     else {
13117330f729Sjoerg       if (FPO->hasAllowReassoc())
13127330f729Sjoerg         Out << " reassoc";
13137330f729Sjoerg       if (FPO->hasNoNaNs())
13147330f729Sjoerg         Out << " nnan";
13157330f729Sjoerg       if (FPO->hasNoInfs())
13167330f729Sjoerg         Out << " ninf";
13177330f729Sjoerg       if (FPO->hasNoSignedZeros())
13187330f729Sjoerg         Out << " nsz";
13197330f729Sjoerg       if (FPO->hasAllowReciprocal())
13207330f729Sjoerg         Out << " arcp";
13217330f729Sjoerg       if (FPO->hasAllowContract())
13227330f729Sjoerg         Out << " contract";
13237330f729Sjoerg       if (FPO->hasApproxFunc())
13247330f729Sjoerg         Out << " afn";
13257330f729Sjoerg     }
13267330f729Sjoerg   }
13277330f729Sjoerg 
13287330f729Sjoerg   if (const OverflowingBinaryOperator *OBO =
13297330f729Sjoerg         dyn_cast<OverflowingBinaryOperator>(U)) {
13307330f729Sjoerg     if (OBO->hasNoUnsignedWrap())
13317330f729Sjoerg       Out << " nuw";
13327330f729Sjoerg     if (OBO->hasNoSignedWrap())
13337330f729Sjoerg       Out << " nsw";
13347330f729Sjoerg   } else if (const PossiblyExactOperator *Div =
13357330f729Sjoerg                dyn_cast<PossiblyExactOperator>(U)) {
13367330f729Sjoerg     if (Div->isExact())
13377330f729Sjoerg       Out << " exact";
13387330f729Sjoerg   } else if (const GEPOperator *GEP = dyn_cast<GEPOperator>(U)) {
13397330f729Sjoerg     if (GEP->isInBounds())
13407330f729Sjoerg       Out << " inbounds";
13417330f729Sjoerg   }
13427330f729Sjoerg }
13437330f729Sjoerg 
WriteConstantInternal(raw_ostream & Out,const Constant * CV,TypePrinting & TypePrinter,SlotTracker * Machine,const Module * Context)13447330f729Sjoerg static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
13457330f729Sjoerg                                   TypePrinting &TypePrinter,
13467330f729Sjoerg                                   SlotTracker *Machine,
13477330f729Sjoerg                                   const Module *Context) {
13487330f729Sjoerg   if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
13497330f729Sjoerg     if (CI->getType()->isIntegerTy(1)) {
13507330f729Sjoerg       Out << (CI->getZExtValue() ? "true" : "false");
13517330f729Sjoerg       return;
13527330f729Sjoerg     }
13537330f729Sjoerg     Out << CI->getValue();
13547330f729Sjoerg     return;
13557330f729Sjoerg   }
13567330f729Sjoerg 
13577330f729Sjoerg   if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
13587330f729Sjoerg     const APFloat &APF = CFP->getValueAPF();
13597330f729Sjoerg     if (&APF.getSemantics() == &APFloat::IEEEsingle() ||
13607330f729Sjoerg         &APF.getSemantics() == &APFloat::IEEEdouble()) {
13617330f729Sjoerg       // We would like to output the FP constant value in exponential notation,
13627330f729Sjoerg       // but we cannot do this if doing so will lose precision.  Check here to
13637330f729Sjoerg       // make sure that we only output it in exponential format if we can parse
13647330f729Sjoerg       // the value back and get the same value.
13657330f729Sjoerg       //
13667330f729Sjoerg       bool ignored;
13677330f729Sjoerg       bool isDouble = &APF.getSemantics() == &APFloat::IEEEdouble();
13687330f729Sjoerg       bool isInf = APF.isInfinity();
13697330f729Sjoerg       bool isNaN = APF.isNaN();
13707330f729Sjoerg       if (!isInf && !isNaN) {
1371*82d56013Sjoerg         double Val = APF.convertToDouble();
13727330f729Sjoerg         SmallString<128> StrVal;
13737330f729Sjoerg         APF.toString(StrVal, 6, 0, false);
13747330f729Sjoerg         // Check to make sure that the stringized number is not some string like
13757330f729Sjoerg         // "Inf" or NaN, that atof will accept, but the lexer will not.  Check
13767330f729Sjoerg         // that the string matches the "[-+]?[0-9]" regex.
13777330f729Sjoerg         //
1378*82d56013Sjoerg         assert((isDigit(StrVal[0]) || ((StrVal[0] == '-' || StrVal[0] == '+') &&
1379*82d56013Sjoerg                                        isDigit(StrVal[1]))) &&
13807330f729Sjoerg                "[-+]?[0-9] regex does not match!");
13817330f729Sjoerg         // Reparse stringized version!
13827330f729Sjoerg         if (APFloat(APFloat::IEEEdouble(), StrVal).convertToDouble() == Val) {
13837330f729Sjoerg           Out << StrVal;
13847330f729Sjoerg           return;
13857330f729Sjoerg         }
13867330f729Sjoerg       }
13877330f729Sjoerg       // Otherwise we could not reparse it to exactly the same value, so we must
13887330f729Sjoerg       // output the string in hexadecimal format!  Note that loading and storing
13897330f729Sjoerg       // floating point types changes the bits of NaNs on some hosts, notably
13907330f729Sjoerg       // x86, so we must not use these types.
13917330f729Sjoerg       static_assert(sizeof(double) == sizeof(uint64_t),
13927330f729Sjoerg                     "assuming that double is 64 bits!");
13937330f729Sjoerg       APFloat apf = APF;
13947330f729Sjoerg       // Floats are represented in ASCII IR as double, convert.
1395*82d56013Sjoerg       // FIXME: We should allow 32-bit hex float and remove this.
1396*82d56013Sjoerg       if (!isDouble) {
1397*82d56013Sjoerg         // A signaling NaN is quieted on conversion, so we need to recreate the
1398*82d56013Sjoerg         // expected value after convert (quiet bit of the payload is clear).
1399*82d56013Sjoerg         bool IsSNAN = apf.isSignaling();
14007330f729Sjoerg         apf.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven,
14017330f729Sjoerg                     &ignored);
1402*82d56013Sjoerg         if (IsSNAN) {
1403*82d56013Sjoerg           APInt Payload = apf.bitcastToAPInt();
1404*82d56013Sjoerg           apf = APFloat::getSNaN(APFloat::IEEEdouble(), apf.isNegative(),
1405*82d56013Sjoerg                                  &Payload);
1406*82d56013Sjoerg         }
1407*82d56013Sjoerg       }
14087330f729Sjoerg       Out << format_hex(apf.bitcastToAPInt().getZExtValue(), 0, /*Upper=*/true);
14097330f729Sjoerg       return;
14107330f729Sjoerg     }
14117330f729Sjoerg 
1412*82d56013Sjoerg     // Either half, bfloat or some form of long double.
14137330f729Sjoerg     // These appear as a magic letter identifying the type, then a
14147330f729Sjoerg     // fixed number of hex digits.
14157330f729Sjoerg     Out << "0x";
14167330f729Sjoerg     APInt API = APF.bitcastToAPInt();
14177330f729Sjoerg     if (&APF.getSemantics() == &APFloat::x87DoubleExtended()) {
14187330f729Sjoerg       Out << 'K';
14197330f729Sjoerg       Out << format_hex_no_prefix(API.getHiBits(16).getZExtValue(), 4,
14207330f729Sjoerg                                   /*Upper=*/true);
14217330f729Sjoerg       Out << format_hex_no_prefix(API.getLoBits(64).getZExtValue(), 16,
14227330f729Sjoerg                                   /*Upper=*/true);
14237330f729Sjoerg       return;
14247330f729Sjoerg     } else if (&APF.getSemantics() == &APFloat::IEEEquad()) {
14257330f729Sjoerg       Out << 'L';
14267330f729Sjoerg       Out << format_hex_no_prefix(API.getLoBits(64).getZExtValue(), 16,
14277330f729Sjoerg                                   /*Upper=*/true);
14287330f729Sjoerg       Out << format_hex_no_prefix(API.getHiBits(64).getZExtValue(), 16,
14297330f729Sjoerg                                   /*Upper=*/true);
14307330f729Sjoerg     } else if (&APF.getSemantics() == &APFloat::PPCDoubleDouble()) {
14317330f729Sjoerg       Out << 'M';
14327330f729Sjoerg       Out << format_hex_no_prefix(API.getLoBits(64).getZExtValue(), 16,
14337330f729Sjoerg                                   /*Upper=*/true);
14347330f729Sjoerg       Out << format_hex_no_prefix(API.getHiBits(64).getZExtValue(), 16,
14357330f729Sjoerg                                   /*Upper=*/true);
14367330f729Sjoerg     } else if (&APF.getSemantics() == &APFloat::IEEEhalf()) {
14377330f729Sjoerg       Out << 'H';
14387330f729Sjoerg       Out << format_hex_no_prefix(API.getZExtValue(), 4,
14397330f729Sjoerg                                   /*Upper=*/true);
1440*82d56013Sjoerg     } else if (&APF.getSemantics() == &APFloat::BFloat()) {
1441*82d56013Sjoerg       Out << 'R';
1442*82d56013Sjoerg       Out << format_hex_no_prefix(API.getZExtValue(), 4,
1443*82d56013Sjoerg                                   /*Upper=*/true);
14447330f729Sjoerg     } else
14457330f729Sjoerg       llvm_unreachable("Unsupported floating point type");
14467330f729Sjoerg     return;
14477330f729Sjoerg   }
14487330f729Sjoerg 
14497330f729Sjoerg   if (isa<ConstantAggregateZero>(CV)) {
14507330f729Sjoerg     Out << "zeroinitializer";
14517330f729Sjoerg     return;
14527330f729Sjoerg   }
14537330f729Sjoerg 
14547330f729Sjoerg   if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV)) {
14557330f729Sjoerg     Out << "blockaddress(";
14567330f729Sjoerg     WriteAsOperandInternal(Out, BA->getFunction(), &TypePrinter, Machine,
14577330f729Sjoerg                            Context);
14587330f729Sjoerg     Out << ", ";
14597330f729Sjoerg     WriteAsOperandInternal(Out, BA->getBasicBlock(), &TypePrinter, Machine,
14607330f729Sjoerg                            Context);
14617330f729Sjoerg     Out << ")";
14627330f729Sjoerg     return;
14637330f729Sjoerg   }
14647330f729Sjoerg 
1465*82d56013Sjoerg   if (const auto *Equiv = dyn_cast<DSOLocalEquivalent>(CV)) {
1466*82d56013Sjoerg     Out << "dso_local_equivalent ";
1467*82d56013Sjoerg     WriteAsOperandInternal(Out, Equiv->getGlobalValue(), &TypePrinter, Machine,
1468*82d56013Sjoerg                            Context);
1469*82d56013Sjoerg     return;
1470*82d56013Sjoerg   }
1471*82d56013Sjoerg 
14727330f729Sjoerg   if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) {
14737330f729Sjoerg     Type *ETy = CA->getType()->getElementType();
14747330f729Sjoerg     Out << '[';
14757330f729Sjoerg     TypePrinter.print(ETy, Out);
14767330f729Sjoerg     Out << ' ';
14777330f729Sjoerg     WriteAsOperandInternal(Out, CA->getOperand(0),
14787330f729Sjoerg                            &TypePrinter, Machine,
14797330f729Sjoerg                            Context);
14807330f729Sjoerg     for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) {
14817330f729Sjoerg       Out << ", ";
14827330f729Sjoerg       TypePrinter.print(ETy, Out);
14837330f729Sjoerg       Out << ' ';
14847330f729Sjoerg       WriteAsOperandInternal(Out, CA->getOperand(i), &TypePrinter, Machine,
14857330f729Sjoerg                              Context);
14867330f729Sjoerg     }
14877330f729Sjoerg     Out << ']';
14887330f729Sjoerg     return;
14897330f729Sjoerg   }
14907330f729Sjoerg 
14917330f729Sjoerg   if (const ConstantDataArray *CA = dyn_cast<ConstantDataArray>(CV)) {
14927330f729Sjoerg     // As a special case, print the array as a string if it is an array of
14937330f729Sjoerg     // i8 with ConstantInt values.
14947330f729Sjoerg     if (CA->isString()) {
14957330f729Sjoerg       Out << "c\"";
14967330f729Sjoerg       printEscapedString(CA->getAsString(), Out);
14977330f729Sjoerg       Out << '"';
14987330f729Sjoerg       return;
14997330f729Sjoerg     }
15007330f729Sjoerg 
15017330f729Sjoerg     Type *ETy = CA->getType()->getElementType();
15027330f729Sjoerg     Out << '[';
15037330f729Sjoerg     TypePrinter.print(ETy, Out);
15047330f729Sjoerg     Out << ' ';
15057330f729Sjoerg     WriteAsOperandInternal(Out, CA->getElementAsConstant(0),
15067330f729Sjoerg                            &TypePrinter, Machine,
15077330f729Sjoerg                            Context);
15087330f729Sjoerg     for (unsigned i = 1, e = CA->getNumElements(); i != e; ++i) {
15097330f729Sjoerg       Out << ", ";
15107330f729Sjoerg       TypePrinter.print(ETy, Out);
15117330f729Sjoerg       Out << ' ';
15127330f729Sjoerg       WriteAsOperandInternal(Out, CA->getElementAsConstant(i), &TypePrinter,
15137330f729Sjoerg                              Machine, Context);
15147330f729Sjoerg     }
15157330f729Sjoerg     Out << ']';
15167330f729Sjoerg     return;
15177330f729Sjoerg   }
15187330f729Sjoerg 
15197330f729Sjoerg   if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(CV)) {
15207330f729Sjoerg     if (CS->getType()->isPacked())
15217330f729Sjoerg       Out << '<';
15227330f729Sjoerg     Out << '{';
15237330f729Sjoerg     unsigned N = CS->getNumOperands();
15247330f729Sjoerg     if (N) {
15257330f729Sjoerg       Out << ' ';
15267330f729Sjoerg       TypePrinter.print(CS->getOperand(0)->getType(), Out);
15277330f729Sjoerg       Out << ' ';
15287330f729Sjoerg 
15297330f729Sjoerg       WriteAsOperandInternal(Out, CS->getOperand(0), &TypePrinter, Machine,
15307330f729Sjoerg                              Context);
15317330f729Sjoerg 
15327330f729Sjoerg       for (unsigned i = 1; i < N; i++) {
15337330f729Sjoerg         Out << ", ";
15347330f729Sjoerg         TypePrinter.print(CS->getOperand(i)->getType(), Out);
15357330f729Sjoerg         Out << ' ';
15367330f729Sjoerg 
15377330f729Sjoerg         WriteAsOperandInternal(Out, CS->getOperand(i), &TypePrinter, Machine,
15387330f729Sjoerg                                Context);
15397330f729Sjoerg       }
15407330f729Sjoerg       Out << ' ';
15417330f729Sjoerg     }
15427330f729Sjoerg 
15437330f729Sjoerg     Out << '}';
15447330f729Sjoerg     if (CS->getType()->isPacked())
15457330f729Sjoerg       Out << '>';
15467330f729Sjoerg     return;
15477330f729Sjoerg   }
15487330f729Sjoerg 
15497330f729Sjoerg   if (isa<ConstantVector>(CV) || isa<ConstantDataVector>(CV)) {
1550*82d56013Sjoerg     auto *CVVTy = cast<FixedVectorType>(CV->getType());
1551*82d56013Sjoerg     Type *ETy = CVVTy->getElementType();
15527330f729Sjoerg     Out << '<';
15537330f729Sjoerg     TypePrinter.print(ETy, Out);
15547330f729Sjoerg     Out << ' ';
15557330f729Sjoerg     WriteAsOperandInternal(Out, CV->getAggregateElement(0U), &TypePrinter,
15567330f729Sjoerg                            Machine, Context);
1557*82d56013Sjoerg     for (unsigned i = 1, e = CVVTy->getNumElements(); i != e; ++i) {
15587330f729Sjoerg       Out << ", ";
15597330f729Sjoerg       TypePrinter.print(ETy, Out);
15607330f729Sjoerg       Out << ' ';
15617330f729Sjoerg       WriteAsOperandInternal(Out, CV->getAggregateElement(i), &TypePrinter,
15627330f729Sjoerg                              Machine, Context);
15637330f729Sjoerg     }
15647330f729Sjoerg     Out << '>';
15657330f729Sjoerg     return;
15667330f729Sjoerg   }
15677330f729Sjoerg 
15687330f729Sjoerg   if (isa<ConstantPointerNull>(CV)) {
15697330f729Sjoerg     Out << "null";
15707330f729Sjoerg     return;
15717330f729Sjoerg   }
15727330f729Sjoerg 
15737330f729Sjoerg   if (isa<ConstantTokenNone>(CV)) {
15747330f729Sjoerg     Out << "none";
15757330f729Sjoerg     return;
15767330f729Sjoerg   }
15777330f729Sjoerg 
1578*82d56013Sjoerg   if (isa<PoisonValue>(CV)) {
1579*82d56013Sjoerg     Out << "poison";
1580*82d56013Sjoerg     return;
1581*82d56013Sjoerg   }
1582*82d56013Sjoerg 
15837330f729Sjoerg   if (isa<UndefValue>(CV)) {
15847330f729Sjoerg     Out << "undef";
15857330f729Sjoerg     return;
15867330f729Sjoerg   }
15877330f729Sjoerg 
15887330f729Sjoerg   if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
15897330f729Sjoerg     Out << CE->getOpcodeName();
15907330f729Sjoerg     WriteOptimizationInfo(Out, CE);
15917330f729Sjoerg     if (CE->isCompare())
15927330f729Sjoerg       Out << ' ' << CmpInst::getPredicateName(
15937330f729Sjoerg                         static_cast<CmpInst::Predicate>(CE->getPredicate()));
15947330f729Sjoerg     Out << " (";
15957330f729Sjoerg 
15967330f729Sjoerg     Optional<unsigned> InRangeOp;
15977330f729Sjoerg     if (const GEPOperator *GEP = dyn_cast<GEPOperator>(CE)) {
15987330f729Sjoerg       TypePrinter.print(GEP->getSourceElementType(), Out);
15997330f729Sjoerg       Out << ", ";
16007330f729Sjoerg       InRangeOp = GEP->getInRangeIndex();
16017330f729Sjoerg       if (InRangeOp)
16027330f729Sjoerg         ++*InRangeOp;
16037330f729Sjoerg     }
16047330f729Sjoerg 
16057330f729Sjoerg     for (User::const_op_iterator OI=CE->op_begin(); OI != CE->op_end(); ++OI) {
16067330f729Sjoerg       if (InRangeOp && unsigned(OI - CE->op_begin()) == *InRangeOp)
16077330f729Sjoerg         Out << "inrange ";
16087330f729Sjoerg       TypePrinter.print((*OI)->getType(), Out);
16097330f729Sjoerg       Out << ' ';
16107330f729Sjoerg       WriteAsOperandInternal(Out, *OI, &TypePrinter, Machine, Context);
16117330f729Sjoerg       if (OI+1 != CE->op_end())
16127330f729Sjoerg         Out << ", ";
16137330f729Sjoerg     }
16147330f729Sjoerg 
16157330f729Sjoerg     if (CE->hasIndices()) {
16167330f729Sjoerg       ArrayRef<unsigned> Indices = CE->getIndices();
16177330f729Sjoerg       for (unsigned i = 0, e = Indices.size(); i != e; ++i)
16187330f729Sjoerg         Out << ", " << Indices[i];
16197330f729Sjoerg     }
16207330f729Sjoerg 
16217330f729Sjoerg     if (CE->isCast()) {
16227330f729Sjoerg       Out << " to ";
16237330f729Sjoerg       TypePrinter.print(CE->getType(), Out);
16247330f729Sjoerg     }
16257330f729Sjoerg 
1626*82d56013Sjoerg     if (CE->getOpcode() == Instruction::ShuffleVector)
1627*82d56013Sjoerg       PrintShuffleMask(Out, CE->getType(), CE->getShuffleMask());
1628*82d56013Sjoerg 
16297330f729Sjoerg     Out << ')';
16307330f729Sjoerg     return;
16317330f729Sjoerg   }
16327330f729Sjoerg 
16337330f729Sjoerg   Out << "<placeholder or erroneous Constant>";
16347330f729Sjoerg }
16357330f729Sjoerg 
writeMDTuple(raw_ostream & Out,const MDTuple * Node,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context)16367330f729Sjoerg static void writeMDTuple(raw_ostream &Out, const MDTuple *Node,
16377330f729Sjoerg                          TypePrinting *TypePrinter, SlotTracker *Machine,
16387330f729Sjoerg                          const Module *Context) {
16397330f729Sjoerg   Out << "!{";
16407330f729Sjoerg   for (unsigned mi = 0, me = Node->getNumOperands(); mi != me; ++mi) {
16417330f729Sjoerg     const Metadata *MD = Node->getOperand(mi);
16427330f729Sjoerg     if (!MD)
16437330f729Sjoerg       Out << "null";
16447330f729Sjoerg     else if (auto *MDV = dyn_cast<ValueAsMetadata>(MD)) {
16457330f729Sjoerg       Value *V = MDV->getValue();
16467330f729Sjoerg       TypePrinter->print(V->getType(), Out);
16477330f729Sjoerg       Out << ' ';
16487330f729Sjoerg       WriteAsOperandInternal(Out, V, TypePrinter, Machine, Context);
16497330f729Sjoerg     } else {
16507330f729Sjoerg       WriteAsOperandInternal(Out, MD, TypePrinter, Machine, Context);
16517330f729Sjoerg     }
16527330f729Sjoerg     if (mi + 1 != me)
16537330f729Sjoerg       Out << ", ";
16547330f729Sjoerg   }
16557330f729Sjoerg 
16567330f729Sjoerg   Out << "}";
16577330f729Sjoerg }
16587330f729Sjoerg 
16597330f729Sjoerg namespace {
16607330f729Sjoerg 
16617330f729Sjoerg struct FieldSeparator {
16627330f729Sjoerg   bool Skip = true;
16637330f729Sjoerg   const char *Sep;
16647330f729Sjoerg 
FieldSeparator__anonf93afd230711::FieldSeparator16657330f729Sjoerg   FieldSeparator(const char *Sep = ", ") : Sep(Sep) {}
16667330f729Sjoerg };
16677330f729Sjoerg 
operator <<(raw_ostream & OS,FieldSeparator & FS)16687330f729Sjoerg raw_ostream &operator<<(raw_ostream &OS, FieldSeparator &FS) {
16697330f729Sjoerg   if (FS.Skip) {
16707330f729Sjoerg     FS.Skip = false;
16717330f729Sjoerg     return OS;
16727330f729Sjoerg   }
16737330f729Sjoerg   return OS << FS.Sep;
16747330f729Sjoerg }
16757330f729Sjoerg 
16767330f729Sjoerg struct MDFieldPrinter {
16777330f729Sjoerg   raw_ostream &Out;
16787330f729Sjoerg   FieldSeparator FS;
16797330f729Sjoerg   TypePrinting *TypePrinter = nullptr;
16807330f729Sjoerg   SlotTracker *Machine = nullptr;
16817330f729Sjoerg   const Module *Context = nullptr;
16827330f729Sjoerg 
MDFieldPrinter__anonf93afd230711::MDFieldPrinter16837330f729Sjoerg   explicit MDFieldPrinter(raw_ostream &Out) : Out(Out) {}
MDFieldPrinter__anonf93afd230711::MDFieldPrinter16847330f729Sjoerg   MDFieldPrinter(raw_ostream &Out, TypePrinting *TypePrinter,
16857330f729Sjoerg                  SlotTracker *Machine, const Module *Context)
16867330f729Sjoerg       : Out(Out), TypePrinter(TypePrinter), Machine(Machine), Context(Context) {
16877330f729Sjoerg   }
16887330f729Sjoerg 
16897330f729Sjoerg   void printTag(const DINode *N);
16907330f729Sjoerg   void printMacinfoType(const DIMacroNode *N);
16917330f729Sjoerg   void printChecksum(const DIFile::ChecksumInfo<StringRef> &N);
16927330f729Sjoerg   void printString(StringRef Name, StringRef Value,
16937330f729Sjoerg                    bool ShouldSkipEmpty = true);
16947330f729Sjoerg   void printMetadata(StringRef Name, const Metadata *MD,
16957330f729Sjoerg                      bool ShouldSkipNull = true);
16967330f729Sjoerg   template <class IntTy>
16977330f729Sjoerg   void printInt(StringRef Name, IntTy Int, bool ShouldSkipZero = true);
1698*82d56013Sjoerg   void printAPInt(StringRef Name, const APInt &Int, bool IsUnsigned,
1699*82d56013Sjoerg                   bool ShouldSkipZero);
17007330f729Sjoerg   void printBool(StringRef Name, bool Value, Optional<bool> Default = None);
17017330f729Sjoerg   void printDIFlags(StringRef Name, DINode::DIFlags Flags);
17027330f729Sjoerg   void printDISPFlags(StringRef Name, DISubprogram::DISPFlags Flags);
17037330f729Sjoerg   template <class IntTy, class Stringifier>
17047330f729Sjoerg   void printDwarfEnum(StringRef Name, IntTy Value, Stringifier toString,
17057330f729Sjoerg                       bool ShouldSkipZero = true);
17067330f729Sjoerg   void printEmissionKind(StringRef Name, DICompileUnit::DebugEmissionKind EK);
17077330f729Sjoerg   void printNameTableKind(StringRef Name,
17087330f729Sjoerg                           DICompileUnit::DebugNameTableKind NTK);
17097330f729Sjoerg };
17107330f729Sjoerg 
17117330f729Sjoerg } // end anonymous namespace
17127330f729Sjoerg 
printTag(const DINode * N)17137330f729Sjoerg void MDFieldPrinter::printTag(const DINode *N) {
17147330f729Sjoerg   Out << FS << "tag: ";
17157330f729Sjoerg   auto Tag = dwarf::TagString(N->getTag());
17167330f729Sjoerg   if (!Tag.empty())
17177330f729Sjoerg     Out << Tag;
17187330f729Sjoerg   else
17197330f729Sjoerg     Out << N->getTag();
17207330f729Sjoerg }
17217330f729Sjoerg 
printMacinfoType(const DIMacroNode * N)17227330f729Sjoerg void MDFieldPrinter::printMacinfoType(const DIMacroNode *N) {
17237330f729Sjoerg   Out << FS << "type: ";
17247330f729Sjoerg   auto Type = dwarf::MacinfoString(N->getMacinfoType());
17257330f729Sjoerg   if (!Type.empty())
17267330f729Sjoerg     Out << Type;
17277330f729Sjoerg   else
17287330f729Sjoerg     Out << N->getMacinfoType();
17297330f729Sjoerg }
17307330f729Sjoerg 
printChecksum(const DIFile::ChecksumInfo<StringRef> & Checksum)17317330f729Sjoerg void MDFieldPrinter::printChecksum(
17327330f729Sjoerg     const DIFile::ChecksumInfo<StringRef> &Checksum) {
17337330f729Sjoerg   Out << FS << "checksumkind: " << Checksum.getKindAsString();
17347330f729Sjoerg   printString("checksum", Checksum.Value, /* ShouldSkipEmpty */ false);
17357330f729Sjoerg }
17367330f729Sjoerg 
printString(StringRef Name,StringRef Value,bool ShouldSkipEmpty)17377330f729Sjoerg void MDFieldPrinter::printString(StringRef Name, StringRef Value,
17387330f729Sjoerg                                  bool ShouldSkipEmpty) {
17397330f729Sjoerg   if (ShouldSkipEmpty && Value.empty())
17407330f729Sjoerg     return;
17417330f729Sjoerg 
17427330f729Sjoerg   Out << FS << Name << ": \"";
17437330f729Sjoerg   printEscapedString(Value, Out);
17447330f729Sjoerg   Out << "\"";
17457330f729Sjoerg }
17467330f729Sjoerg 
writeMetadataAsOperand(raw_ostream & Out,const Metadata * MD,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context)17477330f729Sjoerg static void writeMetadataAsOperand(raw_ostream &Out, const Metadata *MD,
17487330f729Sjoerg                                    TypePrinting *TypePrinter,
17497330f729Sjoerg                                    SlotTracker *Machine,
17507330f729Sjoerg                                    const Module *Context) {
17517330f729Sjoerg   if (!MD) {
17527330f729Sjoerg     Out << "null";
17537330f729Sjoerg     return;
17547330f729Sjoerg   }
17557330f729Sjoerg   WriteAsOperandInternal(Out, MD, TypePrinter, Machine, Context);
17567330f729Sjoerg }
17577330f729Sjoerg 
printMetadata(StringRef Name,const Metadata * MD,bool ShouldSkipNull)17587330f729Sjoerg void MDFieldPrinter::printMetadata(StringRef Name, const Metadata *MD,
17597330f729Sjoerg                                    bool ShouldSkipNull) {
17607330f729Sjoerg   if (ShouldSkipNull && !MD)
17617330f729Sjoerg     return;
17627330f729Sjoerg 
17637330f729Sjoerg   Out << FS << Name << ": ";
17647330f729Sjoerg   writeMetadataAsOperand(Out, MD, TypePrinter, Machine, Context);
17657330f729Sjoerg }
17667330f729Sjoerg 
17677330f729Sjoerg template <class IntTy>
printInt(StringRef Name,IntTy Int,bool ShouldSkipZero)17687330f729Sjoerg void MDFieldPrinter::printInt(StringRef Name, IntTy Int, bool ShouldSkipZero) {
17697330f729Sjoerg   if (ShouldSkipZero && !Int)
17707330f729Sjoerg     return;
17717330f729Sjoerg 
17727330f729Sjoerg   Out << FS << Name << ": " << Int;
17737330f729Sjoerg }
17747330f729Sjoerg 
printAPInt(StringRef Name,const APInt & Int,bool IsUnsigned,bool ShouldSkipZero)1775*82d56013Sjoerg void MDFieldPrinter::printAPInt(StringRef Name, const APInt &Int,
1776*82d56013Sjoerg                                 bool IsUnsigned, bool ShouldSkipZero) {
1777*82d56013Sjoerg   if (ShouldSkipZero && Int.isNullValue())
1778*82d56013Sjoerg     return;
1779*82d56013Sjoerg 
1780*82d56013Sjoerg   Out << FS << Name << ": ";
1781*82d56013Sjoerg   Int.print(Out, !IsUnsigned);
1782*82d56013Sjoerg }
1783*82d56013Sjoerg 
printBool(StringRef Name,bool Value,Optional<bool> Default)17847330f729Sjoerg void MDFieldPrinter::printBool(StringRef Name, bool Value,
17857330f729Sjoerg                                Optional<bool> Default) {
17867330f729Sjoerg   if (Default && Value == *Default)
17877330f729Sjoerg     return;
17887330f729Sjoerg   Out << FS << Name << ": " << (Value ? "true" : "false");
17897330f729Sjoerg }
17907330f729Sjoerg 
printDIFlags(StringRef Name,DINode::DIFlags Flags)17917330f729Sjoerg void MDFieldPrinter::printDIFlags(StringRef Name, DINode::DIFlags Flags) {
17927330f729Sjoerg   if (!Flags)
17937330f729Sjoerg     return;
17947330f729Sjoerg 
17957330f729Sjoerg   Out << FS << Name << ": ";
17967330f729Sjoerg 
17977330f729Sjoerg   SmallVector<DINode::DIFlags, 8> SplitFlags;
17987330f729Sjoerg   auto Extra = DINode::splitFlags(Flags, SplitFlags);
17997330f729Sjoerg 
18007330f729Sjoerg   FieldSeparator FlagsFS(" | ");
18017330f729Sjoerg   for (auto F : SplitFlags) {
18027330f729Sjoerg     auto StringF = DINode::getFlagString(F);
18037330f729Sjoerg     assert(!StringF.empty() && "Expected valid flag");
18047330f729Sjoerg     Out << FlagsFS << StringF;
18057330f729Sjoerg   }
18067330f729Sjoerg   if (Extra || SplitFlags.empty())
18077330f729Sjoerg     Out << FlagsFS << Extra;
18087330f729Sjoerg }
18097330f729Sjoerg 
printDISPFlags(StringRef Name,DISubprogram::DISPFlags Flags)18107330f729Sjoerg void MDFieldPrinter::printDISPFlags(StringRef Name,
18117330f729Sjoerg                                     DISubprogram::DISPFlags Flags) {
18127330f729Sjoerg   // Always print this field, because no flags in the IR at all will be
18137330f729Sjoerg   // interpreted as old-style isDefinition: true.
18147330f729Sjoerg   Out << FS << Name << ": ";
18157330f729Sjoerg 
18167330f729Sjoerg   if (!Flags) {
18177330f729Sjoerg     Out << 0;
18187330f729Sjoerg     return;
18197330f729Sjoerg   }
18207330f729Sjoerg 
18217330f729Sjoerg   SmallVector<DISubprogram::DISPFlags, 8> SplitFlags;
18227330f729Sjoerg   auto Extra = DISubprogram::splitFlags(Flags, SplitFlags);
18237330f729Sjoerg 
18247330f729Sjoerg   FieldSeparator FlagsFS(" | ");
18257330f729Sjoerg   for (auto F : SplitFlags) {
18267330f729Sjoerg     auto StringF = DISubprogram::getFlagString(F);
18277330f729Sjoerg     assert(!StringF.empty() && "Expected valid flag");
18287330f729Sjoerg     Out << FlagsFS << StringF;
18297330f729Sjoerg   }
18307330f729Sjoerg   if (Extra || SplitFlags.empty())
18317330f729Sjoerg     Out << FlagsFS << Extra;
18327330f729Sjoerg }
18337330f729Sjoerg 
printEmissionKind(StringRef Name,DICompileUnit::DebugEmissionKind EK)18347330f729Sjoerg void MDFieldPrinter::printEmissionKind(StringRef Name,
18357330f729Sjoerg                                        DICompileUnit::DebugEmissionKind EK) {
18367330f729Sjoerg   Out << FS << Name << ": " << DICompileUnit::emissionKindString(EK);
18377330f729Sjoerg }
18387330f729Sjoerg 
printNameTableKind(StringRef Name,DICompileUnit::DebugNameTableKind NTK)18397330f729Sjoerg void MDFieldPrinter::printNameTableKind(StringRef Name,
18407330f729Sjoerg                                         DICompileUnit::DebugNameTableKind NTK) {
18417330f729Sjoerg   if (NTK == DICompileUnit::DebugNameTableKind::Default)
18427330f729Sjoerg     return;
18437330f729Sjoerg   Out << FS << Name << ": " << DICompileUnit::nameTableKindString(NTK);
18447330f729Sjoerg }
18457330f729Sjoerg 
18467330f729Sjoerg template <class IntTy, class Stringifier>
printDwarfEnum(StringRef Name,IntTy Value,Stringifier toString,bool ShouldSkipZero)18477330f729Sjoerg void MDFieldPrinter::printDwarfEnum(StringRef Name, IntTy Value,
18487330f729Sjoerg                                     Stringifier toString, bool ShouldSkipZero) {
18497330f729Sjoerg   if (!Value)
18507330f729Sjoerg     return;
18517330f729Sjoerg 
18527330f729Sjoerg   Out << FS << Name << ": ";
18537330f729Sjoerg   auto S = toString(Value);
18547330f729Sjoerg   if (!S.empty())
18557330f729Sjoerg     Out << S;
18567330f729Sjoerg   else
18577330f729Sjoerg     Out << Value;
18587330f729Sjoerg }
18597330f729Sjoerg 
writeGenericDINode(raw_ostream & Out,const GenericDINode * N,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context)18607330f729Sjoerg static void writeGenericDINode(raw_ostream &Out, const GenericDINode *N,
18617330f729Sjoerg                                TypePrinting *TypePrinter, SlotTracker *Machine,
18627330f729Sjoerg                                const Module *Context) {
18637330f729Sjoerg   Out << "!GenericDINode(";
18647330f729Sjoerg   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
18657330f729Sjoerg   Printer.printTag(N);
18667330f729Sjoerg   Printer.printString("header", N->getHeader());
18677330f729Sjoerg   if (N->getNumDwarfOperands()) {
18687330f729Sjoerg     Out << Printer.FS << "operands: {";
18697330f729Sjoerg     FieldSeparator IFS;
18707330f729Sjoerg     for (auto &I : N->dwarf_operands()) {
18717330f729Sjoerg       Out << IFS;
18727330f729Sjoerg       writeMetadataAsOperand(Out, I, TypePrinter, Machine, Context);
18737330f729Sjoerg     }
18747330f729Sjoerg     Out << "}";
18757330f729Sjoerg   }
18767330f729Sjoerg   Out << ")";
18777330f729Sjoerg }
18787330f729Sjoerg 
writeDILocation(raw_ostream & Out,const DILocation * DL,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context)18797330f729Sjoerg static void writeDILocation(raw_ostream &Out, const DILocation *DL,
18807330f729Sjoerg                             TypePrinting *TypePrinter, SlotTracker *Machine,
18817330f729Sjoerg                             const Module *Context) {
18827330f729Sjoerg   Out << "!DILocation(";
18837330f729Sjoerg   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
18847330f729Sjoerg   // Always output the line, since 0 is a relevant and important value for it.
18857330f729Sjoerg   Printer.printInt("line", DL->getLine(), /* ShouldSkipZero */ false);
18867330f729Sjoerg   Printer.printInt("column", DL->getColumn());
18877330f729Sjoerg   Printer.printMetadata("scope", DL->getRawScope(), /* ShouldSkipNull */ false);
18887330f729Sjoerg   Printer.printMetadata("inlinedAt", DL->getRawInlinedAt());
18897330f729Sjoerg   Printer.printBool("isImplicitCode", DL->isImplicitCode(),
18907330f729Sjoerg                     /* Default */ false);
18917330f729Sjoerg   Out << ")";
18927330f729Sjoerg }
18937330f729Sjoerg 
writeDISubrange(raw_ostream & Out,const DISubrange * N,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context)18947330f729Sjoerg static void writeDISubrange(raw_ostream &Out, const DISubrange *N,
18957330f729Sjoerg                             TypePrinting *TypePrinter, SlotTracker *Machine,
18967330f729Sjoerg                             const Module *Context) {
18977330f729Sjoerg   Out << "!DISubrange(";
18987330f729Sjoerg   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
1899*82d56013Sjoerg 
1900*82d56013Sjoerg   auto *Count = N->getRawCountNode();
1901*82d56013Sjoerg   if (auto *CE = dyn_cast_or_null<ConstantAsMetadata>(Count)) {
1902*82d56013Sjoerg     auto *CV = cast<ConstantInt>(CE->getValue());
1903*82d56013Sjoerg     Printer.printInt("count", CV->getSExtValue(),
1904*82d56013Sjoerg                      /* ShouldSkipZero */ false);
1905*82d56013Sjoerg   } else
1906*82d56013Sjoerg     Printer.printMetadata("count", Count, /*ShouldSkipNull */ true);
1907*82d56013Sjoerg 
1908*82d56013Sjoerg   // A lowerBound of constant 0 should not be skipped, since it is different
1909*82d56013Sjoerg   // from an unspecified lower bound (= nullptr).
1910*82d56013Sjoerg   auto *LBound = N->getRawLowerBound();
1911*82d56013Sjoerg   if (auto *LE = dyn_cast_or_null<ConstantAsMetadata>(LBound)) {
1912*82d56013Sjoerg     auto *LV = cast<ConstantInt>(LE->getValue());
1913*82d56013Sjoerg     Printer.printInt("lowerBound", LV->getSExtValue(),
1914*82d56013Sjoerg                      /* ShouldSkipZero */ false);
1915*82d56013Sjoerg   } else
1916*82d56013Sjoerg     Printer.printMetadata("lowerBound", LBound, /*ShouldSkipNull */ true);
1917*82d56013Sjoerg 
1918*82d56013Sjoerg   auto *UBound = N->getRawUpperBound();
1919*82d56013Sjoerg   if (auto *UE = dyn_cast_or_null<ConstantAsMetadata>(UBound)) {
1920*82d56013Sjoerg     auto *UV = cast<ConstantInt>(UE->getValue());
1921*82d56013Sjoerg     Printer.printInt("upperBound", UV->getSExtValue(),
1922*82d56013Sjoerg                      /* ShouldSkipZero */ false);
1923*82d56013Sjoerg   } else
1924*82d56013Sjoerg     Printer.printMetadata("upperBound", UBound, /*ShouldSkipNull */ true);
1925*82d56013Sjoerg 
1926*82d56013Sjoerg   auto *Stride = N->getRawStride();
1927*82d56013Sjoerg   if (auto *SE = dyn_cast_or_null<ConstantAsMetadata>(Stride)) {
1928*82d56013Sjoerg     auto *SV = cast<ConstantInt>(SE->getValue());
1929*82d56013Sjoerg     Printer.printInt("stride", SV->getSExtValue(), /* ShouldSkipZero */ false);
1930*82d56013Sjoerg   } else
1931*82d56013Sjoerg     Printer.printMetadata("stride", Stride, /*ShouldSkipNull */ true);
1932*82d56013Sjoerg 
1933*82d56013Sjoerg   Out << ")";
1934*82d56013Sjoerg }
1935*82d56013Sjoerg 
writeDIGenericSubrange(raw_ostream & Out,const DIGenericSubrange * N,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context)1936*82d56013Sjoerg static void writeDIGenericSubrange(raw_ostream &Out, const DIGenericSubrange *N,
1937*82d56013Sjoerg                                    TypePrinting *TypePrinter,
1938*82d56013Sjoerg                                    SlotTracker *Machine,
1939*82d56013Sjoerg                                    const Module *Context) {
1940*82d56013Sjoerg   Out << "!DIGenericSubrange(";
1941*82d56013Sjoerg   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
1942*82d56013Sjoerg 
1943*82d56013Sjoerg   auto IsConstant = [&](Metadata *Bound) -> bool {
1944*82d56013Sjoerg     if (auto *BE = dyn_cast_or_null<DIExpression>(Bound)) {
1945*82d56013Sjoerg       return BE->isConstant()
1946*82d56013Sjoerg                  ? DIExpression::SignedOrUnsignedConstant::SignedConstant ==
1947*82d56013Sjoerg                        *BE->isConstant()
1948*82d56013Sjoerg                  : false;
1949*82d56013Sjoerg     }
1950*82d56013Sjoerg     return false;
1951*82d56013Sjoerg   };
1952*82d56013Sjoerg 
1953*82d56013Sjoerg   auto GetConstant = [&](Metadata *Bound) -> int64_t {
1954*82d56013Sjoerg     assert(IsConstant(Bound) && "Expected constant");
1955*82d56013Sjoerg     auto *BE = dyn_cast_or_null<DIExpression>(Bound);
1956*82d56013Sjoerg     return static_cast<int64_t>(BE->getElement(1));
1957*82d56013Sjoerg   };
1958*82d56013Sjoerg 
1959*82d56013Sjoerg   auto *Count = N->getRawCountNode();
1960*82d56013Sjoerg   if (IsConstant(Count))
1961*82d56013Sjoerg     Printer.printInt("count", GetConstant(Count),
1962*82d56013Sjoerg                      /* ShouldSkipZero */ false);
19637330f729Sjoerg   else
1964*82d56013Sjoerg     Printer.printMetadata("count", Count, /*ShouldSkipNull */ true);
1965*82d56013Sjoerg 
1966*82d56013Sjoerg   auto *LBound = N->getRawLowerBound();
1967*82d56013Sjoerg   if (IsConstant(LBound))
1968*82d56013Sjoerg     Printer.printInt("lowerBound", GetConstant(LBound),
1969*82d56013Sjoerg                      /* ShouldSkipZero */ false);
1970*82d56013Sjoerg   else
1971*82d56013Sjoerg     Printer.printMetadata("lowerBound", LBound, /*ShouldSkipNull */ true);
1972*82d56013Sjoerg 
1973*82d56013Sjoerg   auto *UBound = N->getRawUpperBound();
1974*82d56013Sjoerg   if (IsConstant(UBound))
1975*82d56013Sjoerg     Printer.printInt("upperBound", GetConstant(UBound),
1976*82d56013Sjoerg                      /* ShouldSkipZero */ false);
1977*82d56013Sjoerg   else
1978*82d56013Sjoerg     Printer.printMetadata("upperBound", UBound, /*ShouldSkipNull */ true);
1979*82d56013Sjoerg 
1980*82d56013Sjoerg   auto *Stride = N->getRawStride();
1981*82d56013Sjoerg   if (IsConstant(Stride))
1982*82d56013Sjoerg     Printer.printInt("stride", GetConstant(Stride),
1983*82d56013Sjoerg                      /* ShouldSkipZero */ false);
1984*82d56013Sjoerg   else
1985*82d56013Sjoerg     Printer.printMetadata("stride", Stride, /*ShouldSkipNull */ true);
1986*82d56013Sjoerg 
19877330f729Sjoerg   Out << ")";
19887330f729Sjoerg }
19897330f729Sjoerg 
writeDIEnumerator(raw_ostream & Out,const DIEnumerator * N,TypePrinting *,SlotTracker *,const Module *)19907330f729Sjoerg static void writeDIEnumerator(raw_ostream &Out, const DIEnumerator *N,
19917330f729Sjoerg                               TypePrinting *, SlotTracker *, const Module *) {
19927330f729Sjoerg   Out << "!DIEnumerator(";
19937330f729Sjoerg   MDFieldPrinter Printer(Out);
19947330f729Sjoerg   Printer.printString("name", N->getName(), /* ShouldSkipEmpty */ false);
1995*82d56013Sjoerg   Printer.printAPInt("value", N->getValue(), N->isUnsigned(),
1996*82d56013Sjoerg                      /*ShouldSkipZero=*/false);
1997*82d56013Sjoerg   if (N->isUnsigned())
19987330f729Sjoerg     Printer.printBool("isUnsigned", true);
19997330f729Sjoerg   Out << ")";
20007330f729Sjoerg }
20017330f729Sjoerg 
writeDIBasicType(raw_ostream & Out,const DIBasicType * N,TypePrinting *,SlotTracker *,const Module *)20027330f729Sjoerg static void writeDIBasicType(raw_ostream &Out, const DIBasicType *N,
20037330f729Sjoerg                              TypePrinting *, SlotTracker *, const Module *) {
20047330f729Sjoerg   Out << "!DIBasicType(";
20057330f729Sjoerg   MDFieldPrinter Printer(Out);
20067330f729Sjoerg   if (N->getTag() != dwarf::DW_TAG_base_type)
20077330f729Sjoerg     Printer.printTag(N);
20087330f729Sjoerg   Printer.printString("name", N->getName());
20097330f729Sjoerg   Printer.printInt("size", N->getSizeInBits());
20107330f729Sjoerg   Printer.printInt("align", N->getAlignInBits());
20117330f729Sjoerg   Printer.printDwarfEnum("encoding", N->getEncoding(),
20127330f729Sjoerg                          dwarf::AttributeEncodingString);
20137330f729Sjoerg   Printer.printDIFlags("flags", N->getFlags());
20147330f729Sjoerg   Out << ")";
20157330f729Sjoerg }
20167330f729Sjoerg 
writeDIStringType(raw_ostream & Out,const DIStringType * N,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context)2017*82d56013Sjoerg static void writeDIStringType(raw_ostream &Out, const DIStringType *N,
2018*82d56013Sjoerg                               TypePrinting *TypePrinter, SlotTracker *Machine,
2019*82d56013Sjoerg                               const Module *Context) {
2020*82d56013Sjoerg   Out << "!DIStringType(";
2021*82d56013Sjoerg   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
2022*82d56013Sjoerg   if (N->getTag() != dwarf::DW_TAG_string_type)
2023*82d56013Sjoerg     Printer.printTag(N);
2024*82d56013Sjoerg   Printer.printString("name", N->getName());
2025*82d56013Sjoerg   Printer.printMetadata("stringLength", N->getRawStringLength());
2026*82d56013Sjoerg   Printer.printMetadata("stringLengthExpression", N->getRawStringLengthExp());
2027*82d56013Sjoerg   Printer.printInt("size", N->getSizeInBits());
2028*82d56013Sjoerg   Printer.printInt("align", N->getAlignInBits());
2029*82d56013Sjoerg   Printer.printDwarfEnum("encoding", N->getEncoding(),
2030*82d56013Sjoerg                          dwarf::AttributeEncodingString);
2031*82d56013Sjoerg   Out << ")";
2032*82d56013Sjoerg }
2033*82d56013Sjoerg 
writeDIDerivedType(raw_ostream & Out,const DIDerivedType * N,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context)20347330f729Sjoerg static void writeDIDerivedType(raw_ostream &Out, const DIDerivedType *N,
20357330f729Sjoerg                                TypePrinting *TypePrinter, SlotTracker *Machine,
20367330f729Sjoerg                                const Module *Context) {
20377330f729Sjoerg   Out << "!DIDerivedType(";
20387330f729Sjoerg   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
20397330f729Sjoerg   Printer.printTag(N);
20407330f729Sjoerg   Printer.printString("name", N->getName());
20417330f729Sjoerg   Printer.printMetadata("scope", N->getRawScope());
20427330f729Sjoerg   Printer.printMetadata("file", N->getRawFile());
20437330f729Sjoerg   Printer.printInt("line", N->getLine());
20447330f729Sjoerg   Printer.printMetadata("baseType", N->getRawBaseType(),
20457330f729Sjoerg                         /* ShouldSkipNull */ false);
20467330f729Sjoerg   Printer.printInt("size", N->getSizeInBits());
20477330f729Sjoerg   Printer.printInt("align", N->getAlignInBits());
20487330f729Sjoerg   Printer.printInt("offset", N->getOffsetInBits());
20497330f729Sjoerg   Printer.printDIFlags("flags", N->getFlags());
20507330f729Sjoerg   Printer.printMetadata("extraData", N->getRawExtraData());
20517330f729Sjoerg   if (const auto &DWARFAddressSpace = N->getDWARFAddressSpace())
20527330f729Sjoerg     Printer.printInt("dwarfAddressSpace", *DWARFAddressSpace,
20537330f729Sjoerg                      /* ShouldSkipZero */ false);
20547330f729Sjoerg   Out << ")";
20557330f729Sjoerg }
20567330f729Sjoerg 
writeDICompositeType(raw_ostream & Out,const DICompositeType * N,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context)20577330f729Sjoerg static void writeDICompositeType(raw_ostream &Out, const DICompositeType *N,
20587330f729Sjoerg                                  TypePrinting *TypePrinter,
20597330f729Sjoerg                                  SlotTracker *Machine, const Module *Context) {
20607330f729Sjoerg   Out << "!DICompositeType(";
20617330f729Sjoerg   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
20627330f729Sjoerg   Printer.printTag(N);
20637330f729Sjoerg   Printer.printString("name", N->getName());
20647330f729Sjoerg   Printer.printMetadata("scope", N->getRawScope());
20657330f729Sjoerg   Printer.printMetadata("file", N->getRawFile());
20667330f729Sjoerg   Printer.printInt("line", N->getLine());
20677330f729Sjoerg   Printer.printMetadata("baseType", N->getRawBaseType());
20687330f729Sjoerg   Printer.printInt("size", N->getSizeInBits());
20697330f729Sjoerg   Printer.printInt("align", N->getAlignInBits());
20707330f729Sjoerg   Printer.printInt("offset", N->getOffsetInBits());
20717330f729Sjoerg   Printer.printDIFlags("flags", N->getFlags());
20727330f729Sjoerg   Printer.printMetadata("elements", N->getRawElements());
20737330f729Sjoerg   Printer.printDwarfEnum("runtimeLang", N->getRuntimeLang(),
20747330f729Sjoerg                          dwarf::LanguageString);
20757330f729Sjoerg   Printer.printMetadata("vtableHolder", N->getRawVTableHolder());
20767330f729Sjoerg   Printer.printMetadata("templateParams", N->getRawTemplateParams());
20777330f729Sjoerg   Printer.printString("identifier", N->getIdentifier());
20787330f729Sjoerg   Printer.printMetadata("discriminator", N->getRawDiscriminator());
2079*82d56013Sjoerg   Printer.printMetadata("dataLocation", N->getRawDataLocation());
2080*82d56013Sjoerg   Printer.printMetadata("associated", N->getRawAssociated());
2081*82d56013Sjoerg   Printer.printMetadata("allocated", N->getRawAllocated());
2082*82d56013Sjoerg   if (auto *RankConst = N->getRankConst())
2083*82d56013Sjoerg     Printer.printInt("rank", RankConst->getSExtValue(),
2084*82d56013Sjoerg                      /* ShouldSkipZero */ false);
2085*82d56013Sjoerg   else
2086*82d56013Sjoerg     Printer.printMetadata("rank", N->getRawRank(), /*ShouldSkipNull */ true);
20877330f729Sjoerg   Out << ")";
20887330f729Sjoerg }
20897330f729Sjoerg 
writeDISubroutineType(raw_ostream & Out,const DISubroutineType * N,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context)20907330f729Sjoerg static void writeDISubroutineType(raw_ostream &Out, const DISubroutineType *N,
20917330f729Sjoerg                                   TypePrinting *TypePrinter,
20927330f729Sjoerg                                   SlotTracker *Machine, const Module *Context) {
20937330f729Sjoerg   Out << "!DISubroutineType(";
20947330f729Sjoerg   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
20957330f729Sjoerg   Printer.printDIFlags("flags", N->getFlags());
20967330f729Sjoerg   Printer.printDwarfEnum("cc", N->getCC(), dwarf::ConventionString);
20977330f729Sjoerg   Printer.printMetadata("types", N->getRawTypeArray(),
20987330f729Sjoerg                         /* ShouldSkipNull */ false);
20997330f729Sjoerg   Out << ")";
21007330f729Sjoerg }
21017330f729Sjoerg 
writeDIFile(raw_ostream & Out,const DIFile * N,TypePrinting *,SlotTracker *,const Module *)21027330f729Sjoerg static void writeDIFile(raw_ostream &Out, const DIFile *N, TypePrinting *,
21037330f729Sjoerg                         SlotTracker *, const Module *) {
21047330f729Sjoerg   Out << "!DIFile(";
21057330f729Sjoerg   MDFieldPrinter Printer(Out);
21067330f729Sjoerg   Printer.printString("filename", N->getFilename(),
21077330f729Sjoerg                       /* ShouldSkipEmpty */ false);
21087330f729Sjoerg   Printer.printString("directory", N->getDirectory(),
21097330f729Sjoerg                       /* ShouldSkipEmpty */ false);
21107330f729Sjoerg   // Print all values for checksum together, or not at all.
21117330f729Sjoerg   if (N->getChecksum())
21127330f729Sjoerg     Printer.printChecksum(*N->getChecksum());
21137330f729Sjoerg   Printer.printString("source", N->getSource().getValueOr(StringRef()),
21147330f729Sjoerg                       /* ShouldSkipEmpty */ true);
21157330f729Sjoerg   Out << ")";
21167330f729Sjoerg }
21177330f729Sjoerg 
writeDICompileUnit(raw_ostream & Out,const DICompileUnit * N,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context)21187330f729Sjoerg static void writeDICompileUnit(raw_ostream &Out, const DICompileUnit *N,
21197330f729Sjoerg                                TypePrinting *TypePrinter, SlotTracker *Machine,
21207330f729Sjoerg                                const Module *Context) {
21217330f729Sjoerg   Out << "!DICompileUnit(";
21227330f729Sjoerg   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
21237330f729Sjoerg   Printer.printDwarfEnum("language", N->getSourceLanguage(),
21247330f729Sjoerg                          dwarf::LanguageString, /* ShouldSkipZero */ false);
21257330f729Sjoerg   Printer.printMetadata("file", N->getRawFile(), /* ShouldSkipNull */ false);
21267330f729Sjoerg   Printer.printString("producer", N->getProducer());
21277330f729Sjoerg   Printer.printBool("isOptimized", N->isOptimized());
21287330f729Sjoerg   Printer.printString("flags", N->getFlags());
21297330f729Sjoerg   Printer.printInt("runtimeVersion", N->getRuntimeVersion(),
21307330f729Sjoerg                    /* ShouldSkipZero */ false);
21317330f729Sjoerg   Printer.printString("splitDebugFilename", N->getSplitDebugFilename());
21327330f729Sjoerg   Printer.printEmissionKind("emissionKind", N->getEmissionKind());
21337330f729Sjoerg   Printer.printMetadata("enums", N->getRawEnumTypes());
21347330f729Sjoerg   Printer.printMetadata("retainedTypes", N->getRawRetainedTypes());
21357330f729Sjoerg   Printer.printMetadata("globals", N->getRawGlobalVariables());
21367330f729Sjoerg   Printer.printMetadata("imports", N->getRawImportedEntities());
21377330f729Sjoerg   Printer.printMetadata("macros", N->getRawMacros());
21387330f729Sjoerg   Printer.printInt("dwoId", N->getDWOId());
21397330f729Sjoerg   Printer.printBool("splitDebugInlining", N->getSplitDebugInlining(), true);
21407330f729Sjoerg   Printer.printBool("debugInfoForProfiling", N->getDebugInfoForProfiling(),
21417330f729Sjoerg                     false);
21427330f729Sjoerg   Printer.printNameTableKind("nameTableKind", N->getNameTableKind());
21437330f729Sjoerg   Printer.printBool("rangesBaseAddress", N->getRangesBaseAddress(), false);
2144*82d56013Sjoerg   Printer.printString("sysroot", N->getSysRoot());
2145*82d56013Sjoerg   Printer.printString("sdk", N->getSDK());
21467330f729Sjoerg   Out << ")";
21477330f729Sjoerg }
21487330f729Sjoerg 
writeDISubprogram(raw_ostream & Out,const DISubprogram * N,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context)21497330f729Sjoerg static void writeDISubprogram(raw_ostream &Out, const DISubprogram *N,
21507330f729Sjoerg                               TypePrinting *TypePrinter, SlotTracker *Machine,
21517330f729Sjoerg                               const Module *Context) {
21527330f729Sjoerg   Out << "!DISubprogram(";
21537330f729Sjoerg   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
21547330f729Sjoerg   Printer.printString("name", N->getName());
21557330f729Sjoerg   Printer.printString("linkageName", N->getLinkageName());
21567330f729Sjoerg   Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
21577330f729Sjoerg   Printer.printMetadata("file", N->getRawFile());
21587330f729Sjoerg   Printer.printInt("line", N->getLine());
21597330f729Sjoerg   Printer.printMetadata("type", N->getRawType());
21607330f729Sjoerg   Printer.printInt("scopeLine", N->getScopeLine());
21617330f729Sjoerg   Printer.printMetadata("containingType", N->getRawContainingType());
21627330f729Sjoerg   if (N->getVirtuality() != dwarf::DW_VIRTUALITY_none ||
21637330f729Sjoerg       N->getVirtualIndex() != 0)
21647330f729Sjoerg     Printer.printInt("virtualIndex", N->getVirtualIndex(), false);
21657330f729Sjoerg   Printer.printInt("thisAdjustment", N->getThisAdjustment());
21667330f729Sjoerg   Printer.printDIFlags("flags", N->getFlags());
21677330f729Sjoerg   Printer.printDISPFlags("spFlags", N->getSPFlags());
21687330f729Sjoerg   Printer.printMetadata("unit", N->getRawUnit());
21697330f729Sjoerg   Printer.printMetadata("templateParams", N->getRawTemplateParams());
21707330f729Sjoerg   Printer.printMetadata("declaration", N->getRawDeclaration());
21717330f729Sjoerg   Printer.printMetadata("retainedNodes", N->getRawRetainedNodes());
21727330f729Sjoerg   Printer.printMetadata("thrownTypes", N->getRawThrownTypes());
21737330f729Sjoerg   Out << ")";
21747330f729Sjoerg }
21757330f729Sjoerg 
writeDILexicalBlock(raw_ostream & Out,const DILexicalBlock * N,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context)21767330f729Sjoerg static void writeDILexicalBlock(raw_ostream &Out, const DILexicalBlock *N,
21777330f729Sjoerg                                 TypePrinting *TypePrinter, SlotTracker *Machine,
21787330f729Sjoerg                                 const Module *Context) {
21797330f729Sjoerg   Out << "!DILexicalBlock(";
21807330f729Sjoerg   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
21817330f729Sjoerg   Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
21827330f729Sjoerg   Printer.printMetadata("file", N->getRawFile());
21837330f729Sjoerg   Printer.printInt("line", N->getLine());
21847330f729Sjoerg   Printer.printInt("column", N->getColumn());
21857330f729Sjoerg   Out << ")";
21867330f729Sjoerg }
21877330f729Sjoerg 
writeDILexicalBlockFile(raw_ostream & Out,const DILexicalBlockFile * N,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context)21887330f729Sjoerg static void writeDILexicalBlockFile(raw_ostream &Out,
21897330f729Sjoerg                                     const DILexicalBlockFile *N,
21907330f729Sjoerg                                     TypePrinting *TypePrinter,
21917330f729Sjoerg                                     SlotTracker *Machine,
21927330f729Sjoerg                                     const Module *Context) {
21937330f729Sjoerg   Out << "!DILexicalBlockFile(";
21947330f729Sjoerg   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
21957330f729Sjoerg   Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
21967330f729Sjoerg   Printer.printMetadata("file", N->getRawFile());
21977330f729Sjoerg   Printer.printInt("discriminator", N->getDiscriminator(),
21987330f729Sjoerg                    /* ShouldSkipZero */ false);
21997330f729Sjoerg   Out << ")";
22007330f729Sjoerg }
22017330f729Sjoerg 
writeDINamespace(raw_ostream & Out,const DINamespace * N,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context)22027330f729Sjoerg static void writeDINamespace(raw_ostream &Out, const DINamespace *N,
22037330f729Sjoerg                              TypePrinting *TypePrinter, SlotTracker *Machine,
22047330f729Sjoerg                              const Module *Context) {
22057330f729Sjoerg   Out << "!DINamespace(";
22067330f729Sjoerg   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
22077330f729Sjoerg   Printer.printString("name", N->getName());
22087330f729Sjoerg   Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
22097330f729Sjoerg   Printer.printBool("exportSymbols", N->getExportSymbols(), false);
22107330f729Sjoerg   Out << ")";
22117330f729Sjoerg }
22127330f729Sjoerg 
writeDICommonBlock(raw_ostream & Out,const DICommonBlock * N,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context)22137330f729Sjoerg static void writeDICommonBlock(raw_ostream &Out, const DICommonBlock *N,
22147330f729Sjoerg                                TypePrinting *TypePrinter, SlotTracker *Machine,
22157330f729Sjoerg                                const Module *Context) {
22167330f729Sjoerg   Out << "!DICommonBlock(";
22177330f729Sjoerg   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
22187330f729Sjoerg   Printer.printMetadata("scope", N->getRawScope(), false);
22197330f729Sjoerg   Printer.printMetadata("declaration", N->getRawDecl(), false);
22207330f729Sjoerg   Printer.printString("name", N->getName());
22217330f729Sjoerg   Printer.printMetadata("file", N->getRawFile());
22227330f729Sjoerg   Printer.printInt("line", N->getLineNo());
22237330f729Sjoerg   Out << ")";
22247330f729Sjoerg }
22257330f729Sjoerg 
writeDIMacro(raw_ostream & Out,const DIMacro * N,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context)22267330f729Sjoerg static void writeDIMacro(raw_ostream &Out, const DIMacro *N,
22277330f729Sjoerg                          TypePrinting *TypePrinter, SlotTracker *Machine,
22287330f729Sjoerg                          const Module *Context) {
22297330f729Sjoerg   Out << "!DIMacro(";
22307330f729Sjoerg   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
22317330f729Sjoerg   Printer.printMacinfoType(N);
22327330f729Sjoerg   Printer.printInt("line", N->getLine());
22337330f729Sjoerg   Printer.printString("name", N->getName());
22347330f729Sjoerg   Printer.printString("value", N->getValue());
22357330f729Sjoerg   Out << ")";
22367330f729Sjoerg }
22377330f729Sjoerg 
writeDIMacroFile(raw_ostream & Out,const DIMacroFile * N,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context)22387330f729Sjoerg static void writeDIMacroFile(raw_ostream &Out, const DIMacroFile *N,
22397330f729Sjoerg                              TypePrinting *TypePrinter, SlotTracker *Machine,
22407330f729Sjoerg                              const Module *Context) {
22417330f729Sjoerg   Out << "!DIMacroFile(";
22427330f729Sjoerg   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
22437330f729Sjoerg   Printer.printInt("line", N->getLine());
22447330f729Sjoerg   Printer.printMetadata("file", N->getRawFile(), /* ShouldSkipNull */ false);
22457330f729Sjoerg   Printer.printMetadata("nodes", N->getRawElements());
22467330f729Sjoerg   Out << ")";
22477330f729Sjoerg }
22487330f729Sjoerg 
writeDIModule(raw_ostream & Out,const DIModule * N,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context)22497330f729Sjoerg static void writeDIModule(raw_ostream &Out, const DIModule *N,
22507330f729Sjoerg                           TypePrinting *TypePrinter, SlotTracker *Machine,
22517330f729Sjoerg                           const Module *Context) {
22527330f729Sjoerg   Out << "!DIModule(";
22537330f729Sjoerg   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
22547330f729Sjoerg   Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
22557330f729Sjoerg   Printer.printString("name", N->getName());
22567330f729Sjoerg   Printer.printString("configMacros", N->getConfigurationMacros());
22577330f729Sjoerg   Printer.printString("includePath", N->getIncludePath());
2258*82d56013Sjoerg   Printer.printString("apinotes", N->getAPINotesFile());
2259*82d56013Sjoerg   Printer.printMetadata("file", N->getRawFile());
2260*82d56013Sjoerg   Printer.printInt("line", N->getLineNo());
2261*82d56013Sjoerg   Printer.printBool("isDecl", N->getIsDecl(), /* Default */ false);
22627330f729Sjoerg   Out << ")";
22637330f729Sjoerg }
22647330f729Sjoerg 
22657330f729Sjoerg 
writeDITemplateTypeParameter(raw_ostream & Out,const DITemplateTypeParameter * N,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context)22667330f729Sjoerg static void writeDITemplateTypeParameter(raw_ostream &Out,
22677330f729Sjoerg                                          const DITemplateTypeParameter *N,
22687330f729Sjoerg                                          TypePrinting *TypePrinter,
22697330f729Sjoerg                                          SlotTracker *Machine,
22707330f729Sjoerg                                          const Module *Context) {
22717330f729Sjoerg   Out << "!DITemplateTypeParameter(";
22727330f729Sjoerg   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
22737330f729Sjoerg   Printer.printString("name", N->getName());
22747330f729Sjoerg   Printer.printMetadata("type", N->getRawType(), /* ShouldSkipNull */ false);
2275*82d56013Sjoerg   Printer.printBool("defaulted", N->isDefault(), /* Default= */ false);
22767330f729Sjoerg   Out << ")";
22777330f729Sjoerg }
22787330f729Sjoerg 
writeDITemplateValueParameter(raw_ostream & Out,const DITemplateValueParameter * N,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context)22797330f729Sjoerg static void writeDITemplateValueParameter(raw_ostream &Out,
22807330f729Sjoerg                                           const DITemplateValueParameter *N,
22817330f729Sjoerg                                           TypePrinting *TypePrinter,
22827330f729Sjoerg                                           SlotTracker *Machine,
22837330f729Sjoerg                                           const Module *Context) {
22847330f729Sjoerg   Out << "!DITemplateValueParameter(";
22857330f729Sjoerg   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
22867330f729Sjoerg   if (N->getTag() != dwarf::DW_TAG_template_value_parameter)
22877330f729Sjoerg     Printer.printTag(N);
22887330f729Sjoerg   Printer.printString("name", N->getName());
22897330f729Sjoerg   Printer.printMetadata("type", N->getRawType());
2290*82d56013Sjoerg   Printer.printBool("defaulted", N->isDefault(), /* Default= */ false);
22917330f729Sjoerg   Printer.printMetadata("value", N->getValue(), /* ShouldSkipNull */ false);
22927330f729Sjoerg   Out << ")";
22937330f729Sjoerg }
22947330f729Sjoerg 
writeDIGlobalVariable(raw_ostream & Out,const DIGlobalVariable * N,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context)22957330f729Sjoerg static void writeDIGlobalVariable(raw_ostream &Out, const DIGlobalVariable *N,
22967330f729Sjoerg                                   TypePrinting *TypePrinter,
22977330f729Sjoerg                                   SlotTracker *Machine, const Module *Context) {
22987330f729Sjoerg   Out << "!DIGlobalVariable(";
22997330f729Sjoerg   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
23007330f729Sjoerg   Printer.printString("name", N->getName());
23017330f729Sjoerg   Printer.printString("linkageName", N->getLinkageName());
23027330f729Sjoerg   Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
23037330f729Sjoerg   Printer.printMetadata("file", N->getRawFile());
23047330f729Sjoerg   Printer.printInt("line", N->getLine());
23057330f729Sjoerg   Printer.printMetadata("type", N->getRawType());
23067330f729Sjoerg   Printer.printBool("isLocal", N->isLocalToUnit());
23077330f729Sjoerg   Printer.printBool("isDefinition", N->isDefinition());
23087330f729Sjoerg   Printer.printMetadata("declaration", N->getRawStaticDataMemberDeclaration());
23097330f729Sjoerg   Printer.printMetadata("templateParams", N->getRawTemplateParams());
23107330f729Sjoerg   Printer.printInt("align", N->getAlignInBits());
23117330f729Sjoerg   Out << ")";
23127330f729Sjoerg }
23137330f729Sjoerg 
writeDILocalVariable(raw_ostream & Out,const DILocalVariable * N,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context)23147330f729Sjoerg static void writeDILocalVariable(raw_ostream &Out, const DILocalVariable *N,
23157330f729Sjoerg                                  TypePrinting *TypePrinter,
23167330f729Sjoerg                                  SlotTracker *Machine, const Module *Context) {
23177330f729Sjoerg   Out << "!DILocalVariable(";
23187330f729Sjoerg   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
23197330f729Sjoerg   Printer.printString("name", N->getName());
23207330f729Sjoerg   Printer.printInt("arg", N->getArg());
23217330f729Sjoerg   Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
23227330f729Sjoerg   Printer.printMetadata("file", N->getRawFile());
23237330f729Sjoerg   Printer.printInt("line", N->getLine());
23247330f729Sjoerg   Printer.printMetadata("type", N->getRawType());
23257330f729Sjoerg   Printer.printDIFlags("flags", N->getFlags());
23267330f729Sjoerg   Printer.printInt("align", N->getAlignInBits());
23277330f729Sjoerg   Out << ")";
23287330f729Sjoerg }
23297330f729Sjoerg 
writeDILabel(raw_ostream & Out,const DILabel * N,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context)23307330f729Sjoerg static void writeDILabel(raw_ostream &Out, const DILabel *N,
23317330f729Sjoerg                          TypePrinting *TypePrinter,
23327330f729Sjoerg                          SlotTracker *Machine, const Module *Context) {
23337330f729Sjoerg   Out << "!DILabel(";
23347330f729Sjoerg   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
23357330f729Sjoerg   Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
23367330f729Sjoerg   Printer.printString("name", N->getName());
23377330f729Sjoerg   Printer.printMetadata("file", N->getRawFile());
23387330f729Sjoerg   Printer.printInt("line", N->getLine());
23397330f729Sjoerg   Out << ")";
23407330f729Sjoerg }
23417330f729Sjoerg 
writeDIExpression(raw_ostream & Out,const DIExpression * N,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context)23427330f729Sjoerg static void writeDIExpression(raw_ostream &Out, const DIExpression *N,
23437330f729Sjoerg                               TypePrinting *TypePrinter, SlotTracker *Machine,
23447330f729Sjoerg                               const Module *Context) {
23457330f729Sjoerg   Out << "!DIExpression(";
23467330f729Sjoerg   FieldSeparator FS;
23477330f729Sjoerg   if (N->isValid()) {
2348*82d56013Sjoerg     for (const DIExpression::ExprOperand &Op : N->expr_ops()) {
2349*82d56013Sjoerg       auto OpStr = dwarf::OperationEncodingString(Op.getOp());
23507330f729Sjoerg       assert(!OpStr.empty() && "Expected valid opcode");
23517330f729Sjoerg 
23527330f729Sjoerg       Out << FS << OpStr;
2353*82d56013Sjoerg       if (Op.getOp() == dwarf::DW_OP_LLVM_convert) {
2354*82d56013Sjoerg         Out << FS << Op.getArg(0);
2355*82d56013Sjoerg         Out << FS << dwarf::AttributeEncodingString(Op.getArg(1));
23567330f729Sjoerg       } else {
2357*82d56013Sjoerg         for (unsigned A = 0, AE = Op.getNumArgs(); A != AE; ++A)
2358*82d56013Sjoerg           Out << FS << Op.getArg(A);
23597330f729Sjoerg       }
23607330f729Sjoerg     }
23617330f729Sjoerg   } else {
23627330f729Sjoerg     for (const auto &I : N->getElements())
23637330f729Sjoerg       Out << FS << I;
23647330f729Sjoerg   }
23657330f729Sjoerg   Out << ")";
23667330f729Sjoerg }
23677330f729Sjoerg 
writeDIArgList(raw_ostream & Out,const DIArgList * N,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context,bool FromValue=false)2368*82d56013Sjoerg static void writeDIArgList(raw_ostream &Out, const DIArgList *N,
2369*82d56013Sjoerg                            TypePrinting *TypePrinter, SlotTracker *Machine,
2370*82d56013Sjoerg                            const Module *Context, bool FromValue = false) {
2371*82d56013Sjoerg   assert(FromValue &&
2372*82d56013Sjoerg          "Unexpected DIArgList metadata outside of value argument");
2373*82d56013Sjoerg   Out << "!DIArgList(";
2374*82d56013Sjoerg   FieldSeparator FS;
2375*82d56013Sjoerg   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
2376*82d56013Sjoerg   for (Metadata *Arg : N->getArgs()) {
2377*82d56013Sjoerg     Out << FS;
2378*82d56013Sjoerg     WriteAsOperandInternal(Out, Arg, TypePrinter, Machine, Context, true);
2379*82d56013Sjoerg   }
2380*82d56013Sjoerg   Out << ")";
2381*82d56013Sjoerg }
2382*82d56013Sjoerg 
writeDIGlobalVariableExpression(raw_ostream & Out,const DIGlobalVariableExpression * N,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context)23837330f729Sjoerg static void writeDIGlobalVariableExpression(raw_ostream &Out,
23847330f729Sjoerg                                             const DIGlobalVariableExpression *N,
23857330f729Sjoerg                                             TypePrinting *TypePrinter,
23867330f729Sjoerg                                             SlotTracker *Machine,
23877330f729Sjoerg                                             const Module *Context) {
23887330f729Sjoerg   Out << "!DIGlobalVariableExpression(";
23897330f729Sjoerg   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
23907330f729Sjoerg   Printer.printMetadata("var", N->getVariable());
23917330f729Sjoerg   Printer.printMetadata("expr", N->getExpression());
23927330f729Sjoerg   Out << ")";
23937330f729Sjoerg }
23947330f729Sjoerg 
writeDIObjCProperty(raw_ostream & Out,const DIObjCProperty * N,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context)23957330f729Sjoerg static void writeDIObjCProperty(raw_ostream &Out, const DIObjCProperty *N,
23967330f729Sjoerg                                 TypePrinting *TypePrinter, SlotTracker *Machine,
23977330f729Sjoerg                                 const Module *Context) {
23987330f729Sjoerg   Out << "!DIObjCProperty(";
23997330f729Sjoerg   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
24007330f729Sjoerg   Printer.printString("name", N->getName());
24017330f729Sjoerg   Printer.printMetadata("file", N->getRawFile());
24027330f729Sjoerg   Printer.printInt("line", N->getLine());
24037330f729Sjoerg   Printer.printString("setter", N->getSetterName());
24047330f729Sjoerg   Printer.printString("getter", N->getGetterName());
24057330f729Sjoerg   Printer.printInt("attributes", N->getAttributes());
24067330f729Sjoerg   Printer.printMetadata("type", N->getRawType());
24077330f729Sjoerg   Out << ")";
24087330f729Sjoerg }
24097330f729Sjoerg 
writeDIImportedEntity(raw_ostream & Out,const DIImportedEntity * N,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context)24107330f729Sjoerg static void writeDIImportedEntity(raw_ostream &Out, const DIImportedEntity *N,
24117330f729Sjoerg                                   TypePrinting *TypePrinter,
24127330f729Sjoerg                                   SlotTracker *Machine, const Module *Context) {
24137330f729Sjoerg   Out << "!DIImportedEntity(";
24147330f729Sjoerg   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
24157330f729Sjoerg   Printer.printTag(N);
24167330f729Sjoerg   Printer.printString("name", N->getName());
24177330f729Sjoerg   Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
24187330f729Sjoerg   Printer.printMetadata("entity", N->getRawEntity());
24197330f729Sjoerg   Printer.printMetadata("file", N->getRawFile());
24207330f729Sjoerg   Printer.printInt("line", N->getLine());
24217330f729Sjoerg   Out << ")";
24227330f729Sjoerg }
24237330f729Sjoerg 
WriteMDNodeBodyInternal(raw_ostream & Out,const MDNode * Node,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context)24247330f729Sjoerg static void WriteMDNodeBodyInternal(raw_ostream &Out, const MDNode *Node,
24257330f729Sjoerg                                     TypePrinting *TypePrinter,
24267330f729Sjoerg                                     SlotTracker *Machine,
24277330f729Sjoerg                                     const Module *Context) {
24287330f729Sjoerg   if (Node->isDistinct())
24297330f729Sjoerg     Out << "distinct ";
24307330f729Sjoerg   else if (Node->isTemporary())
24317330f729Sjoerg     Out << "<temporary!> "; // Handle broken code.
24327330f729Sjoerg 
24337330f729Sjoerg   switch (Node->getMetadataID()) {
24347330f729Sjoerg   default:
24357330f729Sjoerg     llvm_unreachable("Expected uniquable MDNode");
24367330f729Sjoerg #define HANDLE_MDNODE_LEAF(CLASS)                                              \
24377330f729Sjoerg   case Metadata::CLASS##Kind:                                                  \
24387330f729Sjoerg     write##CLASS(Out, cast<CLASS>(Node), TypePrinter, Machine, Context);       \
24397330f729Sjoerg     break;
24407330f729Sjoerg #include "llvm/IR/Metadata.def"
24417330f729Sjoerg   }
24427330f729Sjoerg }
24437330f729Sjoerg 
24447330f729Sjoerg // Full implementation of printing a Value as an operand with support for
24457330f729Sjoerg // TypePrinting, etc.
WriteAsOperandInternal(raw_ostream & Out,const Value * V,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context)24467330f729Sjoerg static void WriteAsOperandInternal(raw_ostream &Out, const Value *V,
24477330f729Sjoerg                                    TypePrinting *TypePrinter,
24487330f729Sjoerg                                    SlotTracker *Machine,
24497330f729Sjoerg                                    const Module *Context) {
24507330f729Sjoerg   if (V->hasName()) {
24517330f729Sjoerg     PrintLLVMName(Out, V);
24527330f729Sjoerg     return;
24537330f729Sjoerg   }
24547330f729Sjoerg 
24557330f729Sjoerg   const Constant *CV = dyn_cast<Constant>(V);
24567330f729Sjoerg   if (CV && !isa<GlobalValue>(CV)) {
24577330f729Sjoerg     assert(TypePrinter && "Constants require TypePrinting!");
24587330f729Sjoerg     WriteConstantInternal(Out, CV, *TypePrinter, Machine, Context);
24597330f729Sjoerg     return;
24607330f729Sjoerg   }
24617330f729Sjoerg 
24627330f729Sjoerg   if (const InlineAsm *IA = dyn_cast<InlineAsm>(V)) {
24637330f729Sjoerg     Out << "asm ";
24647330f729Sjoerg     if (IA->hasSideEffects())
24657330f729Sjoerg       Out << "sideeffect ";
24667330f729Sjoerg     if (IA->isAlignStack())
24677330f729Sjoerg       Out << "alignstack ";
24687330f729Sjoerg     // We don't emit the AD_ATT dialect as it's the assumed default.
24697330f729Sjoerg     if (IA->getDialect() == InlineAsm::AD_Intel)
24707330f729Sjoerg       Out << "inteldialect ";
2471*82d56013Sjoerg     if (IA->canThrow())
2472*82d56013Sjoerg       Out << "unwind ";
24737330f729Sjoerg     Out << '"';
24747330f729Sjoerg     printEscapedString(IA->getAsmString(), Out);
24757330f729Sjoerg     Out << "\", \"";
24767330f729Sjoerg     printEscapedString(IA->getConstraintString(), Out);
24777330f729Sjoerg     Out << '"';
24787330f729Sjoerg     return;
24797330f729Sjoerg   }
24807330f729Sjoerg 
24817330f729Sjoerg   if (auto *MD = dyn_cast<MetadataAsValue>(V)) {
24827330f729Sjoerg     WriteAsOperandInternal(Out, MD->getMetadata(), TypePrinter, Machine,
24837330f729Sjoerg                            Context, /* FromValue */ true);
24847330f729Sjoerg     return;
24857330f729Sjoerg   }
24867330f729Sjoerg 
24877330f729Sjoerg   char Prefix = '%';
24887330f729Sjoerg   int Slot;
24897330f729Sjoerg   // If we have a SlotTracker, use it.
24907330f729Sjoerg   if (Machine) {
24917330f729Sjoerg     if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
24927330f729Sjoerg       Slot = Machine->getGlobalSlot(GV);
24937330f729Sjoerg       Prefix = '@';
24947330f729Sjoerg     } else {
24957330f729Sjoerg       Slot = Machine->getLocalSlot(V);
24967330f729Sjoerg 
24977330f729Sjoerg       // If the local value didn't succeed, then we may be referring to a value
24987330f729Sjoerg       // from a different function.  Translate it, as this can happen when using
24997330f729Sjoerg       // address of blocks.
25007330f729Sjoerg       if (Slot == -1)
25017330f729Sjoerg         if ((Machine = createSlotTracker(V))) {
25027330f729Sjoerg           Slot = Machine->getLocalSlot(V);
25037330f729Sjoerg           delete Machine;
25047330f729Sjoerg         }
25057330f729Sjoerg     }
25067330f729Sjoerg   } else if ((Machine = createSlotTracker(V))) {
25077330f729Sjoerg     // Otherwise, create one to get the # and then destroy it.
25087330f729Sjoerg     if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
25097330f729Sjoerg       Slot = Machine->getGlobalSlot(GV);
25107330f729Sjoerg       Prefix = '@';
25117330f729Sjoerg     } else {
25127330f729Sjoerg       Slot = Machine->getLocalSlot(V);
25137330f729Sjoerg     }
25147330f729Sjoerg     delete Machine;
25157330f729Sjoerg     Machine = nullptr;
25167330f729Sjoerg   } else {
25177330f729Sjoerg     Slot = -1;
25187330f729Sjoerg   }
25197330f729Sjoerg 
25207330f729Sjoerg   if (Slot != -1)
25217330f729Sjoerg     Out << Prefix << Slot;
25227330f729Sjoerg   else
25237330f729Sjoerg     Out << "<badref>";
25247330f729Sjoerg }
25257330f729Sjoerg 
WriteAsOperandInternal(raw_ostream & Out,const Metadata * MD,TypePrinting * TypePrinter,SlotTracker * Machine,const Module * Context,bool FromValue)25267330f729Sjoerg static void WriteAsOperandInternal(raw_ostream &Out, const Metadata *MD,
25277330f729Sjoerg                                    TypePrinting *TypePrinter,
25287330f729Sjoerg                                    SlotTracker *Machine, const Module *Context,
25297330f729Sjoerg                                    bool FromValue) {
2530*82d56013Sjoerg   // Write DIExpressions and DIArgLists inline when used as a value. Improves
2531*82d56013Sjoerg   // readability of debug info intrinsics.
25327330f729Sjoerg   if (const DIExpression *Expr = dyn_cast<DIExpression>(MD)) {
25337330f729Sjoerg     writeDIExpression(Out, Expr, TypePrinter, Machine, Context);
25347330f729Sjoerg     return;
25357330f729Sjoerg   }
2536*82d56013Sjoerg   if (const DIArgList *ArgList = dyn_cast<DIArgList>(MD)) {
2537*82d56013Sjoerg     writeDIArgList(Out, ArgList, TypePrinter, Machine, Context, FromValue);
2538*82d56013Sjoerg     return;
2539*82d56013Sjoerg   }
25407330f729Sjoerg 
25417330f729Sjoerg   if (const MDNode *N = dyn_cast<MDNode>(MD)) {
25427330f729Sjoerg     std::unique_ptr<SlotTracker> MachineStorage;
25437330f729Sjoerg     if (!Machine) {
25447330f729Sjoerg       MachineStorage = std::make_unique<SlotTracker>(Context);
25457330f729Sjoerg       Machine = MachineStorage.get();
25467330f729Sjoerg     }
25477330f729Sjoerg     int Slot = Machine->getMetadataSlot(N);
25487330f729Sjoerg     if (Slot == -1) {
25497330f729Sjoerg       if (const DILocation *Loc = dyn_cast<DILocation>(N)) {
25507330f729Sjoerg         writeDILocation(Out, Loc, TypePrinter, Machine, Context);
25517330f729Sjoerg         return;
25527330f729Sjoerg       }
25537330f729Sjoerg       // Give the pointer value instead of "badref", since this comes up all
25547330f729Sjoerg       // the time when debugging.
25557330f729Sjoerg       Out << "<" << N << ">";
25567330f729Sjoerg     } else
25577330f729Sjoerg       Out << '!' << Slot;
25587330f729Sjoerg     return;
25597330f729Sjoerg   }
25607330f729Sjoerg 
25617330f729Sjoerg   if (const MDString *MDS = dyn_cast<MDString>(MD)) {
25627330f729Sjoerg     Out << "!\"";
25637330f729Sjoerg     printEscapedString(MDS->getString(), Out);
25647330f729Sjoerg     Out << '"';
25657330f729Sjoerg     return;
25667330f729Sjoerg   }
25677330f729Sjoerg 
25687330f729Sjoerg   auto *V = cast<ValueAsMetadata>(MD);
25697330f729Sjoerg   assert(TypePrinter && "TypePrinter required for metadata values");
25707330f729Sjoerg   assert((FromValue || !isa<LocalAsMetadata>(V)) &&
25717330f729Sjoerg          "Unexpected function-local metadata outside of value argument");
25727330f729Sjoerg 
25737330f729Sjoerg   TypePrinter->print(V->getValue()->getType(), Out);
25747330f729Sjoerg   Out << ' ';
25757330f729Sjoerg   WriteAsOperandInternal(Out, V->getValue(), TypePrinter, Machine, Context);
25767330f729Sjoerg }
25777330f729Sjoerg 
25787330f729Sjoerg namespace {
25797330f729Sjoerg 
25807330f729Sjoerg class AssemblyWriter {
25817330f729Sjoerg   formatted_raw_ostream &Out;
25827330f729Sjoerg   const Module *TheModule = nullptr;
25837330f729Sjoerg   const ModuleSummaryIndex *TheIndex = nullptr;
25847330f729Sjoerg   std::unique_ptr<SlotTracker> SlotTrackerStorage;
25857330f729Sjoerg   SlotTracker &Machine;
25867330f729Sjoerg   TypePrinting TypePrinter;
25877330f729Sjoerg   AssemblyAnnotationWriter *AnnotationWriter = nullptr;
25887330f729Sjoerg   SetVector<const Comdat *> Comdats;
25897330f729Sjoerg   bool IsForDebug;
25907330f729Sjoerg   bool ShouldPreserveUseListOrder;
25917330f729Sjoerg   UseListOrderStack UseListOrders;
25927330f729Sjoerg   SmallVector<StringRef, 8> MDNames;
25937330f729Sjoerg   /// Synchronization scope names registered with LLVMContext.
25947330f729Sjoerg   SmallVector<StringRef, 8> SSNs;
25957330f729Sjoerg   DenseMap<const GlobalValueSummary *, GlobalValue::GUID> SummaryToGUIDMap;
25967330f729Sjoerg 
25977330f729Sjoerg public:
25987330f729Sjoerg   /// Construct an AssemblyWriter with an external SlotTracker
25997330f729Sjoerg   AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac, const Module *M,
26007330f729Sjoerg                  AssemblyAnnotationWriter *AAW, bool IsForDebug,
26017330f729Sjoerg                  bool ShouldPreserveUseListOrder = false);
26027330f729Sjoerg 
26037330f729Sjoerg   AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
26047330f729Sjoerg                  const ModuleSummaryIndex *Index, bool IsForDebug);
26057330f729Sjoerg 
26067330f729Sjoerg   void printMDNodeBody(const MDNode *MD);
26077330f729Sjoerg   void printNamedMDNode(const NamedMDNode *NMD);
26087330f729Sjoerg 
26097330f729Sjoerg   void printModule(const Module *M);
26107330f729Sjoerg 
26117330f729Sjoerg   void writeOperand(const Value *Op, bool PrintType);
26127330f729Sjoerg   void writeParamOperand(const Value *Operand, AttributeSet Attrs);
26137330f729Sjoerg   void writeOperandBundles(const CallBase *Call);
26147330f729Sjoerg   void writeSyncScope(const LLVMContext &Context,
26157330f729Sjoerg                       SyncScope::ID SSID);
26167330f729Sjoerg   void writeAtomic(const LLVMContext &Context,
26177330f729Sjoerg                    AtomicOrdering Ordering,
26187330f729Sjoerg                    SyncScope::ID SSID);
26197330f729Sjoerg   void writeAtomicCmpXchg(const LLVMContext &Context,
26207330f729Sjoerg                           AtomicOrdering SuccessOrdering,
26217330f729Sjoerg                           AtomicOrdering FailureOrdering,
26227330f729Sjoerg                           SyncScope::ID SSID);
26237330f729Sjoerg 
26247330f729Sjoerg   void writeAllMDNodes();
26257330f729Sjoerg   void writeMDNode(unsigned Slot, const MDNode *Node);
2626*82d56013Sjoerg   void writeAttribute(const Attribute &Attr, bool InAttrGroup = false);
2627*82d56013Sjoerg   void writeAttributeSet(const AttributeSet &AttrSet, bool InAttrGroup = false);
26287330f729Sjoerg   void writeAllAttributeGroups();
26297330f729Sjoerg 
26307330f729Sjoerg   void printTypeIdentities();
26317330f729Sjoerg   void printGlobal(const GlobalVariable *GV);
26327330f729Sjoerg   void printIndirectSymbol(const GlobalIndirectSymbol *GIS);
26337330f729Sjoerg   void printComdat(const Comdat *C);
26347330f729Sjoerg   void printFunction(const Function *F);
26357330f729Sjoerg   void printArgument(const Argument *FA, AttributeSet Attrs);
26367330f729Sjoerg   void printBasicBlock(const BasicBlock *BB);
26377330f729Sjoerg   void printInstructionLine(const Instruction &I);
26387330f729Sjoerg   void printInstruction(const Instruction &I);
26397330f729Sjoerg 
26407330f729Sjoerg   void printUseListOrder(const UseListOrder &Order);
26417330f729Sjoerg   void printUseLists(const Function *F);
26427330f729Sjoerg 
26437330f729Sjoerg   void printModuleSummaryIndex();
26447330f729Sjoerg   void printSummaryInfo(unsigned Slot, const ValueInfo &VI);
26457330f729Sjoerg   void printSummary(const GlobalValueSummary &Summary);
26467330f729Sjoerg   void printAliasSummary(const AliasSummary *AS);
26477330f729Sjoerg   void printGlobalVarSummary(const GlobalVarSummary *GS);
26487330f729Sjoerg   void printFunctionSummary(const FunctionSummary *FS);
26497330f729Sjoerg   void printTypeIdSummary(const TypeIdSummary &TIS);
26507330f729Sjoerg   void printTypeIdCompatibleVtableSummary(const TypeIdCompatibleVtableInfo &TI);
26517330f729Sjoerg   void printTypeTestResolution(const TypeTestResolution &TTRes);
26527330f729Sjoerg   void printArgs(const std::vector<uint64_t> &Args);
26537330f729Sjoerg   void printWPDRes(const WholeProgramDevirtResolution &WPDRes);
26547330f729Sjoerg   void printTypeIdInfo(const FunctionSummary::TypeIdInfo &TIDInfo);
26557330f729Sjoerg   void printVFuncId(const FunctionSummary::VFuncId VFId);
26567330f729Sjoerg   void
2657*82d56013Sjoerg   printNonConstVCalls(const std::vector<FunctionSummary::VFuncId> &VCallList,
26587330f729Sjoerg                       const char *Tag);
26597330f729Sjoerg   void
2660*82d56013Sjoerg   printConstVCalls(const std::vector<FunctionSummary::ConstVCall> &VCallList,
26617330f729Sjoerg                    const char *Tag);
26627330f729Sjoerg 
26637330f729Sjoerg private:
26647330f729Sjoerg   /// Print out metadata attachments.
26657330f729Sjoerg   void printMetadataAttachments(
26667330f729Sjoerg       const SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs,
26677330f729Sjoerg       StringRef Separator);
26687330f729Sjoerg 
26697330f729Sjoerg   // printInfoComment - Print a little comment after the instruction indicating
26707330f729Sjoerg   // which slot it occupies.
26717330f729Sjoerg   void printInfoComment(const Value &V);
26727330f729Sjoerg 
26737330f729Sjoerg   // printGCRelocateComment - print comment after call to the gc.relocate
26747330f729Sjoerg   // intrinsic indicating base and derived pointer names.
26757330f729Sjoerg   void printGCRelocateComment(const GCRelocateInst &Relocate);
26767330f729Sjoerg };
26777330f729Sjoerg 
26787330f729Sjoerg } // end anonymous namespace
26797330f729Sjoerg 
AssemblyWriter(formatted_raw_ostream & o,SlotTracker & Mac,const Module * M,AssemblyAnnotationWriter * AAW,bool IsForDebug,bool ShouldPreserveUseListOrder)26807330f729Sjoerg AssemblyWriter::AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
26817330f729Sjoerg                                const Module *M, AssemblyAnnotationWriter *AAW,
26827330f729Sjoerg                                bool IsForDebug, bool ShouldPreserveUseListOrder)
26837330f729Sjoerg     : Out(o), TheModule(M), Machine(Mac), TypePrinter(M), AnnotationWriter(AAW),
26847330f729Sjoerg       IsForDebug(IsForDebug),
26857330f729Sjoerg       ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {
26867330f729Sjoerg   if (!TheModule)
26877330f729Sjoerg     return;
26887330f729Sjoerg   for (const GlobalObject &GO : TheModule->global_objects())
26897330f729Sjoerg     if (const Comdat *C = GO.getComdat())
26907330f729Sjoerg       Comdats.insert(C);
26917330f729Sjoerg }
26927330f729Sjoerg 
AssemblyWriter(formatted_raw_ostream & o,SlotTracker & Mac,const ModuleSummaryIndex * Index,bool IsForDebug)26937330f729Sjoerg AssemblyWriter::AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
26947330f729Sjoerg                                const ModuleSummaryIndex *Index, bool IsForDebug)
26957330f729Sjoerg     : Out(o), TheIndex(Index), Machine(Mac), TypePrinter(/*Module=*/nullptr),
26967330f729Sjoerg       IsForDebug(IsForDebug), ShouldPreserveUseListOrder(false) {}
26977330f729Sjoerg 
writeOperand(const Value * Operand,bool PrintType)26987330f729Sjoerg void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType) {
26997330f729Sjoerg   if (!Operand) {
27007330f729Sjoerg     Out << "<null operand!>";
27017330f729Sjoerg     return;
27027330f729Sjoerg   }
27037330f729Sjoerg   if (PrintType) {
27047330f729Sjoerg     TypePrinter.print(Operand->getType(), Out);
27057330f729Sjoerg     Out << ' ';
27067330f729Sjoerg   }
27077330f729Sjoerg   WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine, TheModule);
27087330f729Sjoerg }
27097330f729Sjoerg 
writeSyncScope(const LLVMContext & Context,SyncScope::ID SSID)27107330f729Sjoerg void AssemblyWriter::writeSyncScope(const LLVMContext &Context,
27117330f729Sjoerg                                     SyncScope::ID SSID) {
27127330f729Sjoerg   switch (SSID) {
27137330f729Sjoerg   case SyncScope::System: {
27147330f729Sjoerg     break;
27157330f729Sjoerg   }
27167330f729Sjoerg   default: {
27177330f729Sjoerg     if (SSNs.empty())
27187330f729Sjoerg       Context.getSyncScopeNames(SSNs);
27197330f729Sjoerg 
27207330f729Sjoerg     Out << " syncscope(\"";
27217330f729Sjoerg     printEscapedString(SSNs[SSID], Out);
27227330f729Sjoerg     Out << "\")";
27237330f729Sjoerg     break;
27247330f729Sjoerg   }
27257330f729Sjoerg   }
27267330f729Sjoerg }
27277330f729Sjoerg 
writeAtomic(const LLVMContext & Context,AtomicOrdering Ordering,SyncScope::ID SSID)27287330f729Sjoerg void AssemblyWriter::writeAtomic(const LLVMContext &Context,
27297330f729Sjoerg                                  AtomicOrdering Ordering,
27307330f729Sjoerg                                  SyncScope::ID SSID) {
27317330f729Sjoerg   if (Ordering == AtomicOrdering::NotAtomic)
27327330f729Sjoerg     return;
27337330f729Sjoerg 
27347330f729Sjoerg   writeSyncScope(Context, SSID);
27357330f729Sjoerg   Out << " " << toIRString(Ordering);
27367330f729Sjoerg }
27377330f729Sjoerg 
writeAtomicCmpXchg(const LLVMContext & Context,AtomicOrdering SuccessOrdering,AtomicOrdering FailureOrdering,SyncScope::ID SSID)27387330f729Sjoerg void AssemblyWriter::writeAtomicCmpXchg(const LLVMContext &Context,
27397330f729Sjoerg                                         AtomicOrdering SuccessOrdering,
27407330f729Sjoerg                                         AtomicOrdering FailureOrdering,
27417330f729Sjoerg                                         SyncScope::ID SSID) {
27427330f729Sjoerg   assert(SuccessOrdering != AtomicOrdering::NotAtomic &&
27437330f729Sjoerg          FailureOrdering != AtomicOrdering::NotAtomic);
27447330f729Sjoerg 
27457330f729Sjoerg   writeSyncScope(Context, SSID);
27467330f729Sjoerg   Out << " " << toIRString(SuccessOrdering);
27477330f729Sjoerg   Out << " " << toIRString(FailureOrdering);
27487330f729Sjoerg }
27497330f729Sjoerg 
writeParamOperand(const Value * Operand,AttributeSet Attrs)27507330f729Sjoerg void AssemblyWriter::writeParamOperand(const Value *Operand,
27517330f729Sjoerg                                        AttributeSet Attrs) {
27527330f729Sjoerg   if (!Operand) {
27537330f729Sjoerg     Out << "<null operand!>";
27547330f729Sjoerg     return;
27557330f729Sjoerg   }
27567330f729Sjoerg 
27577330f729Sjoerg   // Print the type
27587330f729Sjoerg   TypePrinter.print(Operand->getType(), Out);
27597330f729Sjoerg   // Print parameter attributes list
2760*82d56013Sjoerg   if (Attrs.hasAttributes()) {
2761*82d56013Sjoerg     Out << ' ';
2762*82d56013Sjoerg     writeAttributeSet(Attrs);
2763*82d56013Sjoerg   }
27647330f729Sjoerg   Out << ' ';
27657330f729Sjoerg   // Print the operand
27667330f729Sjoerg   WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine, TheModule);
27677330f729Sjoerg }
27687330f729Sjoerg 
writeOperandBundles(const CallBase * Call)27697330f729Sjoerg void AssemblyWriter::writeOperandBundles(const CallBase *Call) {
27707330f729Sjoerg   if (!Call->hasOperandBundles())
27717330f729Sjoerg     return;
27727330f729Sjoerg 
27737330f729Sjoerg   Out << " [ ";
27747330f729Sjoerg 
27757330f729Sjoerg   bool FirstBundle = true;
27767330f729Sjoerg   for (unsigned i = 0, e = Call->getNumOperandBundles(); i != e; ++i) {
27777330f729Sjoerg     OperandBundleUse BU = Call->getOperandBundleAt(i);
27787330f729Sjoerg 
27797330f729Sjoerg     if (!FirstBundle)
27807330f729Sjoerg       Out << ", ";
27817330f729Sjoerg     FirstBundle = false;
27827330f729Sjoerg 
27837330f729Sjoerg     Out << '"';
27847330f729Sjoerg     printEscapedString(BU.getTagName(), Out);
27857330f729Sjoerg     Out << '"';
27867330f729Sjoerg 
27877330f729Sjoerg     Out << '(';
27887330f729Sjoerg 
27897330f729Sjoerg     bool FirstInput = true;
27907330f729Sjoerg     for (const auto &Input : BU.Inputs) {
27917330f729Sjoerg       if (!FirstInput)
27927330f729Sjoerg         Out << ", ";
27937330f729Sjoerg       FirstInput = false;
27947330f729Sjoerg 
27957330f729Sjoerg       TypePrinter.print(Input->getType(), Out);
27967330f729Sjoerg       Out << " ";
27977330f729Sjoerg       WriteAsOperandInternal(Out, Input, &TypePrinter, &Machine, TheModule);
27987330f729Sjoerg     }
27997330f729Sjoerg 
28007330f729Sjoerg     Out << ')';
28017330f729Sjoerg   }
28027330f729Sjoerg 
28037330f729Sjoerg   Out << " ]";
28047330f729Sjoerg }
28057330f729Sjoerg 
printModule(const Module * M)28067330f729Sjoerg void AssemblyWriter::printModule(const Module *M) {
28077330f729Sjoerg   Machine.initializeIfNeeded();
28087330f729Sjoerg 
28097330f729Sjoerg   if (ShouldPreserveUseListOrder)
28107330f729Sjoerg     UseListOrders = predictUseListOrder(M);
28117330f729Sjoerg 
28127330f729Sjoerg   if (!M->getModuleIdentifier().empty() &&
28137330f729Sjoerg       // Don't print the ID if it will start a new line (which would
28147330f729Sjoerg       // require a comment char before it).
28157330f729Sjoerg       M->getModuleIdentifier().find('\n') == std::string::npos)
28167330f729Sjoerg     Out << "; ModuleID = '" << M->getModuleIdentifier() << "'\n";
28177330f729Sjoerg 
28187330f729Sjoerg   if (!M->getSourceFileName().empty()) {
28197330f729Sjoerg     Out << "source_filename = \"";
28207330f729Sjoerg     printEscapedString(M->getSourceFileName(), Out);
28217330f729Sjoerg     Out << "\"\n";
28227330f729Sjoerg   }
28237330f729Sjoerg 
28247330f729Sjoerg   const std::string &DL = M->getDataLayoutStr();
28257330f729Sjoerg   if (!DL.empty())
28267330f729Sjoerg     Out << "target datalayout = \"" << DL << "\"\n";
28277330f729Sjoerg   if (!M->getTargetTriple().empty())
28287330f729Sjoerg     Out << "target triple = \"" << M->getTargetTriple() << "\"\n";
28297330f729Sjoerg 
28307330f729Sjoerg   if (!M->getModuleInlineAsm().empty()) {
28317330f729Sjoerg     Out << '\n';
28327330f729Sjoerg 
28337330f729Sjoerg     // Split the string into lines, to make it easier to read the .ll file.
28347330f729Sjoerg     StringRef Asm = M->getModuleInlineAsm();
28357330f729Sjoerg     do {
28367330f729Sjoerg       StringRef Front;
28377330f729Sjoerg       std::tie(Front, Asm) = Asm.split('\n');
28387330f729Sjoerg 
28397330f729Sjoerg       // We found a newline, print the portion of the asm string from the
28407330f729Sjoerg       // last newline up to this newline.
28417330f729Sjoerg       Out << "module asm \"";
28427330f729Sjoerg       printEscapedString(Front, Out);
28437330f729Sjoerg       Out << "\"\n";
28447330f729Sjoerg     } while (!Asm.empty());
28457330f729Sjoerg   }
28467330f729Sjoerg 
28477330f729Sjoerg   printTypeIdentities();
28487330f729Sjoerg 
28497330f729Sjoerg   // Output all comdats.
28507330f729Sjoerg   if (!Comdats.empty())
28517330f729Sjoerg     Out << '\n';
28527330f729Sjoerg   for (const Comdat *C : Comdats) {
28537330f729Sjoerg     printComdat(C);
28547330f729Sjoerg     if (C != Comdats.back())
28557330f729Sjoerg       Out << '\n';
28567330f729Sjoerg   }
28577330f729Sjoerg 
28587330f729Sjoerg   // Output all globals.
28597330f729Sjoerg   if (!M->global_empty()) Out << '\n';
28607330f729Sjoerg   for (const GlobalVariable &GV : M->globals()) {
28617330f729Sjoerg     printGlobal(&GV); Out << '\n';
28627330f729Sjoerg   }
28637330f729Sjoerg 
28647330f729Sjoerg   // Output all aliases.
28657330f729Sjoerg   if (!M->alias_empty()) Out << "\n";
28667330f729Sjoerg   for (const GlobalAlias &GA : M->aliases())
28677330f729Sjoerg     printIndirectSymbol(&GA);
28687330f729Sjoerg 
28697330f729Sjoerg   // Output all ifuncs.
28707330f729Sjoerg   if (!M->ifunc_empty()) Out << "\n";
28717330f729Sjoerg   for (const GlobalIFunc &GI : M->ifuncs())
28727330f729Sjoerg     printIndirectSymbol(&GI);
28737330f729Sjoerg 
28747330f729Sjoerg   // Output global use-lists.
28757330f729Sjoerg   printUseLists(nullptr);
28767330f729Sjoerg 
28777330f729Sjoerg   // Output all of the functions.
2878*82d56013Sjoerg   for (const Function &F : *M) {
2879*82d56013Sjoerg     Out << '\n';
28807330f729Sjoerg     printFunction(&F);
2881*82d56013Sjoerg   }
28827330f729Sjoerg   assert(UseListOrders.empty() && "All use-lists should have been consumed");
28837330f729Sjoerg 
28847330f729Sjoerg   // Output all attribute groups.
28857330f729Sjoerg   if (!Machine.as_empty()) {
28867330f729Sjoerg     Out << '\n';
28877330f729Sjoerg     writeAllAttributeGroups();
28887330f729Sjoerg   }
28897330f729Sjoerg 
28907330f729Sjoerg   // Output named metadata.
28917330f729Sjoerg   if (!M->named_metadata_empty()) Out << '\n';
28927330f729Sjoerg 
28937330f729Sjoerg   for (const NamedMDNode &Node : M->named_metadata())
28947330f729Sjoerg     printNamedMDNode(&Node);
28957330f729Sjoerg 
28967330f729Sjoerg   // Output metadata.
28977330f729Sjoerg   if (!Machine.mdn_empty()) {
28987330f729Sjoerg     Out << '\n';
28997330f729Sjoerg     writeAllMDNodes();
29007330f729Sjoerg   }
29017330f729Sjoerg }
29027330f729Sjoerg 
printModuleSummaryIndex()29037330f729Sjoerg void AssemblyWriter::printModuleSummaryIndex() {
29047330f729Sjoerg   assert(TheIndex);
2905*82d56013Sjoerg   int NumSlots = Machine.initializeIndexIfNeeded();
29067330f729Sjoerg 
29077330f729Sjoerg   Out << "\n";
29087330f729Sjoerg 
29097330f729Sjoerg   // Print module path entries. To print in order, add paths to a vector
29107330f729Sjoerg   // indexed by module slot.
29117330f729Sjoerg   std::vector<std::pair<std::string, ModuleHash>> moduleVec;
2912*82d56013Sjoerg   std::string RegularLTOModuleName =
2913*82d56013Sjoerg       ModuleSummaryIndex::getRegularLTOModuleName();
29147330f729Sjoerg   moduleVec.resize(TheIndex->modulePaths().size());
29157330f729Sjoerg   for (auto &ModPath : TheIndex->modulePaths())
29167330f729Sjoerg     moduleVec[Machine.getModulePathSlot(ModPath.first())] = std::make_pair(
29177330f729Sjoerg         // A module id of -1 is a special entry for a regular LTO module created
29187330f729Sjoerg         // during the thin link.
29197330f729Sjoerg         ModPath.second.first == -1u ? RegularLTOModuleName
2920*82d56013Sjoerg                                     : (std::string)std::string(ModPath.first()),
29217330f729Sjoerg         ModPath.second.second);
29227330f729Sjoerg 
29237330f729Sjoerg   unsigned i = 0;
29247330f729Sjoerg   for (auto &ModPair : moduleVec) {
29257330f729Sjoerg     Out << "^" << i++ << " = module: (";
29267330f729Sjoerg     Out << "path: \"";
29277330f729Sjoerg     printEscapedString(ModPair.first, Out);
29287330f729Sjoerg     Out << "\", hash: (";
29297330f729Sjoerg     FieldSeparator FS;
29307330f729Sjoerg     for (auto Hash : ModPair.second)
29317330f729Sjoerg       Out << FS << Hash;
29327330f729Sjoerg     Out << "))\n";
29337330f729Sjoerg   }
29347330f729Sjoerg 
29357330f729Sjoerg   // FIXME: Change AliasSummary to hold a ValueInfo instead of summary pointer
29367330f729Sjoerg   // for aliasee (then update BitcodeWriter.cpp and remove get/setAliaseeGUID).
29377330f729Sjoerg   for (auto &GlobalList : *TheIndex) {
29387330f729Sjoerg     auto GUID = GlobalList.first;
29397330f729Sjoerg     for (auto &Summary : GlobalList.second.SummaryList)
29407330f729Sjoerg       SummaryToGUIDMap[Summary.get()] = GUID;
29417330f729Sjoerg   }
29427330f729Sjoerg 
29437330f729Sjoerg   // Print the global value summary entries.
29447330f729Sjoerg   for (auto &GlobalList : *TheIndex) {
29457330f729Sjoerg     auto GUID = GlobalList.first;
29467330f729Sjoerg     auto VI = TheIndex->getValueInfo(GlobalList);
29477330f729Sjoerg     printSummaryInfo(Machine.getGUIDSlot(GUID), VI);
29487330f729Sjoerg   }
29497330f729Sjoerg 
29507330f729Sjoerg   // Print the TypeIdMap entries.
2951*82d56013Sjoerg   for (const auto &TID : TheIndex->typeIds()) {
2952*82d56013Sjoerg     Out << "^" << Machine.getTypeIdSlot(TID.second.first)
2953*82d56013Sjoerg         << " = typeid: (name: \"" << TID.second.first << "\"";
2954*82d56013Sjoerg     printTypeIdSummary(TID.second.second);
2955*82d56013Sjoerg     Out << ") ; guid = " << TID.first << "\n";
29567330f729Sjoerg   }
29577330f729Sjoerg 
29587330f729Sjoerg   // Print the TypeIdCompatibleVtableMap entries.
29597330f729Sjoerg   for (auto &TId : TheIndex->typeIdCompatibleVtableMap()) {
29607330f729Sjoerg     auto GUID = GlobalValue::getGUID(TId.first);
29617330f729Sjoerg     Out << "^" << Machine.getGUIDSlot(GUID)
29627330f729Sjoerg         << " = typeidCompatibleVTable: (name: \"" << TId.first << "\"";
29637330f729Sjoerg     printTypeIdCompatibleVtableSummary(TId.second);
29647330f729Sjoerg     Out << ") ; guid = " << GUID << "\n";
29657330f729Sjoerg   }
2966*82d56013Sjoerg 
2967*82d56013Sjoerg   // Don't emit flags when it's not really needed (value is zero by default).
2968*82d56013Sjoerg   if (TheIndex->getFlags()) {
2969*82d56013Sjoerg     Out << "^" << NumSlots << " = flags: " << TheIndex->getFlags() << "\n";
2970*82d56013Sjoerg     ++NumSlots;
2971*82d56013Sjoerg   }
2972*82d56013Sjoerg 
2973*82d56013Sjoerg   Out << "^" << NumSlots << " = blockcount: " << TheIndex->getBlockCount()
2974*82d56013Sjoerg       << "\n";
29757330f729Sjoerg }
29767330f729Sjoerg 
29777330f729Sjoerg static const char *
getWholeProgDevirtResKindName(WholeProgramDevirtResolution::Kind K)29787330f729Sjoerg getWholeProgDevirtResKindName(WholeProgramDevirtResolution::Kind K) {
29797330f729Sjoerg   switch (K) {
29807330f729Sjoerg   case WholeProgramDevirtResolution::Indir:
29817330f729Sjoerg     return "indir";
29827330f729Sjoerg   case WholeProgramDevirtResolution::SingleImpl:
29837330f729Sjoerg     return "singleImpl";
29847330f729Sjoerg   case WholeProgramDevirtResolution::BranchFunnel:
29857330f729Sjoerg     return "branchFunnel";
29867330f729Sjoerg   }
29877330f729Sjoerg   llvm_unreachable("invalid WholeProgramDevirtResolution kind");
29887330f729Sjoerg }
29897330f729Sjoerg 
getWholeProgDevirtResByArgKindName(WholeProgramDevirtResolution::ByArg::Kind K)29907330f729Sjoerg static const char *getWholeProgDevirtResByArgKindName(
29917330f729Sjoerg     WholeProgramDevirtResolution::ByArg::Kind K) {
29927330f729Sjoerg   switch (K) {
29937330f729Sjoerg   case WholeProgramDevirtResolution::ByArg::Indir:
29947330f729Sjoerg     return "indir";
29957330f729Sjoerg   case WholeProgramDevirtResolution::ByArg::UniformRetVal:
29967330f729Sjoerg     return "uniformRetVal";
29977330f729Sjoerg   case WholeProgramDevirtResolution::ByArg::UniqueRetVal:
29987330f729Sjoerg     return "uniqueRetVal";
29997330f729Sjoerg   case WholeProgramDevirtResolution::ByArg::VirtualConstProp:
30007330f729Sjoerg     return "virtualConstProp";
30017330f729Sjoerg   }
30027330f729Sjoerg   llvm_unreachable("invalid WholeProgramDevirtResolution::ByArg kind");
30037330f729Sjoerg }
30047330f729Sjoerg 
getTTResKindName(TypeTestResolution::Kind K)30057330f729Sjoerg static const char *getTTResKindName(TypeTestResolution::Kind K) {
30067330f729Sjoerg   switch (K) {
3007*82d56013Sjoerg   case TypeTestResolution::Unknown:
3008*82d56013Sjoerg     return "unknown";
30097330f729Sjoerg   case TypeTestResolution::Unsat:
30107330f729Sjoerg     return "unsat";
30117330f729Sjoerg   case TypeTestResolution::ByteArray:
30127330f729Sjoerg     return "byteArray";
30137330f729Sjoerg   case TypeTestResolution::Inline:
30147330f729Sjoerg     return "inline";
30157330f729Sjoerg   case TypeTestResolution::Single:
30167330f729Sjoerg     return "single";
30177330f729Sjoerg   case TypeTestResolution::AllOnes:
30187330f729Sjoerg     return "allOnes";
30197330f729Sjoerg   }
30207330f729Sjoerg   llvm_unreachable("invalid TypeTestResolution kind");
30217330f729Sjoerg }
30227330f729Sjoerg 
printTypeTestResolution(const TypeTestResolution & TTRes)30237330f729Sjoerg void AssemblyWriter::printTypeTestResolution(const TypeTestResolution &TTRes) {
30247330f729Sjoerg   Out << "typeTestRes: (kind: " << getTTResKindName(TTRes.TheKind)
30257330f729Sjoerg       << ", sizeM1BitWidth: " << TTRes.SizeM1BitWidth;
30267330f729Sjoerg 
30277330f729Sjoerg   // The following fields are only used if the target does not support the use
30287330f729Sjoerg   // of absolute symbols to store constants. Print only if non-zero.
30297330f729Sjoerg   if (TTRes.AlignLog2)
30307330f729Sjoerg     Out << ", alignLog2: " << TTRes.AlignLog2;
30317330f729Sjoerg   if (TTRes.SizeM1)
30327330f729Sjoerg     Out << ", sizeM1: " << TTRes.SizeM1;
30337330f729Sjoerg   if (TTRes.BitMask)
30347330f729Sjoerg     // BitMask is uint8_t which causes it to print the corresponding char.
30357330f729Sjoerg     Out << ", bitMask: " << (unsigned)TTRes.BitMask;
30367330f729Sjoerg   if (TTRes.InlineBits)
30377330f729Sjoerg     Out << ", inlineBits: " << TTRes.InlineBits;
30387330f729Sjoerg 
30397330f729Sjoerg   Out << ")";
30407330f729Sjoerg }
30417330f729Sjoerg 
printTypeIdSummary(const TypeIdSummary & TIS)30427330f729Sjoerg void AssemblyWriter::printTypeIdSummary(const TypeIdSummary &TIS) {
30437330f729Sjoerg   Out << ", summary: (";
30447330f729Sjoerg   printTypeTestResolution(TIS.TTRes);
30457330f729Sjoerg   if (!TIS.WPDRes.empty()) {
30467330f729Sjoerg     Out << ", wpdResolutions: (";
30477330f729Sjoerg     FieldSeparator FS;
30487330f729Sjoerg     for (auto &WPDRes : TIS.WPDRes) {
30497330f729Sjoerg       Out << FS;
30507330f729Sjoerg       Out << "(offset: " << WPDRes.first << ", ";
30517330f729Sjoerg       printWPDRes(WPDRes.second);
30527330f729Sjoerg       Out << ")";
30537330f729Sjoerg     }
30547330f729Sjoerg     Out << ")";
30557330f729Sjoerg   }
30567330f729Sjoerg   Out << ")";
30577330f729Sjoerg }
30587330f729Sjoerg 
printTypeIdCompatibleVtableSummary(const TypeIdCompatibleVtableInfo & TI)30597330f729Sjoerg void AssemblyWriter::printTypeIdCompatibleVtableSummary(
30607330f729Sjoerg     const TypeIdCompatibleVtableInfo &TI) {
30617330f729Sjoerg   Out << ", summary: (";
30627330f729Sjoerg   FieldSeparator FS;
30637330f729Sjoerg   for (auto &P : TI) {
30647330f729Sjoerg     Out << FS;
30657330f729Sjoerg     Out << "(offset: " << P.AddressPointOffset << ", ";
30667330f729Sjoerg     Out << "^" << Machine.getGUIDSlot(P.VTableVI.getGUID());
30677330f729Sjoerg     Out << ")";
30687330f729Sjoerg   }
30697330f729Sjoerg   Out << ")";
30707330f729Sjoerg }
30717330f729Sjoerg 
printArgs(const std::vector<uint64_t> & Args)30727330f729Sjoerg void AssemblyWriter::printArgs(const std::vector<uint64_t> &Args) {
30737330f729Sjoerg   Out << "args: (";
30747330f729Sjoerg   FieldSeparator FS;
30757330f729Sjoerg   for (auto arg : Args) {
30767330f729Sjoerg     Out << FS;
30777330f729Sjoerg     Out << arg;
30787330f729Sjoerg   }
30797330f729Sjoerg   Out << ")";
30807330f729Sjoerg }
30817330f729Sjoerg 
printWPDRes(const WholeProgramDevirtResolution & WPDRes)30827330f729Sjoerg void AssemblyWriter::printWPDRes(const WholeProgramDevirtResolution &WPDRes) {
30837330f729Sjoerg   Out << "wpdRes: (kind: ";
30847330f729Sjoerg   Out << getWholeProgDevirtResKindName(WPDRes.TheKind);
30857330f729Sjoerg 
30867330f729Sjoerg   if (WPDRes.TheKind == WholeProgramDevirtResolution::SingleImpl)
30877330f729Sjoerg     Out << ", singleImplName: \"" << WPDRes.SingleImplName << "\"";
30887330f729Sjoerg 
30897330f729Sjoerg   if (!WPDRes.ResByArg.empty()) {
30907330f729Sjoerg     Out << ", resByArg: (";
30917330f729Sjoerg     FieldSeparator FS;
30927330f729Sjoerg     for (auto &ResByArg : WPDRes.ResByArg) {
30937330f729Sjoerg       Out << FS;
30947330f729Sjoerg       printArgs(ResByArg.first);
30957330f729Sjoerg       Out << ", byArg: (kind: ";
30967330f729Sjoerg       Out << getWholeProgDevirtResByArgKindName(ResByArg.second.TheKind);
30977330f729Sjoerg       if (ResByArg.second.TheKind ==
30987330f729Sjoerg               WholeProgramDevirtResolution::ByArg::UniformRetVal ||
30997330f729Sjoerg           ResByArg.second.TheKind ==
31007330f729Sjoerg               WholeProgramDevirtResolution::ByArg::UniqueRetVal)
31017330f729Sjoerg         Out << ", info: " << ResByArg.second.Info;
31027330f729Sjoerg 
31037330f729Sjoerg       // The following fields are only used if the target does not support the
31047330f729Sjoerg       // use of absolute symbols to store constants. Print only if non-zero.
31057330f729Sjoerg       if (ResByArg.second.Byte || ResByArg.second.Bit)
31067330f729Sjoerg         Out << ", byte: " << ResByArg.second.Byte
31077330f729Sjoerg             << ", bit: " << ResByArg.second.Bit;
31087330f729Sjoerg 
31097330f729Sjoerg       Out << ")";
31107330f729Sjoerg     }
31117330f729Sjoerg     Out << ")";
31127330f729Sjoerg   }
31137330f729Sjoerg   Out << ")";
31147330f729Sjoerg }
31157330f729Sjoerg 
getSummaryKindName(GlobalValueSummary::SummaryKind SK)31167330f729Sjoerg static const char *getSummaryKindName(GlobalValueSummary::SummaryKind SK) {
31177330f729Sjoerg   switch (SK) {
31187330f729Sjoerg   case GlobalValueSummary::AliasKind:
31197330f729Sjoerg     return "alias";
31207330f729Sjoerg   case GlobalValueSummary::FunctionKind:
31217330f729Sjoerg     return "function";
31227330f729Sjoerg   case GlobalValueSummary::GlobalVarKind:
31237330f729Sjoerg     return "variable";
31247330f729Sjoerg   }
31257330f729Sjoerg   llvm_unreachable("invalid summary kind");
31267330f729Sjoerg }
31277330f729Sjoerg 
printAliasSummary(const AliasSummary * AS)31287330f729Sjoerg void AssemblyWriter::printAliasSummary(const AliasSummary *AS) {
31297330f729Sjoerg   Out << ", aliasee: ";
31307330f729Sjoerg   // The indexes emitted for distributed backends may not include the
31317330f729Sjoerg   // aliasee summary (only if it is being imported directly). Handle
31327330f729Sjoerg   // that case by just emitting "null" as the aliasee.
31337330f729Sjoerg   if (AS->hasAliasee())
31347330f729Sjoerg     Out << "^" << Machine.getGUIDSlot(SummaryToGUIDMap[&AS->getAliasee()]);
31357330f729Sjoerg   else
31367330f729Sjoerg     Out << "null";
31377330f729Sjoerg }
31387330f729Sjoerg 
printGlobalVarSummary(const GlobalVarSummary * GS)31397330f729Sjoerg void AssemblyWriter::printGlobalVarSummary(const GlobalVarSummary *GS) {
31407330f729Sjoerg   auto VTableFuncs = GS->vTableFuncs();
3141*82d56013Sjoerg   Out << ", varFlags: (readonly: " << GS->VarFlags.MaybeReadOnly << ", "
3142*82d56013Sjoerg       << "writeonly: " << GS->VarFlags.MaybeWriteOnly << ", "
3143*82d56013Sjoerg       << "constant: " << GS->VarFlags.Constant;
3144*82d56013Sjoerg   if (!VTableFuncs.empty())
3145*82d56013Sjoerg     Out << ", "
3146*82d56013Sjoerg         << "vcall_visibility: " << GS->VarFlags.VCallVisibility;
3147*82d56013Sjoerg   Out << ")";
3148*82d56013Sjoerg 
31497330f729Sjoerg   if (!VTableFuncs.empty()) {
31507330f729Sjoerg     Out << ", vTableFuncs: (";
31517330f729Sjoerg     FieldSeparator FS;
31527330f729Sjoerg     for (auto &P : VTableFuncs) {
31537330f729Sjoerg       Out << FS;
31547330f729Sjoerg       Out << "(virtFunc: ^" << Machine.getGUIDSlot(P.FuncVI.getGUID())
31557330f729Sjoerg           << ", offset: " << P.VTableOffset;
31567330f729Sjoerg       Out << ")";
31577330f729Sjoerg     }
31587330f729Sjoerg     Out << ")";
31597330f729Sjoerg   }
31607330f729Sjoerg }
31617330f729Sjoerg 
getLinkageName(GlobalValue::LinkageTypes LT)31627330f729Sjoerg static std::string getLinkageName(GlobalValue::LinkageTypes LT) {
31637330f729Sjoerg   switch (LT) {
31647330f729Sjoerg   case GlobalValue::ExternalLinkage:
31657330f729Sjoerg     return "external";
31667330f729Sjoerg   case GlobalValue::PrivateLinkage:
31677330f729Sjoerg     return "private";
31687330f729Sjoerg   case GlobalValue::InternalLinkage:
31697330f729Sjoerg     return "internal";
31707330f729Sjoerg   case GlobalValue::LinkOnceAnyLinkage:
31717330f729Sjoerg     return "linkonce";
31727330f729Sjoerg   case GlobalValue::LinkOnceODRLinkage:
31737330f729Sjoerg     return "linkonce_odr";
31747330f729Sjoerg   case GlobalValue::WeakAnyLinkage:
31757330f729Sjoerg     return "weak";
31767330f729Sjoerg   case GlobalValue::WeakODRLinkage:
31777330f729Sjoerg     return "weak_odr";
31787330f729Sjoerg   case GlobalValue::CommonLinkage:
31797330f729Sjoerg     return "common";
31807330f729Sjoerg   case GlobalValue::AppendingLinkage:
31817330f729Sjoerg     return "appending";
31827330f729Sjoerg   case GlobalValue::ExternalWeakLinkage:
31837330f729Sjoerg     return "extern_weak";
31847330f729Sjoerg   case GlobalValue::AvailableExternallyLinkage:
31857330f729Sjoerg     return "available_externally";
31867330f729Sjoerg   }
31877330f729Sjoerg   llvm_unreachable("invalid linkage");
31887330f729Sjoerg }
31897330f729Sjoerg 
31907330f729Sjoerg // When printing the linkage types in IR where the ExternalLinkage is
31917330f729Sjoerg // not printed, and other linkage types are expected to be printed with
31927330f729Sjoerg // a space after the name.
getLinkageNameWithSpace(GlobalValue::LinkageTypes LT)31937330f729Sjoerg static std::string getLinkageNameWithSpace(GlobalValue::LinkageTypes LT) {
31947330f729Sjoerg   if (LT == GlobalValue::ExternalLinkage)
31957330f729Sjoerg     return "";
31967330f729Sjoerg   return getLinkageName(LT) + " ";
31977330f729Sjoerg }
31987330f729Sjoerg 
getVisibilityName(GlobalValue::VisibilityTypes Vis)3199*82d56013Sjoerg static const char *getVisibilityName(GlobalValue::VisibilityTypes Vis) {
3200*82d56013Sjoerg   switch (Vis) {
3201*82d56013Sjoerg   case GlobalValue::DefaultVisibility:
3202*82d56013Sjoerg     return "default";
3203*82d56013Sjoerg   case GlobalValue::HiddenVisibility:
3204*82d56013Sjoerg     return "hidden";
3205*82d56013Sjoerg   case GlobalValue::ProtectedVisibility:
3206*82d56013Sjoerg     return "protected";
3207*82d56013Sjoerg   }
3208*82d56013Sjoerg   llvm_unreachable("invalid visibility");
3209*82d56013Sjoerg }
3210*82d56013Sjoerg 
printFunctionSummary(const FunctionSummary * FS)32117330f729Sjoerg void AssemblyWriter::printFunctionSummary(const FunctionSummary *FS) {
32127330f729Sjoerg   Out << ", insts: " << FS->instCount();
32137330f729Sjoerg 
32147330f729Sjoerg   FunctionSummary::FFlags FFlags = FS->fflags();
32157330f729Sjoerg   if (FFlags.ReadNone | FFlags.ReadOnly | FFlags.NoRecurse |
3216*82d56013Sjoerg       FFlags.ReturnDoesNotAlias | FFlags.NoInline | FFlags.AlwaysInline) {
32177330f729Sjoerg     Out << ", funcFlags: (";
32187330f729Sjoerg     Out << "readNone: " << FFlags.ReadNone;
32197330f729Sjoerg     Out << ", readOnly: " << FFlags.ReadOnly;
32207330f729Sjoerg     Out << ", noRecurse: " << FFlags.NoRecurse;
32217330f729Sjoerg     Out << ", returnDoesNotAlias: " << FFlags.ReturnDoesNotAlias;
32227330f729Sjoerg     Out << ", noInline: " << FFlags.NoInline;
3223*82d56013Sjoerg     Out << ", alwaysInline: " << FFlags.AlwaysInline;
32247330f729Sjoerg     Out << ")";
32257330f729Sjoerg   }
32267330f729Sjoerg   if (!FS->calls().empty()) {
32277330f729Sjoerg     Out << ", calls: (";
32287330f729Sjoerg     FieldSeparator IFS;
32297330f729Sjoerg     for (auto &Call : FS->calls()) {
32307330f729Sjoerg       Out << IFS;
32317330f729Sjoerg       Out << "(callee: ^" << Machine.getGUIDSlot(Call.first.getGUID());
32327330f729Sjoerg       if (Call.second.getHotness() != CalleeInfo::HotnessType::Unknown)
32337330f729Sjoerg         Out << ", hotness: " << getHotnessName(Call.second.getHotness());
32347330f729Sjoerg       else if (Call.second.RelBlockFreq)
32357330f729Sjoerg         Out << ", relbf: " << Call.second.RelBlockFreq;
32367330f729Sjoerg       Out << ")";
32377330f729Sjoerg     }
32387330f729Sjoerg     Out << ")";
32397330f729Sjoerg   }
32407330f729Sjoerg 
32417330f729Sjoerg   if (const auto *TIdInfo = FS->getTypeIdInfo())
32427330f729Sjoerg     printTypeIdInfo(*TIdInfo);
3243*82d56013Sjoerg 
3244*82d56013Sjoerg   auto PrintRange = [&](const ConstantRange &Range) {
3245*82d56013Sjoerg     Out << "[" << Range.getSignedMin() << ", " << Range.getSignedMax() << "]";
3246*82d56013Sjoerg   };
3247*82d56013Sjoerg 
3248*82d56013Sjoerg   if (!FS->paramAccesses().empty()) {
3249*82d56013Sjoerg     Out << ", params: (";
3250*82d56013Sjoerg     FieldSeparator IFS;
3251*82d56013Sjoerg     for (auto &PS : FS->paramAccesses()) {
3252*82d56013Sjoerg       Out << IFS;
3253*82d56013Sjoerg       Out << "(param: " << PS.ParamNo;
3254*82d56013Sjoerg       Out << ", offset: ";
3255*82d56013Sjoerg       PrintRange(PS.Use);
3256*82d56013Sjoerg       if (!PS.Calls.empty()) {
3257*82d56013Sjoerg         Out << ", calls: (";
3258*82d56013Sjoerg         FieldSeparator IFS;
3259*82d56013Sjoerg         for (auto &Call : PS.Calls) {
3260*82d56013Sjoerg           Out << IFS;
3261*82d56013Sjoerg           Out << "(callee: ^" << Machine.getGUIDSlot(Call.Callee.getGUID());
3262*82d56013Sjoerg           Out << ", param: " << Call.ParamNo;
3263*82d56013Sjoerg           Out << ", offset: ";
3264*82d56013Sjoerg           PrintRange(Call.Offsets);
3265*82d56013Sjoerg           Out << ")";
3266*82d56013Sjoerg         }
3267*82d56013Sjoerg         Out << ")";
3268*82d56013Sjoerg       }
3269*82d56013Sjoerg       Out << ")";
3270*82d56013Sjoerg     }
3271*82d56013Sjoerg     Out << ")";
3272*82d56013Sjoerg   }
32737330f729Sjoerg }
32747330f729Sjoerg 
printTypeIdInfo(const FunctionSummary::TypeIdInfo & TIDInfo)32757330f729Sjoerg void AssemblyWriter::printTypeIdInfo(
32767330f729Sjoerg     const FunctionSummary::TypeIdInfo &TIDInfo) {
32777330f729Sjoerg   Out << ", typeIdInfo: (";
32787330f729Sjoerg   FieldSeparator TIDFS;
32797330f729Sjoerg   if (!TIDInfo.TypeTests.empty()) {
32807330f729Sjoerg     Out << TIDFS;
32817330f729Sjoerg     Out << "typeTests: (";
32827330f729Sjoerg     FieldSeparator FS;
32837330f729Sjoerg     for (auto &GUID : TIDInfo.TypeTests) {
32847330f729Sjoerg       auto TidIter = TheIndex->typeIds().equal_range(GUID);
32857330f729Sjoerg       if (TidIter.first == TidIter.second) {
32867330f729Sjoerg         Out << FS;
32877330f729Sjoerg         Out << GUID;
32887330f729Sjoerg         continue;
32897330f729Sjoerg       }
32907330f729Sjoerg       // Print all type id that correspond to this GUID.
32917330f729Sjoerg       for (auto It = TidIter.first; It != TidIter.second; ++It) {
32927330f729Sjoerg         Out << FS;
32937330f729Sjoerg         auto Slot = Machine.getTypeIdSlot(It->second.first);
32947330f729Sjoerg         assert(Slot != -1);
32957330f729Sjoerg         Out << "^" << Slot;
32967330f729Sjoerg       }
32977330f729Sjoerg     }
32987330f729Sjoerg     Out << ")";
32997330f729Sjoerg   }
33007330f729Sjoerg   if (!TIDInfo.TypeTestAssumeVCalls.empty()) {
33017330f729Sjoerg     Out << TIDFS;
33027330f729Sjoerg     printNonConstVCalls(TIDInfo.TypeTestAssumeVCalls, "typeTestAssumeVCalls");
33037330f729Sjoerg   }
33047330f729Sjoerg   if (!TIDInfo.TypeCheckedLoadVCalls.empty()) {
33057330f729Sjoerg     Out << TIDFS;
33067330f729Sjoerg     printNonConstVCalls(TIDInfo.TypeCheckedLoadVCalls, "typeCheckedLoadVCalls");
33077330f729Sjoerg   }
33087330f729Sjoerg   if (!TIDInfo.TypeTestAssumeConstVCalls.empty()) {
33097330f729Sjoerg     Out << TIDFS;
33107330f729Sjoerg     printConstVCalls(TIDInfo.TypeTestAssumeConstVCalls,
33117330f729Sjoerg                      "typeTestAssumeConstVCalls");
33127330f729Sjoerg   }
33137330f729Sjoerg   if (!TIDInfo.TypeCheckedLoadConstVCalls.empty()) {
33147330f729Sjoerg     Out << TIDFS;
33157330f729Sjoerg     printConstVCalls(TIDInfo.TypeCheckedLoadConstVCalls,
33167330f729Sjoerg                      "typeCheckedLoadConstVCalls");
33177330f729Sjoerg   }
33187330f729Sjoerg   Out << ")";
33197330f729Sjoerg }
33207330f729Sjoerg 
printVFuncId(const FunctionSummary::VFuncId VFId)33217330f729Sjoerg void AssemblyWriter::printVFuncId(const FunctionSummary::VFuncId VFId) {
33227330f729Sjoerg   auto TidIter = TheIndex->typeIds().equal_range(VFId.GUID);
33237330f729Sjoerg   if (TidIter.first == TidIter.second) {
33247330f729Sjoerg     Out << "vFuncId: (";
33257330f729Sjoerg     Out << "guid: " << VFId.GUID;
33267330f729Sjoerg     Out << ", offset: " << VFId.Offset;
33277330f729Sjoerg     Out << ")";
33287330f729Sjoerg     return;
33297330f729Sjoerg   }
33307330f729Sjoerg   // Print all type id that correspond to this GUID.
33317330f729Sjoerg   FieldSeparator FS;
33327330f729Sjoerg   for (auto It = TidIter.first; It != TidIter.second; ++It) {
33337330f729Sjoerg     Out << FS;
33347330f729Sjoerg     Out << "vFuncId: (";
33357330f729Sjoerg     auto Slot = Machine.getTypeIdSlot(It->second.first);
33367330f729Sjoerg     assert(Slot != -1);
33377330f729Sjoerg     Out << "^" << Slot;
33387330f729Sjoerg     Out << ", offset: " << VFId.Offset;
33397330f729Sjoerg     Out << ")";
33407330f729Sjoerg   }
33417330f729Sjoerg }
33427330f729Sjoerg 
printNonConstVCalls(const std::vector<FunctionSummary::VFuncId> & VCallList,const char * Tag)33437330f729Sjoerg void AssemblyWriter::printNonConstVCalls(
3344*82d56013Sjoerg     const std::vector<FunctionSummary::VFuncId> &VCallList, const char *Tag) {
33457330f729Sjoerg   Out << Tag << ": (";
33467330f729Sjoerg   FieldSeparator FS;
33477330f729Sjoerg   for (auto &VFuncId : VCallList) {
33487330f729Sjoerg     Out << FS;
33497330f729Sjoerg     printVFuncId(VFuncId);
33507330f729Sjoerg   }
33517330f729Sjoerg   Out << ")";
33527330f729Sjoerg }
33537330f729Sjoerg 
printConstVCalls(const std::vector<FunctionSummary::ConstVCall> & VCallList,const char * Tag)33547330f729Sjoerg void AssemblyWriter::printConstVCalls(
3355*82d56013Sjoerg     const std::vector<FunctionSummary::ConstVCall> &VCallList,
3356*82d56013Sjoerg     const char *Tag) {
33577330f729Sjoerg   Out << Tag << ": (";
33587330f729Sjoerg   FieldSeparator FS;
33597330f729Sjoerg   for (auto &ConstVCall : VCallList) {
33607330f729Sjoerg     Out << FS;
33617330f729Sjoerg     Out << "(";
33627330f729Sjoerg     printVFuncId(ConstVCall.VFunc);
33637330f729Sjoerg     if (!ConstVCall.Args.empty()) {
33647330f729Sjoerg       Out << ", ";
33657330f729Sjoerg       printArgs(ConstVCall.Args);
33667330f729Sjoerg     }
33677330f729Sjoerg     Out << ")";
33687330f729Sjoerg   }
33697330f729Sjoerg   Out << ")";
33707330f729Sjoerg }
33717330f729Sjoerg 
printSummary(const GlobalValueSummary & Summary)33727330f729Sjoerg void AssemblyWriter::printSummary(const GlobalValueSummary &Summary) {
33737330f729Sjoerg   GlobalValueSummary::GVFlags GVFlags = Summary.flags();
33747330f729Sjoerg   GlobalValue::LinkageTypes LT = (GlobalValue::LinkageTypes)GVFlags.Linkage;
33757330f729Sjoerg   Out << getSummaryKindName(Summary.getSummaryKind()) << ": ";
33767330f729Sjoerg   Out << "(module: ^" << Machine.getModulePathSlot(Summary.modulePath())
33777330f729Sjoerg       << ", flags: (";
33787330f729Sjoerg   Out << "linkage: " << getLinkageName(LT);
3379*82d56013Sjoerg   Out << ", visibility: "
3380*82d56013Sjoerg       << getVisibilityName((GlobalValue::VisibilityTypes)GVFlags.Visibility);
33817330f729Sjoerg   Out << ", notEligibleToImport: " << GVFlags.NotEligibleToImport;
33827330f729Sjoerg   Out << ", live: " << GVFlags.Live;
33837330f729Sjoerg   Out << ", dsoLocal: " << GVFlags.DSOLocal;
33847330f729Sjoerg   Out << ", canAutoHide: " << GVFlags.CanAutoHide;
33857330f729Sjoerg   Out << ")";
33867330f729Sjoerg 
33877330f729Sjoerg   if (Summary.getSummaryKind() == GlobalValueSummary::AliasKind)
33887330f729Sjoerg     printAliasSummary(cast<AliasSummary>(&Summary));
33897330f729Sjoerg   else if (Summary.getSummaryKind() == GlobalValueSummary::FunctionKind)
33907330f729Sjoerg     printFunctionSummary(cast<FunctionSummary>(&Summary));
33917330f729Sjoerg   else
33927330f729Sjoerg     printGlobalVarSummary(cast<GlobalVarSummary>(&Summary));
33937330f729Sjoerg 
33947330f729Sjoerg   auto RefList = Summary.refs();
33957330f729Sjoerg   if (!RefList.empty()) {
33967330f729Sjoerg     Out << ", refs: (";
33977330f729Sjoerg     FieldSeparator FS;
33987330f729Sjoerg     for (auto &Ref : RefList) {
33997330f729Sjoerg       Out << FS;
34007330f729Sjoerg       if (Ref.isReadOnly())
34017330f729Sjoerg         Out << "readonly ";
34027330f729Sjoerg       else if (Ref.isWriteOnly())
34037330f729Sjoerg         Out << "writeonly ";
34047330f729Sjoerg       Out << "^" << Machine.getGUIDSlot(Ref.getGUID());
34057330f729Sjoerg     }
34067330f729Sjoerg     Out << ")";
34077330f729Sjoerg   }
34087330f729Sjoerg 
34097330f729Sjoerg   Out << ")";
34107330f729Sjoerg }
34117330f729Sjoerg 
printSummaryInfo(unsigned Slot,const ValueInfo & VI)34127330f729Sjoerg void AssemblyWriter::printSummaryInfo(unsigned Slot, const ValueInfo &VI) {
34137330f729Sjoerg   Out << "^" << Slot << " = gv: (";
34147330f729Sjoerg   if (!VI.name().empty())
34157330f729Sjoerg     Out << "name: \"" << VI.name() << "\"";
34167330f729Sjoerg   else
34177330f729Sjoerg     Out << "guid: " << VI.getGUID();
34187330f729Sjoerg   if (!VI.getSummaryList().empty()) {
34197330f729Sjoerg     Out << ", summaries: (";
34207330f729Sjoerg     FieldSeparator FS;
34217330f729Sjoerg     for (auto &Summary : VI.getSummaryList()) {
34227330f729Sjoerg       Out << FS;
34237330f729Sjoerg       printSummary(*Summary);
34247330f729Sjoerg     }
34257330f729Sjoerg     Out << ")";
34267330f729Sjoerg   }
34277330f729Sjoerg   Out << ")";
34287330f729Sjoerg   if (!VI.name().empty())
34297330f729Sjoerg     Out << " ; guid = " << VI.getGUID();
34307330f729Sjoerg   Out << "\n";
34317330f729Sjoerg }
34327330f729Sjoerg 
printMetadataIdentifier(StringRef Name,formatted_raw_ostream & Out)34337330f729Sjoerg static void printMetadataIdentifier(StringRef Name,
34347330f729Sjoerg                                     formatted_raw_ostream &Out) {
34357330f729Sjoerg   if (Name.empty()) {
34367330f729Sjoerg     Out << "<empty name> ";
34377330f729Sjoerg   } else {
34387330f729Sjoerg     if (isalpha(static_cast<unsigned char>(Name[0])) || Name[0] == '-' ||
34397330f729Sjoerg         Name[0] == '$' || Name[0] == '.' || Name[0] == '_')
34407330f729Sjoerg       Out << Name[0];
34417330f729Sjoerg     else
34427330f729Sjoerg       Out << '\\' << hexdigit(Name[0] >> 4) << hexdigit(Name[0] & 0x0F);
34437330f729Sjoerg     for (unsigned i = 1, e = Name.size(); i != e; ++i) {
34447330f729Sjoerg       unsigned char C = Name[i];
34457330f729Sjoerg       if (isalnum(static_cast<unsigned char>(C)) || C == '-' || C == '$' ||
34467330f729Sjoerg           C == '.' || C == '_')
34477330f729Sjoerg         Out << C;
34487330f729Sjoerg       else
34497330f729Sjoerg         Out << '\\' << hexdigit(C >> 4) << hexdigit(C & 0x0F);
34507330f729Sjoerg     }
34517330f729Sjoerg   }
34527330f729Sjoerg }
34537330f729Sjoerg 
printNamedMDNode(const NamedMDNode * NMD)34547330f729Sjoerg void AssemblyWriter::printNamedMDNode(const NamedMDNode *NMD) {
34557330f729Sjoerg   Out << '!';
34567330f729Sjoerg   printMetadataIdentifier(NMD->getName(), Out);
34577330f729Sjoerg   Out << " = !{";
34587330f729Sjoerg   for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
34597330f729Sjoerg     if (i)
34607330f729Sjoerg       Out << ", ";
34617330f729Sjoerg 
34627330f729Sjoerg     // Write DIExpressions inline.
34637330f729Sjoerg     // FIXME: Ban DIExpressions in NamedMDNodes, they will serve no purpose.
34647330f729Sjoerg     MDNode *Op = NMD->getOperand(i);
3465*82d56013Sjoerg     assert(!isa<DIArgList>(Op) &&
3466*82d56013Sjoerg            "DIArgLists should not appear in NamedMDNodes");
34677330f729Sjoerg     if (auto *Expr = dyn_cast<DIExpression>(Op)) {
34687330f729Sjoerg       writeDIExpression(Out, Expr, nullptr, nullptr, nullptr);
34697330f729Sjoerg       continue;
34707330f729Sjoerg     }
34717330f729Sjoerg 
34727330f729Sjoerg     int Slot = Machine.getMetadataSlot(Op);
34737330f729Sjoerg     if (Slot == -1)
34747330f729Sjoerg       Out << "<badref>";
34757330f729Sjoerg     else
34767330f729Sjoerg       Out << '!' << Slot;
34777330f729Sjoerg   }
34787330f729Sjoerg   Out << "}\n";
34797330f729Sjoerg }
34807330f729Sjoerg 
PrintVisibility(GlobalValue::VisibilityTypes Vis,formatted_raw_ostream & Out)34817330f729Sjoerg static void PrintVisibility(GlobalValue::VisibilityTypes Vis,
34827330f729Sjoerg                             formatted_raw_ostream &Out) {
34837330f729Sjoerg   switch (Vis) {
34847330f729Sjoerg   case GlobalValue::DefaultVisibility: break;
34857330f729Sjoerg   case GlobalValue::HiddenVisibility:    Out << "hidden "; break;
34867330f729Sjoerg   case GlobalValue::ProtectedVisibility: Out << "protected "; break;
34877330f729Sjoerg   }
34887330f729Sjoerg }
34897330f729Sjoerg 
PrintDSOLocation(const GlobalValue & GV,formatted_raw_ostream & Out)34907330f729Sjoerg static void PrintDSOLocation(const GlobalValue &GV,
34917330f729Sjoerg                              formatted_raw_ostream &Out) {
3492*82d56013Sjoerg   if (GV.isDSOLocal() && !GV.isImplicitDSOLocal())
34937330f729Sjoerg     Out << "dso_local ";
34947330f729Sjoerg }
34957330f729Sjoerg 
PrintDLLStorageClass(GlobalValue::DLLStorageClassTypes SCT,formatted_raw_ostream & Out)34967330f729Sjoerg static void PrintDLLStorageClass(GlobalValue::DLLStorageClassTypes SCT,
34977330f729Sjoerg                                  formatted_raw_ostream &Out) {
34987330f729Sjoerg   switch (SCT) {
34997330f729Sjoerg   case GlobalValue::DefaultStorageClass: break;
35007330f729Sjoerg   case GlobalValue::DLLImportStorageClass: Out << "dllimport "; break;
35017330f729Sjoerg   case GlobalValue::DLLExportStorageClass: Out << "dllexport "; break;
35027330f729Sjoerg   }
35037330f729Sjoerg }
35047330f729Sjoerg 
PrintThreadLocalModel(GlobalVariable::ThreadLocalMode TLM,formatted_raw_ostream & Out)35057330f729Sjoerg static void PrintThreadLocalModel(GlobalVariable::ThreadLocalMode TLM,
35067330f729Sjoerg                                   formatted_raw_ostream &Out) {
35077330f729Sjoerg   switch (TLM) {
35087330f729Sjoerg     case GlobalVariable::NotThreadLocal:
35097330f729Sjoerg       break;
35107330f729Sjoerg     case GlobalVariable::GeneralDynamicTLSModel:
35117330f729Sjoerg       Out << "thread_local ";
35127330f729Sjoerg       break;
35137330f729Sjoerg     case GlobalVariable::LocalDynamicTLSModel:
35147330f729Sjoerg       Out << "thread_local(localdynamic) ";
35157330f729Sjoerg       break;
35167330f729Sjoerg     case GlobalVariable::InitialExecTLSModel:
35177330f729Sjoerg       Out << "thread_local(initialexec) ";
35187330f729Sjoerg       break;
35197330f729Sjoerg     case GlobalVariable::LocalExecTLSModel:
35207330f729Sjoerg       Out << "thread_local(localexec) ";
35217330f729Sjoerg       break;
35227330f729Sjoerg   }
35237330f729Sjoerg }
35247330f729Sjoerg 
getUnnamedAddrEncoding(GlobalVariable::UnnamedAddr UA)35257330f729Sjoerg static StringRef getUnnamedAddrEncoding(GlobalVariable::UnnamedAddr UA) {
35267330f729Sjoerg   switch (UA) {
35277330f729Sjoerg   case GlobalVariable::UnnamedAddr::None:
35287330f729Sjoerg     return "";
35297330f729Sjoerg   case GlobalVariable::UnnamedAddr::Local:
35307330f729Sjoerg     return "local_unnamed_addr";
35317330f729Sjoerg   case GlobalVariable::UnnamedAddr::Global:
35327330f729Sjoerg     return "unnamed_addr";
35337330f729Sjoerg   }
35347330f729Sjoerg   llvm_unreachable("Unknown UnnamedAddr");
35357330f729Sjoerg }
35367330f729Sjoerg 
maybePrintComdat(formatted_raw_ostream & Out,const GlobalObject & GO)35377330f729Sjoerg static void maybePrintComdat(formatted_raw_ostream &Out,
35387330f729Sjoerg                              const GlobalObject &GO) {
35397330f729Sjoerg   const Comdat *C = GO.getComdat();
35407330f729Sjoerg   if (!C)
35417330f729Sjoerg     return;
35427330f729Sjoerg 
35437330f729Sjoerg   if (isa<GlobalVariable>(GO))
35447330f729Sjoerg     Out << ',';
35457330f729Sjoerg   Out << " comdat";
35467330f729Sjoerg 
35477330f729Sjoerg   if (GO.getName() == C->getName())
35487330f729Sjoerg     return;
35497330f729Sjoerg 
35507330f729Sjoerg   Out << '(';
35517330f729Sjoerg   PrintLLVMName(Out, C->getName(), ComdatPrefix);
35527330f729Sjoerg   Out << ')';
35537330f729Sjoerg }
35547330f729Sjoerg 
printGlobal(const GlobalVariable * GV)35557330f729Sjoerg void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
35567330f729Sjoerg   if (GV->isMaterializable())
35577330f729Sjoerg     Out << "; Materializable\n";
35587330f729Sjoerg 
35597330f729Sjoerg   WriteAsOperandInternal(Out, GV, &TypePrinter, &Machine, GV->getParent());
35607330f729Sjoerg   Out << " = ";
35617330f729Sjoerg 
35627330f729Sjoerg   if (!GV->hasInitializer() && GV->hasExternalLinkage())
35637330f729Sjoerg     Out << "external ";
35647330f729Sjoerg 
35657330f729Sjoerg   Out << getLinkageNameWithSpace(GV->getLinkage());
35667330f729Sjoerg   PrintDSOLocation(*GV, Out);
35677330f729Sjoerg   PrintVisibility(GV->getVisibility(), Out);
35687330f729Sjoerg   PrintDLLStorageClass(GV->getDLLStorageClass(), Out);
35697330f729Sjoerg   PrintThreadLocalModel(GV->getThreadLocalMode(), Out);
35707330f729Sjoerg   StringRef UA = getUnnamedAddrEncoding(GV->getUnnamedAddr());
35717330f729Sjoerg   if (!UA.empty())
35727330f729Sjoerg       Out << UA << ' ';
35737330f729Sjoerg 
35747330f729Sjoerg   if (unsigned AddressSpace = GV->getType()->getAddressSpace())
35757330f729Sjoerg     Out << "addrspace(" << AddressSpace << ") ";
35767330f729Sjoerg   if (GV->isExternallyInitialized()) Out << "externally_initialized ";
35777330f729Sjoerg   Out << (GV->isConstant() ? "constant " : "global ");
35787330f729Sjoerg   TypePrinter.print(GV->getValueType(), Out);
35797330f729Sjoerg 
35807330f729Sjoerg   if (GV->hasInitializer()) {
35817330f729Sjoerg     Out << ' ';
35827330f729Sjoerg     writeOperand(GV->getInitializer(), false);
35837330f729Sjoerg   }
35847330f729Sjoerg 
35857330f729Sjoerg   if (GV->hasSection()) {
35867330f729Sjoerg     Out << ", section \"";
35877330f729Sjoerg     printEscapedString(GV->getSection(), Out);
35887330f729Sjoerg     Out << '"';
35897330f729Sjoerg   }
35907330f729Sjoerg   if (GV->hasPartition()) {
35917330f729Sjoerg     Out << ", partition \"";
35927330f729Sjoerg     printEscapedString(GV->getPartition(), Out);
35937330f729Sjoerg     Out << '"';
35947330f729Sjoerg   }
35957330f729Sjoerg 
35967330f729Sjoerg   maybePrintComdat(Out, *GV);
35977330f729Sjoerg   if (GV->getAlignment())
35987330f729Sjoerg     Out << ", align " << GV->getAlignment();
35997330f729Sjoerg 
36007330f729Sjoerg   SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
36017330f729Sjoerg   GV->getAllMetadata(MDs);
36027330f729Sjoerg   printMetadataAttachments(MDs, ", ");
36037330f729Sjoerg 
36047330f729Sjoerg   auto Attrs = GV->getAttributes();
36057330f729Sjoerg   if (Attrs.hasAttributes())
36067330f729Sjoerg     Out << " #" << Machine.getAttributeGroupSlot(Attrs);
36077330f729Sjoerg 
36087330f729Sjoerg   printInfoComment(*GV);
36097330f729Sjoerg }
36107330f729Sjoerg 
printIndirectSymbol(const GlobalIndirectSymbol * GIS)36117330f729Sjoerg void AssemblyWriter::printIndirectSymbol(const GlobalIndirectSymbol *GIS) {
36127330f729Sjoerg   if (GIS->isMaterializable())
36137330f729Sjoerg     Out << "; Materializable\n";
36147330f729Sjoerg 
36157330f729Sjoerg   WriteAsOperandInternal(Out, GIS, &TypePrinter, &Machine, GIS->getParent());
36167330f729Sjoerg   Out << " = ";
36177330f729Sjoerg 
36187330f729Sjoerg   Out << getLinkageNameWithSpace(GIS->getLinkage());
36197330f729Sjoerg   PrintDSOLocation(*GIS, Out);
36207330f729Sjoerg   PrintVisibility(GIS->getVisibility(), Out);
36217330f729Sjoerg   PrintDLLStorageClass(GIS->getDLLStorageClass(), Out);
36227330f729Sjoerg   PrintThreadLocalModel(GIS->getThreadLocalMode(), Out);
36237330f729Sjoerg   StringRef UA = getUnnamedAddrEncoding(GIS->getUnnamedAddr());
36247330f729Sjoerg   if (!UA.empty())
36257330f729Sjoerg       Out << UA << ' ';
36267330f729Sjoerg 
36277330f729Sjoerg   if (isa<GlobalAlias>(GIS))
36287330f729Sjoerg     Out << "alias ";
36297330f729Sjoerg   else if (isa<GlobalIFunc>(GIS))
36307330f729Sjoerg     Out << "ifunc ";
36317330f729Sjoerg   else
36327330f729Sjoerg     llvm_unreachable("Not an alias or ifunc!");
36337330f729Sjoerg 
36347330f729Sjoerg   TypePrinter.print(GIS->getValueType(), Out);
36357330f729Sjoerg 
36367330f729Sjoerg   Out << ", ";
36377330f729Sjoerg 
36387330f729Sjoerg   const Constant *IS = GIS->getIndirectSymbol();
36397330f729Sjoerg 
36407330f729Sjoerg   if (!IS) {
36417330f729Sjoerg     TypePrinter.print(GIS->getType(), Out);
36427330f729Sjoerg     Out << " <<NULL ALIASEE>>";
36437330f729Sjoerg   } else {
36447330f729Sjoerg     writeOperand(IS, !isa<ConstantExpr>(IS));
36457330f729Sjoerg   }
36467330f729Sjoerg 
36477330f729Sjoerg   if (GIS->hasPartition()) {
36487330f729Sjoerg     Out << ", partition \"";
36497330f729Sjoerg     printEscapedString(GIS->getPartition(), Out);
36507330f729Sjoerg     Out << '"';
36517330f729Sjoerg   }
36527330f729Sjoerg 
36537330f729Sjoerg   printInfoComment(*GIS);
36547330f729Sjoerg   Out << '\n';
36557330f729Sjoerg }
36567330f729Sjoerg 
printComdat(const Comdat * C)36577330f729Sjoerg void AssemblyWriter::printComdat(const Comdat *C) {
36587330f729Sjoerg   C->print(Out);
36597330f729Sjoerg }
36607330f729Sjoerg 
printTypeIdentities()36617330f729Sjoerg void AssemblyWriter::printTypeIdentities() {
36627330f729Sjoerg   if (TypePrinter.empty())
36637330f729Sjoerg     return;
36647330f729Sjoerg 
36657330f729Sjoerg   Out << '\n';
36667330f729Sjoerg 
36677330f729Sjoerg   // Emit all numbered types.
36687330f729Sjoerg   auto &NumberedTypes = TypePrinter.getNumberedTypes();
36697330f729Sjoerg   for (unsigned I = 0, E = NumberedTypes.size(); I != E; ++I) {
36707330f729Sjoerg     Out << '%' << I << " = type ";
36717330f729Sjoerg 
36727330f729Sjoerg     // Make sure we print out at least one level of the type structure, so
36737330f729Sjoerg     // that we do not get %2 = type %2
36747330f729Sjoerg     TypePrinter.printStructBody(NumberedTypes[I], Out);
36757330f729Sjoerg     Out << '\n';
36767330f729Sjoerg   }
36777330f729Sjoerg 
36787330f729Sjoerg   auto &NamedTypes = TypePrinter.getNamedTypes();
36797330f729Sjoerg   for (unsigned I = 0, E = NamedTypes.size(); I != E; ++I) {
36807330f729Sjoerg     PrintLLVMName(Out, NamedTypes[I]->getName(), LocalPrefix);
36817330f729Sjoerg     Out << " = type ";
36827330f729Sjoerg 
36837330f729Sjoerg     // Make sure we print out at least one level of the type structure, so
36847330f729Sjoerg     // that we do not get %FILE = type %FILE
36857330f729Sjoerg     TypePrinter.printStructBody(NamedTypes[I], Out);
36867330f729Sjoerg     Out << '\n';
36877330f729Sjoerg   }
36887330f729Sjoerg }
36897330f729Sjoerg 
36907330f729Sjoerg /// printFunction - Print all aspects of a function.
printFunction(const Function * F)36917330f729Sjoerg void AssemblyWriter::printFunction(const Function *F) {
36927330f729Sjoerg   if (AnnotationWriter) AnnotationWriter->emitFunctionAnnot(F, Out);
36937330f729Sjoerg 
36947330f729Sjoerg   if (F->isMaterializable())
36957330f729Sjoerg     Out << "; Materializable\n";
36967330f729Sjoerg 
36977330f729Sjoerg   const AttributeList &Attrs = F->getAttributes();
36987330f729Sjoerg   if (Attrs.hasAttributes(AttributeList::FunctionIndex)) {
36997330f729Sjoerg     AttributeSet AS = Attrs.getFnAttributes();
37007330f729Sjoerg     std::string AttrStr;
37017330f729Sjoerg 
37027330f729Sjoerg     for (const Attribute &Attr : AS) {
37037330f729Sjoerg       if (!Attr.isStringAttribute()) {
37047330f729Sjoerg         if (!AttrStr.empty()) AttrStr += ' ';
37057330f729Sjoerg         AttrStr += Attr.getAsString();
37067330f729Sjoerg       }
37077330f729Sjoerg     }
37087330f729Sjoerg 
37097330f729Sjoerg     if (!AttrStr.empty())
37107330f729Sjoerg       Out << "; Function Attrs: " << AttrStr << '\n';
37117330f729Sjoerg   }
37127330f729Sjoerg 
37137330f729Sjoerg   Machine.incorporateFunction(F);
37147330f729Sjoerg 
37157330f729Sjoerg   if (F->isDeclaration()) {
37167330f729Sjoerg     Out << "declare";
37177330f729Sjoerg     SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
37187330f729Sjoerg     F->getAllMetadata(MDs);
37197330f729Sjoerg     printMetadataAttachments(MDs, " ");
37207330f729Sjoerg     Out << ' ';
37217330f729Sjoerg   } else
37227330f729Sjoerg     Out << "define ";
37237330f729Sjoerg 
37247330f729Sjoerg   Out << getLinkageNameWithSpace(F->getLinkage());
37257330f729Sjoerg   PrintDSOLocation(*F, Out);
37267330f729Sjoerg   PrintVisibility(F->getVisibility(), Out);
37277330f729Sjoerg   PrintDLLStorageClass(F->getDLLStorageClass(), Out);
37287330f729Sjoerg 
37297330f729Sjoerg   // Print the calling convention.
37307330f729Sjoerg   if (F->getCallingConv() != CallingConv::C) {
37317330f729Sjoerg     PrintCallingConv(F->getCallingConv(), Out);
37327330f729Sjoerg     Out << " ";
37337330f729Sjoerg   }
37347330f729Sjoerg 
37357330f729Sjoerg   FunctionType *FT = F->getFunctionType();
37367330f729Sjoerg   if (Attrs.hasAttributes(AttributeList::ReturnIndex))
37377330f729Sjoerg     Out << Attrs.getAsString(AttributeList::ReturnIndex) << ' ';
37387330f729Sjoerg   TypePrinter.print(F->getReturnType(), Out);
37397330f729Sjoerg   Out << ' ';
37407330f729Sjoerg   WriteAsOperandInternal(Out, F, &TypePrinter, &Machine, F->getParent());
37417330f729Sjoerg   Out << '(';
37427330f729Sjoerg 
37437330f729Sjoerg   // Loop over the arguments, printing them...
37447330f729Sjoerg   if (F->isDeclaration() && !IsForDebug) {
37457330f729Sjoerg     // We're only interested in the type here - don't print argument names.
37467330f729Sjoerg     for (unsigned I = 0, E = FT->getNumParams(); I != E; ++I) {
37477330f729Sjoerg       // Insert commas as we go... the first arg doesn't get a comma
37487330f729Sjoerg       if (I)
37497330f729Sjoerg         Out << ", ";
37507330f729Sjoerg       // Output type...
37517330f729Sjoerg       TypePrinter.print(FT->getParamType(I), Out);
37527330f729Sjoerg 
37537330f729Sjoerg       AttributeSet ArgAttrs = Attrs.getParamAttributes(I);
3754*82d56013Sjoerg       if (ArgAttrs.hasAttributes()) {
3755*82d56013Sjoerg         Out << ' ';
3756*82d56013Sjoerg         writeAttributeSet(ArgAttrs);
3757*82d56013Sjoerg       }
37587330f729Sjoerg     }
37597330f729Sjoerg   } else {
37607330f729Sjoerg     // The arguments are meaningful here, print them in detail.
37617330f729Sjoerg     for (const Argument &Arg : F->args()) {
37627330f729Sjoerg       // Insert commas as we go... the first arg doesn't get a comma
37637330f729Sjoerg       if (Arg.getArgNo() != 0)
37647330f729Sjoerg         Out << ", ";
37657330f729Sjoerg       printArgument(&Arg, Attrs.getParamAttributes(Arg.getArgNo()));
37667330f729Sjoerg     }
37677330f729Sjoerg   }
37687330f729Sjoerg 
37697330f729Sjoerg   // Finish printing arguments...
37707330f729Sjoerg   if (FT->isVarArg()) {
37717330f729Sjoerg     if (FT->getNumParams()) Out << ", ";
37727330f729Sjoerg     Out << "...";  // Output varargs portion of signature!
37737330f729Sjoerg   }
37747330f729Sjoerg   Out << ')';
37757330f729Sjoerg   StringRef UA = getUnnamedAddrEncoding(F->getUnnamedAddr());
37767330f729Sjoerg   if (!UA.empty())
37777330f729Sjoerg     Out << ' ' << UA;
37787330f729Sjoerg   // We print the function address space if it is non-zero or if we are writing
37797330f729Sjoerg   // a module with a non-zero program address space or if there is no valid
37807330f729Sjoerg   // Module* so that the file can be parsed without the datalayout string.
37817330f729Sjoerg   const Module *Mod = F->getParent();
37827330f729Sjoerg   if (F->getAddressSpace() != 0 || !Mod ||
37837330f729Sjoerg       Mod->getDataLayout().getProgramAddressSpace() != 0)
37847330f729Sjoerg     Out << " addrspace(" << F->getAddressSpace() << ")";
37857330f729Sjoerg   if (Attrs.hasAttributes(AttributeList::FunctionIndex))
37867330f729Sjoerg     Out << " #" << Machine.getAttributeGroupSlot(Attrs.getFnAttributes());
37877330f729Sjoerg   if (F->hasSection()) {
37887330f729Sjoerg     Out << " section \"";
37897330f729Sjoerg     printEscapedString(F->getSection(), Out);
37907330f729Sjoerg     Out << '"';
37917330f729Sjoerg   }
37927330f729Sjoerg   if (F->hasPartition()) {
37937330f729Sjoerg     Out << " partition \"";
37947330f729Sjoerg     printEscapedString(F->getPartition(), Out);
37957330f729Sjoerg     Out << '"';
37967330f729Sjoerg   }
37977330f729Sjoerg   maybePrintComdat(Out, *F);
37987330f729Sjoerg   if (F->getAlignment())
37997330f729Sjoerg     Out << " align " << F->getAlignment();
38007330f729Sjoerg   if (F->hasGC())
38017330f729Sjoerg     Out << " gc \"" << F->getGC() << '"';
38027330f729Sjoerg   if (F->hasPrefixData()) {
38037330f729Sjoerg     Out << " prefix ";
38047330f729Sjoerg     writeOperand(F->getPrefixData(), true);
38057330f729Sjoerg   }
38067330f729Sjoerg   if (F->hasPrologueData()) {
38077330f729Sjoerg     Out << " prologue ";
38087330f729Sjoerg     writeOperand(F->getPrologueData(), true);
38097330f729Sjoerg   }
38107330f729Sjoerg   if (F->hasPersonalityFn()) {
38117330f729Sjoerg     Out << " personality ";
38127330f729Sjoerg     writeOperand(F->getPersonalityFn(), /*PrintType=*/true);
38137330f729Sjoerg   }
38147330f729Sjoerg 
38157330f729Sjoerg   if (F->isDeclaration()) {
38167330f729Sjoerg     Out << '\n';
38177330f729Sjoerg   } else {
38187330f729Sjoerg     SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
38197330f729Sjoerg     F->getAllMetadata(MDs);
38207330f729Sjoerg     printMetadataAttachments(MDs, " ");
38217330f729Sjoerg 
38227330f729Sjoerg     Out << " {";
38237330f729Sjoerg     // Output all of the function's basic blocks.
38247330f729Sjoerg     for (const BasicBlock &BB : *F)
38257330f729Sjoerg       printBasicBlock(&BB);
38267330f729Sjoerg 
38277330f729Sjoerg     // Output the function's use-lists.
38287330f729Sjoerg     printUseLists(F);
38297330f729Sjoerg 
38307330f729Sjoerg     Out << "}\n";
38317330f729Sjoerg   }
38327330f729Sjoerg 
38337330f729Sjoerg   Machine.purgeFunction();
38347330f729Sjoerg }
38357330f729Sjoerg 
38367330f729Sjoerg /// printArgument - This member is called for every argument that is passed into
38377330f729Sjoerg /// the function.  Simply print it out
printArgument(const Argument * Arg,AttributeSet Attrs)38387330f729Sjoerg void AssemblyWriter::printArgument(const Argument *Arg, AttributeSet Attrs) {
38397330f729Sjoerg   // Output type...
38407330f729Sjoerg   TypePrinter.print(Arg->getType(), Out);
38417330f729Sjoerg 
38427330f729Sjoerg   // Output parameter attributes list
3843*82d56013Sjoerg   if (Attrs.hasAttributes()) {
3844*82d56013Sjoerg     Out << ' ';
3845*82d56013Sjoerg     writeAttributeSet(Attrs);
3846*82d56013Sjoerg   }
38477330f729Sjoerg 
38487330f729Sjoerg   // Output name, if available...
38497330f729Sjoerg   if (Arg->hasName()) {
38507330f729Sjoerg     Out << ' ';
38517330f729Sjoerg     PrintLLVMName(Out, Arg);
38527330f729Sjoerg   } else {
38537330f729Sjoerg     int Slot = Machine.getLocalSlot(Arg);
38547330f729Sjoerg     assert(Slot != -1 && "expect argument in function here");
38557330f729Sjoerg     Out << " %" << Slot;
38567330f729Sjoerg   }
38577330f729Sjoerg }
38587330f729Sjoerg 
38597330f729Sjoerg /// printBasicBlock - This member is called for each basic block in a method.
printBasicBlock(const BasicBlock * BB)38607330f729Sjoerg void AssemblyWriter::printBasicBlock(const BasicBlock *BB) {
3861*82d56013Sjoerg   assert(BB && BB->getParent() && "block without parent!");
3862*82d56013Sjoerg   bool IsEntryBlock = BB->isEntryBlock();
38637330f729Sjoerg   if (BB->hasName()) {              // Print out the label if it exists...
38647330f729Sjoerg     Out << "\n";
38657330f729Sjoerg     PrintLLVMName(Out, BB->getName(), LabelPrefix);
38667330f729Sjoerg     Out << ':';
38677330f729Sjoerg   } else if (!IsEntryBlock) {
38687330f729Sjoerg     Out << "\n";
38697330f729Sjoerg     int Slot = Machine.getLocalSlot(BB);
38707330f729Sjoerg     if (Slot != -1)
38717330f729Sjoerg       Out << Slot << ":";
38727330f729Sjoerg     else
38737330f729Sjoerg       Out << "<badref>:";
38747330f729Sjoerg   }
38757330f729Sjoerg 
3876*82d56013Sjoerg   if (!IsEntryBlock) {
38777330f729Sjoerg     // Output predecessors for the block.
38787330f729Sjoerg     Out.PadToColumn(50);
38797330f729Sjoerg     Out << ";";
38807330f729Sjoerg     const_pred_iterator PI = pred_begin(BB), PE = pred_end(BB);
38817330f729Sjoerg 
38827330f729Sjoerg     if (PI == PE) {
38837330f729Sjoerg       Out << " No predecessors!";
38847330f729Sjoerg     } else {
38857330f729Sjoerg       Out << " preds = ";
38867330f729Sjoerg       writeOperand(*PI, false);
38877330f729Sjoerg       for (++PI; PI != PE; ++PI) {
38887330f729Sjoerg         Out << ", ";
38897330f729Sjoerg         writeOperand(*PI, false);
38907330f729Sjoerg       }
38917330f729Sjoerg     }
38927330f729Sjoerg   }
38937330f729Sjoerg 
38947330f729Sjoerg   Out << "\n";
38957330f729Sjoerg 
38967330f729Sjoerg   if (AnnotationWriter) AnnotationWriter->emitBasicBlockStartAnnot(BB, Out);
38977330f729Sjoerg 
38987330f729Sjoerg   // Output all of the instructions in the basic block...
38997330f729Sjoerg   for (const Instruction &I : *BB) {
39007330f729Sjoerg     printInstructionLine(I);
39017330f729Sjoerg   }
39027330f729Sjoerg 
39037330f729Sjoerg   if (AnnotationWriter) AnnotationWriter->emitBasicBlockEndAnnot(BB, Out);
39047330f729Sjoerg }
39057330f729Sjoerg 
39067330f729Sjoerg /// printInstructionLine - Print an instruction and a newline character.
printInstructionLine(const Instruction & I)39077330f729Sjoerg void AssemblyWriter::printInstructionLine(const Instruction &I) {
39087330f729Sjoerg   printInstruction(I);
39097330f729Sjoerg   Out << '\n';
39107330f729Sjoerg }
39117330f729Sjoerg 
39127330f729Sjoerg /// printGCRelocateComment - print comment after call to the gc.relocate
39137330f729Sjoerg /// intrinsic indicating base and derived pointer names.
printGCRelocateComment(const GCRelocateInst & Relocate)39147330f729Sjoerg void AssemblyWriter::printGCRelocateComment(const GCRelocateInst &Relocate) {
39157330f729Sjoerg   Out << " ; (";
39167330f729Sjoerg   writeOperand(Relocate.getBasePtr(), false);
39177330f729Sjoerg   Out << ", ";
39187330f729Sjoerg   writeOperand(Relocate.getDerivedPtr(), false);
39197330f729Sjoerg   Out << ")";
39207330f729Sjoerg }
39217330f729Sjoerg 
39227330f729Sjoerg /// printInfoComment - Print a little comment after the instruction indicating
39237330f729Sjoerg /// which slot it occupies.
printInfoComment(const Value & V)39247330f729Sjoerg void AssemblyWriter::printInfoComment(const Value &V) {
39257330f729Sjoerg   if (const auto *Relocate = dyn_cast<GCRelocateInst>(&V))
39267330f729Sjoerg     printGCRelocateComment(*Relocate);
39277330f729Sjoerg 
39287330f729Sjoerg   if (AnnotationWriter)
39297330f729Sjoerg     AnnotationWriter->printInfoComment(V, Out);
39307330f729Sjoerg }
39317330f729Sjoerg 
maybePrintCallAddrSpace(const Value * Operand,const Instruction * I,raw_ostream & Out)39327330f729Sjoerg static void maybePrintCallAddrSpace(const Value *Operand, const Instruction *I,
39337330f729Sjoerg                                     raw_ostream &Out) {
39347330f729Sjoerg   // We print the address space of the call if it is non-zero.
39357330f729Sjoerg   unsigned CallAddrSpace = Operand->getType()->getPointerAddressSpace();
39367330f729Sjoerg   bool PrintAddrSpace = CallAddrSpace != 0;
39377330f729Sjoerg   if (!PrintAddrSpace) {
39387330f729Sjoerg     const Module *Mod = getModuleFromVal(I);
39397330f729Sjoerg     // We also print it if it is zero but not equal to the program address space
39407330f729Sjoerg     // or if we can't find a valid Module* to make it possible to parse
39417330f729Sjoerg     // the resulting file even without a datalayout string.
39427330f729Sjoerg     if (!Mod || Mod->getDataLayout().getProgramAddressSpace() != 0)
39437330f729Sjoerg       PrintAddrSpace = true;
39447330f729Sjoerg   }
39457330f729Sjoerg   if (PrintAddrSpace)
39467330f729Sjoerg     Out << " addrspace(" << CallAddrSpace << ")";
39477330f729Sjoerg }
39487330f729Sjoerg 
39497330f729Sjoerg // This member is called for each Instruction in a function..
printInstruction(const Instruction & I)39507330f729Sjoerg void AssemblyWriter::printInstruction(const Instruction &I) {
39517330f729Sjoerg   if (AnnotationWriter) AnnotationWriter->emitInstructionAnnot(&I, Out);
39527330f729Sjoerg 
39537330f729Sjoerg   // Print out indentation for an instruction.
39547330f729Sjoerg   Out << "  ";
39557330f729Sjoerg 
39567330f729Sjoerg   // Print out name if it exists...
39577330f729Sjoerg   if (I.hasName()) {
39587330f729Sjoerg     PrintLLVMName(Out, &I);
39597330f729Sjoerg     Out << " = ";
39607330f729Sjoerg   } else if (!I.getType()->isVoidTy()) {
39617330f729Sjoerg     // Print out the def slot taken.
39627330f729Sjoerg     int SlotNum = Machine.getLocalSlot(&I);
39637330f729Sjoerg     if (SlotNum == -1)
39647330f729Sjoerg       Out << "<badref> = ";
39657330f729Sjoerg     else
39667330f729Sjoerg       Out << '%' << SlotNum << " = ";
39677330f729Sjoerg   }
39687330f729Sjoerg 
39697330f729Sjoerg   if (const CallInst *CI = dyn_cast<CallInst>(&I)) {
39707330f729Sjoerg     if (CI->isMustTailCall())
39717330f729Sjoerg       Out << "musttail ";
39727330f729Sjoerg     else if (CI->isTailCall())
39737330f729Sjoerg       Out << "tail ";
39747330f729Sjoerg     else if (CI->isNoTailCall())
39757330f729Sjoerg       Out << "notail ";
39767330f729Sjoerg   }
39777330f729Sjoerg 
39787330f729Sjoerg   // Print out the opcode...
39797330f729Sjoerg   Out << I.getOpcodeName();
39807330f729Sjoerg 
39817330f729Sjoerg   // If this is an atomic load or store, print out the atomic marker.
39827330f729Sjoerg   if ((isa<LoadInst>(I)  && cast<LoadInst>(I).isAtomic()) ||
39837330f729Sjoerg       (isa<StoreInst>(I) && cast<StoreInst>(I).isAtomic()))
39847330f729Sjoerg     Out << " atomic";
39857330f729Sjoerg 
39867330f729Sjoerg   if (isa<AtomicCmpXchgInst>(I) && cast<AtomicCmpXchgInst>(I).isWeak())
39877330f729Sjoerg     Out << " weak";
39887330f729Sjoerg 
39897330f729Sjoerg   // If this is a volatile operation, print out the volatile marker.
39907330f729Sjoerg   if ((isa<LoadInst>(I)  && cast<LoadInst>(I).isVolatile()) ||
39917330f729Sjoerg       (isa<StoreInst>(I) && cast<StoreInst>(I).isVolatile()) ||
39927330f729Sjoerg       (isa<AtomicCmpXchgInst>(I) && cast<AtomicCmpXchgInst>(I).isVolatile()) ||
39937330f729Sjoerg       (isa<AtomicRMWInst>(I) && cast<AtomicRMWInst>(I).isVolatile()))
39947330f729Sjoerg     Out << " volatile";
39957330f729Sjoerg 
39967330f729Sjoerg   // Print out optimization information.
39977330f729Sjoerg   WriteOptimizationInfo(Out, &I);
39987330f729Sjoerg 
39997330f729Sjoerg   // Print out the compare instruction predicates
40007330f729Sjoerg   if (const CmpInst *CI = dyn_cast<CmpInst>(&I))
40017330f729Sjoerg     Out << ' ' << CmpInst::getPredicateName(CI->getPredicate());
40027330f729Sjoerg 
40037330f729Sjoerg   // Print out the atomicrmw operation
40047330f729Sjoerg   if (const AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(&I))
40057330f729Sjoerg     Out << ' ' << AtomicRMWInst::getOperationName(RMWI->getOperation());
40067330f729Sjoerg 
40077330f729Sjoerg   // Print out the type of the operands...
40087330f729Sjoerg   const Value *Operand = I.getNumOperands() ? I.getOperand(0) : nullptr;
40097330f729Sjoerg 
40107330f729Sjoerg   // Special case conditional branches to swizzle the condition out to the front
40117330f729Sjoerg   if (isa<BranchInst>(I) && cast<BranchInst>(I).isConditional()) {
40127330f729Sjoerg     const BranchInst &BI(cast<BranchInst>(I));
40137330f729Sjoerg     Out << ' ';
40147330f729Sjoerg     writeOperand(BI.getCondition(), true);
40157330f729Sjoerg     Out << ", ";
40167330f729Sjoerg     writeOperand(BI.getSuccessor(0), true);
40177330f729Sjoerg     Out << ", ";
40187330f729Sjoerg     writeOperand(BI.getSuccessor(1), true);
40197330f729Sjoerg 
40207330f729Sjoerg   } else if (isa<SwitchInst>(I)) {
40217330f729Sjoerg     const SwitchInst& SI(cast<SwitchInst>(I));
40227330f729Sjoerg     // Special case switch instruction to get formatting nice and correct.
40237330f729Sjoerg     Out << ' ';
40247330f729Sjoerg     writeOperand(SI.getCondition(), true);
40257330f729Sjoerg     Out << ", ";
40267330f729Sjoerg     writeOperand(SI.getDefaultDest(), true);
40277330f729Sjoerg     Out << " [";
40287330f729Sjoerg     for (auto Case : SI.cases()) {
40297330f729Sjoerg       Out << "\n    ";
40307330f729Sjoerg       writeOperand(Case.getCaseValue(), true);
40317330f729Sjoerg       Out << ", ";
40327330f729Sjoerg       writeOperand(Case.getCaseSuccessor(), true);
40337330f729Sjoerg     }
40347330f729Sjoerg     Out << "\n  ]";
40357330f729Sjoerg   } else if (isa<IndirectBrInst>(I)) {
40367330f729Sjoerg     // Special case indirectbr instruction to get formatting nice and correct.
40377330f729Sjoerg     Out << ' ';
40387330f729Sjoerg     writeOperand(Operand, true);
40397330f729Sjoerg     Out << ", [";
40407330f729Sjoerg 
40417330f729Sjoerg     for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i) {
40427330f729Sjoerg       if (i != 1)
40437330f729Sjoerg         Out << ", ";
40447330f729Sjoerg       writeOperand(I.getOperand(i), true);
40457330f729Sjoerg     }
40467330f729Sjoerg     Out << ']';
40477330f729Sjoerg   } else if (const PHINode *PN = dyn_cast<PHINode>(&I)) {
40487330f729Sjoerg     Out << ' ';
40497330f729Sjoerg     TypePrinter.print(I.getType(), Out);
40507330f729Sjoerg     Out << ' ';
40517330f729Sjoerg 
40527330f729Sjoerg     for (unsigned op = 0, Eop = PN->getNumIncomingValues(); op < Eop; ++op) {
40537330f729Sjoerg       if (op) Out << ", ";
40547330f729Sjoerg       Out << "[ ";
40557330f729Sjoerg       writeOperand(PN->getIncomingValue(op), false); Out << ", ";
40567330f729Sjoerg       writeOperand(PN->getIncomingBlock(op), false); Out << " ]";
40577330f729Sjoerg     }
40587330f729Sjoerg   } else if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(&I)) {
40597330f729Sjoerg     Out << ' ';
40607330f729Sjoerg     writeOperand(I.getOperand(0), true);
4061*82d56013Sjoerg     for (unsigned i : EVI->indices())
4062*82d56013Sjoerg       Out << ", " << i;
40637330f729Sjoerg   } else if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(&I)) {
40647330f729Sjoerg     Out << ' ';
40657330f729Sjoerg     writeOperand(I.getOperand(0), true); Out << ", ";
40667330f729Sjoerg     writeOperand(I.getOperand(1), true);
4067*82d56013Sjoerg     for (unsigned i : IVI->indices())
4068*82d56013Sjoerg       Out << ", " << i;
40697330f729Sjoerg   } else if (const LandingPadInst *LPI = dyn_cast<LandingPadInst>(&I)) {
40707330f729Sjoerg     Out << ' ';
40717330f729Sjoerg     TypePrinter.print(I.getType(), Out);
40727330f729Sjoerg     if (LPI->isCleanup() || LPI->getNumClauses() != 0)
40737330f729Sjoerg       Out << '\n';
40747330f729Sjoerg 
40757330f729Sjoerg     if (LPI->isCleanup())
40767330f729Sjoerg       Out << "          cleanup";
40777330f729Sjoerg 
40787330f729Sjoerg     for (unsigned i = 0, e = LPI->getNumClauses(); i != e; ++i) {
40797330f729Sjoerg       if (i != 0 || LPI->isCleanup()) Out << "\n";
40807330f729Sjoerg       if (LPI->isCatch(i))
40817330f729Sjoerg         Out << "          catch ";
40827330f729Sjoerg       else
40837330f729Sjoerg         Out << "          filter ";
40847330f729Sjoerg 
40857330f729Sjoerg       writeOperand(LPI->getClause(i), true);
40867330f729Sjoerg     }
40877330f729Sjoerg   } else if (const auto *CatchSwitch = dyn_cast<CatchSwitchInst>(&I)) {
40887330f729Sjoerg     Out << " within ";
40897330f729Sjoerg     writeOperand(CatchSwitch->getParentPad(), /*PrintType=*/false);
40907330f729Sjoerg     Out << " [";
40917330f729Sjoerg     unsigned Op = 0;
40927330f729Sjoerg     for (const BasicBlock *PadBB : CatchSwitch->handlers()) {
40937330f729Sjoerg       if (Op > 0)
40947330f729Sjoerg         Out << ", ";
40957330f729Sjoerg       writeOperand(PadBB, /*PrintType=*/true);
40967330f729Sjoerg       ++Op;
40977330f729Sjoerg     }
40987330f729Sjoerg     Out << "] unwind ";
40997330f729Sjoerg     if (const BasicBlock *UnwindDest = CatchSwitch->getUnwindDest())
41007330f729Sjoerg       writeOperand(UnwindDest, /*PrintType=*/true);
41017330f729Sjoerg     else
41027330f729Sjoerg       Out << "to caller";
41037330f729Sjoerg   } else if (const auto *FPI = dyn_cast<FuncletPadInst>(&I)) {
41047330f729Sjoerg     Out << " within ";
41057330f729Sjoerg     writeOperand(FPI->getParentPad(), /*PrintType=*/false);
41067330f729Sjoerg     Out << " [";
41077330f729Sjoerg     for (unsigned Op = 0, NumOps = FPI->getNumArgOperands(); Op < NumOps;
41087330f729Sjoerg          ++Op) {
41097330f729Sjoerg       if (Op > 0)
41107330f729Sjoerg         Out << ", ";
41117330f729Sjoerg       writeOperand(FPI->getArgOperand(Op), /*PrintType=*/true);
41127330f729Sjoerg     }
41137330f729Sjoerg     Out << ']';
41147330f729Sjoerg   } else if (isa<ReturnInst>(I) && !Operand) {
41157330f729Sjoerg     Out << " void";
41167330f729Sjoerg   } else if (const auto *CRI = dyn_cast<CatchReturnInst>(&I)) {
41177330f729Sjoerg     Out << " from ";
41187330f729Sjoerg     writeOperand(CRI->getOperand(0), /*PrintType=*/false);
41197330f729Sjoerg 
41207330f729Sjoerg     Out << " to ";
41217330f729Sjoerg     writeOperand(CRI->getOperand(1), /*PrintType=*/true);
41227330f729Sjoerg   } else if (const auto *CRI = dyn_cast<CleanupReturnInst>(&I)) {
41237330f729Sjoerg     Out << " from ";
41247330f729Sjoerg     writeOperand(CRI->getOperand(0), /*PrintType=*/false);
41257330f729Sjoerg 
41267330f729Sjoerg     Out << " unwind ";
41277330f729Sjoerg     if (CRI->hasUnwindDest())
41287330f729Sjoerg       writeOperand(CRI->getOperand(1), /*PrintType=*/true);
41297330f729Sjoerg     else
41307330f729Sjoerg       Out << "to caller";
41317330f729Sjoerg   } else if (const CallInst *CI = dyn_cast<CallInst>(&I)) {
41327330f729Sjoerg     // Print the calling convention being used.
41337330f729Sjoerg     if (CI->getCallingConv() != CallingConv::C) {
41347330f729Sjoerg       Out << " ";
41357330f729Sjoerg       PrintCallingConv(CI->getCallingConv(), Out);
41367330f729Sjoerg     }
41377330f729Sjoerg 
4138*82d56013Sjoerg     Operand = CI->getCalledOperand();
41397330f729Sjoerg     FunctionType *FTy = CI->getFunctionType();
41407330f729Sjoerg     Type *RetTy = FTy->getReturnType();
41417330f729Sjoerg     const AttributeList &PAL = CI->getAttributes();
41427330f729Sjoerg 
41437330f729Sjoerg     if (PAL.hasAttributes(AttributeList::ReturnIndex))
41447330f729Sjoerg       Out << ' ' << PAL.getAsString(AttributeList::ReturnIndex);
41457330f729Sjoerg 
41467330f729Sjoerg     // Only print addrspace(N) if necessary:
41477330f729Sjoerg     maybePrintCallAddrSpace(Operand, &I, Out);
41487330f729Sjoerg 
41497330f729Sjoerg     // If possible, print out the short form of the call instruction.  We can
41507330f729Sjoerg     // only do this if the first argument is a pointer to a nonvararg function,
41517330f729Sjoerg     // and if the return type is not a pointer to a function.
41527330f729Sjoerg     //
41537330f729Sjoerg     Out << ' ';
41547330f729Sjoerg     TypePrinter.print(FTy->isVarArg() ? FTy : RetTy, Out);
41557330f729Sjoerg     Out << ' ';
41567330f729Sjoerg     writeOperand(Operand, false);
41577330f729Sjoerg     Out << '(';
41587330f729Sjoerg     for (unsigned op = 0, Eop = CI->getNumArgOperands(); op < Eop; ++op) {
41597330f729Sjoerg       if (op > 0)
41607330f729Sjoerg         Out << ", ";
41617330f729Sjoerg       writeParamOperand(CI->getArgOperand(op), PAL.getParamAttributes(op));
41627330f729Sjoerg     }
41637330f729Sjoerg 
41647330f729Sjoerg     // Emit an ellipsis if this is a musttail call in a vararg function.  This
41657330f729Sjoerg     // is only to aid readability, musttail calls forward varargs by default.
41667330f729Sjoerg     if (CI->isMustTailCall() && CI->getParent() &&
41677330f729Sjoerg         CI->getParent()->getParent() &&
41687330f729Sjoerg         CI->getParent()->getParent()->isVarArg())
41697330f729Sjoerg       Out << ", ...";
41707330f729Sjoerg 
41717330f729Sjoerg     Out << ')';
41727330f729Sjoerg     if (PAL.hasAttributes(AttributeList::FunctionIndex))
41737330f729Sjoerg       Out << " #" << Machine.getAttributeGroupSlot(PAL.getFnAttributes());
41747330f729Sjoerg 
41757330f729Sjoerg     writeOperandBundles(CI);
41767330f729Sjoerg   } else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
4177*82d56013Sjoerg     Operand = II->getCalledOperand();
41787330f729Sjoerg     FunctionType *FTy = II->getFunctionType();
41797330f729Sjoerg     Type *RetTy = FTy->getReturnType();
41807330f729Sjoerg     const AttributeList &PAL = II->getAttributes();
41817330f729Sjoerg 
41827330f729Sjoerg     // Print the calling convention being used.
41837330f729Sjoerg     if (II->getCallingConv() != CallingConv::C) {
41847330f729Sjoerg       Out << " ";
41857330f729Sjoerg       PrintCallingConv(II->getCallingConv(), Out);
41867330f729Sjoerg     }
41877330f729Sjoerg 
41887330f729Sjoerg     if (PAL.hasAttributes(AttributeList::ReturnIndex))
41897330f729Sjoerg       Out << ' ' << PAL.getAsString(AttributeList::ReturnIndex);
41907330f729Sjoerg 
41917330f729Sjoerg     // Only print addrspace(N) if necessary:
41927330f729Sjoerg     maybePrintCallAddrSpace(Operand, &I, Out);
41937330f729Sjoerg 
41947330f729Sjoerg     // If possible, print out the short form of the invoke instruction. We can
41957330f729Sjoerg     // only do this if the first argument is a pointer to a nonvararg function,
41967330f729Sjoerg     // and if the return type is not a pointer to a function.
41977330f729Sjoerg     //
41987330f729Sjoerg     Out << ' ';
41997330f729Sjoerg     TypePrinter.print(FTy->isVarArg() ? FTy : RetTy, Out);
42007330f729Sjoerg     Out << ' ';
42017330f729Sjoerg     writeOperand(Operand, false);
42027330f729Sjoerg     Out << '(';
42037330f729Sjoerg     for (unsigned op = 0, Eop = II->getNumArgOperands(); op < Eop; ++op) {
42047330f729Sjoerg       if (op)
42057330f729Sjoerg         Out << ", ";
42067330f729Sjoerg       writeParamOperand(II->getArgOperand(op), PAL.getParamAttributes(op));
42077330f729Sjoerg     }
42087330f729Sjoerg 
42097330f729Sjoerg     Out << ')';
42107330f729Sjoerg     if (PAL.hasAttributes(AttributeList::FunctionIndex))
42117330f729Sjoerg       Out << " #" << Machine.getAttributeGroupSlot(PAL.getFnAttributes());
42127330f729Sjoerg 
42137330f729Sjoerg     writeOperandBundles(II);
42147330f729Sjoerg 
42157330f729Sjoerg     Out << "\n          to ";
42167330f729Sjoerg     writeOperand(II->getNormalDest(), true);
42177330f729Sjoerg     Out << " unwind ";
42187330f729Sjoerg     writeOperand(II->getUnwindDest(), true);
42197330f729Sjoerg   } else if (const CallBrInst *CBI = dyn_cast<CallBrInst>(&I)) {
4220*82d56013Sjoerg     Operand = CBI->getCalledOperand();
42217330f729Sjoerg     FunctionType *FTy = CBI->getFunctionType();
42227330f729Sjoerg     Type *RetTy = FTy->getReturnType();
42237330f729Sjoerg     const AttributeList &PAL = CBI->getAttributes();
42247330f729Sjoerg 
42257330f729Sjoerg     // Print the calling convention being used.
42267330f729Sjoerg     if (CBI->getCallingConv() != CallingConv::C) {
42277330f729Sjoerg       Out << " ";
42287330f729Sjoerg       PrintCallingConv(CBI->getCallingConv(), Out);
42297330f729Sjoerg     }
42307330f729Sjoerg 
42317330f729Sjoerg     if (PAL.hasAttributes(AttributeList::ReturnIndex))
42327330f729Sjoerg       Out << ' ' << PAL.getAsString(AttributeList::ReturnIndex);
42337330f729Sjoerg 
42347330f729Sjoerg     // If possible, print out the short form of the callbr instruction. We can
42357330f729Sjoerg     // only do this if the first argument is a pointer to a nonvararg function,
42367330f729Sjoerg     // and if the return type is not a pointer to a function.
42377330f729Sjoerg     //
42387330f729Sjoerg     Out << ' ';
42397330f729Sjoerg     TypePrinter.print(FTy->isVarArg() ? FTy : RetTy, Out);
42407330f729Sjoerg     Out << ' ';
42417330f729Sjoerg     writeOperand(Operand, false);
42427330f729Sjoerg     Out << '(';
42437330f729Sjoerg     for (unsigned op = 0, Eop = CBI->getNumArgOperands(); op < Eop; ++op) {
42447330f729Sjoerg       if (op)
42457330f729Sjoerg         Out << ", ";
42467330f729Sjoerg       writeParamOperand(CBI->getArgOperand(op), PAL.getParamAttributes(op));
42477330f729Sjoerg     }
42487330f729Sjoerg 
42497330f729Sjoerg     Out << ')';
42507330f729Sjoerg     if (PAL.hasAttributes(AttributeList::FunctionIndex))
42517330f729Sjoerg       Out << " #" << Machine.getAttributeGroupSlot(PAL.getFnAttributes());
42527330f729Sjoerg 
42537330f729Sjoerg     writeOperandBundles(CBI);
42547330f729Sjoerg 
42557330f729Sjoerg     Out << "\n          to ";
42567330f729Sjoerg     writeOperand(CBI->getDefaultDest(), true);
42577330f729Sjoerg     Out << " [";
42587330f729Sjoerg     for (unsigned i = 0, e = CBI->getNumIndirectDests(); i != e; ++i) {
42597330f729Sjoerg       if (i != 0)
42607330f729Sjoerg         Out << ", ";
42617330f729Sjoerg       writeOperand(CBI->getIndirectDest(i), true);
42627330f729Sjoerg     }
42637330f729Sjoerg     Out << ']';
42647330f729Sjoerg   } else if (const AllocaInst *AI = dyn_cast<AllocaInst>(&I)) {
42657330f729Sjoerg     Out << ' ';
42667330f729Sjoerg     if (AI->isUsedWithInAlloca())
42677330f729Sjoerg       Out << "inalloca ";
42687330f729Sjoerg     if (AI->isSwiftError())
42697330f729Sjoerg       Out << "swifterror ";
42707330f729Sjoerg     TypePrinter.print(AI->getAllocatedType(), Out);
42717330f729Sjoerg 
42727330f729Sjoerg     // Explicitly write the array size if the code is broken, if it's an array
42737330f729Sjoerg     // allocation, or if the type is not canonical for scalar allocations.  The
42747330f729Sjoerg     // latter case prevents the type from mutating when round-tripping through
42757330f729Sjoerg     // assembly.
42767330f729Sjoerg     if (!AI->getArraySize() || AI->isArrayAllocation() ||
42777330f729Sjoerg         !AI->getArraySize()->getType()->isIntegerTy(32)) {
42787330f729Sjoerg       Out << ", ";
42797330f729Sjoerg       writeOperand(AI->getArraySize(), true);
42807330f729Sjoerg     }
42817330f729Sjoerg     if (AI->getAlignment()) {
42827330f729Sjoerg       Out << ", align " << AI->getAlignment();
42837330f729Sjoerg     }
42847330f729Sjoerg 
42857330f729Sjoerg     unsigned AddrSpace = AI->getType()->getAddressSpace();
42867330f729Sjoerg     if (AddrSpace != 0) {
42877330f729Sjoerg       Out << ", addrspace(" << AddrSpace << ')';
42887330f729Sjoerg     }
42897330f729Sjoerg   } else if (isa<CastInst>(I)) {
42907330f729Sjoerg     if (Operand) {
42917330f729Sjoerg       Out << ' ';
42927330f729Sjoerg       writeOperand(Operand, true);   // Work with broken code
42937330f729Sjoerg     }
42947330f729Sjoerg     Out << " to ";
42957330f729Sjoerg     TypePrinter.print(I.getType(), Out);
42967330f729Sjoerg   } else if (isa<VAArgInst>(I)) {
42977330f729Sjoerg     if (Operand) {
42987330f729Sjoerg       Out << ' ';
42997330f729Sjoerg       writeOperand(Operand, true);   // Work with broken code
43007330f729Sjoerg     }
43017330f729Sjoerg     Out << ", ";
43027330f729Sjoerg     TypePrinter.print(I.getType(), Out);
43037330f729Sjoerg   } else if (Operand) {   // Print the normal way.
43047330f729Sjoerg     if (const auto *GEP = dyn_cast<GetElementPtrInst>(&I)) {
43057330f729Sjoerg       Out << ' ';
43067330f729Sjoerg       TypePrinter.print(GEP->getSourceElementType(), Out);
43077330f729Sjoerg       Out << ',';
43087330f729Sjoerg     } else if (const auto *LI = dyn_cast<LoadInst>(&I)) {
43097330f729Sjoerg       Out << ' ';
43107330f729Sjoerg       TypePrinter.print(LI->getType(), Out);
43117330f729Sjoerg       Out << ',';
43127330f729Sjoerg     }
43137330f729Sjoerg 
43147330f729Sjoerg     // PrintAllTypes - Instructions who have operands of all the same type
43157330f729Sjoerg     // omit the type from all but the first operand.  If the instruction has
43167330f729Sjoerg     // different type operands (for example br), then they are all printed.
43177330f729Sjoerg     bool PrintAllTypes = false;
43187330f729Sjoerg     Type *TheType = Operand->getType();
43197330f729Sjoerg 
43207330f729Sjoerg     // Select, Store and ShuffleVector always print all types.
43217330f729Sjoerg     if (isa<SelectInst>(I) || isa<StoreInst>(I) || isa<ShuffleVectorInst>(I)
43227330f729Sjoerg         || isa<ReturnInst>(I)) {
43237330f729Sjoerg       PrintAllTypes = true;
43247330f729Sjoerg     } else {
43257330f729Sjoerg       for (unsigned i = 1, E = I.getNumOperands(); i != E; ++i) {
43267330f729Sjoerg         Operand = I.getOperand(i);
43277330f729Sjoerg         // note that Operand shouldn't be null, but the test helps make dump()
43287330f729Sjoerg         // more tolerant of malformed IR
43297330f729Sjoerg         if (Operand && Operand->getType() != TheType) {
43307330f729Sjoerg           PrintAllTypes = true;    // We have differing types!  Print them all!
43317330f729Sjoerg           break;
43327330f729Sjoerg         }
43337330f729Sjoerg       }
43347330f729Sjoerg     }
43357330f729Sjoerg 
43367330f729Sjoerg     if (!PrintAllTypes) {
43377330f729Sjoerg       Out << ' ';
43387330f729Sjoerg       TypePrinter.print(TheType, Out);
43397330f729Sjoerg     }
43407330f729Sjoerg 
43417330f729Sjoerg     Out << ' ';
43427330f729Sjoerg     for (unsigned i = 0, E = I.getNumOperands(); i != E; ++i) {
43437330f729Sjoerg       if (i) Out << ", ";
43447330f729Sjoerg       writeOperand(I.getOperand(i), PrintAllTypes);
43457330f729Sjoerg     }
43467330f729Sjoerg   }
43477330f729Sjoerg 
43487330f729Sjoerg   // Print atomic ordering/alignment for memory operations
43497330f729Sjoerg   if (const LoadInst *LI = dyn_cast<LoadInst>(&I)) {
43507330f729Sjoerg     if (LI->isAtomic())
43517330f729Sjoerg       writeAtomic(LI->getContext(), LI->getOrdering(), LI->getSyncScopeID());
43527330f729Sjoerg     if (LI->getAlignment())
43537330f729Sjoerg       Out << ", align " << LI->getAlignment();
43547330f729Sjoerg   } else if (const StoreInst *SI = dyn_cast<StoreInst>(&I)) {
43557330f729Sjoerg     if (SI->isAtomic())
43567330f729Sjoerg       writeAtomic(SI->getContext(), SI->getOrdering(), SI->getSyncScopeID());
43577330f729Sjoerg     if (SI->getAlignment())
43587330f729Sjoerg       Out << ", align " << SI->getAlignment();
43597330f729Sjoerg   } else if (const AtomicCmpXchgInst *CXI = dyn_cast<AtomicCmpXchgInst>(&I)) {
43607330f729Sjoerg     writeAtomicCmpXchg(CXI->getContext(), CXI->getSuccessOrdering(),
43617330f729Sjoerg                        CXI->getFailureOrdering(), CXI->getSyncScopeID());
4362*82d56013Sjoerg     Out << ", align " << CXI->getAlign().value();
43637330f729Sjoerg   } else if (const AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(&I)) {
43647330f729Sjoerg     writeAtomic(RMWI->getContext(), RMWI->getOrdering(),
43657330f729Sjoerg                 RMWI->getSyncScopeID());
4366*82d56013Sjoerg     Out << ", align " << RMWI->getAlign().value();
43677330f729Sjoerg   } else if (const FenceInst *FI = dyn_cast<FenceInst>(&I)) {
43687330f729Sjoerg     writeAtomic(FI->getContext(), FI->getOrdering(), FI->getSyncScopeID());
4369*82d56013Sjoerg   } else if (const ShuffleVectorInst *SVI = dyn_cast<ShuffleVectorInst>(&I)) {
4370*82d56013Sjoerg     PrintShuffleMask(Out, SVI->getType(), SVI->getShuffleMask());
43717330f729Sjoerg   }
43727330f729Sjoerg 
43737330f729Sjoerg   // Print Metadata info.
43747330f729Sjoerg   SmallVector<std::pair<unsigned, MDNode *>, 4> InstMD;
43757330f729Sjoerg   I.getAllMetadata(InstMD);
43767330f729Sjoerg   printMetadataAttachments(InstMD, ", ");
43777330f729Sjoerg 
43787330f729Sjoerg   // Print a nice comment.
43797330f729Sjoerg   printInfoComment(I);
43807330f729Sjoerg }
43817330f729Sjoerg 
printMetadataAttachments(const SmallVectorImpl<std::pair<unsigned,MDNode * >> & MDs,StringRef Separator)43827330f729Sjoerg void AssemblyWriter::printMetadataAttachments(
43837330f729Sjoerg     const SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs,
43847330f729Sjoerg     StringRef Separator) {
43857330f729Sjoerg   if (MDs.empty())
43867330f729Sjoerg     return;
43877330f729Sjoerg 
43887330f729Sjoerg   if (MDNames.empty())
43897330f729Sjoerg     MDs[0].second->getContext().getMDKindNames(MDNames);
43907330f729Sjoerg 
43917330f729Sjoerg   for (const auto &I : MDs) {
43927330f729Sjoerg     unsigned Kind = I.first;
43937330f729Sjoerg     Out << Separator;
43947330f729Sjoerg     if (Kind < MDNames.size()) {
43957330f729Sjoerg       Out << "!";
43967330f729Sjoerg       printMetadataIdentifier(MDNames[Kind], Out);
43977330f729Sjoerg     } else
43987330f729Sjoerg       Out << "!<unknown kind #" << Kind << ">";
43997330f729Sjoerg     Out << ' ';
44007330f729Sjoerg     WriteAsOperandInternal(Out, I.second, &TypePrinter, &Machine, TheModule);
44017330f729Sjoerg   }
44027330f729Sjoerg }
44037330f729Sjoerg 
writeMDNode(unsigned Slot,const MDNode * Node)44047330f729Sjoerg void AssemblyWriter::writeMDNode(unsigned Slot, const MDNode *Node) {
44057330f729Sjoerg   Out << '!' << Slot << " = ";
44067330f729Sjoerg   printMDNodeBody(Node);
44077330f729Sjoerg   Out << "\n";
44087330f729Sjoerg }
44097330f729Sjoerg 
writeAllMDNodes()44107330f729Sjoerg void AssemblyWriter::writeAllMDNodes() {
44117330f729Sjoerg   SmallVector<const MDNode *, 16> Nodes;
44127330f729Sjoerg   Nodes.resize(Machine.mdn_size());
4413*82d56013Sjoerg   for (auto &I : llvm::make_range(Machine.mdn_begin(), Machine.mdn_end()))
4414*82d56013Sjoerg     Nodes[I.second] = cast<MDNode>(I.first);
44157330f729Sjoerg 
44167330f729Sjoerg   for (unsigned i = 0, e = Nodes.size(); i != e; ++i) {
44177330f729Sjoerg     writeMDNode(i, Nodes[i]);
44187330f729Sjoerg   }
44197330f729Sjoerg }
44207330f729Sjoerg 
printMDNodeBody(const MDNode * Node)44217330f729Sjoerg void AssemblyWriter::printMDNodeBody(const MDNode *Node) {
44227330f729Sjoerg   WriteMDNodeBodyInternal(Out, Node, &TypePrinter, &Machine, TheModule);
44237330f729Sjoerg }
44247330f729Sjoerg 
writeAttribute(const Attribute & Attr,bool InAttrGroup)4425*82d56013Sjoerg void AssemblyWriter::writeAttribute(const Attribute &Attr, bool InAttrGroup) {
4426*82d56013Sjoerg   if (!Attr.isTypeAttribute()) {
4427*82d56013Sjoerg     Out << Attr.getAsString(InAttrGroup);
4428*82d56013Sjoerg     return;
4429*82d56013Sjoerg   }
4430*82d56013Sjoerg 
4431*82d56013Sjoerg   if (Attr.hasAttribute(Attribute::ByVal)) {
4432*82d56013Sjoerg     Out << "byval";
4433*82d56013Sjoerg   } else if (Attr.hasAttribute(Attribute::StructRet)) {
4434*82d56013Sjoerg     Out << "sret";
4435*82d56013Sjoerg   } else if (Attr.hasAttribute(Attribute::ByRef)) {
4436*82d56013Sjoerg     Out << "byref";
4437*82d56013Sjoerg   } else if (Attr.hasAttribute(Attribute::Preallocated)) {
4438*82d56013Sjoerg     Out << "preallocated";
4439*82d56013Sjoerg   } else if (Attr.hasAttribute(Attribute::InAlloca)) {
4440*82d56013Sjoerg     Out << "inalloca";
4441*82d56013Sjoerg   } else {
4442*82d56013Sjoerg     llvm_unreachable("unexpected type attr");
4443*82d56013Sjoerg   }
4444*82d56013Sjoerg 
4445*82d56013Sjoerg   if (Type *Ty = Attr.getValueAsType()) {
4446*82d56013Sjoerg     Out << '(';
4447*82d56013Sjoerg     TypePrinter.print(Ty, Out);
4448*82d56013Sjoerg     Out << ')';
4449*82d56013Sjoerg   }
4450*82d56013Sjoerg }
4451*82d56013Sjoerg 
writeAttributeSet(const AttributeSet & AttrSet,bool InAttrGroup)4452*82d56013Sjoerg void AssemblyWriter::writeAttributeSet(const AttributeSet &AttrSet,
4453*82d56013Sjoerg                                        bool InAttrGroup) {
4454*82d56013Sjoerg   bool FirstAttr = true;
4455*82d56013Sjoerg   for (const auto &Attr : AttrSet) {
4456*82d56013Sjoerg     if (!FirstAttr)
4457*82d56013Sjoerg       Out << ' ';
4458*82d56013Sjoerg     writeAttribute(Attr, InAttrGroup);
4459*82d56013Sjoerg     FirstAttr = false;
4460*82d56013Sjoerg   }
4461*82d56013Sjoerg }
4462*82d56013Sjoerg 
writeAllAttributeGroups()44637330f729Sjoerg void AssemblyWriter::writeAllAttributeGroups() {
44647330f729Sjoerg   std::vector<std::pair<AttributeSet, unsigned>> asVec;
44657330f729Sjoerg   asVec.resize(Machine.as_size());
44667330f729Sjoerg 
4467*82d56013Sjoerg   for (auto &I : llvm::make_range(Machine.as_begin(), Machine.as_end()))
4468*82d56013Sjoerg     asVec[I.second] = I;
44697330f729Sjoerg 
44707330f729Sjoerg   for (const auto &I : asVec)
44717330f729Sjoerg     Out << "attributes #" << I.second << " = { "
44727330f729Sjoerg         << I.first.getAsString(true) << " }\n";
44737330f729Sjoerg }
44747330f729Sjoerg 
printUseListOrder(const UseListOrder & Order)44757330f729Sjoerg void AssemblyWriter::printUseListOrder(const UseListOrder &Order) {
44767330f729Sjoerg   bool IsInFunction = Machine.getFunction();
44777330f729Sjoerg   if (IsInFunction)
44787330f729Sjoerg     Out << "  ";
44797330f729Sjoerg 
44807330f729Sjoerg   Out << "uselistorder";
44817330f729Sjoerg   if (const BasicBlock *BB =
44827330f729Sjoerg           IsInFunction ? nullptr : dyn_cast<BasicBlock>(Order.V)) {
44837330f729Sjoerg     Out << "_bb ";
44847330f729Sjoerg     writeOperand(BB->getParent(), false);
44857330f729Sjoerg     Out << ", ";
44867330f729Sjoerg     writeOperand(BB, false);
44877330f729Sjoerg   } else {
44887330f729Sjoerg     Out << " ";
44897330f729Sjoerg     writeOperand(Order.V, true);
44907330f729Sjoerg   }
44917330f729Sjoerg   Out << ", { ";
44927330f729Sjoerg 
44937330f729Sjoerg   assert(Order.Shuffle.size() >= 2 && "Shuffle too small");
44947330f729Sjoerg   Out << Order.Shuffle[0];
44957330f729Sjoerg   for (unsigned I = 1, E = Order.Shuffle.size(); I != E; ++I)
44967330f729Sjoerg     Out << ", " << Order.Shuffle[I];
44977330f729Sjoerg   Out << " }\n";
44987330f729Sjoerg }
44997330f729Sjoerg 
printUseLists(const Function * F)45007330f729Sjoerg void AssemblyWriter::printUseLists(const Function *F) {
45017330f729Sjoerg   auto hasMore =
45027330f729Sjoerg       [&]() { return !UseListOrders.empty() && UseListOrders.back().F == F; };
45037330f729Sjoerg   if (!hasMore())
45047330f729Sjoerg     // Nothing to do.
45057330f729Sjoerg     return;
45067330f729Sjoerg 
45077330f729Sjoerg   Out << "\n; uselistorder directives\n";
45087330f729Sjoerg   while (hasMore()) {
45097330f729Sjoerg     printUseListOrder(UseListOrders.back());
45107330f729Sjoerg     UseListOrders.pop_back();
45117330f729Sjoerg   }
45127330f729Sjoerg }
45137330f729Sjoerg 
45147330f729Sjoerg //===----------------------------------------------------------------------===//
45157330f729Sjoerg //                       External Interface declarations
45167330f729Sjoerg //===----------------------------------------------------------------------===//
45177330f729Sjoerg 
print(raw_ostream & ROS,AssemblyAnnotationWriter * AAW,bool ShouldPreserveUseListOrder,bool IsForDebug) const45187330f729Sjoerg void Function::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
45197330f729Sjoerg                      bool ShouldPreserveUseListOrder,
45207330f729Sjoerg                      bool IsForDebug) const {
45217330f729Sjoerg   SlotTracker SlotTable(this->getParent());
45227330f729Sjoerg   formatted_raw_ostream OS(ROS);
45237330f729Sjoerg   AssemblyWriter W(OS, SlotTable, this->getParent(), AAW,
45247330f729Sjoerg                    IsForDebug,
45257330f729Sjoerg                    ShouldPreserveUseListOrder);
45267330f729Sjoerg   W.printFunction(this);
45277330f729Sjoerg }
45287330f729Sjoerg 
print(raw_ostream & ROS,AssemblyAnnotationWriter * AAW,bool ShouldPreserveUseListOrder,bool IsForDebug) const4529*82d56013Sjoerg void BasicBlock::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
4530*82d56013Sjoerg                      bool ShouldPreserveUseListOrder,
4531*82d56013Sjoerg                      bool IsForDebug) const {
4532*82d56013Sjoerg   SlotTracker SlotTable(this->getParent());
4533*82d56013Sjoerg   formatted_raw_ostream OS(ROS);
4534*82d56013Sjoerg   AssemblyWriter W(OS, SlotTable, this->getModule(), AAW,
4535*82d56013Sjoerg                    IsForDebug,
4536*82d56013Sjoerg                    ShouldPreserveUseListOrder);
4537*82d56013Sjoerg   W.printBasicBlock(this);
4538*82d56013Sjoerg }
4539*82d56013Sjoerg 
print(raw_ostream & ROS,AssemblyAnnotationWriter * AAW,bool ShouldPreserveUseListOrder,bool IsForDebug) const45407330f729Sjoerg void Module::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
45417330f729Sjoerg                    bool ShouldPreserveUseListOrder, bool IsForDebug) const {
45427330f729Sjoerg   SlotTracker SlotTable(this);
45437330f729Sjoerg   formatted_raw_ostream OS(ROS);
45447330f729Sjoerg   AssemblyWriter W(OS, SlotTable, this, AAW, IsForDebug,
45457330f729Sjoerg                    ShouldPreserveUseListOrder);
45467330f729Sjoerg   W.printModule(this);
45477330f729Sjoerg }
45487330f729Sjoerg 
print(raw_ostream & ROS,bool IsForDebug) const45497330f729Sjoerg void NamedMDNode::print(raw_ostream &ROS, bool IsForDebug) const {
45507330f729Sjoerg   SlotTracker SlotTable(getParent());
45517330f729Sjoerg   formatted_raw_ostream OS(ROS);
45527330f729Sjoerg   AssemblyWriter W(OS, SlotTable, getParent(), nullptr, IsForDebug);
45537330f729Sjoerg   W.printNamedMDNode(this);
45547330f729Sjoerg }
45557330f729Sjoerg 
print(raw_ostream & ROS,ModuleSlotTracker & MST,bool IsForDebug) const45567330f729Sjoerg void NamedMDNode::print(raw_ostream &ROS, ModuleSlotTracker &MST,
45577330f729Sjoerg                         bool IsForDebug) const {
45587330f729Sjoerg   Optional<SlotTracker> LocalST;
45597330f729Sjoerg   SlotTracker *SlotTable;
45607330f729Sjoerg   if (auto *ST = MST.getMachine())
45617330f729Sjoerg     SlotTable = ST;
45627330f729Sjoerg   else {
45637330f729Sjoerg     LocalST.emplace(getParent());
45647330f729Sjoerg     SlotTable = &*LocalST;
45657330f729Sjoerg   }
45667330f729Sjoerg 
45677330f729Sjoerg   formatted_raw_ostream OS(ROS);
45687330f729Sjoerg   AssemblyWriter W(OS, *SlotTable, getParent(), nullptr, IsForDebug);
45697330f729Sjoerg   W.printNamedMDNode(this);
45707330f729Sjoerg }
45717330f729Sjoerg 
print(raw_ostream & ROS,bool) const45727330f729Sjoerg void Comdat::print(raw_ostream &ROS, bool /*IsForDebug*/) const {
45737330f729Sjoerg   PrintLLVMName(ROS, getName(), ComdatPrefix);
45747330f729Sjoerg   ROS << " = comdat ";
45757330f729Sjoerg 
45767330f729Sjoerg   switch (getSelectionKind()) {
45777330f729Sjoerg   case Comdat::Any:
45787330f729Sjoerg     ROS << "any";
45797330f729Sjoerg     break;
45807330f729Sjoerg   case Comdat::ExactMatch:
45817330f729Sjoerg     ROS << "exactmatch";
45827330f729Sjoerg     break;
45837330f729Sjoerg   case Comdat::Largest:
45847330f729Sjoerg     ROS << "largest";
45857330f729Sjoerg     break;
45867330f729Sjoerg   case Comdat::NoDuplicates:
45877330f729Sjoerg     ROS << "noduplicates";
45887330f729Sjoerg     break;
45897330f729Sjoerg   case Comdat::SameSize:
45907330f729Sjoerg     ROS << "samesize";
45917330f729Sjoerg     break;
45927330f729Sjoerg   }
45937330f729Sjoerg 
45947330f729Sjoerg   ROS << '\n';
45957330f729Sjoerg }
45967330f729Sjoerg 
print(raw_ostream & OS,bool,bool NoDetails) const45977330f729Sjoerg void Type::print(raw_ostream &OS, bool /*IsForDebug*/, bool NoDetails) const {
45987330f729Sjoerg   TypePrinting TP;
45997330f729Sjoerg   TP.print(const_cast<Type*>(this), OS);
46007330f729Sjoerg 
46017330f729Sjoerg   if (NoDetails)
46027330f729Sjoerg     return;
46037330f729Sjoerg 
46047330f729Sjoerg   // If the type is a named struct type, print the body as well.
46057330f729Sjoerg   if (StructType *STy = dyn_cast<StructType>(const_cast<Type*>(this)))
46067330f729Sjoerg     if (!STy->isLiteral()) {
46077330f729Sjoerg       OS << " = type ";
46087330f729Sjoerg       TP.printStructBody(STy, OS);
46097330f729Sjoerg     }
46107330f729Sjoerg }
46117330f729Sjoerg 
isReferencingMDNode(const Instruction & I)46127330f729Sjoerg static bool isReferencingMDNode(const Instruction &I) {
46137330f729Sjoerg   if (const auto *CI = dyn_cast<CallInst>(&I))
46147330f729Sjoerg     if (Function *F = CI->getCalledFunction())
46157330f729Sjoerg       if (F->isIntrinsic())
46167330f729Sjoerg         for (auto &Op : I.operands())
46177330f729Sjoerg           if (auto *V = dyn_cast_or_null<MetadataAsValue>(Op))
46187330f729Sjoerg             if (isa<MDNode>(V->getMetadata()))
46197330f729Sjoerg               return true;
46207330f729Sjoerg   return false;
46217330f729Sjoerg }
46227330f729Sjoerg 
print(raw_ostream & ROS,bool IsForDebug) const46237330f729Sjoerg void Value::print(raw_ostream &ROS, bool IsForDebug) const {
46247330f729Sjoerg   bool ShouldInitializeAllMetadata = false;
46257330f729Sjoerg   if (auto *I = dyn_cast<Instruction>(this))
46267330f729Sjoerg     ShouldInitializeAllMetadata = isReferencingMDNode(*I);
46277330f729Sjoerg   else if (isa<Function>(this) || isa<MetadataAsValue>(this))
46287330f729Sjoerg     ShouldInitializeAllMetadata = true;
46297330f729Sjoerg 
46307330f729Sjoerg   ModuleSlotTracker MST(getModuleFromVal(this), ShouldInitializeAllMetadata);
46317330f729Sjoerg   print(ROS, MST, IsForDebug);
46327330f729Sjoerg }
46337330f729Sjoerg 
print(raw_ostream & ROS,ModuleSlotTracker & MST,bool IsForDebug) const46347330f729Sjoerg void Value::print(raw_ostream &ROS, ModuleSlotTracker &MST,
46357330f729Sjoerg                   bool IsForDebug) const {
46367330f729Sjoerg   formatted_raw_ostream OS(ROS);
46377330f729Sjoerg   SlotTracker EmptySlotTable(static_cast<const Module *>(nullptr));
46387330f729Sjoerg   SlotTracker &SlotTable =
46397330f729Sjoerg       MST.getMachine() ? *MST.getMachine() : EmptySlotTable;
46407330f729Sjoerg   auto incorporateFunction = [&](const Function *F) {
46417330f729Sjoerg     if (F)
46427330f729Sjoerg       MST.incorporateFunction(*F);
46437330f729Sjoerg   };
46447330f729Sjoerg 
46457330f729Sjoerg   if (const Instruction *I = dyn_cast<Instruction>(this)) {
46467330f729Sjoerg     incorporateFunction(I->getParent() ? I->getParent()->getParent() : nullptr);
46477330f729Sjoerg     AssemblyWriter W(OS, SlotTable, getModuleFromVal(I), nullptr, IsForDebug);
46487330f729Sjoerg     W.printInstruction(*I);
46497330f729Sjoerg   } else if (const BasicBlock *BB = dyn_cast<BasicBlock>(this)) {
46507330f729Sjoerg     incorporateFunction(BB->getParent());
46517330f729Sjoerg     AssemblyWriter W(OS, SlotTable, getModuleFromVal(BB), nullptr, IsForDebug);
46527330f729Sjoerg     W.printBasicBlock(BB);
46537330f729Sjoerg   } else if (const GlobalValue *GV = dyn_cast<GlobalValue>(this)) {
46547330f729Sjoerg     AssemblyWriter W(OS, SlotTable, GV->getParent(), nullptr, IsForDebug);
46557330f729Sjoerg     if (const GlobalVariable *V = dyn_cast<GlobalVariable>(GV))
46567330f729Sjoerg       W.printGlobal(V);
46577330f729Sjoerg     else if (const Function *F = dyn_cast<Function>(GV))
46587330f729Sjoerg       W.printFunction(F);
46597330f729Sjoerg     else
46607330f729Sjoerg       W.printIndirectSymbol(cast<GlobalIndirectSymbol>(GV));
46617330f729Sjoerg   } else if (const MetadataAsValue *V = dyn_cast<MetadataAsValue>(this)) {
46627330f729Sjoerg     V->getMetadata()->print(ROS, MST, getModuleFromVal(V));
46637330f729Sjoerg   } else if (const Constant *C = dyn_cast<Constant>(this)) {
46647330f729Sjoerg     TypePrinting TypePrinter;
46657330f729Sjoerg     TypePrinter.print(C->getType(), OS);
46667330f729Sjoerg     OS << ' ';
46677330f729Sjoerg     WriteConstantInternal(OS, C, TypePrinter, MST.getMachine(), nullptr);
46687330f729Sjoerg   } else if (isa<InlineAsm>(this) || isa<Argument>(this)) {
46697330f729Sjoerg     this->printAsOperand(OS, /* PrintType */ true, MST);
46707330f729Sjoerg   } else {
46717330f729Sjoerg     llvm_unreachable("Unknown value to print out!");
46727330f729Sjoerg   }
46737330f729Sjoerg }
46747330f729Sjoerg 
46757330f729Sjoerg /// Print without a type, skipping the TypePrinting object.
46767330f729Sjoerg ///
46777330f729Sjoerg /// \return \c true iff printing was successful.
printWithoutType(const Value & V,raw_ostream & O,SlotTracker * Machine,const Module * M)46787330f729Sjoerg static bool printWithoutType(const Value &V, raw_ostream &O,
46797330f729Sjoerg                              SlotTracker *Machine, const Module *M) {
46807330f729Sjoerg   if (V.hasName() || isa<GlobalValue>(V) ||
46817330f729Sjoerg       (!isa<Constant>(V) && !isa<MetadataAsValue>(V))) {
46827330f729Sjoerg     WriteAsOperandInternal(O, &V, nullptr, Machine, M);
46837330f729Sjoerg     return true;
46847330f729Sjoerg   }
46857330f729Sjoerg   return false;
46867330f729Sjoerg }
46877330f729Sjoerg 
printAsOperandImpl(const Value & V,raw_ostream & O,bool PrintType,ModuleSlotTracker & MST)46887330f729Sjoerg static void printAsOperandImpl(const Value &V, raw_ostream &O, bool PrintType,
46897330f729Sjoerg                                ModuleSlotTracker &MST) {
46907330f729Sjoerg   TypePrinting TypePrinter(MST.getModule());
46917330f729Sjoerg   if (PrintType) {
46927330f729Sjoerg     TypePrinter.print(V.getType(), O);
46937330f729Sjoerg     O << ' ';
46947330f729Sjoerg   }
46957330f729Sjoerg 
46967330f729Sjoerg   WriteAsOperandInternal(O, &V, &TypePrinter, MST.getMachine(),
46977330f729Sjoerg                          MST.getModule());
46987330f729Sjoerg }
46997330f729Sjoerg 
printAsOperand(raw_ostream & O,bool PrintType,const Module * M) const47007330f729Sjoerg void Value::printAsOperand(raw_ostream &O, bool PrintType,
47017330f729Sjoerg                            const Module *M) const {
47027330f729Sjoerg   if (!M)
47037330f729Sjoerg     M = getModuleFromVal(this);
47047330f729Sjoerg 
47057330f729Sjoerg   if (!PrintType)
47067330f729Sjoerg     if (printWithoutType(*this, O, nullptr, M))
47077330f729Sjoerg       return;
47087330f729Sjoerg 
47097330f729Sjoerg   SlotTracker Machine(
47107330f729Sjoerg       M, /* ShouldInitializeAllMetadata */ isa<MetadataAsValue>(this));
47117330f729Sjoerg   ModuleSlotTracker MST(Machine, M);
47127330f729Sjoerg   printAsOperandImpl(*this, O, PrintType, MST);
47137330f729Sjoerg }
47147330f729Sjoerg 
printAsOperand(raw_ostream & O,bool PrintType,ModuleSlotTracker & MST) const47157330f729Sjoerg void Value::printAsOperand(raw_ostream &O, bool PrintType,
47167330f729Sjoerg                            ModuleSlotTracker &MST) const {
47177330f729Sjoerg   if (!PrintType)
47187330f729Sjoerg     if (printWithoutType(*this, O, MST.getMachine(), MST.getModule()))
47197330f729Sjoerg       return;
47207330f729Sjoerg 
47217330f729Sjoerg   printAsOperandImpl(*this, O, PrintType, MST);
47227330f729Sjoerg }
47237330f729Sjoerg 
printMetadataImpl(raw_ostream & ROS,const Metadata & MD,ModuleSlotTracker & MST,const Module * M,bool OnlyAsOperand)47247330f729Sjoerg static void printMetadataImpl(raw_ostream &ROS, const Metadata &MD,
47257330f729Sjoerg                               ModuleSlotTracker &MST, const Module *M,
47267330f729Sjoerg                               bool OnlyAsOperand) {
47277330f729Sjoerg   formatted_raw_ostream OS(ROS);
47287330f729Sjoerg 
47297330f729Sjoerg   TypePrinting TypePrinter(M);
47307330f729Sjoerg 
47317330f729Sjoerg   WriteAsOperandInternal(OS, &MD, &TypePrinter, MST.getMachine(), M,
47327330f729Sjoerg                          /* FromValue */ true);
47337330f729Sjoerg 
47347330f729Sjoerg   auto *N = dyn_cast<MDNode>(&MD);
4735*82d56013Sjoerg   if (OnlyAsOperand || !N || isa<DIExpression>(MD) || isa<DIArgList>(MD))
47367330f729Sjoerg     return;
47377330f729Sjoerg 
47387330f729Sjoerg   OS << " = ";
47397330f729Sjoerg   WriteMDNodeBodyInternal(OS, N, &TypePrinter, MST.getMachine(), M);
47407330f729Sjoerg }
47417330f729Sjoerg 
printAsOperand(raw_ostream & OS,const Module * M) const47427330f729Sjoerg void Metadata::printAsOperand(raw_ostream &OS, const Module *M) const {
47437330f729Sjoerg   ModuleSlotTracker MST(M, isa<MDNode>(this));
47447330f729Sjoerg   printMetadataImpl(OS, *this, MST, M, /* OnlyAsOperand */ true);
47457330f729Sjoerg }
47467330f729Sjoerg 
printAsOperand(raw_ostream & OS,ModuleSlotTracker & MST,const Module * M) const47477330f729Sjoerg void Metadata::printAsOperand(raw_ostream &OS, ModuleSlotTracker &MST,
47487330f729Sjoerg                               const Module *M) const {
47497330f729Sjoerg   printMetadataImpl(OS, *this, MST, M, /* OnlyAsOperand */ true);
47507330f729Sjoerg }
47517330f729Sjoerg 
print(raw_ostream & OS,const Module * M,bool) const47527330f729Sjoerg void Metadata::print(raw_ostream &OS, const Module *M,
47537330f729Sjoerg                      bool /*IsForDebug*/) const {
47547330f729Sjoerg   ModuleSlotTracker MST(M, isa<MDNode>(this));
47557330f729Sjoerg   printMetadataImpl(OS, *this, MST, M, /* OnlyAsOperand */ false);
47567330f729Sjoerg }
47577330f729Sjoerg 
print(raw_ostream & OS,ModuleSlotTracker & MST,const Module * M,bool) const47587330f729Sjoerg void Metadata::print(raw_ostream &OS, ModuleSlotTracker &MST,
47597330f729Sjoerg                      const Module *M, bool /*IsForDebug*/) const {
47607330f729Sjoerg   printMetadataImpl(OS, *this, MST, M, /* OnlyAsOperand */ false);
47617330f729Sjoerg }
47627330f729Sjoerg 
print(raw_ostream & ROS,bool IsForDebug) const47637330f729Sjoerg void ModuleSummaryIndex::print(raw_ostream &ROS, bool IsForDebug) const {
47647330f729Sjoerg   SlotTracker SlotTable(this);
47657330f729Sjoerg   formatted_raw_ostream OS(ROS);
47667330f729Sjoerg   AssemblyWriter W(OS, SlotTable, this, IsForDebug);
47677330f729Sjoerg   W.printModuleSummaryIndex();
47687330f729Sjoerg }
47697330f729Sjoerg 
47707330f729Sjoerg #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
47717330f729Sjoerg // Value::dump - allow easy printing of Values from the debugger.
47727330f729Sjoerg LLVM_DUMP_METHOD
dump() const47737330f729Sjoerg void Value::dump() const { print(dbgs(), /*IsForDebug=*/true); dbgs() << '\n'; }
47747330f729Sjoerg 
47757330f729Sjoerg // Type::dump - allow easy printing of Types from the debugger.
47767330f729Sjoerg LLVM_DUMP_METHOD
dump() const47777330f729Sjoerg void Type::dump() const { print(dbgs(), /*IsForDebug=*/true); dbgs() << '\n'; }
47787330f729Sjoerg 
47797330f729Sjoerg // Module::dump() - Allow printing of Modules from the debugger.
47807330f729Sjoerg LLVM_DUMP_METHOD
dump() const47817330f729Sjoerg void Module::dump() const {
47827330f729Sjoerg   print(dbgs(), nullptr,
47837330f729Sjoerg         /*ShouldPreserveUseListOrder=*/false, /*IsForDebug=*/true);
47847330f729Sjoerg }
47857330f729Sjoerg 
47867330f729Sjoerg // Allow printing of Comdats from the debugger.
47877330f729Sjoerg LLVM_DUMP_METHOD
dump() const47887330f729Sjoerg void Comdat::dump() const { print(dbgs(), /*IsForDebug=*/true); }
47897330f729Sjoerg 
47907330f729Sjoerg // NamedMDNode::dump() - Allow printing of NamedMDNodes from the debugger.
47917330f729Sjoerg LLVM_DUMP_METHOD
dump() const47927330f729Sjoerg void NamedMDNode::dump() const { print(dbgs(), /*IsForDebug=*/true); }
47937330f729Sjoerg 
47947330f729Sjoerg LLVM_DUMP_METHOD
dump() const47957330f729Sjoerg void Metadata::dump() const { dump(nullptr); }
47967330f729Sjoerg 
47977330f729Sjoerg LLVM_DUMP_METHOD
dump(const Module * M) const47987330f729Sjoerg void Metadata::dump(const Module *M) const {
47997330f729Sjoerg   print(dbgs(), M, /*IsForDebug=*/true);
48007330f729Sjoerg   dbgs() << '\n';
48017330f729Sjoerg }
48027330f729Sjoerg 
48037330f729Sjoerg // Allow printing of ModuleSummaryIndex from the debugger.
48047330f729Sjoerg LLVM_DUMP_METHOD
dump() const48057330f729Sjoerg void ModuleSummaryIndex::dump() const { print(dbgs(), /*IsForDebug=*/true); }
48067330f729Sjoerg #endif
4807