//===- AsmWriter.cpp - Printing LLVM as an assembly file ------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This library implements `print` family of functions in classes like
// Module, Function, Value, etc. In-memory representation of those classes is
// converted to IR strings.
//
// Note that these routines must be extremely tolerant of various errors in the
// LLVM code, because it can be used for debugging transformations.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/AssemblyAnnotationWriter.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Comdat.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalIFunc.h"
#include "llvm/IR/GlobalIndirectSymbol.h"
#include "llvm/IR/GlobalObject.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/IRPrintingPasses.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/ModuleSlotTracker.h"
#include "llvm/IR/ModuleSummaryIndex.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/Statepoint.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/TypeFinder.h"
#include "llvm/IR/Use.h"
#include "llvm/IR/UseListOrder.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
#include <cctype>
#include <cstddef>
#include <cstdint>
#include <iterator>
#include <memory>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

using namespace llvm;

// Make virtual table appear in this compilation unit.
AssemblyAnnotationWriter::~AssemblyAnnotationWriter() = default;

//===----------------------------------------------------------------------===//
// Helper Functions
//===----------------------------------------------------------------------===//

namespace {

struct OrderMap {
  DenseMap<const Value *, std::pair<unsigned, bool>> IDs;

  unsigned size() const { return IDs.size(); }
  std::pair<unsigned, bool> &operator[](const Value *V) { return IDs[V]; }

  std::pair<unsigned, bool> lookup(const Value *V) const {
    return IDs.lookup(V);
  }

  void index(const Value *V) {
    // Explicitly sequence get-size and insert-value operations to avoid UB.
    unsigned ID = IDs.size() + 1;
    IDs[V].first = ID;
  }
};

} // end anonymous namespace

static void orderValue(const Value *V, OrderMap &OM) {
  if (OM.lookup(V).first)
    return;

  if (const Constant *C = dyn_cast<Constant>(V))
    if (C->getNumOperands() && !isa<GlobalValue>(C))
      for (const Value *Op : C->operands())
        if (!isa<BasicBlock>(Op) && !isa<GlobalValue>(Op))
          orderValue(Op, OM);

  // Note: we cannot cache this lookup above, since inserting into the map
  // changes the map's size, and thus affects the other IDs.
  OM.index(V);
}

static OrderMap orderModule(const Module *M) {
  // This needs to match the order used by ValueEnumerator::ValueEnumerator()
  // and ValueEnumerator::incorporateFunction().
  OrderMap OM;

  for (const GlobalVariable &G : M->globals()) {
    if (G.hasInitializer())
      if (!isa<GlobalValue>(G.getInitializer()))
        orderValue(G.getInitializer(), OM);
    orderValue(&G, OM);
  }
  for (const GlobalAlias &A : M->aliases()) {
    if (!isa<GlobalValue>(A.getAliasee()))
      orderValue(A.getAliasee(), OM);
    orderValue(&A, OM);
  }
  for (const GlobalIFunc &I : M->ifuncs()) {
    if (!isa<GlobalValue>(I.getResolver()))
      orderValue(I.getResolver(), OM);
    orderValue(&I, OM);
  }
  for (const Function &F : *M) {
    for (const Use &U : F.operands())
      if (!isa<GlobalValue>(U.get()))
        orderValue(U.get(), OM);

    orderValue(&F, OM);

    if (F.isDeclaration())
      continue;

    for (const Argument &A : F.args())
      orderValue(&A, OM);
    for (const BasicBlock &BB : F) {
      orderValue(&BB, OM);
      for (const Instruction &I : BB) {
        for (const Value *Op : I.operands())
          if ((isa<Constant>(*Op) && !isa<GlobalValue>(*Op)) ||
              isa<InlineAsm>(*Op))
            orderValue(Op, OM);
        orderValue(&I, OM);
      }
    }
  }
  return OM;
}

static void predictValueUseListOrderImpl(const Value *V, const Function *F,
                                         unsigned ID, const OrderMap &OM,
                                         UseListOrderStack &Stack) {
  // Predict use-list order for this one.
  using Entry = std::pair<const Use *, unsigned>;
  SmallVector<Entry, 64> List;
  for (const Use &U : V->uses())
    // Check if this user will be serialized.
    if (OM.lookup(U.getUser()).first)
      List.push_back(std::make_pair(&U, List.size()));

  if (List.size() < 2)
    // We may have lost some users.
    return;

  bool GetsReversed =
      !isa<GlobalVariable>(V) && !isa<Function>(V) && !isa<BasicBlock>(V);
  if (auto *BA = dyn_cast<BlockAddress>(V))
    ID = OM.lookup(BA->getBasicBlock()).first;
  llvm::sort(List, [&](const Entry &L, const Entry &R) {
    const Use *LU = L.first;
    const Use *RU = R.first;
    if (LU == RU)
      return false;

    auto LID = OM.lookup(LU->getUser()).first;
    auto RID = OM.lookup(RU->getUser()).first;

    // If ID is 4, then expect: 7 6 5 1 2 3.
    if (LID < RID) {
      if (GetsReversed)
        if (RID <= ID)
          return true;
      return false;
    }
    if (RID < LID) {
      if (GetsReversed)
        if (LID <= ID)
          return false;
      return true;
    }

    // LID and RID are equal, so we have different operands of the same user.
    // Assume operands are added in order for all instructions.
    if (GetsReversed)
      if (LID <= ID)
        return LU->getOperandNo() < RU->getOperandNo();
    return LU->getOperandNo() > RU->getOperandNo();
  });

  if (llvm::is_sorted(List, [](const Entry &L, const Entry &R) {
        return L.second < R.second;
      }))
    // Order is already correct.
    return;

  // Store the shuffle.
  Stack.emplace_back(V, F, List.size());
  assert(List.size() == Stack.back().Shuffle.size() && "Wrong size");
  for (size_t I = 0, E = List.size(); I != E; ++I)
    Stack.back().Shuffle[I] = List[I].second;
}

static void predictValueUseListOrder(const Value *V, const Function *F,
                                     OrderMap &OM, UseListOrderStack &Stack) {
  auto &IDPair = OM[V];
  assert(IDPair.first && "Unmapped value");
  if (IDPair.second)
    // Already predicted.
    return;

  // Do the actual prediction.
  IDPair.second = true;
  if (!V->use_empty() && std::next(V->use_begin()) != V->use_end())
    predictValueUseListOrderImpl(V, F, IDPair.first, OM, Stack);

  // Recursive descent into constants.
  if (const Constant *C = dyn_cast<Constant>(V))
    if (C->getNumOperands()) // Visit GlobalValues.
      for (const Value *Op : C->operands())
        if (isa<Constant>(Op)) // Visit GlobalValues.
          predictValueUseListOrder(Op, F, OM, Stack);
}

static UseListOrderStack predictUseListOrder(const Module *M) {
  OrderMap OM = orderModule(M);

  // Use-list orders need to be serialized after all the users have been added
  // to a value, or else the shuffles will be incomplete.  Store them per
  // function in a stack.
  //
  // Aside from function order, the order of values doesn't matter much here.
  UseListOrderStack Stack;

  // We want to visit the functions backward now so we can list function-local
  // constants in the last Function they're used in.  Module-level constants
  // have already been visited above.
  for (const Function &F : make_range(M->rbegin(), M->rend())) {
    if (F.isDeclaration())
      continue;
    for (const BasicBlock &BB : F)
      predictValueUseListOrder(&BB, &F, OM, Stack);
    for (const Argument &A : F.args())
      predictValueUseListOrder(&A, &F, OM, Stack);
    for (const BasicBlock &BB : F)
      for (const Instruction &I : BB)
        for (const Value *Op : I.operands())
          if (isa<Constant>(*Op) || isa<InlineAsm>(*Op)) // Visit GlobalValues.
            predictValueUseListOrder(Op, &F, OM, Stack);
    for (const BasicBlock &BB : F)
      for (const Instruction &I : BB)
        predictValueUseListOrder(&I, &F, OM, Stack);
  }

  // Visit globals last.
  for (const GlobalVariable &G : M->globals())
    predictValueUseListOrder(&G, nullptr, OM, Stack);
  for (const Function &F : *M)
    predictValueUseListOrder(&F, nullptr, OM, Stack);
  for (const GlobalAlias &A : M->aliases())
    predictValueUseListOrder(&A, nullptr, OM, Stack);
  for (const GlobalIFunc &I : M->ifuncs())
    predictValueUseListOrder(&I, nullptr, OM, Stack);
  for (const GlobalVariable &G : M->globals())
    if (G.hasInitializer())
      predictValueUseListOrder(G.getInitializer(), nullptr, OM, Stack);
  for (const GlobalAlias &A : M->aliases())
    predictValueUseListOrder(A.getAliasee(), nullptr, OM, Stack);
  for (const GlobalIFunc &I : M->ifuncs())
    predictValueUseListOrder(I.getResolver(), nullptr, OM, Stack);
  for (const Function &F : *M)
    for (const Use &U : F.operands())
      predictValueUseListOrder(U.get(), nullptr, OM, Stack);

  return Stack;
}

static const Module *getModuleFromVal(const Value *V) {
  if (const Argument *MA = dyn_cast<Argument>(V))
    return MA->getParent() ? MA->getParent()->getParent() : nullptr;

  if (const BasicBlock *BB = dyn_cast<BasicBlock>(V))
    return BB->getParent() ? BB->getParent()->getParent() : nullptr;

  if (const Instruction *I = dyn_cast<Instruction>(V)) {
    const Function *M = I->getParent() ? I->getParent()->getParent() : nullptr;
    return M ? M->getParent() : nullptr;
  }

  if (const GlobalValue *GV = dyn_cast<GlobalValue>(V))
    return GV->getParent();

  if (const auto *MAV = dyn_cast<MetadataAsValue>(V)) {
    for (const User *U : MAV->users())
      if (isa<Instruction>(U))
        if (const Module *M = getModuleFromVal(U))
          return M;
    return nullptr;
  }

  return nullptr;
}

static void PrintCallingConv(unsigned cc, raw_ostream &Out) {
  switch (cc) {
  default:                         Out << "cc" << cc; break;
  case CallingConv::Fast:          Out << "fastcc"; break;
  case CallingConv::Cold:          Out << "coldcc"; break;
  case CallingConv::WebKit_JS:     Out << "webkit_jscc"; break;
  case CallingConv::AnyReg:        Out << "anyregcc"; break;
  case CallingConv::PreserveMost:  Out << "preserve_mostcc"; break;
  case CallingConv::PreserveAll:   Out << "preserve_allcc"; break;
  case CallingConv::CXX_FAST_TLS:  Out << "cxx_fast_tlscc"; break;
  case CallingConv::GHC:           Out << "ghccc"; break;
  case CallingConv::Tail:          Out << "tailcc"; break;
  case CallingConv::CFGuard_Check: Out << "cfguard_checkcc"; break;
  case CallingConv::X86_StdCall:   Out << "x86_stdcallcc"; break;
  case CallingConv::X86_FastCall:  Out << "x86_fastcallcc"; break;
  case CallingConv::X86_ThisCall:  Out << "x86_thiscallcc"; break;
  case CallingConv::X86_RegCall:   Out << "x86_regcallcc"; break;
  case CallingConv::X86_VectorCall:Out << "x86_vectorcallcc"; break;
  case CallingConv::Intel_OCL_BI:  Out << "intel_ocl_bicc"; break;
  case CallingConv::ARM_APCS:      Out << "arm_apcscc"; break;
  case CallingConv::ARM_AAPCS:     Out << "arm_aapcscc"; break;
  case CallingConv::ARM_AAPCS_VFP: Out << "arm_aapcs_vfpcc"; break;
  case CallingConv::AArch64_VectorCall: Out << "aarch64_vector_pcs"; break;
  case CallingConv::AArch64_SVE_VectorCall:
    Out << "aarch64_sve_vector_pcs";
    break;
  case CallingConv::MSP430_INTR:   Out << "msp430_intrcc"; break;
  case CallingConv::AVR_INTR:      Out << "avr_intrcc "; break;
  case CallingConv::AVR_SIGNAL:    Out << "avr_signalcc "; break;
  case CallingConv::PTX_Kernel:    Out << "ptx_kernel"; break;
  case CallingConv::PTX_Device:    Out << "ptx_device"; break;
  case CallingConv::X86_64_SysV:   Out << "x86_64_sysvcc"; break;
  case CallingConv::Win64:         Out << "win64cc"; break;
  case CallingConv::SPIR_FUNC:     Out << "spir_func"; break;
  case CallingConv::SPIR_KERNEL:   Out << "spir_kernel"; break;
  case CallingConv::Swift:         Out << "swiftcc"; break;
  case CallingConv::X86_INTR:      Out << "x86_intrcc"; break;
  case CallingConv::HHVM:          Out << "hhvmcc"; break;
  case CallingConv::HHVM_C:        Out << "hhvm_ccc"; break;
  case CallingConv::AMDGPU_VS:     Out << "amdgpu_vs"; break;
  case CallingConv::AMDGPU_LS:     Out << "amdgpu_ls"; break;
  case CallingConv::AMDGPU_HS:     Out << "amdgpu_hs"; break;
  case CallingConv::AMDGPU_ES:     Out << "amdgpu_es"; break;
  case CallingConv::AMDGPU_GS:     Out << "amdgpu_gs"; break;
  case CallingConv::AMDGPU_PS:     Out << "amdgpu_ps"; break;
  case CallingConv::AMDGPU_CS:     Out << "amdgpu_cs"; break;
  case CallingConv::AMDGPU_KERNEL: Out << "amdgpu_kernel"; break;
  }
}

enum PrefixType {
  GlobalPrefix,
  ComdatPrefix,
  LabelPrefix,
  LocalPrefix,
  NoPrefix
};

void llvm::printLLVMNameWithoutPrefix(raw_ostream &OS, StringRef Name) {
  assert(!Name.empty() && "Cannot get empty name!");

  // Scan the name to see if it needs quotes first.
  bool NeedsQuotes = isdigit(static_cast<unsigned char>(Name[0]));
  if (!NeedsQuotes) {
    for (unsigned i = 0, e = Name.size(); i != e; ++i) {
      // By making this unsigned, the value passed in to isalnum will always be
      // in the range 0-255.  This is important when building with MSVC because
      // its implementation will assert.  This situation can arise when dealing
      // with UTF-8 multibyte characters.
      unsigned char C = Name[i];
      if (!isalnum(static_cast<unsigned char>(C)) && C != '-' && C != '.' &&
          C != '_') {
        NeedsQuotes = true;
        break;
      }
    }
  }

  // If we didn't need any quotes, just write out the name in one blast.
  if (!NeedsQuotes) {
    OS << Name;
    return;
  }

  // Okay, we need quotes.  Output the quotes and escape any scary characters as
  // needed.
  OS << '"';
  printEscapedString(Name, OS);
  OS << '"';
}

/// Turn the specified name into an 'LLVM name', which is either prefixed with %
/// (if the string only contains simple characters) or is surrounded with ""'s
/// (if it has special chars in it). Print it out.
static void PrintLLVMName(raw_ostream &OS, StringRef Name, PrefixType Prefix) {
  switch (Prefix) {
  case NoPrefix:
    break;
  case GlobalPrefix:
    OS << '@';
    break;
  case ComdatPrefix:
    OS << '$';
    break;
  case LabelPrefix:
    break;
  case LocalPrefix:
    OS << '%';
    break;
  }
  printLLVMNameWithoutPrefix(OS, Name);
}

/// Turn the specified name into an 'LLVM name', which is either prefixed with %
/// (if the string only contains simple characters) or is surrounded with ""'s
/// (if it has special chars in it). Print it out.
static void PrintLLVMName(raw_ostream &OS, const Value *V) {
  PrintLLVMName(OS, V->getName(),
                isa<GlobalValue>(V) ? GlobalPrefix : LocalPrefix);
}

static void PrintShuffleMask(raw_ostream &Out, Type *Ty, ArrayRef<int> Mask) {
  Out << ", <";
  if (isa<ScalableVectorType>(Ty))
    Out << "vscale x ";
  Out << Mask.size() << " x i32> ";
  bool FirstElt = true;
  if (all_of(Mask, [](int Elt) { return Elt == 0; })) {
    Out << "zeroinitializer";
  } else if (all_of(Mask, [](int Elt) { return Elt == UndefMaskElem; })) {
    Out << "undef";
  } else {
    Out << "<";
    for (int Elt : Mask) {
      if (FirstElt)
        FirstElt = false;
      else
        Out << ", ";
      Out << "i32 ";
      if (Elt == UndefMaskElem)
        Out << "undef";
      else
        Out << Elt;
    }
    Out << ">";
  }
}

namespace {

class TypePrinting {
public:
  TypePrinting(const Module *M = nullptr) : DeferredM(M) {}

  TypePrinting(const TypePrinting &) = delete;
  TypePrinting &operator=(const TypePrinting &) = delete;

  /// The named types that are used by the current module.
  TypeFinder &getNamedTypes();

  /// The numbered types, number to type mapping.
  std::vector<StructType *> &getNumberedTypes();

  bool empty();

  void print(Type *Ty, raw_ostream &OS);

  void printStructBody(StructType *Ty, raw_ostream &OS);

private:
  void incorporateTypes();

  /// A module to process lazily when needed. Set to nullptr as soon as used.
  const Module *DeferredM;

  TypeFinder NamedTypes;

  // The numbered types, along with their value.
  DenseMap<StructType *, unsigned> Type2Number;

  std::vector<StructType *> NumberedTypes;
};

} // end anonymous namespace

TypeFinder &TypePrinting::getNamedTypes() {
  incorporateTypes();
  return NamedTypes;
}

std::vector<StructType *> &TypePrinting::getNumberedTypes() {
  incorporateTypes();

  // We know all the numbers that each type is used and we know that it is a
  // dense assignment. Convert the map to an index table, if it's not done
  // already (judging from the sizes):
  if (NumberedTypes.size() == Type2Number.size())
    return NumberedTypes;

  NumberedTypes.resize(Type2Number.size());
  for (const auto &P : Type2Number) {
    assert(P.second < NumberedTypes.size() && "Didn't get a dense numbering?");
    assert(!NumberedTypes[P.second] && "Didn't get a unique numbering?");
    NumberedTypes[P.second] = P.first;
  }
  return NumberedTypes;
}

bool TypePrinting::empty() {
  incorporateTypes();
  return NamedTypes.empty() && Type2Number.empty();
}

void TypePrinting::incorporateTypes() {
  if (!DeferredM)
    return;

  NamedTypes.run(*DeferredM, false);
  DeferredM = nullptr;

  // The list of struct types we got back includes all the struct types, split
  // the unnamed ones out to a numbering and remove the anonymous structs.
  unsigned NextNumber = 0;

  std::vector<StructType*>::iterator NextToUse = NamedTypes.begin(), I, E;
  for (I = NamedTypes.begin(), E = NamedTypes.end(); I != E; ++I) {
    StructType *STy = *I;

    // Ignore anonymous types.
    if (STy->isLiteral())
      continue;

    if (STy->getName().empty())
      Type2Number[STy] = NextNumber++;
    else
      *NextToUse++ = STy;
  }

  NamedTypes.erase(NextToUse, NamedTypes.end());
}

/// Write the specified type to the specified raw_ostream, making use of type
/// names or up references to shorten the type name where possible.
void TypePrinting::print(Type *Ty, raw_ostream &OS) {
  switch (Ty->getTypeID()) {
  case Type::VoidTyID:      OS << "void"; return;
  case Type::HalfTyID:      OS << "half"; return;
  case Type::BFloatTyID:    OS << "bfloat"; return;
  case Type::FloatTyID:     OS << "float"; return;
  case Type::DoubleTyID:    OS << "double"; return;
  case Type::X86_FP80TyID:  OS << "x86_fp80"; return;
  case Type::FP128TyID:     OS << "fp128"; return;
  case Type::PPC_FP128TyID: OS << "ppc_fp128"; return;
  case Type::LabelTyID:     OS << "label"; return;
  case Type::MetadataTyID:  OS << "metadata"; return;
  case Type::X86_MMXTyID:   OS << "x86_mmx"; return;
  case Type::TokenTyID:     OS << "token"; return;
  case Type::IntegerTyID:
    OS << 'i' << cast<IntegerType>(Ty)->getBitWidth();
    return;

  case Type::FunctionTyID: {
    FunctionType *FTy = cast<FunctionType>(Ty);
    print(FTy->getReturnType(), OS);
    OS << " (";
    for (FunctionType::param_iterator I = FTy->param_begin(),
         E = FTy->param_end(); I != E; ++I) {
      if (I != FTy->param_begin())
        OS << ", ";
      print(*I, OS);
    }
    if (FTy->isVarArg()) {
      if (FTy->getNumParams()) OS << ", ";
      OS << "...";
    }
    OS << ')';
    return;
  }
  case Type::StructTyID: {
    StructType *STy = cast<StructType>(Ty);

    if (STy->isLiteral())
      return printStructBody(STy, OS);

    if (!STy->getName().empty())
      return PrintLLVMName(OS, STy->getName(), LocalPrefix);

    incorporateTypes();
    const auto I = Type2Number.find(STy);
    if (I != Type2Number.end())
      OS << '%' << I->second;
    else  // Not enumerated, print the hex address.
      OS << "%\"type " << STy << '\"';
    return;
  }
  case Type::PointerTyID: {
    PointerType *PTy = cast<PointerType>(Ty);
    print(PTy->getElementType(), OS);
    if (unsigned AddressSpace = PTy->getAddressSpace())
      OS << " addrspace(" << AddressSpace << ')';
    OS << '*';
    return;
  }
  case Type::ArrayTyID: {
    ArrayType *ATy = cast<ArrayType>(Ty);
    OS << '[' << ATy->getNumElements() << " x ";
    print(ATy->getElementType(), OS);
    OS << ']';
    return;
  }
  case Type::FixedVectorTyID:
  case Type::ScalableVectorTyID: {
    VectorType *PTy = cast<VectorType>(Ty);
    ElementCount EC = PTy->getElementCount();
    OS << "<";
    if (EC.Scalable)
      OS << "vscale x ";
    OS << EC.Min << " x ";
    print(PTy->getElementType(), OS);
    OS << '>';
    return;
  }
  }
  llvm_unreachable("Invalid TypeID");
}

void TypePrinting::printStructBody(StructType *STy, raw_ostream &OS) {
  if (STy->isOpaque()) {
    OS << "opaque";
    return;
  }

  if (STy->isPacked())
    OS << '<';

  if (STy->getNumElements() == 0) {
    OS << "{}";
  } else {
    StructType::element_iterator I = STy->element_begin();
    OS << "{ ";
    print(*I++, OS);
    for (StructType::element_iterator E = STy->element_end(); I != E; ++I) {
      OS << ", ";
      print(*I, OS);
    }

    OS << " }";
  }
  if (STy->isPacked())
    OS << '>';
}

namespace llvm {

//===----------------------------------------------------------------------===//
// SlotTracker Class: Enumerate slot numbers for unnamed values
//===----------------------------------------------------------------------===//
/// This class provides computation of slot numbers for LLVM Assembly writing.
///
class SlotTracker {
public:
  /// ValueMap - A mapping of Values to slot numbers.
  using ValueMap = DenseMap<const Value *, unsigned>;

private:
  /// TheModule - The module for which we are holding slot numbers.
  const Module* TheModule;

  /// TheFunction - The function for which we are holding slot numbers.
  const Function* TheFunction = nullptr;
  bool FunctionProcessed = false;
  bool ShouldInitializeAllMetadata;

  /// The summary index for which we are holding slot numbers.
  const ModuleSummaryIndex *TheIndex = nullptr;

  /// mMap - The slot map for the module level data.
  ValueMap mMap;
  unsigned mNext = 0;

  /// fMap - The slot map for the function level data.
  ValueMap fMap;
  unsigned fNext = 0;

  /// mdnMap - Map for MDNodes.
  DenseMap<const MDNode*, unsigned> mdnMap;
  unsigned mdnNext = 0;

  /// asMap - The slot map for attribute sets.
  DenseMap<AttributeSet, unsigned> asMap;
  unsigned asNext = 0;

  /// ModulePathMap - The slot map for Module paths used in the summary index.
  StringMap<unsigned> ModulePathMap;
  unsigned ModulePathNext = 0;

  /// GUIDMap - The slot map for GUIDs used in the summary index.
  DenseMap<GlobalValue::GUID, unsigned> GUIDMap;
  unsigned GUIDNext = 0;

  /// TypeIdMap - The slot map for type ids used in the summary index.
  StringMap<unsigned> TypeIdMap;
  unsigned TypeIdNext = 0;

public:
  /// Construct from a module.
  ///
  /// If \c ShouldInitializeAllMetadata, initializes all metadata in all
  /// functions, giving correct numbering for metadata referenced only from
  /// within a function (even if no functions have been initialized).
  explicit SlotTracker(const Module *M,
                       bool ShouldInitializeAllMetadata = false);

  /// Construct from a function, starting out in incorp state.
  ///
  /// If \c ShouldInitializeAllMetadata, initializes all metadata in all
  /// functions, giving correct numbering for metadata referenced only from
  /// within a function (even if no functions have been initialized).
  explicit SlotTracker(const Function *F,
                       bool ShouldInitializeAllMetadata = false);

  /// Construct from a module summary index.
  explicit SlotTracker(const ModuleSummaryIndex *Index);

  SlotTracker(const SlotTracker &) = delete;
  SlotTracker &operator=(const SlotTracker &) = delete;

  /// Return the slot number of the specified value in it's type
  /// plane.  If something is not in the SlotTracker, return -1.
  int getLocalSlot(const Value *V);
  int getGlobalSlot(const GlobalValue *V);
  int getMetadataSlot(const MDNode *N);
  int getAttributeGroupSlot(AttributeSet AS);
  int getModulePathSlot(StringRef Path);
  int getGUIDSlot(GlobalValue::GUID GUID);
  int getTypeIdSlot(StringRef Id);

  /// If you'd like to deal with a function instead of just a module, use
  /// this method to get its data into the SlotTracker.
  void incorporateFunction(const Function *F) {
    TheFunction = F;
    FunctionProcessed = false;
  }

  const Function *getFunction() const { return TheFunction; }

  /// After calling incorporateFunction, use this method to remove the
  /// most recently incorporated function from the SlotTracker. This
  /// will reset the state of the machine back to just the module contents.
  void purgeFunction();

  /// MDNode map iterators.
  using mdn_iterator = DenseMap<const MDNode*, unsigned>::iterator;

  mdn_iterator mdn_begin() { return mdnMap.begin(); }
  mdn_iterator mdn_end() { return mdnMap.end(); }
  unsigned mdn_size() const { return mdnMap.size(); }
  bool mdn_empty() const { return mdnMap.empty(); }

  /// AttributeSet map iterators.
  using as_iterator = DenseMap<AttributeSet, unsigned>::iterator;

  as_iterator as_begin()   { return asMap.begin(); }
  as_iterator as_end()     { return asMap.end(); }
  unsigned as_size() const { return asMap.size(); }
  bool as_empty() const    { return asMap.empty(); }

  /// GUID map iterators.
  using guid_iterator = DenseMap<GlobalValue::GUID, unsigned>::iterator;

  /// These functions do the actual initialization.
  inline void initializeIfNeeded();
  int initializeIndexIfNeeded();

  // Implementation Details
private:
  /// CreateModuleSlot - Insert the specified GlobalValue* into the slot table.
  void CreateModuleSlot(const GlobalValue *V);

  /// CreateMetadataSlot - Insert the specified MDNode* into the slot table.
  void CreateMetadataSlot(const MDNode *N);

  /// CreateFunctionSlot - Insert the specified Value* into the slot table.
  void CreateFunctionSlot(const Value *V);

  /// Insert the specified AttributeSet into the slot table.
  void CreateAttributeSetSlot(AttributeSet AS);

  inline void CreateModulePathSlot(StringRef Path);
  void CreateGUIDSlot(GlobalValue::GUID GUID);
  void CreateTypeIdSlot(StringRef Id);

  /// Add all of the module level global variables (and their initializers)
  /// and function declarations, but not the contents of those functions.
  void processModule();
  // Returns number of allocated slots
  int processIndex();

  /// Add all of the functions arguments, basic blocks, and instructions.
  void processFunction();

  /// Add the metadata directly attached to a GlobalObject.
  void processGlobalObjectMetadata(const GlobalObject &GO);

  /// Add all of the metadata from a function.
  void processFunctionMetadata(const Function &F);

  /// Add all of the metadata from an instruction.
  void processInstructionMetadata(const Instruction &I);
};

} // end namespace llvm

ModuleSlotTracker::ModuleSlotTracker(SlotTracker &Machine, const Module *M,
                                     const Function *F)
    : M(M), F(F), Machine(&Machine) {}

ModuleSlotTracker::ModuleSlotTracker(const Module *M,
                                     bool ShouldInitializeAllMetadata)
    : ShouldCreateStorage(M),
      ShouldInitializeAllMetadata(ShouldInitializeAllMetadata), M(M) {}

ModuleSlotTracker::~ModuleSlotTracker() = default;

SlotTracker *ModuleSlotTracker::getMachine() {
  if (!ShouldCreateStorage)
    return Machine;

  ShouldCreateStorage = false;
  MachineStorage =
      std::make_unique<SlotTracker>(M, ShouldInitializeAllMetadata);
  Machine = MachineStorage.get();
  return Machine;
}

void ModuleSlotTracker::incorporateFunction(const Function &F) {
  // Using getMachine() may lazily create the slot tracker.
  if (!getMachine())
    return;

  // Nothing to do if this is the right function already.
  if (this->F == &F)
    return;
  if (this->F)
    Machine->purgeFunction();
  Machine->incorporateFunction(&F);
  this->F = &F;
}

int ModuleSlotTracker::getLocalSlot(const Value *V) {
  assert(F && "No function incorporated");
  return Machine->getLocalSlot(V);
}

static SlotTracker *createSlotTracker(const Value *V) {
  if (const Argument *FA = dyn_cast<Argument>(V))
    return new SlotTracker(FA->getParent());

  if (const Instruction *I = dyn_cast<Instruction>(V))
    if (I->getParent())
      return new SlotTracker(I->getParent()->getParent());

  if (const BasicBlock *BB = dyn_cast<BasicBlock>(V))
    return new SlotTracker(BB->getParent());

  if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V))
    return new SlotTracker(GV->getParent());

  if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(V))
    return new SlotTracker(GA->getParent());

  if (const GlobalIFunc *GIF = dyn_cast<GlobalIFunc>(V))
    return new SlotTracker(GIF->getParent());

  if (const Function *Func = dyn_cast<Function>(V))
    return new SlotTracker(Func);

  return nullptr;
}

#if 0
#define ST_DEBUG(X) dbgs() << X
#else
#define ST_DEBUG(X)
#endif

// Module level constructor. Causes the contents of the Module (sans functions)
// to be added to the slot table.
SlotTracker::SlotTracker(const Module *M, bool ShouldInitializeAllMetadata)
    : TheModule(M), ShouldInitializeAllMetadata(ShouldInitializeAllMetadata) {}

// Function level constructor. Causes the contents of the Module and the one
// function provided to be added to the slot table.
SlotTracker::SlotTracker(const Function *F, bool ShouldInitializeAllMetadata)
    : TheModule(F ? F->getParent() : nullptr), TheFunction(F),
      ShouldInitializeAllMetadata(ShouldInitializeAllMetadata) {}

SlotTracker::SlotTracker(const ModuleSummaryIndex *Index)
    : TheModule(nullptr), ShouldInitializeAllMetadata(false), TheIndex(Index) {}

inline void SlotTracker::initializeIfNeeded() {
  if (TheModule) {
    processModule();
    TheModule = nullptr; ///< Prevent re-processing next time we're called.
  }

  if (TheFunction && !FunctionProcessed)
    processFunction();
}

int SlotTracker::initializeIndexIfNeeded() {
  if (!TheIndex)
    return 0;
  int NumSlots = processIndex();
  TheIndex = nullptr; ///< Prevent re-processing next time we're called.
  return NumSlots;
}

// Iterate through all the global variables, functions, and global
// variable initializers and create slots for them.
void SlotTracker::processModule() {
  ST_DEBUG("begin processModule!\n");

  // Add all of the unnamed global variables to the value table.
  for (const GlobalVariable &Var : TheModule->globals()) {
    if (!Var.hasName())
      CreateModuleSlot(&Var);
    processGlobalObjectMetadata(Var);
    auto Attrs = Var.getAttributes();
    if (Attrs.hasAttributes())
      CreateAttributeSetSlot(Attrs);
  }

  for (const GlobalAlias &A : TheModule->aliases()) {
    if (!A.hasName())
      CreateModuleSlot(&A);
  }

  for (const GlobalIFunc &I : TheModule->ifuncs()) {
    if (!I.hasName())
      CreateModuleSlot(&I);
  }

  // Add metadata used by named metadata.
  for (const NamedMDNode &NMD : TheModule->named_metadata()) {
    for (unsigned i = 0, e = NMD.getNumOperands(); i != e; ++i)
      CreateMetadataSlot(NMD.getOperand(i));
  }

  for (const Function &F : *TheModule) {
    if (!F.hasName())
      // Add all the unnamed functions to the table.
      CreateModuleSlot(&F);

    if (ShouldInitializeAllMetadata)
      processFunctionMetadata(F);

    // Add all the function attributes to the table.
    // FIXME: Add attributes of other objects?
    AttributeSet FnAttrs = F.getAttributes().getFnAttributes();
    if (FnAttrs.hasAttributes())
      CreateAttributeSetSlot(FnAttrs);
  }

  ST_DEBUG("end processModule!\n");
}

// Process the arguments, basic blocks, and instructions  of a function.
void SlotTracker::processFunction() {
  ST_DEBUG("begin processFunction!\n");
  fNext = 0;

  // Process function metadata if it wasn't hit at the module-level.
  if (!ShouldInitializeAllMetadata)
    processFunctionMetadata(*TheFunction);

  // Add all the function arguments with no names.
  for(Function::const_arg_iterator AI = TheFunction->arg_begin(),
      AE = TheFunction->arg_end(); AI != AE; ++AI)
    if (!AI->hasName())
      CreateFunctionSlot(&*AI);

  ST_DEBUG("Inserting Instructions:\n");

  // Add all of the basic blocks and instructions with no names.
  for (auto &BB : *TheFunction) {
    if (!BB.hasName())
      CreateFunctionSlot(&BB);

    for (auto &I : BB) {
      if (!I.getType()->isVoidTy() && !I.hasName())
        CreateFunctionSlot(&I);

      // We allow direct calls to any llvm.foo function here, because the
      // target may not be linked into the optimizer.
      if (const auto *Call = dyn_cast<CallBase>(&I)) {
        // Add all the call attributes to the table.
        AttributeSet Attrs = Call->getAttributes().getFnAttributes();
        if (Attrs.hasAttributes())
          CreateAttributeSetSlot(Attrs);
      }
    }
  }

  FunctionProcessed = true;

  ST_DEBUG("end processFunction!\n");
}

// Iterate through all the GUID in the index and create slots for them.
int SlotTracker::processIndex() {
  ST_DEBUG("begin processIndex!\n");
  assert(TheIndex);

  // The first block of slots are just the module ids, which start at 0 and are
  // assigned consecutively. Since the StringMap iteration order isn't
  // guaranteed, use a std::map to order by module ID before assigning slots.
  std::map<uint64_t, StringRef> ModuleIdToPathMap;
  for (auto &ModPath : TheIndex->modulePaths())
    ModuleIdToPathMap[ModPath.second.first] = ModPath.first();
  for (auto &ModPair : ModuleIdToPathMap)
    CreateModulePathSlot(ModPair.second);

  // Start numbering the GUIDs after the module ids.
  GUIDNext = ModulePathNext;

  for (auto &GlobalList : *TheIndex)
    CreateGUIDSlot(GlobalList.first);

  for (auto &TId : TheIndex->typeIdCompatibleVtableMap())
    CreateGUIDSlot(GlobalValue::getGUID(TId.first));

  // Start numbering the TypeIds after the GUIDs.
  TypeIdNext = GUIDNext;
  for (auto TidIter = TheIndex->typeIds().begin();
       TidIter != TheIndex->typeIds().end(); TidIter++)
    CreateTypeIdSlot(TidIter->second.first);

  ST_DEBUG("end processIndex!\n");
  return TypeIdNext;
}

void SlotTracker::processGlobalObjectMetadata(const GlobalObject &GO) {
  SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
  GO.getAllMetadata(MDs);
  for (auto &MD : MDs)
    CreateMetadataSlot(MD.second);
}

void SlotTracker::processFunctionMetadata(const Function &F) {
  processGlobalObjectMetadata(F);
  for (auto &BB : F) {
    for (auto &I : BB)
      processInstructionMetadata(I);
  }
}

void SlotTracker::processInstructionMetadata(const Instruction &I) {
  // Process metadata used directly by intrinsics.
  if (const CallInst *CI = dyn_cast<CallInst>(&I))
    if (Function *F = CI->getCalledFunction())
      if (F->isIntrinsic())
        for (auto &Op : I.operands())
          if (auto *V = dyn_cast_or_null<MetadataAsValue>(Op))
            if (MDNode *N = dyn_cast<MDNode>(V->getMetadata()))
              CreateMetadataSlot(N);

  // Process metadata attached to this instruction.
  SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
  I.getAllMetadata(MDs);
  for (auto &MD : MDs)
    CreateMetadataSlot(MD.second);
}

/// Clean up after incorporating a function. This is the only way to get out of
/// the function incorporation state that affects get*Slot/Create*Slot. Function
/// incorporation state is indicated by TheFunction != 0.
void SlotTracker::purgeFunction() {
  ST_DEBUG("begin purgeFunction!\n");
  fMap.clear(); // Simply discard the function level map
  TheFunction = nullptr;
  FunctionProcessed = false;
  ST_DEBUG("end purgeFunction!\n");
}

/// getGlobalSlot - Get the slot number of a global value.
int SlotTracker::getGlobalSlot(const GlobalValue *V) {
  // Check for uninitialized state and do lazy initialization.
  initializeIfNeeded();

  // Find the value in the module map
  ValueMap::iterator MI = mMap.find(V);
  return MI == mMap.end() ? -1 : (int)MI->second;
}

/// getMetadataSlot - Get the slot number of a MDNode.
int SlotTracker::getMetadataSlot(const MDNode *N) {
  // Check for uninitialized state and do lazy initialization.
  initializeIfNeeded();

  // Find the MDNode in the module map
  mdn_iterator MI = mdnMap.find(N);
  return MI == mdnMap.end() ? -1 : (int)MI->second;
}

/// getLocalSlot - Get the slot number for a value that is local to a function.
int SlotTracker::getLocalSlot(const Value *V) {
  assert(!isa<Constant>(V) && "Can't get a constant or global slot with this!");

  // Check for uninitialized state and do lazy initialization.
  initializeIfNeeded();

  ValueMap::iterator FI = fMap.find(V);
  return FI == fMap.end() ? -1 : (int)FI->second;
}

int SlotTracker::getAttributeGroupSlot(AttributeSet AS) {
  // Check for uninitialized state and do lazy initialization.
  initializeIfNeeded();

  // Find the AttributeSet in the module map.
  as_iterator AI = asMap.find(AS);
  return AI == asMap.end() ? -1 : (int)AI->second;
}

int SlotTracker::getModulePathSlot(StringRef Path) {
  // Check for uninitialized state and do lazy initialization.
  initializeIndexIfNeeded();

  // Find the Module path in the map
  auto I = ModulePathMap.find(Path);
  return I == ModulePathMap.end() ? -1 : (int)I->second;
}

int SlotTracker::getGUIDSlot(GlobalValue::GUID GUID) {
  // Check for uninitialized state and do lazy initialization.
  initializeIndexIfNeeded();

  // Find the GUID in the map
  guid_iterator I = GUIDMap.find(GUID);
  return I == GUIDMap.end() ? -1 : (int)I->second;
}

int SlotTracker::getTypeIdSlot(StringRef Id) {
  // Check for uninitialized state and do lazy initialization.
  initializeIndexIfNeeded();

  // Find the TypeId string in the map
  auto I = TypeIdMap.find(Id);
  return I == TypeIdMap.end() ? -1 : (int)I->second;
}

/// CreateModuleSlot - Insert the specified GlobalValue* into the slot table.
void SlotTracker::CreateModuleSlot(const GlobalValue *V) {
  assert(V && "Can't insert a null Value into SlotTracker!");
  assert(!V->getType()->isVoidTy() && "Doesn't need a slot!");
  assert(!V->hasName() && "Doesn't need a slot!");

  unsigned DestSlot = mNext++;
  mMap[V] = DestSlot;

  ST_DEBUG("  Inserting value [" << V->getType() << "] = " << V << " slot=" <<
           DestSlot << " [");
  // G = Global, F = Function, A = Alias, I = IFunc, o = other
  ST_DEBUG((isa<GlobalVariable>(V) ? 'G' :
            (isa<Function>(V) ? 'F' :
             (isa<GlobalAlias>(V) ? 'A' :
              (isa<GlobalIFunc>(V) ? 'I' : 'o')))) << "]\n");
}

/// CreateSlot - Create a new slot for the specified value if it has no name.
void SlotTracker::CreateFunctionSlot(const Value *V) {
  assert(!V->getType()->isVoidTy() && !V->hasName() && "Doesn't need a slot!");

  unsigned DestSlot = fNext++;
  fMap[V] = DestSlot;

  // G = Global, F = Function, o = other
  ST_DEBUG("  Inserting value [" << V->getType() << "] = " << V << " slot=" <<
           DestSlot << " [o]\n");
}

/// CreateModuleSlot - Insert the specified MDNode* into the slot table.
void SlotTracker::CreateMetadataSlot(const MDNode *N) {
  assert(N && "Can't insert a null Value into SlotTracker!");

  // Don't make slots for DIExpressions. We just print them inline everywhere.
  if (isa<DIExpression>(N))
    return;

  unsigned DestSlot = mdnNext;
  if (!mdnMap.insert(std::make_pair(N, DestSlot)).second)
    return;
  ++mdnNext;

  // Recursively add any MDNodes referenced by operands.
  for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
    if (const MDNode *Op = dyn_cast_or_null<MDNode>(N->getOperand(i)))
      CreateMetadataSlot(Op);
}

void SlotTracker::CreateAttributeSetSlot(AttributeSet AS) {
  assert(AS.hasAttributes() && "Doesn't need a slot!");

  as_iterator I = asMap.find(AS);
  if (I != asMap.end())
    return;

  unsigned DestSlot = asNext++;
  asMap[AS] = DestSlot;
}

/// Create a new slot for the specified Module
void SlotTracker::CreateModulePathSlot(StringRef Path) {
  ModulePathMap[Path] = ModulePathNext++;
}

/// Create a new slot for the specified GUID
void SlotTracker::CreateGUIDSlot(GlobalValue::GUID GUID) {
  GUIDMap[GUID] = GUIDNext++;
}

/// Create a new slot for the specified Id
void SlotTracker::CreateTypeIdSlot(StringRef Id) {
  TypeIdMap[Id] = TypeIdNext++;
}

//===----------------------------------------------------------------------===//
// AsmWriter Implementation
//===----------------------------------------------------------------------===//

static void WriteAsOperandInternal(raw_ostream &Out, const Value *V,
                                   TypePrinting *TypePrinter,
                                   SlotTracker *Machine,
                                   const Module *Context);

static void WriteAsOperandInternal(raw_ostream &Out, const Metadata *MD,
                                   TypePrinting *TypePrinter,
                                   SlotTracker *Machine, const Module *Context,
                                   bool FromValue = false);

static void WriteOptimizationInfo(raw_ostream &Out, const User *U) {
  if (const FPMathOperator *FPO = dyn_cast<const FPMathOperator>(U)) {
    // 'Fast' is an abbreviation for all fast-math-flags.
    if (FPO->isFast())
      Out << " fast";
    else {
      if (FPO->hasAllowReassoc())
        Out << " reassoc";
      if (FPO->hasNoNaNs())
        Out << " nnan";
      if (FPO->hasNoInfs())
        Out << " ninf";
      if (FPO->hasNoSignedZeros())
        Out << " nsz";
      if (FPO->hasAllowReciprocal())
        Out << " arcp";
      if (FPO->hasAllowContract())
        Out << " contract";
      if (FPO->hasApproxFunc())
        Out << " afn";
    }
  }

  if (const OverflowingBinaryOperator *OBO =
        dyn_cast<OverflowingBinaryOperator>(U)) {
    if (OBO->hasNoUnsignedWrap())
      Out << " nuw";
    if (OBO->hasNoSignedWrap())
      Out << " nsw";
  } else if (const PossiblyExactOperator *Div =
               dyn_cast<PossiblyExactOperator>(U)) {
    if (Div->isExact())
      Out << " exact";
  } else if (const GEPOperator *GEP = dyn_cast<GEPOperator>(U)) {
    if (GEP->isInBounds())
      Out << " inbounds";
  }
}

static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
                                  TypePrinting &TypePrinter,
                                  SlotTracker *Machine,
                                  const Module *Context) {
  if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
    if (CI->getType()->isIntegerTy(1)) {
      Out << (CI->getZExtValue() ? "true" : "false");
      return;
    }
    Out << CI->getValue();
    return;
  }

  if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
    const APFloat &APF = CFP->getValueAPF();
    if (&APF.getSemantics() == &APFloat::IEEEsingle() ||
        &APF.getSemantics() == &APFloat::IEEEdouble()) {
      // We would like to output the FP constant value in exponential notation,
      // but we cannot do this if doing so will lose precision.  Check here to
      // make sure that we only output it in exponential format if we can parse
      // the value back and get the same value.
      //
      bool ignored;
      bool isDouble = &APF.getSemantics() == &APFloat::IEEEdouble();
      bool isInf = APF.isInfinity();
      bool isNaN = APF.isNaN();
      if (!isInf && !isNaN) {
        double Val = isDouble ? APF.convertToDouble() : APF.convertToFloat();
        SmallString<128> StrVal;
        APF.toString(StrVal, 6, 0, false);
        // Check to make sure that the stringized number is not some string like
        // "Inf" or NaN, that atof will accept, but the lexer will not.  Check
        // that the string matches the "[-+]?[0-9]" regex.
        //
        assert(((StrVal[0] >= '0' && StrVal[0] <= '9') ||
                ((StrVal[0] == '-' || StrVal[0] == '+') &&
                 (StrVal[1] >= '0' && StrVal[1] <= '9'))) &&
               "[-+]?[0-9] regex does not match!");
        // Reparse stringized version!
        if (APFloat(APFloat::IEEEdouble(), StrVal).convertToDouble() == Val) {
          Out << StrVal;
          return;
        }
      }
      // Otherwise we could not reparse it to exactly the same value, so we must
      // output the string in hexadecimal format!  Note that loading and storing
      // floating point types changes the bits of NaNs on some hosts, notably
      // x86, so we must not use these types.
      static_assert(sizeof(double) == sizeof(uint64_t),
                    "assuming that double is 64 bits!");
      APFloat apf = APF;
      // Floats are represented in ASCII IR as double, convert.
      if (!isDouble)
        apf.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven,
                          &ignored);
      Out << format_hex(apf.bitcastToAPInt().getZExtValue(), 0, /*Upper=*/true);
      return;
    }

    // Either half, bfloat or some form of long double.
    // These appear as a magic letter identifying the type, then a
    // fixed number of hex digits.
    Out << "0x";
    APInt API = APF.bitcastToAPInt();
    if (&APF.getSemantics() == &APFloat::x87DoubleExtended()) {
      Out << 'K';
      Out << format_hex_no_prefix(API.getHiBits(16).getZExtValue(), 4,
                                  /*Upper=*/true);
      Out << format_hex_no_prefix(API.getLoBits(64).getZExtValue(), 16,
                                  /*Upper=*/true);
      return;
    } else if (&APF.getSemantics() == &APFloat::IEEEquad()) {
      Out << 'L';
      Out << format_hex_no_prefix(API.getLoBits(64).getZExtValue(), 16,
                                  /*Upper=*/true);
      Out << format_hex_no_prefix(API.getHiBits(64).getZExtValue(), 16,
                                  /*Upper=*/true);
    } else if (&APF.getSemantics() == &APFloat::PPCDoubleDouble()) {
      Out << 'M';
      Out << format_hex_no_prefix(API.getLoBits(64).getZExtValue(), 16,
                                  /*Upper=*/true);
      Out << format_hex_no_prefix(API.getHiBits(64).getZExtValue(), 16,
                                  /*Upper=*/true);
    } else if (&APF.getSemantics() == &APFloat::IEEEhalf()) {
      Out << 'H';
      Out << format_hex_no_prefix(API.getZExtValue(), 4,
                                  /*Upper=*/true);
    } else if (&APF.getSemantics() == &APFloat::BFloat()) {
      Out << 'R';
      Out << format_hex_no_prefix(API.getZExtValue(), 4,
                                  /*Upper=*/true);
    } else
      llvm_unreachable("Unsupported floating point type");
    return;
  }

  if (isa<ConstantAggregateZero>(CV)) {
    Out << "zeroinitializer";
    return;
  }

  if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV)) {
    Out << "blockaddress(";
    WriteAsOperandInternal(Out, BA->getFunction(), &TypePrinter, Machine,
                           Context);
    Out << ", ";
    WriteAsOperandInternal(Out, BA->getBasicBlock(), &TypePrinter, Machine,
                           Context);
    Out << ")";
    return;
  }

  if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) {
    Type *ETy = CA->getType()->getElementType();
    Out << '[';
    TypePrinter.print(ETy, Out);
    Out << ' ';
    WriteAsOperandInternal(Out, CA->getOperand(0),
                           &TypePrinter, Machine,
                           Context);
    for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) {
      Out << ", ";
      TypePrinter.print(ETy, Out);
      Out << ' ';
      WriteAsOperandInternal(Out, CA->getOperand(i), &TypePrinter, Machine,
                             Context);
    }
    Out << ']';
    return;
  }

  if (const ConstantDataArray *CA = dyn_cast<ConstantDataArray>(CV)) {
    // As a special case, print the array as a string if it is an array of
    // i8 with ConstantInt values.
    if (CA->isString()) {
      Out << "c\"";
      printEscapedString(CA->getAsString(), Out);
      Out << '"';
      return;
    }

    Type *ETy = CA->getType()->getElementType();
    Out << '[';
    TypePrinter.print(ETy, Out);
    Out << ' ';
    WriteAsOperandInternal(Out, CA->getElementAsConstant(0),
                           &TypePrinter, Machine,
                           Context);
    for (unsigned i = 1, e = CA->getNumElements(); i != e; ++i) {
      Out << ", ";
      TypePrinter.print(ETy, Out);
      Out << ' ';
      WriteAsOperandInternal(Out, CA->getElementAsConstant(i), &TypePrinter,
                             Machine, Context);
    }
    Out << ']';
    return;
  }

  if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(CV)) {
    if (CS->getType()->isPacked())
      Out << '<';
    Out << '{';
    unsigned N = CS->getNumOperands();
    if (N) {
      Out << ' ';
      TypePrinter.print(CS->getOperand(0)->getType(), Out);
      Out << ' ';

      WriteAsOperandInternal(Out, CS->getOperand(0), &TypePrinter, Machine,
                             Context);

      for (unsigned i = 1; i < N; i++) {
        Out << ", ";
        TypePrinter.print(CS->getOperand(i)->getType(), Out);
        Out << ' ';

        WriteAsOperandInternal(Out, CS->getOperand(i), &TypePrinter, Machine,
                               Context);
      }
      Out << ' ';
    }

    Out << '}';
    if (CS->getType()->isPacked())
      Out << '>';
    return;
  }

  if (isa<ConstantVector>(CV) || isa<ConstantDataVector>(CV)) {
    auto *CVVTy = cast<VectorType>(CV->getType());
    Type *ETy = CVVTy->getElementType();
    Out << '<';
    TypePrinter.print(ETy, Out);
    Out << ' ';
    WriteAsOperandInternal(Out, CV->getAggregateElement(0U), &TypePrinter,
                           Machine, Context);
    for (unsigned i = 1, e = CVVTy->getNumElements(); i != e; ++i) {
      Out << ", ";
      TypePrinter.print(ETy, Out);
      Out << ' ';
      WriteAsOperandInternal(Out, CV->getAggregateElement(i), &TypePrinter,
                             Machine, Context);
    }
    Out << '>';
    return;
  }

  if (isa<ConstantPointerNull>(CV)) {
    Out << "null";
    return;
  }

  if (isa<ConstantTokenNone>(CV)) {
    Out << "none";
    return;
  }

  if (isa<UndefValue>(CV)) {
    Out << "undef";
    return;
  }

  if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
    Out << CE->getOpcodeName();
    WriteOptimizationInfo(Out, CE);
    if (CE->isCompare())
      Out << ' ' << CmpInst::getPredicateName(
                        static_cast<CmpInst::Predicate>(CE->getPredicate()));
    Out << " (";

    Optional<unsigned> InRangeOp;
    if (const GEPOperator *GEP = dyn_cast<GEPOperator>(CE)) {
      TypePrinter.print(GEP->getSourceElementType(), Out);
      Out << ", ";
      InRangeOp = GEP->getInRangeIndex();
      if (InRangeOp)
        ++*InRangeOp;
    }

    for (User::const_op_iterator OI=CE->op_begin(); OI != CE->op_end(); ++OI) {
      if (InRangeOp && unsigned(OI - CE->op_begin()) == *InRangeOp)
        Out << "inrange ";
      TypePrinter.print((*OI)->getType(), Out);
      Out << ' ';
      WriteAsOperandInternal(Out, *OI, &TypePrinter, Machine, Context);
      if (OI+1 != CE->op_end())
        Out << ", ";
    }

    if (CE->hasIndices()) {
      ArrayRef<unsigned> Indices = CE->getIndices();
      for (unsigned i = 0, e = Indices.size(); i != e; ++i)
        Out << ", " << Indices[i];
    }

    if (CE->isCast()) {
      Out << " to ";
      TypePrinter.print(CE->getType(), Out);
    }

    if (CE->getOpcode() == Instruction::ShuffleVector)
      PrintShuffleMask(Out, CE->getType(), CE->getShuffleMask());

    Out << ')';
    return;
  }

  Out << "<placeholder or erroneous Constant>";
}

static void writeMDTuple(raw_ostream &Out, const MDTuple *Node,
                         TypePrinting *TypePrinter, SlotTracker *Machine,
                         const Module *Context) {
  Out << "!{";
  for (unsigned mi = 0, me = Node->getNumOperands(); mi != me; ++mi) {
    const Metadata *MD = Node->getOperand(mi);
    if (!MD)
      Out << "null";
    else if (auto *MDV = dyn_cast<ValueAsMetadata>(MD)) {
      Value *V = MDV->getValue();
      TypePrinter->print(V->getType(), Out);
      Out << ' ';
      WriteAsOperandInternal(Out, V, TypePrinter, Machine, Context);
    } else {
      WriteAsOperandInternal(Out, MD, TypePrinter, Machine, Context);
    }
    if (mi + 1 != me)
      Out << ", ";
  }

  Out << "}";
}

namespace {

struct FieldSeparator {
  bool Skip = true;
  const char *Sep;

  FieldSeparator(const char *Sep = ", ") : Sep(Sep) {}
};

raw_ostream &operator<<(raw_ostream &OS, FieldSeparator &FS) {
  if (FS.Skip) {
    FS.Skip = false;
    return OS;
  }
  return OS << FS.Sep;
}

struct MDFieldPrinter {
  raw_ostream &Out;
  FieldSeparator FS;
  TypePrinting *TypePrinter = nullptr;
  SlotTracker *Machine = nullptr;
  const Module *Context = nullptr;

  explicit MDFieldPrinter(raw_ostream &Out) : Out(Out) {}
  MDFieldPrinter(raw_ostream &Out, TypePrinting *TypePrinter,
                 SlotTracker *Machine, const Module *Context)
      : Out(Out), TypePrinter(TypePrinter), Machine(Machine), Context(Context) {
  }

  void printTag(const DINode *N);
  void printMacinfoType(const DIMacroNode *N);
  void printChecksum(const DIFile::ChecksumInfo<StringRef> &N);
  void printString(StringRef Name, StringRef Value,
                   bool ShouldSkipEmpty = true);
  void printMetadata(StringRef Name, const Metadata *MD,
                     bool ShouldSkipNull = true);
  template <class IntTy>
  void printInt(StringRef Name, IntTy Int, bool ShouldSkipZero = true);
  void printAPInt(StringRef Name, const APInt &Int, bool IsUnsigned,
                  bool ShouldSkipZero);
  void printBool(StringRef Name, bool Value, Optional<bool> Default = None);
  void printDIFlags(StringRef Name, DINode::DIFlags Flags);
  void printDISPFlags(StringRef Name, DISubprogram::DISPFlags Flags);
  template <class IntTy, class Stringifier>
  void printDwarfEnum(StringRef Name, IntTy Value, Stringifier toString,
                      bool ShouldSkipZero = true);
  void printEmissionKind(StringRef Name, DICompileUnit::DebugEmissionKind EK);
  void printNameTableKind(StringRef Name,
                          DICompileUnit::DebugNameTableKind NTK);
};

} // end anonymous namespace

void MDFieldPrinter::printTag(const DINode *N) {
  Out << FS << "tag: ";
  auto Tag = dwarf::TagString(N->getTag());
  if (!Tag.empty())
    Out << Tag;
  else
    Out << N->getTag();
}

void MDFieldPrinter::printMacinfoType(const DIMacroNode *N) {
  Out << FS << "type: ";
  auto Type = dwarf::MacinfoString(N->getMacinfoType());
  if (!Type.empty())
    Out << Type;
  else
    Out << N->getMacinfoType();
}

void MDFieldPrinter::printChecksum(
    const DIFile::ChecksumInfo<StringRef> &Checksum) {
  Out << FS << "checksumkind: " << Checksum.getKindAsString();
  printString("checksum", Checksum.Value, /* ShouldSkipEmpty */ false);
}

void MDFieldPrinter::printString(StringRef Name, StringRef Value,
                                 bool ShouldSkipEmpty) {
  if (ShouldSkipEmpty && Value.empty())
    return;

  Out << FS << Name << ": \"";
  printEscapedString(Value, Out);
  Out << "\"";
}

static void writeMetadataAsOperand(raw_ostream &Out, const Metadata *MD,
                                   TypePrinting *TypePrinter,
                                   SlotTracker *Machine,
                                   const Module *Context) {
  if (!MD) {
    Out << "null";
    return;
  }
  WriteAsOperandInternal(Out, MD, TypePrinter, Machine, Context);
}

void MDFieldPrinter::printMetadata(StringRef Name, const Metadata *MD,
                                   bool ShouldSkipNull) {
  if (ShouldSkipNull && !MD)
    return;

  Out << FS << Name << ": ";
  writeMetadataAsOperand(Out, MD, TypePrinter, Machine, Context);
}

template <class IntTy>
void MDFieldPrinter::printInt(StringRef Name, IntTy Int, bool ShouldSkipZero) {
  if (ShouldSkipZero && !Int)
    return;

  Out << FS << Name << ": " << Int;
}

void MDFieldPrinter::printAPInt(StringRef Name, const APInt &Int,
                                bool IsUnsigned, bool ShouldSkipZero) {
  if (ShouldSkipZero && Int.isNullValue())
    return;

  Out << FS << Name << ": ";
  Int.print(Out, !IsUnsigned);
}

void MDFieldPrinter::printBool(StringRef Name, bool Value,
                               Optional<bool> Default) {
  if (Default && Value == *Default)
    return;
  Out << FS << Name << ": " << (Value ? "true" : "false");
}

void MDFieldPrinter::printDIFlags(StringRef Name, DINode::DIFlags Flags) {
  if (!Flags)
    return;

  Out << FS << Name << ": ";

  SmallVector<DINode::DIFlags, 8> SplitFlags;
  auto Extra = DINode::splitFlags(Flags, SplitFlags);

  FieldSeparator FlagsFS(" | ");
  for (auto F : SplitFlags) {
    auto StringF = DINode::getFlagString(F);
    assert(!StringF.empty() && "Expected valid flag");
    Out << FlagsFS << StringF;
  }
  if (Extra || SplitFlags.empty())
    Out << FlagsFS << Extra;
}

void MDFieldPrinter::printDISPFlags(StringRef Name,
                                    DISubprogram::DISPFlags Flags) {
  // Always print this field, because no flags in the IR at all will be
  // interpreted as old-style isDefinition: true.
  Out << FS << Name << ": ";

  if (!Flags) {
    Out << 0;
    return;
  }

  SmallVector<DISubprogram::DISPFlags, 8> SplitFlags;
  auto Extra = DISubprogram::splitFlags(Flags, SplitFlags);

  FieldSeparator FlagsFS(" | ");
  for (auto F : SplitFlags) {
    auto StringF = DISubprogram::getFlagString(F);
    assert(!StringF.empty() && "Expected valid flag");
    Out << FlagsFS << StringF;
  }
  if (Extra || SplitFlags.empty())
    Out << FlagsFS << Extra;
}

void MDFieldPrinter::printEmissionKind(StringRef Name,
                                       DICompileUnit::DebugEmissionKind EK) {
  Out << FS << Name << ": " << DICompileUnit::emissionKindString(EK);
}

void MDFieldPrinter::printNameTableKind(StringRef Name,
                                        DICompileUnit::DebugNameTableKind NTK) {
  if (NTK == DICompileUnit::DebugNameTableKind::Default)
    return;
  Out << FS << Name << ": " << DICompileUnit::nameTableKindString(NTK);
}

template <class IntTy, class Stringifier>
void MDFieldPrinter::printDwarfEnum(StringRef Name, IntTy Value,
                                    Stringifier toString, bool ShouldSkipZero) {
  if (!Value)
    return;

  Out << FS << Name << ": ";
  auto S = toString(Value);
  if (!S.empty())
    Out << S;
  else
    Out << Value;
}

static void writeGenericDINode(raw_ostream &Out, const GenericDINode *N,
                               TypePrinting *TypePrinter, SlotTracker *Machine,
                               const Module *Context) {
  Out << "!GenericDINode(";
  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
  Printer.printTag(N);
  Printer.printString("header", N->getHeader());
  if (N->getNumDwarfOperands()) {
    Out << Printer.FS << "operands: {";
    FieldSeparator IFS;
    for (auto &I : N->dwarf_operands()) {
      Out << IFS;
      writeMetadataAsOperand(Out, I, TypePrinter, Machine, Context);
    }
    Out << "}";
  }
  Out << ")";
}

static void writeDILocation(raw_ostream &Out, const DILocation *DL,
                            TypePrinting *TypePrinter, SlotTracker *Machine,
                            const Module *Context) {
  Out << "!DILocation(";
  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
  // Always output the line, since 0 is a relevant and important value for it.
  Printer.printInt("line", DL->getLine(), /* ShouldSkipZero */ false);
  Printer.printInt("column", DL->getColumn());
  Printer.printMetadata("scope", DL->getRawScope(), /* ShouldSkipNull */ false);
  Printer.printMetadata("inlinedAt", DL->getRawInlinedAt());
  Printer.printBool("isImplicitCode", DL->isImplicitCode(),
                    /* Default */ false);
  Out << ")";
}

static void writeDISubrange(raw_ostream &Out, const DISubrange *N,
                            TypePrinting *TypePrinter, SlotTracker *Machine,
                            const Module *Context) {
  Out << "!DISubrange(";
  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
  if (auto *CE = N->getCount().dyn_cast<ConstantInt*>())
    Printer.printInt("count", CE->getSExtValue(), /* ShouldSkipZero */ false);
  else
    Printer.printMetadata("count", N->getCount().dyn_cast<DIVariable *>(),
                          /*ShouldSkipNull */ true);

  // A lowerBound of constant 0 should not be skipped, since it is different
  // from an unspecified lower bound (= nullptr).
  auto *LBound = N->getRawLowerBound();
  if (auto *LE = dyn_cast_or_null<ConstantAsMetadata>(LBound)) {
    auto *LV = cast<ConstantInt>(LE->getValue());
    Printer.printInt("lowerBound", LV->getSExtValue(),
                     /* ShouldSkipZero */ false);
  } else
    Printer.printMetadata("lowerBound", LBound, /*ShouldSkipNull */ true);

  auto *UBound = N->getRawUpperBound();
  if (auto *UE = dyn_cast_or_null<ConstantAsMetadata>(UBound)) {
    auto *UV = cast<ConstantInt>(UE->getValue());
    Printer.printInt("upperBound", UV->getSExtValue(),
                     /* ShouldSkipZero */ false);
  } else
    Printer.printMetadata("upperBound", UBound, /*ShouldSkipNull */ true);

  auto *Stride = N->getRawStride();
  if (auto *SE = dyn_cast_or_null<ConstantAsMetadata>(Stride)) {
    auto *SV = cast<ConstantInt>(SE->getValue());
    Printer.printInt("stride", SV->getSExtValue(), /* ShouldSkipZero */ false);
  } else
    Printer.printMetadata("stride", Stride, /*ShouldSkipNull */ true);

  Out << ")";
}

static void writeDIEnumerator(raw_ostream &Out, const DIEnumerator *N,
                              TypePrinting *, SlotTracker *, const Module *) {
  Out << "!DIEnumerator(";
  MDFieldPrinter Printer(Out);
  Printer.printString("name", N->getName(), /* ShouldSkipEmpty */ false);
  Printer.printAPInt("value", N->getValue(), N->isUnsigned(),
                     /*ShouldSkipZero=*/false);
  if (N->isUnsigned())
    Printer.printBool("isUnsigned", true);
  Out << ")";
}

static void writeDIBasicType(raw_ostream &Out, const DIBasicType *N,
                             TypePrinting *, SlotTracker *, const Module *) {
  Out << "!DIBasicType(";
  MDFieldPrinter Printer(Out);
  if (N->getTag() != dwarf::DW_TAG_base_type)
    Printer.printTag(N);
  Printer.printString("name", N->getName());
  Printer.printInt("size", N->getSizeInBits());
  Printer.printInt("align", N->getAlignInBits());
  Printer.printDwarfEnum("encoding", N->getEncoding(),
                         dwarf::AttributeEncodingString);
  Printer.printDIFlags("flags", N->getFlags());
  Out << ")";
}

static void writeDIDerivedType(raw_ostream &Out, const DIDerivedType *N,
                               TypePrinting *TypePrinter, SlotTracker *Machine,
                               const Module *Context) {
  Out << "!DIDerivedType(";
  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
  Printer.printTag(N);
  Printer.printString("name", N->getName());
  Printer.printMetadata("scope", N->getRawScope());
  Printer.printMetadata("file", N->getRawFile());
  Printer.printInt("line", N->getLine());
  Printer.printMetadata("baseType", N->getRawBaseType(),
                        /* ShouldSkipNull */ false);
  Printer.printInt("size", N->getSizeInBits());
  Printer.printInt("align", N->getAlignInBits());
  Printer.printInt("offset", N->getOffsetInBits());
  Printer.printDIFlags("flags", N->getFlags());
  Printer.printMetadata("extraData", N->getRawExtraData());
  if (const auto &DWARFAddressSpace = N->getDWARFAddressSpace())
    Printer.printInt("dwarfAddressSpace", *DWARFAddressSpace,
                     /* ShouldSkipZero */ false);
  Out << ")";
}

static void writeDICompositeType(raw_ostream &Out, const DICompositeType *N,
                                 TypePrinting *TypePrinter,
                                 SlotTracker *Machine, const Module *Context) {
  Out << "!DICompositeType(";
  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
  Printer.printTag(N);
  Printer.printString("name", N->getName());
  Printer.printMetadata("scope", N->getRawScope());
  Printer.printMetadata("file", N->getRawFile());
  Printer.printInt("line", N->getLine());
  Printer.printMetadata("baseType", N->getRawBaseType());
  Printer.printInt("size", N->getSizeInBits());
  Printer.printInt("align", N->getAlignInBits());
  Printer.printInt("offset", N->getOffsetInBits());
  Printer.printDIFlags("flags", N->getFlags());
  Printer.printMetadata("elements", N->getRawElements());
  Printer.printDwarfEnum("runtimeLang", N->getRuntimeLang(),
                         dwarf::LanguageString);
  Printer.printMetadata("vtableHolder", N->getRawVTableHolder());
  Printer.printMetadata("templateParams", N->getRawTemplateParams());
  Printer.printString("identifier", N->getIdentifier());
  Printer.printMetadata("discriminator", N->getRawDiscriminator());
  Printer.printMetadata("dataLocation", N->getRawDataLocation());
  Out << ")";
}

static void writeDISubroutineType(raw_ostream &Out, const DISubroutineType *N,
                                  TypePrinting *TypePrinter,
                                  SlotTracker *Machine, const Module *Context) {
  Out << "!DISubroutineType(";
  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
  Printer.printDIFlags("flags", N->getFlags());
  Printer.printDwarfEnum("cc", N->getCC(), dwarf::ConventionString);
  Printer.printMetadata("types", N->getRawTypeArray(),
                        /* ShouldSkipNull */ false);
  Out << ")";
}

static void writeDIFile(raw_ostream &Out, const DIFile *N, TypePrinting *,
                        SlotTracker *, const Module *) {
  Out << "!DIFile(";
  MDFieldPrinter Printer(Out);
  Printer.printString("filename", N->getFilename(),
                      /* ShouldSkipEmpty */ false);
  Printer.printString("directory", N->getDirectory(),
                      /* ShouldSkipEmpty */ false);
  // Print all values for checksum together, or not at all.
  if (N->getChecksum())
    Printer.printChecksum(*N->getChecksum());
  Printer.printString("source", N->getSource().getValueOr(StringRef()),
                      /* ShouldSkipEmpty */ true);
  Out << ")";
}

static void writeDICompileUnit(raw_ostream &Out, const DICompileUnit *N,
                               TypePrinting *TypePrinter, SlotTracker *Machine,
                               const Module *Context) {
  Out << "!DICompileUnit(";
  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
  Printer.printDwarfEnum("language", N->getSourceLanguage(),
                         dwarf::LanguageString, /* ShouldSkipZero */ false);
  Printer.printMetadata("file", N->getRawFile(), /* ShouldSkipNull */ false);
  Printer.printString("producer", N->getProducer());
  Printer.printBool("isOptimized", N->isOptimized());
  Printer.printString("flags", N->getFlags());
  Printer.printInt("runtimeVersion", N->getRuntimeVersion(),
                   /* ShouldSkipZero */ false);
  Printer.printString("splitDebugFilename", N->getSplitDebugFilename());
  Printer.printEmissionKind("emissionKind", N->getEmissionKind());
  Printer.printMetadata("enums", N->getRawEnumTypes());
  Printer.printMetadata("retainedTypes", N->getRawRetainedTypes());
  Printer.printMetadata("globals", N->getRawGlobalVariables());
  Printer.printMetadata("imports", N->getRawImportedEntities());
  Printer.printMetadata("macros", N->getRawMacros());
  Printer.printInt("dwoId", N->getDWOId());
  Printer.printBool("splitDebugInlining", N->getSplitDebugInlining(), true);
  Printer.printBool("debugInfoForProfiling", N->getDebugInfoForProfiling(),
                    false);
  Printer.printNameTableKind("nameTableKind", N->getNameTableKind());
  Printer.printBool("rangesBaseAddress", N->getRangesBaseAddress(), false);
  Printer.printString("sysroot", N->getSysRoot());
  Printer.printString("sdk", N->getSDK());
  Out << ")";
}

static void writeDISubprogram(raw_ostream &Out, const DISubprogram *N,
                              TypePrinting *TypePrinter, SlotTracker *Machine,
                              const Module *Context) {
  Out << "!DISubprogram(";
  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
  Printer.printString("name", N->getName());
  Printer.printString("linkageName", N->getLinkageName());
  Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
  Printer.printMetadata("file", N->getRawFile());
  Printer.printInt("line", N->getLine());
  Printer.printMetadata("type", N->getRawType());
  Printer.printInt("scopeLine", N->getScopeLine());
  Printer.printMetadata("containingType", N->getRawContainingType());
  if (N->getVirtuality() != dwarf::DW_VIRTUALITY_none ||
      N->getVirtualIndex() != 0)
    Printer.printInt("virtualIndex", N->getVirtualIndex(), false);
  Printer.printInt("thisAdjustment", N->getThisAdjustment());
  Printer.printDIFlags("flags", N->getFlags());
  Printer.printDISPFlags("spFlags", N->getSPFlags());
  Printer.printMetadata("unit", N->getRawUnit());
  Printer.printMetadata("templateParams", N->getRawTemplateParams());
  Printer.printMetadata("declaration", N->getRawDeclaration());
  Printer.printMetadata("retainedNodes", N->getRawRetainedNodes());
  Printer.printMetadata("thrownTypes", N->getRawThrownTypes());
  Out << ")";
}

static void writeDILexicalBlock(raw_ostream &Out, const DILexicalBlock *N,
                                TypePrinting *TypePrinter, SlotTracker *Machine,
                                const Module *Context) {
  Out << "!DILexicalBlock(";
  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
  Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
  Printer.printMetadata("file", N->getRawFile());
  Printer.printInt("line", N->getLine());
  Printer.printInt("column", N->getColumn());
  Out << ")";
}

static void writeDILexicalBlockFile(raw_ostream &Out,
                                    const DILexicalBlockFile *N,
                                    TypePrinting *TypePrinter,
                                    SlotTracker *Machine,
                                    const Module *Context) {
  Out << "!DILexicalBlockFile(";
  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
  Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
  Printer.printMetadata("file", N->getRawFile());
  Printer.printInt("discriminator", N->getDiscriminator(),
                   /* ShouldSkipZero */ false);
  Out << ")";
}

static void writeDINamespace(raw_ostream &Out, const DINamespace *N,
                             TypePrinting *TypePrinter, SlotTracker *Machine,
                             const Module *Context) {
  Out << "!DINamespace(";
  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
  Printer.printString("name", N->getName());
  Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
  Printer.printBool("exportSymbols", N->getExportSymbols(), false);
  Out << ")";
}

static void writeDICommonBlock(raw_ostream &Out, const DICommonBlock *N,
                               TypePrinting *TypePrinter, SlotTracker *Machine,
                               const Module *Context) {
  Out << "!DICommonBlock(";
  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
  Printer.printMetadata("scope", N->getRawScope(), false);
  Printer.printMetadata("declaration", N->getRawDecl(), false);
  Printer.printString("name", N->getName());
  Printer.printMetadata("file", N->getRawFile());
  Printer.printInt("line", N->getLineNo());
  Out << ")";
}

static void writeDIMacro(raw_ostream &Out, const DIMacro *N,
                         TypePrinting *TypePrinter, SlotTracker *Machine,
                         const Module *Context) {
  Out << "!DIMacro(";
  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
  Printer.printMacinfoType(N);
  Printer.printInt("line", N->getLine());
  Printer.printString("name", N->getName());
  Printer.printString("value", N->getValue());
  Out << ")";
}

static void writeDIMacroFile(raw_ostream &Out, const DIMacroFile *N,
                             TypePrinting *TypePrinter, SlotTracker *Machine,
                             const Module *Context) {
  Out << "!DIMacroFile(";
  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
  Printer.printInt("line", N->getLine());
  Printer.printMetadata("file", N->getRawFile(), /* ShouldSkipNull */ false);
  Printer.printMetadata("nodes", N->getRawElements());
  Out << ")";
}

static void writeDIModule(raw_ostream &Out, const DIModule *N,
                          TypePrinting *TypePrinter, SlotTracker *Machine,
                          const Module *Context) {
  Out << "!DIModule(";
  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
  Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
  Printer.printString("name", N->getName());
  Printer.printString("configMacros", N->getConfigurationMacros());
  Printer.printString("includePath", N->getIncludePath());
  Printer.printString("apinotes", N->getAPINotesFile());
  Printer.printMetadata("file", N->getRawFile());
  Printer.printInt("line", N->getLineNo());
  Out << ")";
}


static void writeDITemplateTypeParameter(raw_ostream &Out,
                                         const DITemplateTypeParameter *N,
                                         TypePrinting *TypePrinter,
                                         SlotTracker *Machine,
                                         const Module *Context) {
  Out << "!DITemplateTypeParameter(";
  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
  Printer.printString("name", N->getName());
  Printer.printMetadata("type", N->getRawType(), /* ShouldSkipNull */ false);
  Printer.printBool("defaulted", N->isDefault(), /* Default= */ false);
  Out << ")";
}

static void writeDITemplateValueParameter(raw_ostream &Out,
                                          const DITemplateValueParameter *N,
                                          TypePrinting *TypePrinter,
                                          SlotTracker *Machine,
                                          const Module *Context) {
  Out << "!DITemplateValueParameter(";
  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
  if (N->getTag() != dwarf::DW_TAG_template_value_parameter)
    Printer.printTag(N);
  Printer.printString("name", N->getName());
  Printer.printMetadata("type", N->getRawType());
  Printer.printBool("defaulted", N->isDefault(), /* Default= */ false);
  Printer.printMetadata("value", N->getValue(), /* ShouldSkipNull */ false);
  Out << ")";
}

static void writeDIGlobalVariable(raw_ostream &Out, const DIGlobalVariable *N,
                                  TypePrinting *TypePrinter,
                                  SlotTracker *Machine, const Module *Context) {
  Out << "!DIGlobalVariable(";
  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
  Printer.printString("name", N->getName());
  Printer.printString("linkageName", N->getLinkageName());
  Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
  Printer.printMetadata("file", N->getRawFile());
  Printer.printInt("line", N->getLine());
  Printer.printMetadata("type", N->getRawType());
  Printer.printBool("isLocal", N->isLocalToUnit());
  Printer.printBool("isDefinition", N->isDefinition());
  Printer.printMetadata("declaration", N->getRawStaticDataMemberDeclaration());
  Printer.printMetadata("templateParams", N->getRawTemplateParams());
  Printer.printInt("align", N->getAlignInBits());
  Out << ")";
}

static void writeDILocalVariable(raw_ostream &Out, const DILocalVariable *N,
                                 TypePrinting *TypePrinter,
                                 SlotTracker *Machine, const Module *Context) {
  Out << "!DILocalVariable(";
  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
  Printer.printString("name", N->getName());
  Printer.printInt("arg", N->getArg());
  Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
  Printer.printMetadata("file", N->getRawFile());
  Printer.printInt("line", N->getLine());
  Printer.printMetadata("type", N->getRawType());
  Printer.printDIFlags("flags", N->getFlags());
  Printer.printInt("align", N->getAlignInBits());
  Out << ")";
}

static void writeDILabel(raw_ostream &Out, const DILabel *N,
                         TypePrinting *TypePrinter,
                         SlotTracker *Machine, const Module *Context) {
  Out << "!DILabel(";
  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
  Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
  Printer.printString("name", N->getName());
  Printer.printMetadata("file", N->getRawFile());
  Printer.printInt("line", N->getLine());
  Out << ")";
}

static void writeDIExpression(raw_ostream &Out, const DIExpression *N,
                              TypePrinting *TypePrinter, SlotTracker *Machine,
                              const Module *Context) {
  Out << "!DIExpression(";
  FieldSeparator FS;
  if (N->isValid()) {
    for (auto I = N->expr_op_begin(), E = N->expr_op_end(); I != E; ++I) {
      auto OpStr = dwarf::OperationEncodingString(I->getOp());
      assert(!OpStr.empty() && "Expected valid opcode");

      Out << FS << OpStr;
      if (I->getOp() == dwarf::DW_OP_LLVM_convert) {
        Out << FS << I->getArg(0);
        Out << FS << dwarf::AttributeEncodingString(I->getArg(1));
      } else {
        for (unsigned A = 0, AE = I->getNumArgs(); A != AE; ++A)
          Out << FS << I->getArg(A);
      }
    }
  } else {
    for (const auto &I : N->getElements())
      Out << FS << I;
  }
  Out << ")";
}

static void writeDIGlobalVariableExpression(raw_ostream &Out,
                                            const DIGlobalVariableExpression *N,
                                            TypePrinting *TypePrinter,
                                            SlotTracker *Machine,
                                            const Module *Context) {
  Out << "!DIGlobalVariableExpression(";
  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
  Printer.printMetadata("var", N->getVariable());
  Printer.printMetadata("expr", N->getExpression());
  Out << ")";
}

static void writeDIObjCProperty(raw_ostream &Out, const DIObjCProperty *N,
                                TypePrinting *TypePrinter, SlotTracker *Machine,
                                const Module *Context) {
  Out << "!DIObjCProperty(";
  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
  Printer.printString("name", N->getName());
  Printer.printMetadata("file", N->getRawFile());
  Printer.printInt("line", N->getLine());
  Printer.printString("setter", N->getSetterName());
  Printer.printString("getter", N->getGetterName());
  Printer.printInt("attributes", N->getAttributes());
  Printer.printMetadata("type", N->getRawType());
  Out << ")";
}

static void writeDIImportedEntity(raw_ostream &Out, const DIImportedEntity *N,
                                  TypePrinting *TypePrinter,
                                  SlotTracker *Machine, const Module *Context) {
  Out << "!DIImportedEntity(";
  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
  Printer.printTag(N);
  Printer.printString("name", N->getName());
  Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
  Printer.printMetadata("entity", N->getRawEntity());
  Printer.printMetadata("file", N->getRawFile());
  Printer.printInt("line", N->getLine());
  Out << ")";
}

static void WriteMDNodeBodyInternal(raw_ostream &Out, const MDNode *Node,
                                    TypePrinting *TypePrinter,
                                    SlotTracker *Machine,
                                    const Module *Context) {
  if (Node->isDistinct())
    Out << "distinct ";
  else if (Node->isTemporary())
    Out << "<temporary!> "; // Handle broken code.

  switch (Node->getMetadataID()) {
  default:
    llvm_unreachable("Expected uniquable MDNode");
#define HANDLE_MDNODE_LEAF(CLASS)                                              \
  case Metadata::CLASS##Kind:                                                  \
    write##CLASS(Out, cast<CLASS>(Node), TypePrinter, Machine, Context);       \
    break;
#include "llvm/IR/Metadata.def"
  }
}

// Full implementation of printing a Value as an operand with support for
// TypePrinting, etc.
static void WriteAsOperandInternal(raw_ostream &Out, const Value *V,
                                   TypePrinting *TypePrinter,
                                   SlotTracker *Machine,
                                   const Module *Context) {
  if (V->hasName()) {
    PrintLLVMName(Out, V);
    return;
  }

  const Constant *CV = dyn_cast<Constant>(V);
  if (CV && !isa<GlobalValue>(CV)) {
    assert(TypePrinter && "Constants require TypePrinting!");
    WriteConstantInternal(Out, CV, *TypePrinter, Machine, Context);
    return;
  }

  if (const InlineAsm *IA = dyn_cast<InlineAsm>(V)) {
    Out << "asm ";
    if (IA->hasSideEffects())
      Out << "sideeffect ";
    if (IA->isAlignStack())
      Out << "alignstack ";
    // We don't emit the AD_ATT dialect as it's the assumed default.
    if (IA->getDialect() == InlineAsm::AD_Intel)
      Out << "inteldialect ";
    Out << '"';
    printEscapedString(IA->getAsmString(), Out);
    Out << "\", \"";
    printEscapedString(IA->getConstraintString(), Out);
    Out << '"';
    return;
  }

  if (auto *MD = dyn_cast<MetadataAsValue>(V)) {
    WriteAsOperandInternal(Out, MD->getMetadata(), TypePrinter, Machine,
                           Context, /* FromValue */ true);
    return;
  }

  char Prefix = '%';
  int Slot;
  // If we have a SlotTracker, use it.
  if (Machine) {
    if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
      Slot = Machine->getGlobalSlot(GV);
      Prefix = '@';
    } else {
      Slot = Machine->getLocalSlot(V);

      // If the local value didn't succeed, then we may be referring to a value
      // from a different function.  Translate it, as this can happen when using
      // address of blocks.
      if (Slot == -1)
        if ((Machine = createSlotTracker(V))) {
          Slot = Machine->getLocalSlot(V);
          delete Machine;
        }
    }
  } else if ((Machine = createSlotTracker(V))) {
    // Otherwise, create one to get the # and then destroy it.
    if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
      Slot = Machine->getGlobalSlot(GV);
      Prefix = '@';
    } else {
      Slot = Machine->getLocalSlot(V);
    }
    delete Machine;
    Machine = nullptr;
  } else {
    Slot = -1;
  }

  if (Slot != -1)
    Out << Prefix << Slot;
  else
    Out << "<badref>";
}

static void WriteAsOperandInternal(raw_ostream &Out, const Metadata *MD,
                                   TypePrinting *TypePrinter,
                                   SlotTracker *Machine, const Module *Context,
                                   bool FromValue) {
  // Write DIExpressions inline when used as a value. Improves readability of
  // debug info intrinsics.
  if (const DIExpression *Expr = dyn_cast<DIExpression>(MD)) {
    writeDIExpression(Out, Expr, TypePrinter, Machine, Context);
    return;
  }

  if (const MDNode *N = dyn_cast<MDNode>(MD)) {
    std::unique_ptr<SlotTracker> MachineStorage;
    if (!Machine) {
      MachineStorage = std::make_unique<SlotTracker>(Context);
      Machine = MachineStorage.get();
    }
    int Slot = Machine->getMetadataSlot(N);
    if (Slot == -1) {
      if (const DILocation *Loc = dyn_cast<DILocation>(N)) {
        writeDILocation(Out, Loc, TypePrinter, Machine, Context);
        return;
      }
      // Give the pointer value instead of "badref", since this comes up all
      // the time when debugging.
      Out << "<" << N << ">";
    } else
      Out << '!' << Slot;
    return;
  }

  if (const MDString *MDS = dyn_cast<MDString>(MD)) {
    Out << "!\"";
    printEscapedString(MDS->getString(), Out);
    Out << '"';
    return;
  }

  auto *V = cast<ValueAsMetadata>(MD);
  assert(TypePrinter && "TypePrinter required for metadata values");
  assert((FromValue || !isa<LocalAsMetadata>(V)) &&
         "Unexpected function-local metadata outside of value argument");

  TypePrinter->print(V->getValue()->getType(), Out);
  Out << ' ';
  WriteAsOperandInternal(Out, V->getValue(), TypePrinter, Machine, Context);
}

namespace {

class AssemblyWriter {
  formatted_raw_ostream &Out;
  const Module *TheModule = nullptr;
  const ModuleSummaryIndex *TheIndex = nullptr;
  std::unique_ptr<SlotTracker> SlotTrackerStorage;
  SlotTracker &Machine;
  TypePrinting TypePrinter;
  AssemblyAnnotationWriter *AnnotationWriter = nullptr;
  SetVector<const Comdat *> Comdats;
  bool IsForDebug;
  bool ShouldPreserveUseListOrder;
  UseListOrderStack UseListOrders;
  SmallVector<StringRef, 8> MDNames;
  /// Synchronization scope names registered with LLVMContext.
  SmallVector<StringRef, 8> SSNs;
  DenseMap<const GlobalValueSummary *, GlobalValue::GUID> SummaryToGUIDMap;

public:
  /// Construct an AssemblyWriter with an external SlotTracker
  AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac, const Module *M,
                 AssemblyAnnotationWriter *AAW, bool IsForDebug,
                 bool ShouldPreserveUseListOrder = false);

  AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
                 const ModuleSummaryIndex *Index, bool IsForDebug);

  void printMDNodeBody(const MDNode *MD);
  void printNamedMDNode(const NamedMDNode *NMD);

  void printModule(const Module *M);

  void writeOperand(const Value *Op, bool PrintType);
  void writeParamOperand(const Value *Operand, AttributeSet Attrs);
  void writeOperandBundles(const CallBase *Call);
  void writeSyncScope(const LLVMContext &Context,
                      SyncScope::ID SSID);
  void writeAtomic(const LLVMContext &Context,
                   AtomicOrdering Ordering,
                   SyncScope::ID SSID);
  void writeAtomicCmpXchg(const LLVMContext &Context,
                          AtomicOrdering SuccessOrdering,
                          AtomicOrdering FailureOrdering,
                          SyncScope::ID SSID);

  void writeAllMDNodes();
  void writeMDNode(unsigned Slot, const MDNode *Node);
  void writeAttribute(const Attribute &Attr, bool InAttrGroup = false);
  void writeAttributeSet(const AttributeSet &AttrSet, bool InAttrGroup = false);
  void writeAllAttributeGroups();

  void printTypeIdentities();
  void printGlobal(const GlobalVariable *GV);
  void printIndirectSymbol(const GlobalIndirectSymbol *GIS);
  void printComdat(const Comdat *C);
  void printFunction(const Function *F);
  void printArgument(const Argument *FA, AttributeSet Attrs);
  void printBasicBlock(const BasicBlock *BB);
  void printInstructionLine(const Instruction &I);
  void printInstruction(const Instruction &I);

  void printUseListOrder(const UseListOrder &Order);
  void printUseLists(const Function *F);

  void printModuleSummaryIndex();
  void printSummaryInfo(unsigned Slot, const ValueInfo &VI);
  void printSummary(const GlobalValueSummary &Summary);
  void printAliasSummary(const AliasSummary *AS);
  void printGlobalVarSummary(const GlobalVarSummary *GS);
  void printFunctionSummary(const FunctionSummary *FS);
  void printTypeIdSummary(const TypeIdSummary &TIS);
  void printTypeIdCompatibleVtableSummary(const TypeIdCompatibleVtableInfo &TI);
  void printTypeTestResolution(const TypeTestResolution &TTRes);
  void printArgs(const std::vector<uint64_t> &Args);
  void printWPDRes(const WholeProgramDevirtResolution &WPDRes);
  void printTypeIdInfo(const FunctionSummary::TypeIdInfo &TIDInfo);
  void printVFuncId(const FunctionSummary::VFuncId VFId);
  void
  printNonConstVCalls(const std::vector<FunctionSummary::VFuncId> &VCallList,
                      const char *Tag);
  void
  printConstVCalls(const std::vector<FunctionSummary::ConstVCall> &VCallList,
                   const char *Tag);

private:
  /// Print out metadata attachments.
  void printMetadataAttachments(
      const SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs,
      StringRef Separator);

  // printInfoComment - Print a little comment after the instruction indicating
  // which slot it occupies.
  void printInfoComment(const Value &V);

  // printGCRelocateComment - print comment after call to the gc.relocate
  // intrinsic indicating base and derived pointer names.
  void printGCRelocateComment(const GCRelocateInst &Relocate);
};

} // end anonymous namespace

AssemblyWriter::AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
                               const Module *M, AssemblyAnnotationWriter *AAW,
                               bool IsForDebug, bool ShouldPreserveUseListOrder)
    : Out(o), TheModule(M), Machine(Mac), TypePrinter(M), AnnotationWriter(AAW),
      IsForDebug(IsForDebug),
      ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {
  if (!TheModule)
    return;
  for (const GlobalObject &GO : TheModule->global_objects())
    if (const Comdat *C = GO.getComdat())
      Comdats.insert(C);
}

AssemblyWriter::AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
                               const ModuleSummaryIndex *Index, bool IsForDebug)
    : Out(o), TheIndex(Index), Machine(Mac), TypePrinter(/*Module=*/nullptr),
      IsForDebug(IsForDebug), ShouldPreserveUseListOrder(false) {}

void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType) {
  if (!Operand) {
    Out << "<null operand!>";
    return;
  }
  if (PrintType) {
    TypePrinter.print(Operand->getType(), Out);
    Out << ' ';
  }
  WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine, TheModule);
}

void AssemblyWriter::writeSyncScope(const LLVMContext &Context,
                                    SyncScope::ID SSID) {
  switch (SSID) {
  case SyncScope::System: {
    break;
  }
  default: {
    if (SSNs.empty())
      Context.getSyncScopeNames(SSNs);

    Out << " syncscope(\"";
    printEscapedString(SSNs[SSID], Out);
    Out << "\")";
    break;
  }
  }
}

void AssemblyWriter::writeAtomic(const LLVMContext &Context,
                                 AtomicOrdering Ordering,
                                 SyncScope::ID SSID) {
  if (Ordering == AtomicOrdering::NotAtomic)
    return;

  writeSyncScope(Context, SSID);
  Out << " " << toIRString(Ordering);
}

void AssemblyWriter::writeAtomicCmpXchg(const LLVMContext &Context,
                                        AtomicOrdering SuccessOrdering,
                                        AtomicOrdering FailureOrdering,
                                        SyncScope::ID SSID) {
  assert(SuccessOrdering != AtomicOrdering::NotAtomic &&
         FailureOrdering != AtomicOrdering::NotAtomic);

  writeSyncScope(Context, SSID);
  Out << " " << toIRString(SuccessOrdering);
  Out << " " << toIRString(FailureOrdering);
}

void AssemblyWriter::writeParamOperand(const Value *Operand,
                                       AttributeSet Attrs) {
  if (!Operand) {
    Out << "<null operand!>";
    return;
  }

  // Print the type
  TypePrinter.print(Operand->getType(), Out);
  // Print parameter attributes list
  if (Attrs.hasAttributes()) {
    Out << ' ';
    writeAttributeSet(Attrs);
  }
  Out << ' ';
  // Print the operand
  WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine, TheModule);
}

void AssemblyWriter::writeOperandBundles(const CallBase *Call) {
  if (!Call->hasOperandBundles())
    return;

  Out << " [ ";

  bool FirstBundle = true;
  for (unsigned i = 0, e = Call->getNumOperandBundles(); i != e; ++i) {
    OperandBundleUse BU = Call->getOperandBundleAt(i);

    if (!FirstBundle)
      Out << ", ";
    FirstBundle = false;

    Out << '"';
    printEscapedString(BU.getTagName(), Out);
    Out << '"';

    Out << '(';

    bool FirstInput = true;
    for (const auto &Input : BU.Inputs) {
      if (!FirstInput)
        Out << ", ";
      FirstInput = false;

      TypePrinter.print(Input->getType(), Out);
      Out << " ";
      WriteAsOperandInternal(Out, Input, &TypePrinter, &Machine, TheModule);
    }

    Out << ')';
  }

  Out << " ]";
}

void AssemblyWriter::printModule(const Module *M) {
  Machine.initializeIfNeeded();

  if (ShouldPreserveUseListOrder)
    UseListOrders = predictUseListOrder(M);

  if (!M->getModuleIdentifier().empty() &&
      // Don't print the ID if it will start a new line (which would
      // require a comment char before it).
      M->getModuleIdentifier().find('\n') == std::string::npos)
    Out << "; ModuleID = '" << M->getModuleIdentifier() << "'\n";

  if (!M->getSourceFileName().empty()) {
    Out << "source_filename = \"";
    printEscapedString(M->getSourceFileName(), Out);
    Out << "\"\n";
  }

  const std::string &DL = M->getDataLayoutStr();
  if (!DL.empty())
    Out << "target datalayout = \"" << DL << "\"\n";
  if (!M->getTargetTriple().empty())
    Out << "target triple = \"" << M->getTargetTriple() << "\"\n";

  if (!M->getModuleInlineAsm().empty()) {
    Out << '\n';

    // Split the string into lines, to make it easier to read the .ll file.
    StringRef Asm = M->getModuleInlineAsm();
    do {
      StringRef Front;
      std::tie(Front, Asm) = Asm.split('\n');

      // We found a newline, print the portion of the asm string from the
      // last newline up to this newline.
      Out << "module asm \"";
      printEscapedString(Front, Out);
      Out << "\"\n";
    } while (!Asm.empty());
  }

  printTypeIdentities();

  // Output all comdats.
  if (!Comdats.empty())
    Out << '\n';
  for (const Comdat *C : Comdats) {
    printComdat(C);
    if (C != Comdats.back())
      Out << '\n';
  }

  // Output all globals.
  if (!M->global_empty()) Out << '\n';
  for (const GlobalVariable &GV : M->globals()) {
    printGlobal(&GV); Out << '\n';
  }

  // Output all aliases.
  if (!M->alias_empty()) Out << "\n";
  for (const GlobalAlias &GA : M->aliases())
    printIndirectSymbol(&GA);

  // Output all ifuncs.
  if (!M->ifunc_empty()) Out << "\n";
  for (const GlobalIFunc &GI : M->ifuncs())
    printIndirectSymbol(&GI);

  // Output global use-lists.
  printUseLists(nullptr);

  // Output all of the functions.
  for (const Function &F : *M) {
    Out << '\n';
    printFunction(&F);
  }
  assert(UseListOrders.empty() && "All use-lists should have been consumed");

  // Output all attribute groups.
  if (!Machine.as_empty()) {
    Out << '\n';
    writeAllAttributeGroups();
  }

  // Output named metadata.
  if (!M->named_metadata_empty()) Out << '\n';

  for (const NamedMDNode &Node : M->named_metadata())
    printNamedMDNode(&Node);

  // Output metadata.
  if (!Machine.mdn_empty()) {
    Out << '\n';
    writeAllMDNodes();
  }
}

void AssemblyWriter::printModuleSummaryIndex() {
  assert(TheIndex);
  int NumSlots = Machine.initializeIndexIfNeeded();

  Out << "\n";

  // Print module path entries. To print in order, add paths to a vector
  // indexed by module slot.
  std::vector<std::pair<std::string, ModuleHash>> moduleVec;
  std::string RegularLTOModuleName =
      ModuleSummaryIndex::getRegularLTOModuleName();
  moduleVec.resize(TheIndex->modulePaths().size());
  for (auto &ModPath : TheIndex->modulePaths())
    moduleVec[Machine.getModulePathSlot(ModPath.first())] = std::make_pair(
        // A module id of -1 is a special entry for a regular LTO module created
        // during the thin link.
        ModPath.second.first == -1u ? RegularLTOModuleName
                                    : (std::string)std::string(ModPath.first()),
        ModPath.second.second);

  unsigned i = 0;
  for (auto &ModPair : moduleVec) {
    Out << "^" << i++ << " = module: (";
    Out << "path: \"";
    printEscapedString(ModPair.first, Out);
    Out << "\", hash: (";
    FieldSeparator FS;
    for (auto Hash : ModPair.second)
      Out << FS << Hash;
    Out << "))\n";
  }

  // FIXME: Change AliasSummary to hold a ValueInfo instead of summary pointer
  // for aliasee (then update BitcodeWriter.cpp and remove get/setAliaseeGUID).
  for (auto &GlobalList : *TheIndex) {
    auto GUID = GlobalList.first;
    for (auto &Summary : GlobalList.second.SummaryList)
      SummaryToGUIDMap[Summary.get()] = GUID;
  }

  // Print the global value summary entries.
  for (auto &GlobalList : *TheIndex) {
    auto GUID = GlobalList.first;
    auto VI = TheIndex->getValueInfo(GlobalList);
    printSummaryInfo(Machine.getGUIDSlot(GUID), VI);
  }

  // Print the TypeIdMap entries.
  for (auto TidIter = TheIndex->typeIds().begin();
       TidIter != TheIndex->typeIds().end(); TidIter++) {
    Out << "^" << Machine.getTypeIdSlot(TidIter->second.first)
        << " = typeid: (name: \"" << TidIter->second.first << "\"";
    printTypeIdSummary(TidIter->second.second);
    Out << ") ; guid = " << TidIter->first << "\n";
  }

  // Print the TypeIdCompatibleVtableMap entries.
  for (auto &TId : TheIndex->typeIdCompatibleVtableMap()) {
    auto GUID = GlobalValue::getGUID(TId.first);
    Out << "^" << Machine.getGUIDSlot(GUID)
        << " = typeidCompatibleVTable: (name: \"" << TId.first << "\"";
    printTypeIdCompatibleVtableSummary(TId.second);
    Out << ") ; guid = " << GUID << "\n";
  }

  // Don't emit flags when it's not really needed (value is zero by default).
  if (TheIndex->getFlags()) {
    Out << "^" << NumSlots << " = flags: " << TheIndex->getFlags() << "\n";
    ++NumSlots;
  }

  Out << "^" << NumSlots << " = blockcount: " << TheIndex->getBlockCount()
      << "\n";
}

static const char *
getWholeProgDevirtResKindName(WholeProgramDevirtResolution::Kind K) {
  switch (K) {
  case WholeProgramDevirtResolution::Indir:
    return "indir";
  case WholeProgramDevirtResolution::SingleImpl:
    return "singleImpl";
  case WholeProgramDevirtResolution::BranchFunnel:
    return "branchFunnel";
  }
  llvm_unreachable("invalid WholeProgramDevirtResolution kind");
}

static const char *getWholeProgDevirtResByArgKindName(
    WholeProgramDevirtResolution::ByArg::Kind K) {
  switch (K) {
  case WholeProgramDevirtResolution::ByArg::Indir:
    return "indir";
  case WholeProgramDevirtResolution::ByArg::UniformRetVal:
    return "uniformRetVal";
  case WholeProgramDevirtResolution::ByArg::UniqueRetVal:
    return "uniqueRetVal";
  case WholeProgramDevirtResolution::ByArg::VirtualConstProp:
    return "virtualConstProp";
  }
  llvm_unreachable("invalid WholeProgramDevirtResolution::ByArg kind");
}

static const char *getTTResKindName(TypeTestResolution::Kind K) {
  switch (K) {
  case TypeTestResolution::Unsat:
    return "unsat";
  case TypeTestResolution::ByteArray:
    return "byteArray";
  case TypeTestResolution::Inline:
    return "inline";
  case TypeTestResolution::Single:
    return "single";
  case TypeTestResolution::AllOnes:
    return "allOnes";
  }
  llvm_unreachable("invalid TypeTestResolution kind");
}

void AssemblyWriter::printTypeTestResolution(const TypeTestResolution &TTRes) {
  Out << "typeTestRes: (kind: " << getTTResKindName(TTRes.TheKind)
      << ", sizeM1BitWidth: " << TTRes.SizeM1BitWidth;

  // The following fields are only used if the target does not support the use
  // of absolute symbols to store constants. Print only if non-zero.
  if (TTRes.AlignLog2)
    Out << ", alignLog2: " << TTRes.AlignLog2;
  if (TTRes.SizeM1)
    Out << ", sizeM1: " << TTRes.SizeM1;
  if (TTRes.BitMask)
    // BitMask is uint8_t which causes it to print the corresponding char.
    Out << ", bitMask: " << (unsigned)TTRes.BitMask;
  if (TTRes.InlineBits)
    Out << ", inlineBits: " << TTRes.InlineBits;

  Out << ")";
}

void AssemblyWriter::printTypeIdSummary(const TypeIdSummary &TIS) {
  Out << ", summary: (";
  printTypeTestResolution(TIS.TTRes);
  if (!TIS.WPDRes.empty()) {
    Out << ", wpdResolutions: (";
    FieldSeparator FS;
    for (auto &WPDRes : TIS.WPDRes) {
      Out << FS;
      Out << "(offset: " << WPDRes.first << ", ";
      printWPDRes(WPDRes.second);
      Out << ")";
    }
    Out << ")";
  }
  Out << ")";
}

void AssemblyWriter::printTypeIdCompatibleVtableSummary(
    const TypeIdCompatibleVtableInfo &TI) {
  Out << ", summary: (";
  FieldSeparator FS;
  for (auto &P : TI) {
    Out << FS;
    Out << "(offset: " << P.AddressPointOffset << ", ";
    Out << "^" << Machine.getGUIDSlot(P.VTableVI.getGUID());
    Out << ")";
  }
  Out << ")";
}

void AssemblyWriter::printArgs(const std::vector<uint64_t> &Args) {
  Out << "args: (";
  FieldSeparator FS;
  for (auto arg : Args) {
    Out << FS;
    Out << arg;
  }
  Out << ")";
}

void AssemblyWriter::printWPDRes(const WholeProgramDevirtResolution &WPDRes) {
  Out << "wpdRes: (kind: ";
  Out << getWholeProgDevirtResKindName(WPDRes.TheKind);

  if (WPDRes.TheKind == WholeProgramDevirtResolution::SingleImpl)
    Out << ", singleImplName: \"" << WPDRes.SingleImplName << "\"";

  if (!WPDRes.ResByArg.empty()) {
    Out << ", resByArg: (";
    FieldSeparator FS;
    for (auto &ResByArg : WPDRes.ResByArg) {
      Out << FS;
      printArgs(ResByArg.first);
      Out << ", byArg: (kind: ";
      Out << getWholeProgDevirtResByArgKindName(ResByArg.second.TheKind);
      if (ResByArg.second.TheKind ==
              WholeProgramDevirtResolution::ByArg::UniformRetVal ||
          ResByArg.second.TheKind ==
              WholeProgramDevirtResolution::ByArg::UniqueRetVal)
        Out << ", info: " << ResByArg.second.Info;

      // The following fields are only used if the target does not support the
      // use of absolute symbols to store constants. Print only if non-zero.
      if (ResByArg.second.Byte || ResByArg.second.Bit)
        Out << ", byte: " << ResByArg.second.Byte
            << ", bit: " << ResByArg.second.Bit;

      Out << ")";
    }
    Out << ")";
  }
  Out << ")";
}

static const char *getSummaryKindName(GlobalValueSummary::SummaryKind SK) {
  switch (SK) {
  case GlobalValueSummary::AliasKind:
    return "alias";
  case GlobalValueSummary::FunctionKind:
    return "function";
  case GlobalValueSummary::GlobalVarKind:
    return "variable";
  }
  llvm_unreachable("invalid summary kind");
}

void AssemblyWriter::printAliasSummary(const AliasSummary *AS) {
  Out << ", aliasee: ";
  // The indexes emitted for distributed backends may not include the
  // aliasee summary (only if it is being imported directly). Handle
  // that case by just emitting "null" as the aliasee.
  if (AS->hasAliasee())
    Out << "^" << Machine.getGUIDSlot(SummaryToGUIDMap[&AS->getAliasee()]);
  else
    Out << "null";
}

void AssemblyWriter::printGlobalVarSummary(const GlobalVarSummary *GS) {
  auto VTableFuncs = GS->vTableFuncs();
  Out << ", varFlags: (readonly: " << GS->VarFlags.MaybeReadOnly << ", "
      << "writeonly: " << GS->VarFlags.MaybeWriteOnly << ", "
      << "constant: " << GS->VarFlags.Constant;
  if (!VTableFuncs.empty())
    Out << ", "
        << "vcall_visibility: " << GS->VarFlags.VCallVisibility;
  Out << ")";

  if (!VTableFuncs.empty()) {
    Out << ", vTableFuncs: (";
    FieldSeparator FS;
    for (auto &P : VTableFuncs) {
      Out << FS;
      Out << "(virtFunc: ^" << Machine.getGUIDSlot(P.FuncVI.getGUID())
          << ", offset: " << P.VTableOffset;
      Out << ")";
    }
    Out << ")";
  }
}

static std::string getLinkageName(GlobalValue::LinkageTypes LT) {
  switch (LT) {
  case GlobalValue::ExternalLinkage:
    return "external";
  case GlobalValue::PrivateLinkage:
    return "private";
  case GlobalValue::InternalLinkage:
    return "internal";
  case GlobalValue::LinkOnceAnyLinkage:
    return "linkonce";
  case GlobalValue::LinkOnceODRLinkage:
    return "linkonce_odr";
  case GlobalValue::WeakAnyLinkage:
    return "weak";
  case GlobalValue::WeakODRLinkage:
    return "weak_odr";
  case GlobalValue::CommonLinkage:
    return "common";
  case GlobalValue::AppendingLinkage:
    return "appending";
  case GlobalValue::ExternalWeakLinkage:
    return "extern_weak";
  case GlobalValue::AvailableExternallyLinkage:
    return "available_externally";
  }
  llvm_unreachable("invalid linkage");
}

// When printing the linkage types in IR where the ExternalLinkage is
// not printed, and other linkage types are expected to be printed with
// a space after the name.
static std::string getLinkageNameWithSpace(GlobalValue::LinkageTypes LT) {
  if (LT == GlobalValue::ExternalLinkage)
    return "";
  return getLinkageName(LT) + " ";
}

void AssemblyWriter::printFunctionSummary(const FunctionSummary *FS) {
  Out << ", insts: " << FS->instCount();

  FunctionSummary::FFlags FFlags = FS->fflags();
  if (FFlags.ReadNone | FFlags.ReadOnly | FFlags.NoRecurse |
      FFlags.ReturnDoesNotAlias | FFlags.NoInline | FFlags.AlwaysInline) {
    Out << ", funcFlags: (";
    Out << "readNone: " << FFlags.ReadNone;
    Out << ", readOnly: " << FFlags.ReadOnly;
    Out << ", noRecurse: " << FFlags.NoRecurse;
    Out << ", returnDoesNotAlias: " << FFlags.ReturnDoesNotAlias;
    Out << ", noInline: " << FFlags.NoInline;
    Out << ", alwaysInline: " << FFlags.AlwaysInline;
    Out << ")";
  }
  if (!FS->calls().empty()) {
    Out << ", calls: (";
    FieldSeparator IFS;
    for (auto &Call : FS->calls()) {
      Out << IFS;
      Out << "(callee: ^" << Machine.getGUIDSlot(Call.first.getGUID());
      if (Call.second.getHotness() != CalleeInfo::HotnessType::Unknown)
        Out << ", hotness: " << getHotnessName(Call.second.getHotness());
      else if (Call.second.RelBlockFreq)
        Out << ", relbf: " << Call.second.RelBlockFreq;
      Out << ")";
    }
    Out << ")";
  }

  if (const auto *TIdInfo = FS->getTypeIdInfo())
    printTypeIdInfo(*TIdInfo);

  auto PrintRange = [&](const ConstantRange &Range) {
    Out << "[" << Range.getLower() << ", " << Range.getSignedMax() << "]";
  };

  if (!FS->paramAccesses().empty()) {
    Out << ", params: (";
    FieldSeparator IFS;
    for (auto &PS : FS->paramAccesses()) {
      Out << IFS;
      Out << "(param: " << PS.ParamNo;
      Out << ", offset: ";
      PrintRange(PS.Use);
      if (!PS.Calls.empty()) {
        Out << ", calls: (";
        FieldSeparator IFS;
        for (auto &Call : PS.Calls) {
          Out << IFS;
          Out << "(callee: ^" << Machine.getGUIDSlot(Call.Callee);
          Out << ", param: " << Call.ParamNo;
          Out << ", offset: ";
          PrintRange(Call.Offsets);
          Out << ")";
        }
        Out << ")";
      }
      Out << ")";
    }
    Out << ")";
  }
}

void AssemblyWriter::printTypeIdInfo(
    const FunctionSummary::TypeIdInfo &TIDInfo) {
  Out << ", typeIdInfo: (";
  FieldSeparator TIDFS;
  if (!TIDInfo.TypeTests.empty()) {
    Out << TIDFS;
    Out << "typeTests: (";
    FieldSeparator FS;
    for (auto &GUID : TIDInfo.TypeTests) {
      auto TidIter = TheIndex->typeIds().equal_range(GUID);
      if (TidIter.first == TidIter.second) {
        Out << FS;
        Out << GUID;
        continue;
      }
      // Print all type id that correspond to this GUID.
      for (auto It = TidIter.first; It != TidIter.second; ++It) {
        Out << FS;
        auto Slot = Machine.getTypeIdSlot(It->second.first);
        assert(Slot != -1);
        Out << "^" << Slot;
      }
    }
    Out << ")";
  }
  if (!TIDInfo.TypeTestAssumeVCalls.empty()) {
    Out << TIDFS;
    printNonConstVCalls(TIDInfo.TypeTestAssumeVCalls, "typeTestAssumeVCalls");
  }
  if (!TIDInfo.TypeCheckedLoadVCalls.empty()) {
    Out << TIDFS;
    printNonConstVCalls(TIDInfo.TypeCheckedLoadVCalls, "typeCheckedLoadVCalls");
  }
  if (!TIDInfo.TypeTestAssumeConstVCalls.empty()) {
    Out << TIDFS;
    printConstVCalls(TIDInfo.TypeTestAssumeConstVCalls,
                     "typeTestAssumeConstVCalls");
  }
  if (!TIDInfo.TypeCheckedLoadConstVCalls.empty()) {
    Out << TIDFS;
    printConstVCalls(TIDInfo.TypeCheckedLoadConstVCalls,
                     "typeCheckedLoadConstVCalls");
  }
  Out << ")";
}

void AssemblyWriter::printVFuncId(const FunctionSummary::VFuncId VFId) {
  auto TidIter = TheIndex->typeIds().equal_range(VFId.GUID);
  if (TidIter.first == TidIter.second) {
    Out << "vFuncId: (";
    Out << "guid: " << VFId.GUID;
    Out << ", offset: " << VFId.Offset;
    Out << ")";
    return;
  }
  // Print all type id that correspond to this GUID.
  FieldSeparator FS;
  for (auto It = TidIter.first; It != TidIter.second; ++It) {
    Out << FS;
    Out << "vFuncId: (";
    auto Slot = Machine.getTypeIdSlot(It->second.first);
    assert(Slot != -1);
    Out << "^" << Slot;
    Out << ", offset: " << VFId.Offset;
    Out << ")";
  }
}

void AssemblyWriter::printNonConstVCalls(
    const std::vector<FunctionSummary::VFuncId> &VCallList, const char *Tag) {
  Out << Tag << ": (";
  FieldSeparator FS;
  for (auto &VFuncId : VCallList) {
    Out << FS;
    printVFuncId(VFuncId);
  }
  Out << ")";
}

void AssemblyWriter::printConstVCalls(
    const std::vector<FunctionSummary::ConstVCall> &VCallList,
    const char *Tag) {
  Out << Tag << ": (";
  FieldSeparator FS;
  for (auto &ConstVCall : VCallList) {
    Out << FS;
    Out << "(";
    printVFuncId(ConstVCall.VFunc);
    if (!ConstVCall.Args.empty()) {
      Out << ", ";
      printArgs(ConstVCall.Args);
    }
    Out << ")";
  }
  Out << ")";
}

void AssemblyWriter::printSummary(const GlobalValueSummary &Summary) {
  GlobalValueSummary::GVFlags GVFlags = Summary.flags();
  GlobalValue::LinkageTypes LT = (GlobalValue::LinkageTypes)GVFlags.Linkage;
  Out << getSummaryKindName(Summary.getSummaryKind()) << ": ";
  Out << "(module: ^" << Machine.getModulePathSlot(Summary.modulePath())
      << ", flags: (";
  Out << "linkage: " << getLinkageName(LT);
  Out << ", notEligibleToImport: " << GVFlags.NotEligibleToImport;
  Out << ", live: " << GVFlags.Live;
  Out << ", dsoLocal: " << GVFlags.DSOLocal;
  Out << ", canAutoHide: " << GVFlags.CanAutoHide;
  Out << ")";

  if (Summary.getSummaryKind() == GlobalValueSummary::AliasKind)
    printAliasSummary(cast<AliasSummary>(&Summary));
  else if (Summary.getSummaryKind() == GlobalValueSummary::FunctionKind)
    printFunctionSummary(cast<FunctionSummary>(&Summary));
  else
    printGlobalVarSummary(cast<GlobalVarSummary>(&Summary));

  auto RefList = Summary.refs();
  if (!RefList.empty()) {
    Out << ", refs: (";
    FieldSeparator FS;
    for (auto &Ref : RefList) {
      Out << FS;
      if (Ref.isReadOnly())
        Out << "readonly ";
      else if (Ref.isWriteOnly())
        Out << "writeonly ";
      Out << "^" << Machine.getGUIDSlot(Ref.getGUID());
    }
    Out << ")";
  }

  Out << ")";
}

void AssemblyWriter::printSummaryInfo(unsigned Slot, const ValueInfo &VI) {
  Out << "^" << Slot << " = gv: (";
  if (!VI.name().empty())
    Out << "name: \"" << VI.name() << "\"";
  else
    Out << "guid: " << VI.getGUID();
  if (!VI.getSummaryList().empty()) {
    Out << ", summaries: (";
    FieldSeparator FS;
    for (auto &Summary : VI.getSummaryList()) {
      Out << FS;
      printSummary(*Summary);
    }
    Out << ")";
  }
  Out << ")";
  if (!VI.name().empty())
    Out << " ; guid = " << VI.getGUID();
  Out << "\n";
}

static void printMetadataIdentifier(StringRef Name,
                                    formatted_raw_ostream &Out) {
  if (Name.empty()) {
    Out << "<empty name> ";
  } else {
    if (isalpha(static_cast<unsigned char>(Name[0])) || Name[0] == '-' ||
        Name[0] == '$' || Name[0] == '.' || Name[0] == '_')
      Out << Name[0];
    else
      Out << '\\' << hexdigit(Name[0] >> 4) << hexdigit(Name[0] & 0x0F);
    for (unsigned i = 1, e = Name.size(); i != e; ++i) {
      unsigned char C = Name[i];
      if (isalnum(static_cast<unsigned char>(C)) || C == '-' || C == '$' ||
          C == '.' || C == '_')
        Out << C;
      else
        Out << '\\' << hexdigit(C >> 4) << hexdigit(C & 0x0F);
    }
  }
}

void AssemblyWriter::printNamedMDNode(const NamedMDNode *NMD) {
  Out << '!';
  printMetadataIdentifier(NMD->getName(), Out);
  Out << " = !{";
  for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
    if (i)
      Out << ", ";

    // Write DIExpressions inline.
    // FIXME: Ban DIExpressions in NamedMDNodes, they will serve no purpose.
    MDNode *Op = NMD->getOperand(i);
    if (auto *Expr = dyn_cast<DIExpression>(Op)) {
      writeDIExpression(Out, Expr, nullptr, nullptr, nullptr);
      continue;
    }

    int Slot = Machine.getMetadataSlot(Op);
    if (Slot == -1)
      Out << "<badref>";
    else
      Out << '!' << Slot;
  }
  Out << "}\n";
}

static void PrintVisibility(GlobalValue::VisibilityTypes Vis,
                            formatted_raw_ostream &Out) {
  switch (Vis) {
  case GlobalValue::DefaultVisibility: break;
  case GlobalValue::HiddenVisibility:    Out << "hidden "; break;
  case GlobalValue::ProtectedVisibility: Out << "protected "; break;
  }
}

static void PrintDSOLocation(const GlobalValue &GV,
                             formatted_raw_ostream &Out) {
  if (GV.isDSOLocal() && !GV.isImplicitDSOLocal())
    Out << "dso_local ";
}

static void PrintDLLStorageClass(GlobalValue::DLLStorageClassTypes SCT,
                                 formatted_raw_ostream &Out) {
  switch (SCT) {
  case GlobalValue::DefaultStorageClass: break;
  case GlobalValue::DLLImportStorageClass: Out << "dllimport "; break;
  case GlobalValue::DLLExportStorageClass: Out << "dllexport "; break;
  }
}

static void PrintThreadLocalModel(GlobalVariable::ThreadLocalMode TLM,
                                  formatted_raw_ostream &Out) {
  switch (TLM) {
    case GlobalVariable::NotThreadLocal:
      break;
    case GlobalVariable::GeneralDynamicTLSModel:
      Out << "thread_local ";
      break;
    case GlobalVariable::LocalDynamicTLSModel:
      Out << "thread_local(localdynamic) ";
      break;
    case GlobalVariable::InitialExecTLSModel:
      Out << "thread_local(initialexec) ";
      break;
    case GlobalVariable::LocalExecTLSModel:
      Out << "thread_local(localexec) ";
      break;
  }
}

static StringRef getUnnamedAddrEncoding(GlobalVariable::UnnamedAddr UA) {
  switch (UA) {
  case GlobalVariable::UnnamedAddr::None:
    return "";
  case GlobalVariable::UnnamedAddr::Local:
    return "local_unnamed_addr";
  case GlobalVariable::UnnamedAddr::Global:
    return "unnamed_addr";
  }
  llvm_unreachable("Unknown UnnamedAddr");
}

static void maybePrintComdat(formatted_raw_ostream &Out,
                             const GlobalObject &GO) {
  const Comdat *C = GO.getComdat();
  if (!C)
    return;

  if (isa<GlobalVariable>(GO))
    Out << ',';
  Out << " comdat";

  if (GO.getName() == C->getName())
    return;

  Out << '(';
  PrintLLVMName(Out, C->getName(), ComdatPrefix);
  Out << ')';
}

void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
  if (GV->isMaterializable())
    Out << "; Materializable\n";

  WriteAsOperandInternal(Out, GV, &TypePrinter, &Machine, GV->getParent());
  Out << " = ";

  if (!GV->hasInitializer() && GV->hasExternalLinkage())
    Out << "external ";

  Out << getLinkageNameWithSpace(GV->getLinkage());
  PrintDSOLocation(*GV, Out);
  PrintVisibility(GV->getVisibility(), Out);
  PrintDLLStorageClass(GV->getDLLStorageClass(), Out);
  PrintThreadLocalModel(GV->getThreadLocalMode(), Out);
  StringRef UA = getUnnamedAddrEncoding(GV->getUnnamedAddr());
  if (!UA.empty())
      Out << UA << ' ';

  if (unsigned AddressSpace = GV->getType()->getAddressSpace())
    Out << "addrspace(" << AddressSpace << ") ";
  if (GV->isExternallyInitialized()) Out << "externally_initialized ";
  Out << (GV->isConstant() ? "constant " : "global ");
  TypePrinter.print(GV->getValueType(), Out);

  if (GV->hasInitializer()) {
    Out << ' ';
    writeOperand(GV->getInitializer(), false);
  }

  if (GV->hasSection()) {
    Out << ", section \"";
    printEscapedString(GV->getSection(), Out);
    Out << '"';
  }
  if (GV->hasPartition()) {
    Out << ", partition \"";
    printEscapedString(GV->getPartition(), Out);
    Out << '"';
  }

  maybePrintComdat(Out, *GV);
  if (GV->getAlignment())
    Out << ", align " << GV->getAlignment();

  SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
  GV->getAllMetadata(MDs);
  printMetadataAttachments(MDs, ", ");

  auto Attrs = GV->getAttributes();
  if (Attrs.hasAttributes())
    Out << " #" << Machine.getAttributeGroupSlot(Attrs);

  printInfoComment(*GV);
}

void AssemblyWriter::printIndirectSymbol(const GlobalIndirectSymbol *GIS) {
  if (GIS->isMaterializable())
    Out << "; Materializable\n";

  WriteAsOperandInternal(Out, GIS, &TypePrinter, &Machine, GIS->getParent());
  Out << " = ";

  Out << getLinkageNameWithSpace(GIS->getLinkage());
  PrintDSOLocation(*GIS, Out);
  PrintVisibility(GIS->getVisibility(), Out);
  PrintDLLStorageClass(GIS->getDLLStorageClass(), Out);
  PrintThreadLocalModel(GIS->getThreadLocalMode(), Out);
  StringRef UA = getUnnamedAddrEncoding(GIS->getUnnamedAddr());
  if (!UA.empty())
      Out << UA << ' ';

  if (isa<GlobalAlias>(GIS))
    Out << "alias ";
  else if (isa<GlobalIFunc>(GIS))
    Out << "ifunc ";
  else
    llvm_unreachable("Not an alias or ifunc!");

  TypePrinter.print(GIS->getValueType(), Out);

  Out << ", ";

  const Constant *IS = GIS->getIndirectSymbol();

  if (!IS) {
    TypePrinter.print(GIS->getType(), Out);
    Out << " <<NULL ALIASEE>>";
  } else {
    writeOperand(IS, !isa<ConstantExpr>(IS));
  }

  if (GIS->hasPartition()) {
    Out << ", partition \"";
    printEscapedString(GIS->getPartition(), Out);
    Out << '"';
  }

  printInfoComment(*GIS);
  Out << '\n';
}

void AssemblyWriter::printComdat(const Comdat *C) {
  C->print(Out);
}

void AssemblyWriter::printTypeIdentities() {
  if (TypePrinter.empty())
    return;

  Out << '\n';

  // Emit all numbered types.
  auto &NumberedTypes = TypePrinter.getNumberedTypes();
  for (unsigned I = 0, E = NumberedTypes.size(); I != E; ++I) {
    Out << '%' << I << " = type ";

    // Make sure we print out at least one level of the type structure, so
    // that we do not get %2 = type %2
    TypePrinter.printStructBody(NumberedTypes[I], Out);
    Out << '\n';
  }

  auto &NamedTypes = TypePrinter.getNamedTypes();
  for (unsigned I = 0, E = NamedTypes.size(); I != E; ++I) {
    PrintLLVMName(Out, NamedTypes[I]->getName(), LocalPrefix);
    Out << " = type ";

    // Make sure we print out at least one level of the type structure, so
    // that we do not get %FILE = type %FILE
    TypePrinter.printStructBody(NamedTypes[I], Out);
    Out << '\n';
  }
}

/// printFunction - Print all aspects of a function.
void AssemblyWriter::printFunction(const Function *F) {
  if (AnnotationWriter) AnnotationWriter->emitFunctionAnnot(F, Out);

  if (F->isMaterializable())
    Out << "; Materializable\n";

  const AttributeList &Attrs = F->getAttributes();
  if (Attrs.hasAttributes(AttributeList::FunctionIndex)) {
    AttributeSet AS = Attrs.getFnAttributes();
    std::string AttrStr;

    for (const Attribute &Attr : AS) {
      if (!Attr.isStringAttribute()) {
        if (!AttrStr.empty()) AttrStr += ' ';
        AttrStr += Attr.getAsString();
      }
    }

    if (!AttrStr.empty())
      Out << "; Function Attrs: " << AttrStr << '\n';
  }

  Machine.incorporateFunction(F);

  if (F->isDeclaration()) {
    Out << "declare";
    SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
    F->getAllMetadata(MDs);
    printMetadataAttachments(MDs, " ");
    Out << ' ';
  } else
    Out << "define ";

  Out << getLinkageNameWithSpace(F->getLinkage());
  PrintDSOLocation(*F, Out);
  PrintVisibility(F->getVisibility(), Out);
  PrintDLLStorageClass(F->getDLLStorageClass(), Out);

  // Print the calling convention.
  if (F->getCallingConv() != CallingConv::C) {
    PrintCallingConv(F->getCallingConv(), Out);
    Out << " ";
  }

  FunctionType *FT = F->getFunctionType();
  if (Attrs.hasAttributes(AttributeList::ReturnIndex))
    Out << Attrs.getAsString(AttributeList::ReturnIndex) << ' ';
  TypePrinter.print(F->getReturnType(), Out);
  Out << ' ';
  WriteAsOperandInternal(Out, F, &TypePrinter, &Machine, F->getParent());
  Out << '(';

  // Loop over the arguments, printing them...
  if (F->isDeclaration() && !IsForDebug) {
    // We're only interested in the type here - don't print argument names.
    for (unsigned I = 0, E = FT->getNumParams(); I != E; ++I) {
      // Insert commas as we go... the first arg doesn't get a comma
      if (I)
        Out << ", ";
      // Output type...
      TypePrinter.print(FT->getParamType(I), Out);

      AttributeSet ArgAttrs = Attrs.getParamAttributes(I);
      if (ArgAttrs.hasAttributes()) {
        Out << ' ';
        writeAttributeSet(ArgAttrs);
      }
    }
  } else {
    // The arguments are meaningful here, print them in detail.
    for (const Argument &Arg : F->args()) {
      // Insert commas as we go... the first arg doesn't get a comma
      if (Arg.getArgNo() != 0)
        Out << ", ";
      printArgument(&Arg, Attrs.getParamAttributes(Arg.getArgNo()));
    }
  }

  // Finish printing arguments...
  if (FT->isVarArg()) {
    if (FT->getNumParams()) Out << ", ";
    Out << "...";  // Output varargs portion of signature!
  }
  Out << ')';
  StringRef UA = getUnnamedAddrEncoding(F->getUnnamedAddr());
  if (!UA.empty())
    Out << ' ' << UA;
  // We print the function address space if it is non-zero or if we are writing
  // a module with a non-zero program address space or if there is no valid
  // Module* so that the file can be parsed without the datalayout string.
  const Module *Mod = F->getParent();
  if (F->getAddressSpace() != 0 || !Mod ||
      Mod->getDataLayout().getProgramAddressSpace() != 0)
    Out << " addrspace(" << F->getAddressSpace() << ")";
  if (Attrs.hasAttributes(AttributeList::FunctionIndex))
    Out << " #" << Machine.getAttributeGroupSlot(Attrs.getFnAttributes());
  if (F->hasSection()) {
    Out << " section \"";
    printEscapedString(F->getSection(), Out);
    Out << '"';
  }
  if (F->hasPartition()) {
    Out << " partition \"";
    printEscapedString(F->getPartition(), Out);
    Out << '"';
  }
  maybePrintComdat(Out, *F);
  if (F->getAlignment())
    Out << " align " << F->getAlignment();
  if (F->hasGC())
    Out << " gc \"" << F->getGC() << '"';
  if (F->hasPrefixData()) {
    Out << " prefix ";
    writeOperand(F->getPrefixData(), true);
  }
  if (F->hasPrologueData()) {
    Out << " prologue ";
    writeOperand(F->getPrologueData(), true);
  }
  if (F->hasPersonalityFn()) {
    Out << " personality ";
    writeOperand(F->getPersonalityFn(), /*PrintType=*/true);
  }

  if (F->isDeclaration()) {
    Out << '\n';
  } else {
    SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
    F->getAllMetadata(MDs);
    printMetadataAttachments(MDs, " ");

    Out << " {";
    // Output all of the function's basic blocks.
    for (const BasicBlock &BB : *F)
      printBasicBlock(&BB);

    // Output the function's use-lists.
    printUseLists(F);

    Out << "}\n";
  }

  Machine.purgeFunction();
}

/// printArgument - This member is called for every argument that is passed into
/// the function.  Simply print it out
void AssemblyWriter::printArgument(const Argument *Arg, AttributeSet Attrs) {
  // Output type...
  TypePrinter.print(Arg->getType(), Out);

  // Output parameter attributes list
  if (Attrs.hasAttributes()) {
    Out << ' ';
    writeAttributeSet(Attrs);
  }

  // Output name, if available...
  if (Arg->hasName()) {
    Out << ' ';
    PrintLLVMName(Out, Arg);
  } else {
    int Slot = Machine.getLocalSlot(Arg);
    assert(Slot != -1 && "expect argument in function here");
    Out << " %" << Slot;
  }
}

/// printBasicBlock - This member is called for each basic block in a method.
void AssemblyWriter::printBasicBlock(const BasicBlock *BB) {
  assert(BB && BB->getParent() && "block without parent!");
  bool IsEntryBlock = BB == &BB->getParent()->getEntryBlock();
  if (BB->hasName()) {              // Print out the label if it exists...
    Out << "\n";
    PrintLLVMName(Out, BB->getName(), LabelPrefix);
    Out << ':';
  } else if (!IsEntryBlock) {
    Out << "\n";
    int Slot = Machine.getLocalSlot(BB);
    if (Slot != -1)
      Out << Slot << ":";
    else
      Out << "<badref>:";
  }

  if (!IsEntryBlock) {
    // Output predecessors for the block.
    Out.PadToColumn(50);
    Out << ";";
    const_pred_iterator PI = pred_begin(BB), PE = pred_end(BB);

    if (PI == PE) {
      Out << " No predecessors!";
    } else {
      Out << " preds = ";
      writeOperand(*PI, false);
      for (++PI; PI != PE; ++PI) {
        Out << ", ";
        writeOperand(*PI, false);
      }
    }
  }

  Out << "\n";

  if (AnnotationWriter) AnnotationWriter->emitBasicBlockStartAnnot(BB, Out);

  // Output all of the instructions in the basic block...
  for (const Instruction &I : *BB) {
    printInstructionLine(I);
  }

  if (AnnotationWriter) AnnotationWriter->emitBasicBlockEndAnnot(BB, Out);
}

/// printInstructionLine - Print an instruction and a newline character.
void AssemblyWriter::printInstructionLine(const Instruction &I) {
  printInstruction(I);
  Out << '\n';
}

/// printGCRelocateComment - print comment after call to the gc.relocate
/// intrinsic indicating base and derived pointer names.
void AssemblyWriter::printGCRelocateComment(const GCRelocateInst &Relocate) {
  Out << " ; (";
  writeOperand(Relocate.getBasePtr(), false);
  Out << ", ";
  writeOperand(Relocate.getDerivedPtr(), false);
  Out << ")";
}

/// printInfoComment - Print a little comment after the instruction indicating
/// which slot it occupies.
void AssemblyWriter::printInfoComment(const Value &V) {
  if (const auto *Relocate = dyn_cast<GCRelocateInst>(&V))
    printGCRelocateComment(*Relocate);

  if (AnnotationWriter)
    AnnotationWriter->printInfoComment(V, Out);
}

static void maybePrintCallAddrSpace(const Value *Operand, const Instruction *I,
                                    raw_ostream &Out) {
  // We print the address space of the call if it is non-zero.
  unsigned CallAddrSpace = Operand->getType()->getPointerAddressSpace();
  bool PrintAddrSpace = CallAddrSpace != 0;
  if (!PrintAddrSpace) {
    const Module *Mod = getModuleFromVal(I);
    // We also print it if it is zero but not equal to the program address space
    // or if we can't find a valid Module* to make it possible to parse
    // the resulting file even without a datalayout string.
    if (!Mod || Mod->getDataLayout().getProgramAddressSpace() != 0)
      PrintAddrSpace = true;
  }
  if (PrintAddrSpace)
    Out << " addrspace(" << CallAddrSpace << ")";
}

// This member is called for each Instruction in a function..
void AssemblyWriter::printInstruction(const Instruction &I) {
  if (AnnotationWriter) AnnotationWriter->emitInstructionAnnot(&I, Out);

  // Print out indentation for an instruction.
  Out << "  ";

  // Print out name if it exists...
  if (I.hasName()) {
    PrintLLVMName(Out, &I);
    Out << " = ";
  } else if (!I.getType()->isVoidTy()) {
    // Print out the def slot taken.
    int SlotNum = Machine.getLocalSlot(&I);
    if (SlotNum == -1)
      Out << "<badref> = ";
    else
      Out << '%' << SlotNum << " = ";
  }

  if (const CallInst *CI = dyn_cast<CallInst>(&I)) {
    if (CI->isMustTailCall())
      Out << "musttail ";
    else if (CI->isTailCall())
      Out << "tail ";
    else if (CI->isNoTailCall())
      Out << "notail ";
  }

  // Print out the opcode...
  Out << I.getOpcodeName();

  // If this is an atomic load or store, print out the atomic marker.
  if ((isa<LoadInst>(I)  && cast<LoadInst>(I).isAtomic()) ||
      (isa<StoreInst>(I) && cast<StoreInst>(I).isAtomic()))
    Out << " atomic";

  if (isa<AtomicCmpXchgInst>(I) && cast<AtomicCmpXchgInst>(I).isWeak())
    Out << " weak";

  // If this is a volatile operation, print out the volatile marker.
  if ((isa<LoadInst>(I)  && cast<LoadInst>(I).isVolatile()) ||
      (isa<StoreInst>(I) && cast<StoreInst>(I).isVolatile()) ||
      (isa<AtomicCmpXchgInst>(I) && cast<AtomicCmpXchgInst>(I).isVolatile()) ||
      (isa<AtomicRMWInst>(I) && cast<AtomicRMWInst>(I).isVolatile()))
    Out << " volatile";

  // Print out optimization information.
  WriteOptimizationInfo(Out, &I);

  // Print out the compare instruction predicates
  if (const CmpInst *CI = dyn_cast<CmpInst>(&I))
    Out << ' ' << CmpInst::getPredicateName(CI->getPredicate());

  // Print out the atomicrmw operation
  if (const AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(&I))
    Out << ' ' << AtomicRMWInst::getOperationName(RMWI->getOperation());

  // Print out the type of the operands...
  const Value *Operand = I.getNumOperands() ? I.getOperand(0) : nullptr;

  // Special case conditional branches to swizzle the condition out to the front
  if (isa<BranchInst>(I) && cast<BranchInst>(I).isConditional()) {
    const BranchInst &BI(cast<BranchInst>(I));
    Out << ' ';
    writeOperand(BI.getCondition(), true);
    Out << ", ";
    writeOperand(BI.getSuccessor(0), true);
    Out << ", ";
    writeOperand(BI.getSuccessor(1), true);

  } else if (isa<SwitchInst>(I)) {
    const SwitchInst& SI(cast<SwitchInst>(I));
    // Special case switch instruction to get formatting nice and correct.
    Out << ' ';
    writeOperand(SI.getCondition(), true);
    Out << ", ";
    writeOperand(SI.getDefaultDest(), true);
    Out << " [";
    for (auto Case : SI.cases()) {
      Out << "\n    ";
      writeOperand(Case.getCaseValue(), true);
      Out << ", ";
      writeOperand(Case.getCaseSuccessor(), true);
    }
    Out << "\n  ]";
  } else if (isa<IndirectBrInst>(I)) {
    // Special case indirectbr instruction to get formatting nice and correct.
    Out << ' ';
    writeOperand(Operand, true);
    Out << ", [";

    for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i) {
      if (i != 1)
        Out << ", ";
      writeOperand(I.getOperand(i), true);
    }
    Out << ']';
  } else if (const PHINode *PN = dyn_cast<PHINode>(&I)) {
    Out << ' ';
    TypePrinter.print(I.getType(), Out);
    Out << ' ';

    for (unsigned op = 0, Eop = PN->getNumIncomingValues(); op < Eop; ++op) {
      if (op) Out << ", ";
      Out << "[ ";
      writeOperand(PN->getIncomingValue(op), false); Out << ", ";
      writeOperand(PN->getIncomingBlock(op), false); Out << " ]";
    }
  } else if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(&I)) {
    Out << ' ';
    writeOperand(I.getOperand(0), true);
    for (const unsigned *i = EVI->idx_begin(), *e = EVI->idx_end(); i != e; ++i)
      Out << ", " << *i;
  } else if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(&I)) {
    Out << ' ';
    writeOperand(I.getOperand(0), true); Out << ", ";
    writeOperand(I.getOperand(1), true);
    for (const unsigned *i = IVI->idx_begin(), *e = IVI->idx_end(); i != e; ++i)
      Out << ", " << *i;
  } else if (const LandingPadInst *LPI = dyn_cast<LandingPadInst>(&I)) {
    Out << ' ';
    TypePrinter.print(I.getType(), Out);
    if (LPI->isCleanup() || LPI->getNumClauses() != 0)
      Out << '\n';

    if (LPI->isCleanup())
      Out << "          cleanup";

    for (unsigned i = 0, e = LPI->getNumClauses(); i != e; ++i) {
      if (i != 0 || LPI->isCleanup()) Out << "\n";
      if (LPI->isCatch(i))
        Out << "          catch ";
      else
        Out << "          filter ";

      writeOperand(LPI->getClause(i), true);
    }
  } else if (const auto *CatchSwitch = dyn_cast<CatchSwitchInst>(&I)) {
    Out << " within ";
    writeOperand(CatchSwitch->getParentPad(), /*PrintType=*/false);
    Out << " [";
    unsigned Op = 0;
    for (const BasicBlock *PadBB : CatchSwitch->handlers()) {
      if (Op > 0)
        Out << ", ";
      writeOperand(PadBB, /*PrintType=*/true);
      ++Op;
    }
    Out << "] unwind ";
    if (const BasicBlock *UnwindDest = CatchSwitch->getUnwindDest())
      writeOperand(UnwindDest, /*PrintType=*/true);
    else
      Out << "to caller";
  } else if (const auto *FPI = dyn_cast<FuncletPadInst>(&I)) {
    Out << " within ";
    writeOperand(FPI->getParentPad(), /*PrintType=*/false);
    Out << " [";
    for (unsigned Op = 0, NumOps = FPI->getNumArgOperands(); Op < NumOps;
         ++Op) {
      if (Op > 0)
        Out << ", ";
      writeOperand(FPI->getArgOperand(Op), /*PrintType=*/true);
    }
    Out << ']';
  } else if (isa<ReturnInst>(I) && !Operand) {
    Out << " void";
  } else if (const auto *CRI = dyn_cast<CatchReturnInst>(&I)) {
    Out << " from ";
    writeOperand(CRI->getOperand(0), /*PrintType=*/false);

    Out << " to ";
    writeOperand(CRI->getOperand(1), /*PrintType=*/true);
  } else if (const auto *CRI = dyn_cast<CleanupReturnInst>(&I)) {
    Out << " from ";
    writeOperand(CRI->getOperand(0), /*PrintType=*/false);

    Out << " unwind ";
    if (CRI->hasUnwindDest())
      writeOperand(CRI->getOperand(1), /*PrintType=*/true);
    else
      Out << "to caller";
  } else if (const CallInst *CI = dyn_cast<CallInst>(&I)) {
    // Print the calling convention being used.
    if (CI->getCallingConv() != CallingConv::C) {
      Out << " ";
      PrintCallingConv(CI->getCallingConv(), Out);
    }

    Operand = CI->getCalledOperand();
    FunctionType *FTy = CI->getFunctionType();
    Type *RetTy = FTy->getReturnType();
    const AttributeList &PAL = CI->getAttributes();

    if (PAL.hasAttributes(AttributeList::ReturnIndex))
      Out << ' ' << PAL.getAsString(AttributeList::ReturnIndex);

    // Only print addrspace(N) if necessary:
    maybePrintCallAddrSpace(Operand, &I, Out);

    // If possible, print out the short form of the call instruction.  We can
    // only do this if the first argument is a pointer to a nonvararg function,
    // and if the return type is not a pointer to a function.
    //
    Out << ' ';
    TypePrinter.print(FTy->isVarArg() ? FTy : RetTy, Out);
    Out << ' ';
    writeOperand(Operand, false);
    Out << '(';
    for (unsigned op = 0, Eop = CI->getNumArgOperands(); op < Eop; ++op) {
      if (op > 0)
        Out << ", ";
      writeParamOperand(CI->getArgOperand(op), PAL.getParamAttributes(op));
    }

    // Emit an ellipsis if this is a musttail call in a vararg function.  This
    // is only to aid readability, musttail calls forward varargs by default.
    if (CI->isMustTailCall() && CI->getParent() &&
        CI->getParent()->getParent() &&
        CI->getParent()->getParent()->isVarArg())
      Out << ", ...";

    Out << ')';
    if (PAL.hasAttributes(AttributeList::FunctionIndex))
      Out << " #" << Machine.getAttributeGroupSlot(PAL.getFnAttributes());

    writeOperandBundles(CI);
  } else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
    Operand = II->getCalledOperand();
    FunctionType *FTy = II->getFunctionType();
    Type *RetTy = FTy->getReturnType();
    const AttributeList &PAL = II->getAttributes();

    // Print the calling convention being used.
    if (II->getCallingConv() != CallingConv::C) {
      Out << " ";
      PrintCallingConv(II->getCallingConv(), Out);
    }

    if (PAL.hasAttributes(AttributeList::ReturnIndex))
      Out << ' ' << PAL.getAsString(AttributeList::ReturnIndex);

    // Only print addrspace(N) if necessary:
    maybePrintCallAddrSpace(Operand, &I, Out);

    // If possible, print out the short form of the invoke instruction. We can
    // only do this if the first argument is a pointer to a nonvararg function,
    // and if the return type is not a pointer to a function.
    //
    Out << ' ';
    TypePrinter.print(FTy->isVarArg() ? FTy : RetTy, Out);
    Out << ' ';
    writeOperand(Operand, false);
    Out << '(';
    for (unsigned op = 0, Eop = II->getNumArgOperands(); op < Eop; ++op) {
      if (op)
        Out << ", ";
      writeParamOperand(II->getArgOperand(op), PAL.getParamAttributes(op));
    }

    Out << ')';
    if (PAL.hasAttributes(AttributeList::FunctionIndex))
      Out << " #" << Machine.getAttributeGroupSlot(PAL.getFnAttributes());

    writeOperandBundles(II);

    Out << "\n          to ";
    writeOperand(II->getNormalDest(), true);
    Out << " unwind ";
    writeOperand(II->getUnwindDest(), true);
  } else if (const CallBrInst *CBI = dyn_cast<CallBrInst>(&I)) {
    Operand = CBI->getCalledOperand();
    FunctionType *FTy = CBI->getFunctionType();
    Type *RetTy = FTy->getReturnType();
    const AttributeList &PAL = CBI->getAttributes();

    // Print the calling convention being used.
    if (CBI->getCallingConv() != CallingConv::C) {
      Out << " ";
      PrintCallingConv(CBI->getCallingConv(), Out);
    }

    if (PAL.hasAttributes(AttributeList::ReturnIndex))
      Out << ' ' << PAL.getAsString(AttributeList::ReturnIndex);

    // If possible, print out the short form of the callbr instruction. We can
    // only do this if the first argument is a pointer to a nonvararg function,
    // and if the return type is not a pointer to a function.
    //
    Out << ' ';
    TypePrinter.print(FTy->isVarArg() ? FTy : RetTy, Out);
    Out << ' ';
    writeOperand(Operand, false);
    Out << '(';
    for (unsigned op = 0, Eop = CBI->getNumArgOperands(); op < Eop; ++op) {
      if (op)
        Out << ", ";
      writeParamOperand(CBI->getArgOperand(op), PAL.getParamAttributes(op));
    }

    Out << ')';
    if (PAL.hasAttributes(AttributeList::FunctionIndex))
      Out << " #" << Machine.getAttributeGroupSlot(PAL.getFnAttributes());

    writeOperandBundles(CBI);

    Out << "\n          to ";
    writeOperand(CBI->getDefaultDest(), true);
    Out << " [";
    for (unsigned i = 0, e = CBI->getNumIndirectDests(); i != e; ++i) {
      if (i != 0)
        Out << ", ";
      writeOperand(CBI->getIndirectDest(i), true);
    }
    Out << ']';
  } else if (const AllocaInst *AI = dyn_cast<AllocaInst>(&I)) {
    Out << ' ';
    if (AI->isUsedWithInAlloca())
      Out << "inalloca ";
    if (AI->isSwiftError())
      Out << "swifterror ";
    TypePrinter.print(AI->getAllocatedType(), Out);

    // Explicitly write the array size if the code is broken, if it's an array
    // allocation, or if the type is not canonical for scalar allocations.  The
    // latter case prevents the type from mutating when round-tripping through
    // assembly.
    if (!AI->getArraySize() || AI->isArrayAllocation() ||
        !AI->getArraySize()->getType()->isIntegerTy(32)) {
      Out << ", ";
      writeOperand(AI->getArraySize(), true);
    }
    if (AI->getAlignment()) {
      Out << ", align " << AI->getAlignment();
    }

    unsigned AddrSpace = AI->getType()->getAddressSpace();
    if (AddrSpace != 0) {
      Out << ", addrspace(" << AddrSpace << ')';
    }
  } else if (isa<CastInst>(I)) {
    if (Operand) {
      Out << ' ';
      writeOperand(Operand, true);   // Work with broken code
    }
    Out << " to ";
    TypePrinter.print(I.getType(), Out);
  } else if (isa<VAArgInst>(I)) {
    if (Operand) {
      Out << ' ';
      writeOperand(Operand, true);   // Work with broken code
    }
    Out << ", ";
    TypePrinter.print(I.getType(), Out);
  } else if (Operand) {   // Print the normal way.
    if (const auto *GEP = dyn_cast<GetElementPtrInst>(&I)) {
      Out << ' ';
      TypePrinter.print(GEP->getSourceElementType(), Out);
      Out << ',';
    } else if (const auto *LI = dyn_cast<LoadInst>(&I)) {
      Out << ' ';
      TypePrinter.print(LI->getType(), Out);
      Out << ',';
    }

    // PrintAllTypes - Instructions who have operands of all the same type
    // omit the type from all but the first operand.  If the instruction has
    // different type operands (for example br), then they are all printed.
    bool PrintAllTypes = false;
    Type *TheType = Operand->getType();

    // Select, Store and ShuffleVector always print all types.
    if (isa<SelectInst>(I) || isa<StoreInst>(I) || isa<ShuffleVectorInst>(I)
        || isa<ReturnInst>(I)) {
      PrintAllTypes = true;
    } else {
      for (unsigned i = 1, E = I.getNumOperands(); i != E; ++i) {
        Operand = I.getOperand(i);
        // note that Operand shouldn't be null, but the test helps make dump()
        // more tolerant of malformed IR
        if (Operand && Operand->getType() != TheType) {
          PrintAllTypes = true;    // We have differing types!  Print them all!
          break;
        }
      }
    }

    if (!PrintAllTypes) {
      Out << ' ';
      TypePrinter.print(TheType, Out);
    }

    Out << ' ';
    for (unsigned i = 0, E = I.getNumOperands(); i != E; ++i) {
      if (i) Out << ", ";
      writeOperand(I.getOperand(i), PrintAllTypes);
    }
  }

  // Print atomic ordering/alignment for memory operations
  if (const LoadInst *LI = dyn_cast<LoadInst>(&I)) {
    if (LI->isAtomic())
      writeAtomic(LI->getContext(), LI->getOrdering(), LI->getSyncScopeID());
    if (LI->getAlignment())
      Out << ", align " << LI->getAlignment();
  } else if (const StoreInst *SI = dyn_cast<StoreInst>(&I)) {
    if (SI->isAtomic())
      writeAtomic(SI->getContext(), SI->getOrdering(), SI->getSyncScopeID());
    if (SI->getAlignment())
      Out << ", align " << SI->getAlignment();
  } else if (const AtomicCmpXchgInst *CXI = dyn_cast<AtomicCmpXchgInst>(&I)) {
    writeAtomicCmpXchg(CXI->getContext(), CXI->getSuccessOrdering(),
                       CXI->getFailureOrdering(), CXI->getSyncScopeID());
  } else if (const AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(&I)) {
    writeAtomic(RMWI->getContext(), RMWI->getOrdering(),
                RMWI->getSyncScopeID());
  } else if (const FenceInst *FI = dyn_cast<FenceInst>(&I)) {
    writeAtomic(FI->getContext(), FI->getOrdering(), FI->getSyncScopeID());
  } else if (const ShuffleVectorInst *SVI = dyn_cast<ShuffleVectorInst>(&I)) {
    PrintShuffleMask(Out, SVI->getType(), SVI->getShuffleMask());
  }

  // Print Metadata info.
  SmallVector<std::pair<unsigned, MDNode *>, 4> InstMD;
  I.getAllMetadata(InstMD);
  printMetadataAttachments(InstMD, ", ");

  // Print a nice comment.
  printInfoComment(I);
}

void AssemblyWriter::printMetadataAttachments(
    const SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs,
    StringRef Separator) {
  if (MDs.empty())
    return;

  if (MDNames.empty())
    MDs[0].second->getContext().getMDKindNames(MDNames);

  for (const auto &I : MDs) {
    unsigned Kind = I.first;
    Out << Separator;
    if (Kind < MDNames.size()) {
      Out << "!";
      printMetadataIdentifier(MDNames[Kind], Out);
    } else
      Out << "!<unknown kind #" << Kind << ">";
    Out << ' ';
    WriteAsOperandInternal(Out, I.second, &TypePrinter, &Machine, TheModule);
  }
}

void AssemblyWriter::writeMDNode(unsigned Slot, const MDNode *Node) {
  Out << '!' << Slot << " = ";
  printMDNodeBody(Node);
  Out << "\n";
}

void AssemblyWriter::writeAllMDNodes() {
  SmallVector<const MDNode *, 16> Nodes;
  Nodes.resize(Machine.mdn_size());
  for (SlotTracker::mdn_iterator I = Machine.mdn_begin(), E = Machine.mdn_end();
       I != E; ++I)
    Nodes[I->second] = cast<MDNode>(I->first);

  for (unsigned i = 0, e = Nodes.size(); i != e; ++i) {
    writeMDNode(i, Nodes[i]);
  }
}

void AssemblyWriter::printMDNodeBody(const MDNode *Node) {
  WriteMDNodeBodyInternal(Out, Node, &TypePrinter, &Machine, TheModule);
}

void AssemblyWriter::writeAttribute(const Attribute &Attr, bool InAttrGroup) {
  if (!Attr.isTypeAttribute()) {
    Out << Attr.getAsString(InAttrGroup);
    return;
  }

  assert((Attr.hasAttribute(Attribute::ByVal) ||
          Attr.hasAttribute(Attribute::Preallocated)) &&
         "unexpected type attr");

  if (Attr.hasAttribute(Attribute::ByVal)) {
    Out << "byval";
  } else {
    Out << "preallocated";
  }

  if (Type *Ty = Attr.getValueAsType()) {
    Out << '(';
    TypePrinter.print(Ty, Out);
    Out << ')';
  }
}

void AssemblyWriter::writeAttributeSet(const AttributeSet &AttrSet,
                                       bool InAttrGroup) {
  bool FirstAttr = true;
  for (const auto &Attr : AttrSet) {
    if (!FirstAttr)
      Out << ' ';
    writeAttribute(Attr, InAttrGroup);
    FirstAttr = false;
  }
}

void AssemblyWriter::writeAllAttributeGroups() {
  std::vector<std::pair<AttributeSet, unsigned>> asVec;
  asVec.resize(Machine.as_size());

  for (SlotTracker::as_iterator I = Machine.as_begin(), E = Machine.as_end();
       I != E; ++I)
    asVec[I->second] = *I;

  for (const auto &I : asVec)
    Out << "attributes #" << I.second << " = { "
        << I.first.getAsString(true) << " }\n";
}

void AssemblyWriter::printUseListOrder(const UseListOrder &Order) {
  bool IsInFunction = Machine.getFunction();
  if (IsInFunction)
    Out << "  ";

  Out << "uselistorder";
  if (const BasicBlock *BB =
          IsInFunction ? nullptr : dyn_cast<BasicBlock>(Order.V)) {
    Out << "_bb ";
    writeOperand(BB->getParent(), false);
    Out << ", ";
    writeOperand(BB, false);
  } else {
    Out << " ";
    writeOperand(Order.V, true);
  }
  Out << ", { ";

  assert(Order.Shuffle.size() >= 2 && "Shuffle too small");
  Out << Order.Shuffle[0];
  for (unsigned I = 1, E = Order.Shuffle.size(); I != E; ++I)
    Out << ", " << Order.Shuffle[I];
  Out << " }\n";
}

void AssemblyWriter::printUseLists(const Function *F) {
  auto hasMore =
      [&]() { return !UseListOrders.empty() && UseListOrders.back().F == F; };
  if (!hasMore())
    // Nothing to do.
    return;

  Out << "\n; uselistorder directives\n";
  while (hasMore()) {
    printUseListOrder(UseListOrders.back());
    UseListOrders.pop_back();
  }
}

//===----------------------------------------------------------------------===//
//                       External Interface declarations
//===----------------------------------------------------------------------===//

void Function::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
                     bool ShouldPreserveUseListOrder,
                     bool IsForDebug) const {
  SlotTracker SlotTable(this->getParent());
  formatted_raw_ostream OS(ROS);
  AssemblyWriter W(OS, SlotTable, this->getParent(), AAW,
                   IsForDebug,
                   ShouldPreserveUseListOrder);
  W.printFunction(this);
}

void BasicBlock::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
                     bool ShouldPreserveUseListOrder,
                     bool IsForDebug) const {
  SlotTracker SlotTable(this->getModule());
  formatted_raw_ostream OS(ROS);
  AssemblyWriter W(OS, SlotTable, this->getModule(), AAW,
                   IsForDebug,
                   ShouldPreserveUseListOrder);
  W.printBasicBlock(this);
}

void Module::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
                   bool ShouldPreserveUseListOrder, bool IsForDebug) const {
  SlotTracker SlotTable(this);
  formatted_raw_ostream OS(ROS);
  AssemblyWriter W(OS, SlotTable, this, AAW, IsForDebug,
                   ShouldPreserveUseListOrder);
  W.printModule(this);
}

void NamedMDNode::print(raw_ostream &ROS, bool IsForDebug) const {
  SlotTracker SlotTable(getParent());
  formatted_raw_ostream OS(ROS);
  AssemblyWriter W(OS, SlotTable, getParent(), nullptr, IsForDebug);
  W.printNamedMDNode(this);
}

void NamedMDNode::print(raw_ostream &ROS, ModuleSlotTracker &MST,
                        bool IsForDebug) const {
  Optional<SlotTracker> LocalST;
  SlotTracker *SlotTable;
  if (auto *ST = MST.getMachine())
    SlotTable = ST;
  else {
    LocalST.emplace(getParent());
    SlotTable = &*LocalST;
  }

  formatted_raw_ostream OS(ROS);
  AssemblyWriter W(OS, *SlotTable, getParent(), nullptr, IsForDebug);
  W.printNamedMDNode(this);
}

void Comdat::print(raw_ostream &ROS, bool /*IsForDebug*/) const {
  PrintLLVMName(ROS, getName(), ComdatPrefix);
  ROS << " = comdat ";

  switch (getSelectionKind()) {
  case Comdat::Any:
    ROS << "any";
    break;
  case Comdat::ExactMatch:
    ROS << "exactmatch";
    break;
  case Comdat::Largest:
    ROS << "largest";
    break;
  case Comdat::NoDuplicates:
    ROS << "noduplicates";
    break;
  case Comdat::SameSize:
    ROS << "samesize";
    break;
  }

  ROS << '\n';
}

void Type::print(raw_ostream &OS, bool /*IsForDebug*/, bool NoDetails) const {
  TypePrinting TP;
  TP.print(const_cast<Type*>(this), OS);

  if (NoDetails)
    return;

  // If the type is a named struct type, print the body as well.
  if (StructType *STy = dyn_cast<StructType>(const_cast<Type*>(this)))
    if (!STy->isLiteral()) {
      OS << " = type ";
      TP.printStructBody(STy, OS);
    }
}

static bool isReferencingMDNode(const Instruction &I) {
  if (const auto *CI = dyn_cast<CallInst>(&I))
    if (Function *F = CI->getCalledFunction())
      if (F->isIntrinsic())
        for (auto &Op : I.operands())
          if (auto *V = dyn_cast_or_null<MetadataAsValue>(Op))
            if (isa<MDNode>(V->getMetadata()))
              return true;
  return false;
}

void Value::print(raw_ostream &ROS, bool IsForDebug) const {
  bool ShouldInitializeAllMetadata = false;
  if (auto *I = dyn_cast<Instruction>(this))
    ShouldInitializeAllMetadata = isReferencingMDNode(*I);
  else if (isa<Function>(this) || isa<MetadataAsValue>(this))
    ShouldInitializeAllMetadata = true;

  ModuleSlotTracker MST(getModuleFromVal(this), ShouldInitializeAllMetadata);
  print(ROS, MST, IsForDebug);
}

void Value::print(raw_ostream &ROS, ModuleSlotTracker &MST,
                  bool IsForDebug) const {
  formatted_raw_ostream OS(ROS);
  SlotTracker EmptySlotTable(static_cast<const Module *>(nullptr));
  SlotTracker &SlotTable =
      MST.getMachine() ? *MST.getMachine() : EmptySlotTable;
  auto incorporateFunction = [&](const Function *F) {
    if (F)
      MST.incorporateFunction(*F);
  };

  if (const Instruction *I = dyn_cast<Instruction>(this)) {
    incorporateFunction(I->getParent() ? I->getParent()->getParent() : nullptr);
    AssemblyWriter W(OS, SlotTable, getModuleFromVal(I), nullptr, IsForDebug);
    W.printInstruction(*I);
  } else if (const BasicBlock *BB = dyn_cast<BasicBlock>(this)) {
    incorporateFunction(BB->getParent());
    AssemblyWriter W(OS, SlotTable, getModuleFromVal(BB), nullptr, IsForDebug);
    W.printBasicBlock(BB);
  } else if (const GlobalValue *GV = dyn_cast<GlobalValue>(this)) {
    AssemblyWriter W(OS, SlotTable, GV->getParent(), nullptr, IsForDebug);
    if (const GlobalVariable *V = dyn_cast<GlobalVariable>(GV))
      W.printGlobal(V);
    else if (const Function *F = dyn_cast<Function>(GV))
      W.printFunction(F);
    else
      W.printIndirectSymbol(cast<GlobalIndirectSymbol>(GV));
  } else if (const MetadataAsValue *V = dyn_cast<MetadataAsValue>(this)) {
    V->getMetadata()->print(ROS, MST, getModuleFromVal(V));
  } else if (const Constant *C = dyn_cast<Constant>(this)) {
    TypePrinting TypePrinter;
    TypePrinter.print(C->getType(), OS);
    OS << ' ';
    WriteConstantInternal(OS, C, TypePrinter, MST.getMachine(), nullptr);
  } else if (isa<InlineAsm>(this) || isa<Argument>(this)) {
    this->printAsOperand(OS, /* PrintType */ true, MST);
  } else {
    llvm_unreachable("Unknown value to print out!");
  }
}

/// Print without a type, skipping the TypePrinting object.
///
/// \return \c true iff printing was successful.
static bool printWithoutType(const Value &V, raw_ostream &O,
                             SlotTracker *Machine, const Module *M) {
  if (V.hasName() || isa<GlobalValue>(V) ||
      (!isa<Constant>(V) && !isa<MetadataAsValue>(V))) {
    WriteAsOperandInternal(O, &V, nullptr, Machine, M);
    return true;
  }
  return false;
}

static void printAsOperandImpl(const Value &V, raw_ostream &O, bool PrintType,
                               ModuleSlotTracker &MST) {
  TypePrinting TypePrinter(MST.getModule());
  if (PrintType) {
    TypePrinter.print(V.getType(), O);
    O << ' ';
  }

  WriteAsOperandInternal(O, &V, &TypePrinter, MST.getMachine(),
                         MST.getModule());
}

void Value::printAsOperand(raw_ostream &O, bool PrintType,
                           const Module *M) const {
  if (!M)
    M = getModuleFromVal(this);

  if (!PrintType)
    if (printWithoutType(*this, O, nullptr, M))
      return;

  SlotTracker Machine(
      M, /* ShouldInitializeAllMetadata */ isa<MetadataAsValue>(this));
  ModuleSlotTracker MST(Machine, M);
  printAsOperandImpl(*this, O, PrintType, MST);
}

void Value::printAsOperand(raw_ostream &O, bool PrintType,
                           ModuleSlotTracker &MST) const {
  if (!PrintType)
    if (printWithoutType(*this, O, MST.getMachine(), MST.getModule()))
      return;

  printAsOperandImpl(*this, O, PrintType, MST);
}

static void printMetadataImpl(raw_ostream &ROS, const Metadata &MD,
                              ModuleSlotTracker &MST, const Module *M,
                              bool OnlyAsOperand) {
  formatted_raw_ostream OS(ROS);

  TypePrinting TypePrinter(M);

  WriteAsOperandInternal(OS, &MD, &TypePrinter, MST.getMachine(), M,
                         /* FromValue */ true);

  auto *N = dyn_cast<MDNode>(&MD);
  if (OnlyAsOperand || !N || isa<DIExpression>(MD))
    return;

  OS << " = ";
  WriteMDNodeBodyInternal(OS, N, &TypePrinter, MST.getMachine(), M);
}

void Metadata::printAsOperand(raw_ostream &OS, const Module *M) const {
  ModuleSlotTracker MST(M, isa<MDNode>(this));
  printMetadataImpl(OS, *this, MST, M, /* OnlyAsOperand */ true);
}

void Metadata::printAsOperand(raw_ostream &OS, ModuleSlotTracker &MST,
                              const Module *M) const {
  printMetadataImpl(OS, *this, MST, M, /* OnlyAsOperand */ true);
}

void Metadata::print(raw_ostream &OS, const Module *M,
                     bool /*IsForDebug*/) const {
  ModuleSlotTracker MST(M, isa<MDNode>(this));
  printMetadataImpl(OS, *this, MST, M, /* OnlyAsOperand */ false);
}

void Metadata::print(raw_ostream &OS, ModuleSlotTracker &MST,
                     const Module *M, bool /*IsForDebug*/) const {
  printMetadataImpl(OS, *this, MST, M, /* OnlyAsOperand */ false);
}

void ModuleSummaryIndex::print(raw_ostream &ROS, bool IsForDebug) const {
  SlotTracker SlotTable(this);
  formatted_raw_ostream OS(ROS);
  AssemblyWriter W(OS, SlotTable, this, IsForDebug);
  W.printModuleSummaryIndex();
}

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
// Value::dump - allow easy printing of Values from the debugger.
LLVM_DUMP_METHOD
void Value::dump() const { print(dbgs(), /*IsForDebug=*/true); dbgs() << '\n'; }

// Type::dump - allow easy printing of Types from the debugger.
LLVM_DUMP_METHOD
void Type::dump() const { print(dbgs(), /*IsForDebug=*/true); dbgs() << '\n'; }

// Module::dump() - Allow printing of Modules from the debugger.
LLVM_DUMP_METHOD
void Module::dump() const {
  print(dbgs(), nullptr,
        /*ShouldPreserveUseListOrder=*/false, /*IsForDebug=*/true);
}

// Allow printing of Comdats from the debugger.
LLVM_DUMP_METHOD
void Comdat::dump() const { print(dbgs(), /*IsForDebug=*/true); }

// NamedMDNode::dump() - Allow printing of NamedMDNodes from the debugger.
LLVM_DUMP_METHOD
void NamedMDNode::dump() const { print(dbgs(), /*IsForDebug=*/true); }

LLVM_DUMP_METHOD
void Metadata::dump() const { dump(nullptr); }

LLVM_DUMP_METHOD
void Metadata::dump(const Module *M) const {
  print(dbgs(), M, /*IsForDebug=*/true);
  dbgs() << '\n';
}

// Allow printing of ModuleSummaryIndex from the debugger.
LLVM_DUMP_METHOD
void ModuleSummaryIndex::dump() const { print(dbgs(), /*IsForDebug=*/true); }
#endif
