//===--- SILPrinter.cpp - Pretty-printing of SIL Code ---------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
///
/// \file
///
/// This file defines the logic to pretty-print SIL, Instructions, etc.
///
//===----------------------------------------------------------------------===//

#include "swift/Strings.h"
#include "swift/Demangling/Demangle.h"
#include "swift/Basic/QuotedString.h"
#include "swift/SIL/SILPrintContext.h"
#include "swift/SIL/ApplySite.h"
#include "swift/SIL/CFG.h"
#include "swift/SIL/SILFunction.h"
#include "swift/SIL/SILCoverageMap.h"
#include "swift/SIL/SILDebugScope.h"
#include "swift/SIL/SILDeclRef.h"
#include "swift/SIL/SILModule.h"
#include "swift/SIL/SILVisitor.h"
#include "swift/SIL/SILVTable.h"
#include "swift/AST/Decl.h"
#include "swift/AST/GenericEnvironment.h"
#include "swift/AST/Module.h"
#include "swift/AST/PrintOptions.h"
#include "swift/AST/ProtocolConformance.h"
#include "swift/AST/Types.h"
#include "swift/Basic/STLExtras.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/FileSystem.h"


using namespace swift;
using ID = SILPrintContext::ID;

llvm::cl::opt<bool>
SILPrintNoColor("sil-print-no-color", llvm::cl::init(""),
                llvm::cl::desc("Don't use color when printing SIL"));

llvm::cl::opt<bool>
SILFullDemangle("sil-full-demangle", llvm::cl::init(false),
                llvm::cl::desc("Fully demangle symbol names in SIL output"));

llvm::cl::opt<bool>
SILPrintDebugInfo("sil-print-debuginfo", llvm::cl::init(false),
                llvm::cl::desc("Include debug info in SIL output"));

llvm::cl::opt<bool> SILPrintGenericSpecializationInfo(
    "sil-print-generic-specialization-info", llvm::cl::init(false),
    llvm::cl::desc("Include generic specialization"
                   "information info in SIL output"));

static std::string demangleSymbol(StringRef Name) {
  if (SILFullDemangle)
    return Demangle::demangleSymbolAsString(Name);
  return Demangle::demangleSymbolAsString(Name,
                    Demangle::DemangleOptions::SimplifiedUIDemangleOptions());
}

enum SILColorKind {
  SC_Type,
};

namespace {
/// RAII based coloring of SIL output.
class SILColor {
  raw_ostream &OS;
  enum raw_ostream::Colors Color;
public:
#define DEF_COL(NAME, RAW) case NAME: Color = raw_ostream::RAW; break;

  explicit SILColor(raw_ostream &OS, SILColorKind K) : OS(OS) {
    if (!OS.has_colors() || SILPrintNoColor)
      return;
    switch (K) {
      DEF_COL(SC_Type, YELLOW)
    }
    OS.resetColor();
    OS.changeColor(Color);
  }

  explicit SILColor(raw_ostream &OS, ID::ID_Kind K) : OS(OS) {
    if (!OS.has_colors() || SILPrintNoColor)
      return;
    switch (K) {
      DEF_COL(ID::SILUndef, RED)
      DEF_COL(ID::SILBasicBlock, GREEN)
      DEF_COL(ID::SSAValue, MAGENTA)
      DEF_COL(ID::Null, YELLOW)
    }
    OS.resetColor();
    OS.changeColor(Color);
  }
  
  ~SILColor() {
    if (!OS.has_colors() || SILPrintNoColor)
      return;
    // FIXME: instead of resetColor(), we can look into
    // capturing the current active color and restoring it.
    OS.resetColor();
  }
#undef DEF_COL
};
} // end anonymous namespace

void SILPrintContext::ID::print(raw_ostream &OS) {
  SILColor C(OS, Kind);
  switch (Kind) {
  case ID::SILUndef:
    OS << "undef";
    return;
  case ID::SILBasicBlock: OS << "bb"; break;
  case ID::SSAValue: OS << '%'; break;
  case ID::Null: OS << "<<NULL OPERAND>>"; return;
  }
  OS << Number;
}

namespace swift {
raw_ostream &operator<<(raw_ostream &OS, SILPrintContext::ID i) {
  i.print(OS);
  return OS;
}
} // namespace swift

/// IDAndType - Used when a client wants to print something like "%0 : $Int".
struct SILValuePrinterInfo {
  ID ValueID;
  SILType Type;
  Optional<ValueOwnershipKind> OwnershipKind;

  SILValuePrinterInfo(ID ValueID) : ValueID(ValueID), Type(), OwnershipKind() {}
  SILValuePrinterInfo(ID ValueID, SILType Type)
      : ValueID(ValueID), Type(Type), OwnershipKind() {}
  SILValuePrinterInfo(ID ValueID, SILType Type,
                      ValueOwnershipKind OwnershipKind)
      : ValueID(ValueID), Type(Type), OwnershipKind(OwnershipKind) {}
};

/// Return the fully qualified dotted path for DeclContext.
static void printFullContext(const DeclContext *Context, raw_ostream &Buffer) {
  if (!Context)
    return;
  switch (Context->getContextKind()) {
  case DeclContextKind::Module:
    if (Context == cast<ModuleDecl>(Context)->getASTContext().TheBuiltinModule)
      Buffer << cast<ModuleDecl>(Context)->getName() << ".";
    return;

  case DeclContextKind::FileUnit:
    // Ignore the file; just print the module.
    printFullContext(Context->getParent(), Buffer);
    return;

  case DeclContextKind::Initializer:
    // FIXME
    Buffer << "<initializer>";
    return;

  case DeclContextKind::AbstractClosureExpr:
    // FIXME
    Buffer << "<anonymous function>";
    return;

  case DeclContextKind::SerializedLocal:
    Buffer << "<serialized local context>";
    return;

  case DeclContextKind::GenericTypeDecl: {
    auto *generic = cast<GenericTypeDecl>(Context);
    printFullContext(generic->getDeclContext(), Buffer);
    Buffer << generic->getName() << ".";
    return;
  }

  case DeclContextKind::ExtensionDecl: {
    const NominalTypeDecl *ExtNominal =
      cast<ExtensionDecl>(Context)->getExtendedNominal();
    printFullContext(ExtNominal->getDeclContext(), Buffer);
    Buffer << ExtNominal->getName() << ".";
    return;
  }
  
  case DeclContextKind::TopLevelCodeDecl:
    // FIXME
    Buffer << "<top level code>";
    return;
  case DeclContextKind::AbstractFunctionDecl:
    // FIXME
    Buffer << "<abstract function>";
    return;
  case DeclContextKind::SubscriptDecl:
    // FIXME
    Buffer << "<subscript>";
    return;
  case DeclContextKind::EnumElementDecl:
    // FIXME
    Buffer << "<enum element>";
    return;
  }
  llvm_unreachable("bad decl context");
}

static void printValueDecl(ValueDecl *Decl, raw_ostream &OS) {
  printFullContext(Decl->getDeclContext(), OS);
  assert(Decl->hasName());

  if (Decl->isOperator()) {
    OS << '"' << Decl->getBaseName() << '"';
  } else {
    bool shouldEscape = !Decl->getBaseName().isSpecial() &&
        llvm::StringSwitch<bool>(Decl->getBaseName().userFacingName())
            // FIXME: Represent "init" by a special name and remove this case
            .Case("init", false)
#define KEYWORD(kw) \
            .Case(#kw, true)
#include "swift/Syntax/TokenKinds.def"
            .Default(false);

    if (shouldEscape) {
      OS << '`' << Decl->getBaseName().userFacingName() << '`';
    } else {
      OS << Decl->getBaseName().userFacingName();
    }
  }
}

/// SILDeclRef uses sigil "#" and prints the fully qualified dotted path.
void SILDeclRef::print(raw_ostream &OS) const {
  OS << "#";
  if (isNull()) {
    OS << "<null>";
    return;
  }

  bool isDot = true;
  if (!hasDecl()) {
    OS << "<anonymous function>";
  } else if (kind == SILDeclRef::Kind::Func) {
    auto *FD = cast<FuncDecl>(getDecl());
    auto accessor = dyn_cast<AccessorDecl>(FD);
    if (!accessor) {
      printValueDecl(FD, OS);
      isDot = false;
    } else {
      switch (accessor->getAccessorKind()) {
      case AccessorKind::WillSet:
        printValueDecl(accessor->getStorage(), OS);
        OS << "!willSet";
        break;
      case AccessorKind::DidSet:
        printValueDecl(accessor->getStorage(), OS);
        OS << "!didSet";
        break;
      case AccessorKind::Get:
        printValueDecl(accessor->getStorage(), OS);
        OS << "!getter";
        break;
      case AccessorKind::Set:
        printValueDecl(accessor->getStorage(), OS);
        OS << "!setter";
        break;
      case AccessorKind::Address:
        printValueDecl(accessor->getStorage(), OS);
        OS << "!addressor";
        break;
      case AccessorKind::MutableAddress:
        printValueDecl(accessor->getStorage(), OS);
        OS << "!mutableAddressor";
        break;
      case AccessorKind::Read:
        printValueDecl(accessor->getStorage(), OS);
        OS << "!read";
        break;
      case AccessorKind::Modify:
        printValueDecl(accessor->getStorage(), OS);
        OS << "!modify";
        break;
      }
    }
  } else {
    printValueDecl(getDecl(), OS);
  }
  switch (kind) {
  case SILDeclRef::Kind::Func:
    break;
  case SILDeclRef::Kind::Allocator:
    OS << "!allocator";
    break;
  case SILDeclRef::Kind::Initializer:
    OS << "!initializer";
    break;
  case SILDeclRef::Kind::EnumElement:
    OS << "!enumelt";
    break;
  case SILDeclRef::Kind::Destroyer:
    OS << "!destroyer";
    break;
  case SILDeclRef::Kind::Deallocator:
    OS << "!deallocator";
    break;
  case SILDeclRef::Kind::IVarInitializer:
    OS << "!ivarinitializer";
    break;
  case SILDeclRef::Kind::IVarDestroyer:
    OS << "!ivardestroyer";
    break;
  case SILDeclRef::Kind::GlobalAccessor:
    OS << "!globalaccessor";
    break;
  case SILDeclRef::Kind::DefaultArgGenerator:
    OS << "!defaultarg" << "." << defaultArgIndex;
    break;
  case SILDeclRef::Kind::StoredPropertyInitializer:
    OS << "!propertyinit";
    break;
  }

  auto uncurryLevel = getParameterListCount() - 1;
  if (uncurryLevel != 0)
    OS << (isDot ? '.' : '!')  << uncurryLevel;

  if (isForeign)
    OS << ((isDot || uncurryLevel != 0) ? '.' : '!')  << "foreign";

  if (isDirectReference)
    OS << ((isDot || uncurryLevel != 0) ? '.' : '!')  << "direct";
}

void SILDeclRef::dump() const {
  print(llvm::errs());
  llvm::errs() << '\n';
}

/// Pretty-print the generic specialization information.
static void printGenericSpecializationInfo(
    raw_ostream &OS, StringRef Kind, StringRef Name,
    const GenericSpecializationInformation *SpecializationInfo,
    SubstitutionMap Subs = { }) {
  if (!SpecializationInfo)
    return;

  auto PrintSubstitutions = [&](SubstitutionMap Subs) {
    OS << '<';
    interleave(Subs.getReplacementTypes(),
               [&](Type type) { OS << type; },
               [&] { OS << ", "; });
    OS << '>';
  };

  OS << "// Generic specialization information for " << Kind << " " << Name;
  if (!Subs.empty()) {
    OS << " ";
    PrintSubstitutions(Subs);
  }

  OS << ":\n";

  while (SpecializationInfo) {
    OS << "// Caller: " << SpecializationInfo->getCaller()->getName() << '\n';
    OS << "// Parent: " << SpecializationInfo->getParent()->getName() << '\n';
    OS << "// Substitutions: ";
    PrintSubstitutions(SpecializationInfo->getSubstitutions());
    OS << '\n';
    OS << "//\n";
    if (!SpecializationInfo->getCaller()->isSpecialization())
      return;
    SpecializationInfo =
      SpecializationInfo->getCaller()->getSpecializationInfo();
  }
}

static void print(raw_ostream &OS, SILValueCategory category) {
  switch (category) {
  case SILValueCategory::Object: return;
  case SILValueCategory::Address: OS << '*'; return;
  }
  llvm_unreachable("bad value category!");
}

static StringRef getCastConsumptionKindName(CastConsumptionKind kind) {
  switch (kind) {
  case CastConsumptionKind::TakeAlways: return "take_always";
  case CastConsumptionKind::TakeOnSuccess: return "take_on_success";
  case CastConsumptionKind::CopyOnSuccess: return "copy_on_success";
  case CastConsumptionKind::BorrowAlways: return "borrow_always";
  }
  llvm_unreachable("bad cast consumption kind");
}

static void printSILTypeColorAndSigil(raw_ostream &OS, SILType t) {
  SILColor C(OS, SC_Type);
  OS << '$';
  
  // Potentially add a leading sigil for the value category.
  ::print(OS, t.getCategory());
}
      
void SILType::print(raw_ostream &OS) const {
  printSILTypeColorAndSigil(OS, *this);
  
  // Print other types as their Swift representation.
  PrintOptions SubPrinter = PrintOptions::printSIL();
  getASTType().print(OS, SubPrinter);
}

void SILType::dump() const {
  print(llvm::errs());
  llvm::errs() << '\n';
}

namespace {
  
class SILPrinter;

/// SILPrinter class - This holds the internal implementation details of
/// printing SIL structures.
class SILPrinter : public SILInstructionVisitor<SILPrinter> {
  SILPrintContext &Ctx;
  struct {
    llvm::formatted_raw_ostream OS;
    PrintOptions ASTOptions;
  } PrintState;
  unsigned LastBufferID;

  // Printers for the underlying stream.
#define SIMPLE_PRINTER(TYPE) \
  SILPrinter &operator<<(TYPE value) { \
    PrintState.OS << value;            \
    return *this;                      \
  }
  SIMPLE_PRINTER(char)
  SIMPLE_PRINTER(unsigned)
  SIMPLE_PRINTER(uint64_t)
  SIMPLE_PRINTER(StringRef)
  SIMPLE_PRINTER(Identifier)
  SIMPLE_PRINTER(ID)
  SIMPLE_PRINTER(QuotedString)
  SIMPLE_PRINTER(SILDeclRef)
  SIMPLE_PRINTER(APInt)
  SIMPLE_PRINTER(ValueOwnershipKind)
#undef SIMPLE_PRINTER

  SILPrinter &operator<<(SILValuePrinterInfo i) {
    SILColor C(PrintState.OS, SC_Type);
    *this << i.ValueID;
    if (!i.Type)
      return *this;
    *this << " : ";
    if (i.OwnershipKind && *i.OwnershipKind != ValueOwnershipKind::Any) {
      *this << "@" << i.OwnershipKind.getValue() << " ";
    }
    return *this << i.Type;
  }

  SILPrinter &operator<<(Type t) {
    // Print the type using our print options.
    t.print(PrintState.OS, PrintState.ASTOptions);
    return *this;
  }
  
  SILPrinter &operator<<(SILType t) {
    printSILTypeColorAndSigil(PrintState.OS, t);
    t.getASTType().print(PrintState.OS, PrintState.ASTOptions);
    return *this;
  }
  
public:
  SILPrinter(
      SILPrintContext &PrintCtx,
      llvm::DenseMap<CanType, Identifier> *AlternativeTypeNames = nullptr)
      : Ctx(PrintCtx),
        PrintState{{PrintCtx.OS()}, PrintOptions::printSIL()},
        LastBufferID(0) {
    PrintState.ASTOptions.AlternativeTypeNames = AlternativeTypeNames;
    PrintState.ASTOptions.PrintForSIL = true;
  }

  SILValuePrinterInfo getIDAndType(SILValue V) {
    return {Ctx.getID(V), V ? V->getType() : SILType()};
  }
  SILValuePrinterInfo getIDAndTypeAndOwnership(SILValue V) {
    return {Ctx.getID(V), V ? V->getType() : SILType(), V.getOwnershipKind()};
  }

  //===--------------------------------------------------------------------===//
  // Big entrypoints.
  void print(const SILFunction *F) {
    // If we are asked to emit sorted SIL, print out our BBs in RPOT order.
    if (Ctx.sortSIL()) {
      std::vector<SILBasicBlock *> RPOT;
      auto *UnsafeF = const_cast<SILFunction *>(F);
      std::copy(po_begin(UnsafeF), po_end(UnsafeF),
                std::back_inserter(RPOT));
      std::reverse(RPOT.begin(), RPOT.end());
      Ctx.initBlockIDs(RPOT);
      interleave(RPOT,
                 [&](SILBasicBlock *B) { print(B); },
                 [&] { *this << '\n'; });
      return;
    }

    interleave(*F,
               [&](const SILBasicBlock &B) { print(&B); },
               [&] { *this << '\n'; });
  }

  void printBlockArgumentUses(const SILBasicBlock *BB) {
    if (BB->args_empty())
      return;

    for (SILValue V : BB->getArguments()) {
      if (V->use_empty())
        continue;
      *this << "// " << Ctx.getID(V);
      PrintState.OS.PadToColumn(50);
      *this << "// user";
      if (std::next(V->use_begin()) != V->use_end())
        *this << 's';
      *this << ": ";

      llvm::SmallVector<ID, 32> UserIDs;
      for (auto *Op : V->getUses())
        UserIDs.push_back(Ctx.getID(Op->getUser()));

      // Display the user ids sorted to give a stable use order in the
      // printer's output if we are asked to do so. This makes diffing large
      // sections of SIL significantly easier at the expense of not showing
      // the _TRUE_ order of the users in the use list.
      if (Ctx.sortSIL()) {
        std::sort(UserIDs.begin(), UserIDs.end());
      }

      interleave(UserIDs.begin(), UserIDs.end(),
                 [&] (ID id) { *this << id; },
                 [&] { *this << ", "; });
      *this << '\n';
    }
  }

  void printBlockArguments(const SILBasicBlock *BB) {
    if (BB->args_empty())
      return;
    *this << '(';
    ArrayRef<SILArgument *> Args = BB->getArguments();

    // If SIL ownership is enabled and the given function has not had ownership
    // stripped out, print out ownership of SILArguments.
    if (BB->getParent()->hasOwnership()) {
      *this << getIDAndTypeAndOwnership(Args[0]);
      for (SILArgument *Arg : Args.drop_front()) {
        *this << ", " << getIDAndTypeAndOwnership(Arg);
      }
      *this << ')';
      return;
    }

    // Otherwise, fall back to the old behavior
    *this << getIDAndType(Args[0]);
    for (SILArgument *Arg : Args.drop_front()) {
      *this << ", " << getIDAndType(Arg);
    }
    *this << ')';
  }

  void print(const SILBasicBlock *BB) {
    // Output uses for BB arguments. These are put into place as comments before
    // the block header.
    printBlockArgumentUses(BB);

    // Then print the name of our block, the arguments, and the block colon.
    *this << Ctx.getID(BB);
    printBlockArguments(BB);
    *this << ":";

    if (!BB->pred_empty()) {
      PrintState.OS.PadToColumn(50);
      
      *this << "// Preds:";

      llvm::SmallVector<ID, 32> PredIDs;
      for (auto *BBI : BB->getPredecessorBlocks())
        PredIDs.push_back(Ctx.getID(BBI));

      // Display the pred ids sorted to give a stable use order in the printer's
      // output if we are asked to do so. This makes diffing large sections of
      // SIL significantly easier at the expense of not showing the _TRUE_ order
      // of the users in the use list.
      if (Ctx.sortSIL()) {
        std::sort(PredIDs.begin(), PredIDs.end());
      }

      for (auto Id : PredIDs)
        *this << ' ' << Id;
    }
    *this << '\n';

    for (const SILInstruction &I : *BB) {
      Ctx.printInstructionCallBack(&I);
      if (SILPrintGenericSpecializationInfo) {
        if (auto AI = ApplySite::isa(const_cast<SILInstruction *>(&I)))
          if (AI.getSpecializationInfo() && AI.getCalleeFunction())
            printGenericSpecializationInfo(
                PrintState.OS, "call-site", AI.getCalleeFunction()->getName(),
                AI.getSpecializationInfo(), AI.getSubstitutionMap());
      }
      print(&I);
    }
  }

  //===--------------------------------------------------------------------===//
  // SILInstruction Printing Logic

  bool printTypeDependentOperands(const SILInstruction *I) {
    ArrayRef<Operand> TypeDepOps = I->getTypeDependentOperands();
    if (TypeDepOps.empty())
      return false;

    PrintState.OS.PadToColumn(50);
    *this << "// type-defs: ";
    interleave(TypeDepOps,
               [&](const Operand &op) { *this << Ctx.getID(op.get()); },
               [&] { *this << ", "; });
    return true;
  }

  /// Print out the users of the SILValue \p V. Return true if we printed out
  /// either an id or a use list. Return false otherwise.
  bool printUsersOfSILNode(const SILNode *node, bool printedSlashes) {
    llvm::SmallVector<SILValue, 8> values;
    if (auto *value = dyn_cast<ValueBase>(node)) {
      values.push_back(value);
    } else if (auto *inst = dyn_cast<SILInstruction>(node)) {
      assert(!isa<SingleValueInstruction>(inst) && "SingleValueInstruction was "
                                                   "handled by the previous "
                                                   "value base check.");
      copy(inst->getResults(), std::back_inserter(values));
    }

    // If the set of values is empty, we need to print the ID of
    // the instruction.  Otherwise, if none of the values has a use,
    // we don't need to do anything.
    if (!values.empty()) {
      bool hasUse = false;
      for (auto value : values) {
        if (!value->use_empty()) hasUse = true;
      }
      if (!hasUse)
        return printedSlashes;
    }

    if (printedSlashes) {
      *this << "; ";
    } else {
      PrintState.OS.PadToColumn(50);
      *this << "// ";
    }
    if (values.empty()) {
      *this << "id: " << Ctx.getID(node);
      return true;
    }

    llvm::SmallVector<ID, 32> UserIDs;
    for (auto value : values)
      for (auto *Op : value->getUses())
        UserIDs.push_back(Ctx.getID(Op->getUser()));

    *this << "user";
    if (UserIDs.size() != 1)
      *this << 's';
    *this << ": ";

    // If we are asked to, display the user ids sorted to give a stable use
    // order in the printer's output. This makes diffing large sections of SIL
    // significantly easier.
    if (Ctx.sortSIL()) {
      std::sort(UserIDs.begin(), UserIDs.end());
    }

    interleave(UserIDs.begin(), UserIDs.end(), [&](ID id) { *this << id; },
               [&] { *this << ", "; });
    return true;
  }

  void printDebugLocRef(SILLocation Loc, const SourceManager &SM,
                        bool PrintComma = true) {
    auto DL = Loc.decodeDebugLoc(SM);
    if (!DL.Filename.empty()) {
      if (PrintComma)
        *this << ", ";
      *this << "loc " << QuotedString(DL.Filename) << ':' << DL.Line << ':'
            << DL.Column;
    }
  }

  void printDebugScope(const SILDebugScope *DS, const SourceManager &SM) {
    if (!DS)
      return;

    if (!Ctx.hasScopeID(DS)) {
      printDebugScope(DS->Parent.dyn_cast<const SILDebugScope *>(), SM);
      printDebugScope(DS->InlinedCallSite, SM);
      unsigned ID = Ctx.assignScopeID(DS);
      *this << "sil_scope " << ID << " { ";
      printDebugLocRef(DS->Loc, SM, false);
      *this << " parent ";
      if (auto *F = DS->Parent.dyn_cast<SILFunction *>())
        *this << "@" << F->getName() << " : $" << F->getLoweredFunctionType();
      else {
        auto *PS = DS->Parent.get<const SILDebugScope *>();
        *this << Ctx.getScopeID(PS);
      }
      if (auto *CS = DS->InlinedCallSite)
        *this << " inlined_at " << Ctx.getScopeID(CS);
      *this << " }\n";
    }
  }

  void printDebugScopeRef(const SILDebugScope *DS, const SourceManager &SM,
                          bool PrintComma = true) {
    if (DS) {
      if (PrintComma)
        *this << ", ";
      *this << "scope " << Ctx.getScopeID(DS);
    }
  }

  void printSILLocation(SILLocation L, SILModule &M, const SILDebugScope *DS,
                        bool printedSlashes) {
    if (!L.isNull()) {
      if (!printedSlashes) {
        PrintState.OS.PadToColumn(50);
        *this << "//";
      }
      *this << " ";

      // To minimize output, only print the line and column number for
      // everything but the first instruction.
      L.getSourceLoc().printLineAndColumn(PrintState.OS,
                                          M.getASTContext().SourceMgr);

      // Print the type of location.
      switch (L.getKind()) {
      case SILLocation::NoneKind:
        assert(L.isAutoGenerated() && "This kind shouldn't be printed.");
        break;
      case SILLocation::RegularKind:
        break;
      case SILLocation::ReturnKind:
        *this << ":return";
        break;
      case SILLocation::ImplicitReturnKind:
        *this << ":imp_return";
        break;
      case SILLocation::InlinedKind:
        *this << ":inlined";
        break;
      case SILLocation::MandatoryInlinedKind:
        *this << ":minlined";
        break;
      case SILLocation::CleanupKind:
        *this << ":cleanup";
        break;
      case SILLocation::ArtificialUnreachableKind:
        *this << ":art_unreach";
        break;
      }
      if (L.isSILFile())
        *this << ":sil";
      if (L.isAutoGenerated())
        *this << ":auto_gen";
      if (L.isInPrologue())
        *this << ":in_prologue";
    }
    if (L.isNull()) {
      if (!printedSlashes) {
        PrintState.OS.PadToColumn(50);
        *this << "//";
      }
      if (L.isInTopLevel())
        *this << " top_level";
      else if (L.isAutoGenerated())
        *this << " auto_gen";
      else
        *this << " no_loc";
      if (L.isInPrologue())
        *this << ":in_prologue";
    }

    if (!DS)
      return;

    // Print inlined-at location, if any.
    const SILDebugScope *CS = DS;
    while ((CS = CS->InlinedCallSite)) {
      *this << ": ";
      if (auto *InlinedF = CS->getInlinedFunction())
        *this << demangleSymbol(InlinedF->getName());
      else
        *this << '?';
      *this << " perf_inlined_at ";
      auto CallSite = CS->Loc;
      if (!CallSite.isNull() && CallSite.isASTNode())
        CallSite.getSourceLoc().print(
            PrintState.OS, M.getASTContext().SourceMgr, LastBufferID);
      else
        *this << "?";
    }
  }

  void printInstOpCode(const SILInstruction *I) {
    *this << getSILInstructionName(I->getKind()) << " ";
  }

  void print(const SILInstruction *I) {
    if (auto *FRI = dyn_cast<FunctionRefInst>(I))
      *this << "  // function_ref "
            << demangleSymbol(FRI->getReferencedFunction()->getName())
            << "\n";
    else if (auto *FRI = dyn_cast<DynamicFunctionRefInst>(I))
      *this << "  // dynamic_function_ref "
            << demangleSymbol(FRI->getReferencedFunction()->getName())
            << "\n";
    else if (auto *FRI = dyn_cast<PreviousDynamicFunctionRefInst>(I))
      *this << "  // prev_dynamic_function_ref "
            << demangleSymbol(FRI->getReferencedFunction()->getName())
            << "\n";

    *this << "  ";

    // Print results.
    auto results = I->getResults();
    if (results.size() == 1 &&
        I->isStaticInitializerInst() &&
        I == &I->getParent()->back()) {
      *this << "%initval = ";
    } else if (results.size() == 1) {
      ID Name = Ctx.getID(results[0]);
      *this << Name << " = ";
    } else if (results.size() > 1) {
      *this << '(';
      bool first = true;
      for (auto result : results) {
        if (first) {
          first = false;
        } else {
          *this << ", ";
        }
        ID Name = Ctx.getID(result);
        *this << Name;
      }
      *this << ") = ";
    }

    // Print the opcode.
    printInstOpCode(I);

    // Use the visitor to print the rest of the instruction.
    visit(const_cast<SILInstruction*>(I));

    // Maybe print debugging information.
    bool printedSlashes = false;
    if (Ctx.printDebugInfo() && !I->isStaticInitializerInst()) {
      auto &SM = I->getModule().getASTContext().SourceMgr;
      printDebugLocRef(I->getLoc(), SM);
      printDebugScopeRef(I->getDebugScope(), SM);
    }
    printedSlashes = printTypeDependentOperands(I);

    // Print users, or id for valueless instructions.
    printedSlashes = printUsersOfSILNode(I, printedSlashes);

    // Print SIL location.
    if (Ctx.printVerbose()) {
      printSILLocation(I->getLoc(), I->getModule(), I->getDebugScope(),
                       printedSlashes);
    }
    
    *this << '\n';
  }

  void print(const SILNode *node) {
    switch (node->getKind()) {
#define INST(ID, PARENT) \
    case SILNodeKind::ID:
#include "swift/SIL/SILNodes.def"
      print(cast<SILInstruction>(node));
      return;

#define ARGUMENT(ID, PARENT) \
    case SILNodeKind::ID:
#include "swift/SIL/SILNodes.def"
      printSILArgument(cast<SILArgument>(node));
      return;

    case SILNodeKind::SILUndef:
      printSILUndef(cast<SILUndef>(node));
      return;

#define MULTIPLE_VALUE_INST_RESULT(ID, PARENT) \
    case SILNodeKind::ID:
#include "swift/SIL/SILNodes.def"
      printSILMultipleValueInstructionResult(
          cast<MultipleValueInstructionResult>(node));
      return;
    }
    llvm_unreachable("bad kind");
  }

  void printSILArgument(const SILArgument *arg) {
    // This should really only happen during debugging.
    *this << Ctx.getID(arg) << " = argument of "
          << Ctx.getID(arg->getParent()) << " : " << arg->getType();

    // Print users.
    (void) printUsersOfSILNode(arg, false);

    *this << '\n';
  }

  void printSILUndef(const SILUndef *undef) {
    // This should really only happen during debugging.
    *this << "undef<" << undef->getType() << ">\n";
  }

  void printSILMultipleValueInstructionResult(
      const MultipleValueInstructionResult *result) {
    // This should really only happen during debugging.
    if (result->getParent()->getNumResults() == 1) {
      *this << "**" << Ctx.getID(result) << "** = ";
    } else {
      *this << '(';
      interleave(result->getParent()->getResults(),
                 [&](SILValue value) {
                   if (value == SILValue(result)) {
                     *this << "**" << Ctx.getID(result) << "**";
                     return;
                   }
                   *this << Ctx.getID(value);
                 },
                 [&] { *this << ", "; });
      *this << ')';
    }

    *this << " = ";
    printInstOpCode(result->getParent());
    auto *nonConstParent =
        const_cast<MultipleValueInstruction *>(result->getParent());
    visit(static_cast<SILInstruction *>(nonConstParent));

    // Print users.
    (void)printUsersOfSILNode(result, false);

    *this << '\n';
  }

  void printInContext(const SILNode *node) {
    auto sortByID = [&](const SILNode *a, const SILNode *b) {
      return Ctx.getID(a).Number < Ctx.getID(b).Number;
    };

    if (auto *I = dyn_cast<SILInstruction>(node)) {
      auto operands = map<SmallVector<SILValue,4>>(I->getAllOperands(),
                                                   [](Operand const &o) {
                                                     return o.get();
                                                   });
      std::sort(operands.begin(), operands.end(), sortByID);
      for (auto &operand : operands) {
        *this << "   ";
        print(operand);
      }
    }
    
    *this << "-> ";
    print(node);

    if (auto V = dyn_cast<ValueBase>(node)) {    
      auto users = map<SmallVector<const SILInstruction*,4>>(V->getUses(),
                                                       [](Operand *o) {
                                                         return o->getUser();
                                                       });
      std::sort(users.begin(), users.end(), sortByID);
      for (auto &user : users) {
        *this << "   ";
        print(user);
      }
    }
  }

  void printDebugVar(Optional<SILDebugVariable> Var) {
    if (!Var || Var->Name.empty())
      return;
    if (Var->Constant)
      *this << ", let";
    else
      *this << ", var";
    *this << ", name \"" << Var->Name << '"';
    if (Var->ArgNo)
      *this << ", argno " << Var->ArgNo;
  }

  void visitAllocStackInst(AllocStackInst *AVI) {
    *this << AVI->getElementType();
    printDebugVar(AVI->getVarInfo());
  }

  void printAllocRefInstBase(AllocRefInstBase *ARI) {
    if (ARI->isObjC())
      *this << "[objc] ";
    if (ARI->canAllocOnStack())
      *this << "[stack] ";
    auto Types = ARI->getTailAllocatedTypes();
    auto Counts = ARI->getTailAllocatedCounts();
    for (unsigned Idx = 0, NumTypes = Types.size(); Idx < NumTypes; ++Idx) {
      *this << "[tail_elems " << Types[Idx] << " * "
            << getIDAndType(Counts[Idx].get()) << "] ";
    }
  }

  void visitAllocRefInst(AllocRefInst *ARI) {
    printAllocRefInstBase(ARI);
    *this << ARI->getType();
  }

  void visitAllocRefDynamicInst(AllocRefDynamicInst *ARDI) {
    printAllocRefInstBase(ARDI);
    *this << getIDAndType(ARDI->getMetatypeOperand());
    *this << ", " << ARDI->getType();
  }

  void visitAllocValueBufferInst(AllocValueBufferInst *AVBI) {
    *this << AVBI->getValueType() << " in " << getIDAndType(AVBI->getOperand());
  }

  void visitAllocBoxInst(AllocBoxInst *ABI) {
    *this << ABI->getType();
    printDebugVar(ABI->getVarInfo());
  }

  void printSubstitutions(SubstitutionMap Subs,
                          GenericSignature *Sig = nullptr) {
    if (!Subs.hasAnySubstitutableParams()) return;

    // FIXME: This is a hack to cope with cases where the substitution map uses
    // a generic signature that's close-to-but-not-the-same-as expected.
    auto genericSig = Sig ? Sig : Subs.getGenericSignature();

    *this << '<';
    bool first = true;
    for (auto gp : genericSig->getGenericParams()) {
      if (first) first = false;
      else *this << ", ";

      *this << Type(gp).subst(Subs);
    }
    *this << '>';
  }

  template <class Inst>
  void visitApplyInstBase(Inst *AI) {
    *this << Ctx.getID(AI->getCallee());
    printSubstitutions(AI->getSubstitutionMap(),
                       AI->getOrigCalleeType()->getGenericSignature());
    *this << '(';
    interleave(AI->getArguments(),
               [&](const SILValue &arg) { *this << Ctx.getID(arg); },
               [&] { *this << ", "; });
    *this << ") : ";
    if (auto callee = AI->getCallee())
      *this << callee->getType();
    else
      *this << "<<NULL CALLEE>>";
  }

  void visitApplyInst(ApplyInst *AI) {
    if (AI->isNonThrowing())
      *this << "[nothrow] ";
    visitApplyInstBase(AI);
  }

  void visitBeginApplyInst(BeginApplyInst *AI) {
    if (AI->isNonThrowing())
      *this << "[nothrow] ";
    visitApplyInstBase(AI);
  }

  void visitTryApplyInst(TryApplyInst *AI) {
    visitApplyInstBase(AI);
    *this << ", normal " << Ctx.getID(AI->getNormalBB());
    *this << ", error " << Ctx.getID(AI->getErrorBB());
  }

  void visitPartialApplyInst(PartialApplyInst *CI) {
    switch (CI->getFunctionType()->getCalleeConvention()) {
    case ParameterConvention::Direct_Owned:
      // Default; do nothing.
      break;
    case ParameterConvention::Direct_Guaranteed:
      *this << "[callee_guaranteed] ";
      break;
    
    // Should not apply to callees.
    case ParameterConvention::Direct_Unowned:
    case ParameterConvention::Indirect_In:
    case ParameterConvention::Indirect_In_Constant:
    case ParameterConvention::Indirect_Inout:
    case ParameterConvention::Indirect_In_Guaranteed:
    case ParameterConvention::Indirect_InoutAliasable:
      llvm_unreachable("unexpected callee convention!");
    }
    if (CI->isOnStack())
      *this << "[on_stack] ";
    visitApplyInstBase(CI);
  }

  void visitAbortApplyInst(AbortApplyInst *AI) {
    *this << Ctx.getID(AI->getOperand());
  }

  void visitEndApplyInst(EndApplyInst *AI) {
    *this << Ctx.getID(AI->getOperand());
  }

  void visitFunctionRefInst(FunctionRefInst *FRI) {
    FRI->getReferencedFunction()->printName(PrintState.OS);
    *this << " : " << FRI->getType();
  }
  void visitDynamicFunctionRefInst(DynamicFunctionRefInst *FRI) {
    FRI->getReferencedFunction()->printName(PrintState.OS);
    *this << " : " << FRI->getType();
  }
  void
  visitPreviousDynamicFunctionRefInst(PreviousDynamicFunctionRefInst *FRI) {
    FRI->getReferencedFunction()->printName(PrintState.OS);
    *this << " : " << FRI->getType();
  }

  void visitBuiltinInst(BuiltinInst *BI) {
    *this << QuotedString(BI->getName().str());
    printSubstitutions(BI->getSubstitutions());
    *this << "(";
    
    interleave(BI->getArguments(), [&](SILValue v) {
      *this << getIDAndType(v);
    }, [&]{
      *this << ", ";
    });
    
    *this << ") : ";
    *this << BI->getType();
  }
  
  void visitAllocGlobalInst(AllocGlobalInst *AGI) {
    if (AGI->getReferencedGlobal()) {
      AGI->getReferencedGlobal()->printName(PrintState.OS);
    } else {
      *this << "<<placeholder>>";
    }
  }
  
  void visitGlobalAddrInst(GlobalAddrInst *GAI) {
    if (GAI->getReferencedGlobal()) {
      GAI->getReferencedGlobal()->printName(PrintState.OS);
    } else {
      *this << "<<placeholder>>";
    }
    *this << " : " << GAI->getType();
  }

  void visitGlobalValueInst(GlobalValueInst *GVI) {
    GVI->getReferencedGlobal()->printName(PrintState.OS);
    *this << " : " << GVI->getType();
  }

  void visitIntegerLiteralInst(IntegerLiteralInst *ILI) {
    const auto &lit = ILI->getValue();
    *this << ILI->getType() << ", " << lit;
  }
  void visitFloatLiteralInst(FloatLiteralInst *FLI) {
    *this << FLI->getType() << ", 0x";
    APInt bits = FLI->getBits();
    *this << bits.toString(16, /*Signed*/ false);
    llvm::SmallString<12> decimal;
    FLI->getValue().toString(decimal);
    *this << " // " << decimal;
  }
  static StringRef getStringEncodingName(StringLiteralInst::Encoding kind) {
    switch (kind) {
    case StringLiteralInst::Encoding::Bytes: return "bytes ";
    case StringLiteralInst::Encoding::UTF8: return "utf8 ";
    case StringLiteralInst::Encoding::UTF16: return "utf16 ";
    case StringLiteralInst::Encoding::ObjCSelector: return "objc_selector ";
    }
    llvm_unreachable("bad string literal encoding");
  }

  void visitStringLiteralInst(StringLiteralInst *SLI) {
    *this << getStringEncodingName(SLI->getEncoding());

    if (SLI->getEncoding() != StringLiteralInst::Encoding::Bytes) {
      // FIXME: this isn't correct: this doesn't properly handle translating
      // UTF16 into UTF8, and the SIL parser always parses as UTF8.
      *this << QuotedString(SLI->getValue());
      return;
    }

    // "Bytes" are always output in a hexadecimal form.
    *this << '"' << llvm::toHex(SLI->getValue()) << '"';
  }

  void printLoadOwnershipQualifier(LoadOwnershipQualifier Qualifier) {
    switch (Qualifier) {
    case LoadOwnershipQualifier::Unqualified:
      return;
    case LoadOwnershipQualifier::Take:
      *this << "[take] ";
      return;
    case LoadOwnershipQualifier::Copy:
      *this << "[copy] ";
      return;
    case LoadOwnershipQualifier::Trivial:
      *this << "[trivial] ";
      return;
    }
  }

  void visitLoadInst(LoadInst *LI) {
    printLoadOwnershipQualifier(LI->getOwnershipQualifier());
    *this << getIDAndType(LI->getOperand());
  }

  void visitLoadBorrowInst(LoadBorrowInst *LBI) {
    *this << getIDAndType(LBI->getOperand());
  }

  void visitBeginBorrowInst(BeginBorrowInst *LBI) {
    *this << getIDAndType(LBI->getOperand());
  }

  void printStoreOwnershipQualifier(StoreOwnershipQualifier Qualifier) {
    switch (Qualifier) {
    case StoreOwnershipQualifier::Unqualified:
      return;
    case StoreOwnershipQualifier::Init:
      *this << "[init] ";
      return;
    case StoreOwnershipQualifier::Assign:
      *this << "[assign] ";
      return;
    case StoreOwnershipQualifier::Trivial:
      *this << "[trivial] ";
      return;
    }
  }

  void visitStoreInst(StoreInst *SI) {
    *this << Ctx.getID(SI->getSrc()) << " to ";
    printStoreOwnershipQualifier(SI->getOwnershipQualifier());
    *this << getIDAndType(SI->getDest());
  }

  void visitStoreBorrowInst(StoreBorrowInst *SI) {
    *this << Ctx.getID(SI->getSrc()) << " to ";
    *this << getIDAndType(SI->getDest());
  }

  void visitEndBorrowInst(EndBorrowInst *EBI) {
    *this << getIDAndType(EBI->getOperand());
  }

  void visitAssignInst(AssignInst *AI) {
    *this << Ctx.getID(AI->getSrc()) << " to " << getIDAndType(AI->getDest());
  }

  void visitMarkUninitializedInst(MarkUninitializedInst *MU) {
    switch (MU->getKind()) {
    case MarkUninitializedInst::Var: *this << "[var] "; break;
    case MarkUninitializedInst::RootSelf:  *this << "[rootself] "; break;
    case MarkUninitializedInst::CrossModuleRootSelf:
      *this << "[crossmodulerootself] ";
      break;
    case MarkUninitializedInst::DerivedSelf:  *this << "[derivedself] "; break;
    case MarkUninitializedInst::DerivedSelfOnly:
      *this << "[derivedselfonly] ";
      break;
    case MarkUninitializedInst::DelegatingSelf: *this << "[delegatingself] ";break;
    case MarkUninitializedInst::DelegatingSelfAllocated:
      *this << "[delegatingselfallocated] ";
      break;
    }
    
    *this << getIDAndType(MU->getOperand());
  }

  void visitMarkFunctionEscapeInst(MarkFunctionEscapeInst *MFE) {
    interleave(MFE->getElements(),
               [&](SILValue Var) { *this << getIDAndType(Var); },
               [&] { *this << ", "; });
  }

  void visitDebugValueInst(DebugValueInst *DVI) {
    *this << getIDAndType(DVI->getOperand());
    printDebugVar(DVI->getVarInfo());
  }

  void visitDebugValueAddrInst(DebugValueAddrInst *DVAI) {
    *this << getIDAndType(DVAI->getOperand());
    printDebugVar(DVAI->getVarInfo());
  }

#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
  void visitLoad##Name##Inst(Load##Name##Inst *LI) { \
    if (LI->isTake()) \
      *this << "[take] "; \
    *this << getIDAndType(LI->getOperand()); \
  } \
  void visitStore##Name##Inst(Store##Name##Inst *SI) { \
    *this << Ctx.getID(SI->getSrc()) << " to "; \
    if (SI->isInitializationOfDest()) \
      *this << "[initialization] "; \
    *this << getIDAndType(SI->getDest()); \
  }
#define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
  NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, "...")
#include "swift/AST/ReferenceStorage.def"

  void visitCopyAddrInst(CopyAddrInst *CI) {
    if (CI->isTakeOfSrc())
      *this << "[take] ";
    *this << Ctx.getID(CI->getSrc()) << " to ";
    if (CI->isInitializationOfDest())
      *this << "[initialization] ";
    *this << getIDAndType(CI->getDest());
  }

  void visitBindMemoryInst(BindMemoryInst *BI) {
    *this << getIDAndType(BI->getBase()) << ", ";
    *this << getIDAndType(BI->getIndex()) << " to ";
    *this << BI->getBoundType();
  }
  
  void visitUnconditionalCheckedCastInst(UnconditionalCheckedCastInst *CI) {
    *this << getIDAndType(CI->getOperand()) << " to " << CI->getType();
  }
  
  void visitCheckedCastBranchInst(CheckedCastBranchInst *CI) {
    if (CI->isExact())
      *this << "[exact] ";
    *this << getIDAndType(CI->getOperand()) << " to " << CI->getCastType()
          << ", " << Ctx.getID(CI->getSuccessBB()) << ", "
          << Ctx.getID(CI->getFailureBB());
    if (CI->getTrueBBCount())
      *this << " !true_count(" << CI->getTrueBBCount().getValue() << ")";
    if (CI->getFalseBBCount())
      *this << " !false_count(" << CI->getFalseBBCount().getValue() << ")";
  }

  void visitCheckedCastValueBranchInst(CheckedCastValueBranchInst *CI) {
    *this << getIDAndType(CI->getOperand()) << " to " << CI->getCastType()
          << ", " << Ctx.getID(CI->getSuccessBB()) << ", "
          << Ctx.getID(CI->getFailureBB());
  }

  void visitUnconditionalCheckedCastAddrInst(UnconditionalCheckedCastAddrInst *CI) {
    *this << CI->getSourceType() << " in " << getIDAndType(CI->getSrc())
          << " to " << CI->getTargetType() << " in "
          << getIDAndType(CI->getDest());
  }

  void visitUnconditionalCheckedCastValueInst(
      UnconditionalCheckedCastValueInst *CI) {
    *this << getIDAndType(CI->getOperand()) << " to " << CI->getType();
  }

  void visitCheckedCastAddrBranchInst(CheckedCastAddrBranchInst *CI) {
    *this << getCastConsumptionKindName(CI->getConsumptionKind()) << ' '
          << CI->getSourceType() << " in " << getIDAndType(CI->getSrc())
          << " to " << CI->getTargetType() << " in "
          << getIDAndType(CI->getDest()) << ", "
          << Ctx.getID(CI->getSuccessBB()) << ", "
          << Ctx.getID(CI->getFailureBB());
    if (CI->getTrueBBCount())
      *this << " !true_count(" << CI->getTrueBBCount().getValue() << ")";
    if (CI->getFalseBBCount())
      *this << " !false_count(" << CI->getFalseBBCount().getValue() << ")";
  }

  void printUncheckedConversionInst(ConversionInst *CI, SILValue operand) {
    *this << getIDAndType(operand) << " to " << CI->getType();
  }

  void visitUncheckedOwnershipConversionInst(
      UncheckedOwnershipConversionInst *UOCI) {
    *this << getIDAndType(UOCI->getOperand()) << ", "
          << "@" << UOCI->getOperand().getOwnershipKind() << " to "
          << "@" << UOCI->getConversionOwnershipKind();
  }

  void visitConvertFunctionInst(ConvertFunctionInst *CI) {
    *this << getIDAndType(CI->getOperand()) << " to ";
    if (CI->withoutActuallyEscaping())
      *this << "[without_actually_escaping] ";
    *this << CI->getType();
  }
  void visitConvertEscapeToNoEscapeInst(ConvertEscapeToNoEscapeInst *CI) {
    *this << (CI->isLifetimeGuaranteed() ? "" : "[not_guaranteed] ")
          << getIDAndType(CI->getOperand()) << " to " << CI->getType();
  }
  void visitThinFunctionToPointerInst(ThinFunctionToPointerInst *CI) {
    printUncheckedConversionInst(CI, CI->getOperand());
  }
  void visitPointerToThinFunctionInst(PointerToThinFunctionInst *CI) {
    printUncheckedConversionInst(CI, CI->getOperand());
  }
  void visitUpcastInst(UpcastInst *CI) {
    printUncheckedConversionInst(CI, CI->getOperand());
  }
  void visitAddressToPointerInst(AddressToPointerInst *CI) {
    printUncheckedConversionInst(CI, CI->getOperand());
  }
  void visitPointerToAddressInst(PointerToAddressInst *CI) {
    *this << getIDAndType(CI->getOperand()) << " to ";
    if (CI->isStrict())
      *this << "[strict] ";
    if (CI->isInvariant())
      *this << "[invariant] ";
    *this << CI->getType();
  }
  void visitUncheckedRefCastInst(UncheckedRefCastInst *CI) {
    printUncheckedConversionInst(CI, CI->getOperand());
  }
  void visitUncheckedRefCastAddrInst(UncheckedRefCastAddrInst *CI) {
    *this << ' ' << CI->getSourceType() << " in " << getIDAndType(CI->getSrc())
          << " to " << CI->getTargetType() << " in "
          << getIDAndType(CI->getDest());
  }
  void visitUncheckedAddrCastInst(UncheckedAddrCastInst *CI) {
    printUncheckedConversionInst(CI, CI->getOperand());
  }
  void visitUncheckedTrivialBitCastInst(UncheckedTrivialBitCastInst *CI) {
    printUncheckedConversionInst(CI, CI->getOperand());
  }
  void visitUncheckedBitwiseCastInst(UncheckedBitwiseCastInst *CI) {
    printUncheckedConversionInst(CI, CI->getOperand());
  }
  void visitRefToRawPointerInst(RefToRawPointerInst *CI) {
    printUncheckedConversionInst(CI, CI->getOperand());
  }
  void visitRawPointerToRefInst(RawPointerToRefInst *CI) {
    printUncheckedConversionInst(CI, CI->getOperand());
  }

#define LOADABLE_REF_STORAGE(Name, ...) \
  void visitRefTo##Name##Inst(RefTo##Name##Inst *CI) { \
    printUncheckedConversionInst(CI, CI->getOperand()); \
  } \
  void visit##Name##ToRefInst(Name##ToRefInst *CI) { \
    printUncheckedConversionInst(CI, CI->getOperand()); \
  }
#include "swift/AST/ReferenceStorage.def"
  void visitThinToThickFunctionInst(ThinToThickFunctionInst *CI) {
    printUncheckedConversionInst(CI, CI->getOperand());
  }
  void visitThickToObjCMetatypeInst(ThickToObjCMetatypeInst *CI) {
    printUncheckedConversionInst(CI, CI->getOperand());
  }
  void visitObjCToThickMetatypeInst(ObjCToThickMetatypeInst *CI) {
    printUncheckedConversionInst(CI, CI->getOperand());
  }
  void visitObjCMetatypeToObjectInst(ObjCMetatypeToObjectInst *CI) {
    printUncheckedConversionInst(CI, CI->getOperand());
  }
  void visitObjCExistentialMetatypeToObjectInst(
                                      ObjCExistentialMetatypeToObjectInst *CI) {
    printUncheckedConversionInst(CI, CI->getOperand());
  }
  void visitObjCProtocolInst(ObjCProtocolInst *CI) {
    *this << "#" << CI->getProtocol()->getName() << " : " << CI->getType();
  }
  
  void visitRefToBridgeObjectInst(RefToBridgeObjectInst *I) {
    *this << getIDAndType(I->getConverted()) << ", "
          << getIDAndType(I->getBitsOperand());
  }
  
  void visitBridgeObjectToRefInst(BridgeObjectToRefInst *I) {
    printUncheckedConversionInst(I, I->getOperand());
  }
  void visitBridgeObjectToWordInst(BridgeObjectToWordInst *I) {
    printUncheckedConversionInst(I, I->getOperand());
  }

  void visitCopyValueInst(CopyValueInst *I) {
    *this << getIDAndType(I->getOperand());
  }

#define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
  void visitCopy##Name##ValueInst(Copy##Name##ValueInst *I) { \
    *this << getIDAndType(I->getOperand()); \
  }
#include "swift/AST/ReferenceStorage.def"

  void visitDestroyValueInst(DestroyValueInst *I) {
    *this << getIDAndType(I->getOperand());
  }

  void visitStructInst(StructInst *SI) {
    *this << SI->getType() << " (";
    interleave(SI->getElements(),
               [&](const SILValue &V) { *this << getIDAndType(V); },
               [&] { *this << ", "; });
    *this << ')';
  }

  void visitObjectInst(ObjectInst *OI) {
    *this << OI->getType() << " (";
    interleave(OI->getBaseElements(),
               [&](const SILValue &V) { *this << getIDAndType(V); },
               [&] { *this << ", "; });
    if (!OI->getTailElements().empty()) {
      *this << ", [tail_elems] ";
      interleave(OI->getTailElements(),
                 [&](const SILValue &V) { *this << getIDAndType(V); },
                 [&] { *this << ", "; });
    }
    *this << ')';
  }

  void visitTupleInst(TupleInst *TI) {
    
    // Check to see if the type of the tuple can be inferred accurately from the
    // elements.
    bool SimpleType = true;
    for (auto &Elt : TI->getType().castTo<TupleType>()->getElements()) {
      if (Elt.hasName() || Elt.isVararg()) {
        SimpleType = false;
        break;
      }
    }
    
    // If the type is simple, just print the tuple elements.
    if (SimpleType) {
      *this << '(';
      interleave(TI->getElements(),
                 [&](const SILValue &V){ *this << getIDAndType(V); },
                 [&] { *this << ", "; });
      *this << ')';
    } else {
      // Otherwise, print the type, then each value.
      *this << TI->getType() << " (";
      interleave(TI->getElements(),
                 [&](const SILValue &V) { *this << Ctx.getID(V); },
                 [&] { *this << ", "; });
      *this << ')';
    }
  }
  
  void visitEnumInst(EnumInst *UI) {
    *this << UI->getType() << ", "
          << SILDeclRef(UI->getElement(), SILDeclRef::Kind::EnumElement);
    if (UI->hasOperand()) {
      *this << ", " << getIDAndType(UI->getOperand());
    }
  }

  void visitInitEnumDataAddrInst(InitEnumDataAddrInst *UDAI) {
    *this << getIDAndType(UDAI->getOperand()) << ", "
          << SILDeclRef(UDAI->getElement(), SILDeclRef::Kind::EnumElement);
  }
  
  void visitUncheckedEnumDataInst(UncheckedEnumDataInst *UDAI) {
    *this << getIDAndType(UDAI->getOperand()) << ", "
          << SILDeclRef(UDAI->getElement(), SILDeclRef::Kind::EnumElement);
  }
  
  void visitUncheckedTakeEnumDataAddrInst(UncheckedTakeEnumDataAddrInst *UDAI) {
    *this << getIDAndType(UDAI->getOperand()) << ", "
          << SILDeclRef(UDAI->getElement(), SILDeclRef::Kind::EnumElement);
  }
  
  void visitInjectEnumAddrInst(InjectEnumAddrInst *IUAI) {
    *this << getIDAndType(IUAI->getOperand()) << ", "
          << SILDeclRef(IUAI->getElement(), SILDeclRef::Kind::EnumElement);
  }
  
  void visitTupleExtractInst(TupleExtractInst *EI) {
    *this << getIDAndType(EI->getOperand()) << ", " << EI->getFieldNo();
  }

  void visitTupleElementAddrInst(TupleElementAddrInst *EI) {
    *this << getIDAndType(EI->getOperand()) << ", " << EI->getFieldNo();
  }
  void visitStructExtractInst(StructExtractInst *EI) {
    *this << getIDAndType(EI->getOperand()) << ", #";
    printFullContext(EI->getField()->getDeclContext(), PrintState.OS);
    *this << EI->getField()->getName().get();
  }
  void visitStructElementAddrInst(StructElementAddrInst *EI) {
    *this << getIDAndType(EI->getOperand()) << ", #";
    printFullContext(EI->getField()->getDeclContext(), PrintState.OS);
    *this << EI->getField()->getName().get();
  }
  void visitRefElementAddrInst(RefElementAddrInst *EI) {
    *this << getIDAndType(EI->getOperand()) << ", #";
    printFullContext(EI->getField()->getDeclContext(), PrintState.OS);
    *this << EI->getField()->getName().get();
  }

  void visitRefTailAddrInst(RefTailAddrInst *RTAI) {
    *this << getIDAndType(RTAI->getOperand()) << ", " << RTAI->getTailType();
  }

  void visitDestructureStructInst(DestructureStructInst *DSI) {
    *this << getIDAndType(DSI->getOperand());
  }

  void visitDestructureTupleInst(DestructureTupleInst *DTI) {
    *this << getIDAndType(DTI->getOperand());
  }

  void printMethodInst(MethodInst *I, SILValue Operand) {
    *this << getIDAndType(Operand) << ", " << I->getMember();
  }
  
  void visitClassMethodInst(ClassMethodInst *AMI) {
    printMethodInst(AMI, AMI->getOperand());
    *this << " : " << AMI->getMember().getDecl()->getInterfaceType();
    *this << ", ";
    *this << AMI->getType();
  }
  void visitSuperMethodInst(SuperMethodInst *AMI) {
    printMethodInst(AMI, AMI->getOperand());
    *this << " : " << AMI->getMember().getDecl()->getInterfaceType();
    *this << ", ";
    *this << AMI->getType();
  }
  void visitObjCMethodInst(ObjCMethodInst *AMI) {
    printMethodInst(AMI, AMI->getOperand());
    *this << " : " << AMI->getMember().getDecl()->getInterfaceType();
    *this << ", ";
    *this << AMI->getType();
  }
  void visitObjCSuperMethodInst(ObjCSuperMethodInst *AMI) {
    printMethodInst(AMI, AMI->getOperand());
    *this << " : " << AMI->getMember().getDecl()->getInterfaceType();
    *this << ", ";
    *this << AMI->getType();
  }
  void visitWitnessMethodInst(WitnessMethodInst *WMI) {
    PrintOptions QualifiedSILTypeOptions =
        PrintOptions::printQualifiedSILType();
    QualifiedSILTypeOptions.CurrentModule = WMI->getModule().getSwiftModule();
    *this << "$" << WMI->getLookupType() << ", " << WMI->getMember() << " : ";
    WMI->getMember().getDecl()->getInterfaceType().print(
        PrintState.OS, QualifiedSILTypeOptions);
    if (!WMI->getTypeDependentOperands().empty()) {
      *this << ", ";
      *this << getIDAndType(WMI->getTypeDependentOperands()[0].get());
    }
    *this << " : " << WMI->getType();
  }
  void visitOpenExistentialAddrInst(OpenExistentialAddrInst *OI) {
    if (OI->getAccessKind() == OpenedExistentialAccess::Immutable)
      *this << "immutable_access ";
    else
      *this << "mutable_access ";
    *this << getIDAndType(OI->getOperand()) << " to " << OI->getType();
  }
  void visitOpenExistentialRefInst(OpenExistentialRefInst *OI) {
    *this << getIDAndType(OI->getOperand()) << " to " << OI->getType();
  }
  void visitOpenExistentialMetatypeInst(OpenExistentialMetatypeInst *OI) {
    *this << getIDAndType(OI->getOperand()) << " to " << OI->getType();
  }
  void visitOpenExistentialBoxInst(OpenExistentialBoxInst *OI) {
    *this << getIDAndType(OI->getOperand()) << " to " << OI->getType();
  }
  void visitOpenExistentialBoxValueInst(OpenExistentialBoxValueInst *OI) {
    *this << getIDAndType(OI->getOperand()) << " to " << OI->getType();
  }
  void visitOpenExistentialValueInst(OpenExistentialValueInst *OI) {
    *this << getIDAndType(OI->getOperand()) << " to " << OI->getType();
  }
  void visitInitExistentialAddrInst(InitExistentialAddrInst *AEI) {
    *this << getIDAndType(AEI->getOperand()) << ", $"
          << AEI->getFormalConcreteType();
  }
  void visitInitExistentialValueInst(InitExistentialValueInst *AEI) {
    *this << getIDAndType(AEI->getOperand()) << ", $"
          << AEI->getFormalConcreteType() << ", " << AEI->getType();
  }
  void visitInitExistentialRefInst(InitExistentialRefInst *AEI) {
    *this << getIDAndType(AEI->getOperand()) << " : $"
          << AEI->getFormalConcreteType() << ", " << AEI->getType();
  }
  void visitInitExistentialMetatypeInst(InitExistentialMetatypeInst *AEI) {
    *this << getIDAndType(AEI->getOperand()) << ", " << AEI->getType();
  }
  void visitAllocExistentialBoxInst(AllocExistentialBoxInst *AEBI) {
    *this << AEBI->getExistentialType() << ", $"
          << AEBI->getFormalConcreteType();
  }
  void visitDeinitExistentialAddrInst(DeinitExistentialAddrInst *DEI) {
    *this << getIDAndType(DEI->getOperand());
  }
  void visitDeinitExistentialValueInst(DeinitExistentialValueInst *DEI) {
    *this << getIDAndType(DEI->getOperand());
  }
  void visitDeallocExistentialBoxInst(DeallocExistentialBoxInst *DEI) {
    *this << getIDAndType(DEI->getOperand()) << ", $" << DEI->getConcreteType();
  }
  void visitProjectBlockStorageInst(ProjectBlockStorageInst *PBSI) {
    *this << getIDAndType(PBSI->getOperand());
  }
  void visitInitBlockStorageHeaderInst(InitBlockStorageHeaderInst *IBSHI) {
    *this << getIDAndType(IBSHI->getBlockStorage()) << ", invoke "
          << Ctx.getID(IBSHI->getInvokeFunction());
    printSubstitutions(IBSHI->getSubstitutions());
    *this << " : " << IBSHI->getInvokeFunction()->getType()
          << ", type " << IBSHI->getType();
  }
  void visitValueMetatypeInst(ValueMetatypeInst *MI) {
    *this << MI->getType() << ", " << getIDAndType(MI->getOperand());
  }
  void visitExistentialMetatypeInst(ExistentialMetatypeInst *MI) {
    *this << MI->getType() << ", " << getIDAndType(MI->getOperand());
  }
  void visitMetatypeInst(MetatypeInst *MI) { *this << MI->getType(); }

  void visitFixLifetimeInst(FixLifetimeInst *RI) {
    *this << getIDAndType(RI->getOperand());
  }

  void visitEndLifetimeInst(EndLifetimeInst *ELI) {
    *this << getIDAndType(ELI->getOperand());
  }
  void visitValueToBridgeObjectInst(ValueToBridgeObjectInst *VBOI) {
    *this << getIDAndType(VBOI->getOperand());
  }
  void visitClassifyBridgeObjectInst(ClassifyBridgeObjectInst *CBOI) {
    *this << getIDAndType(CBOI->getOperand());
  }
  void visitMarkDependenceInst(MarkDependenceInst *MDI) {
    *this << getIDAndType(MDI->getValue()) << " on "
          << getIDAndType(MDI->getBase());
  }
  void visitCopyBlockInst(CopyBlockInst *RI) {
    *this << getIDAndType(RI->getOperand());
  }
  void visitCopyBlockWithoutEscapingInst(CopyBlockWithoutEscapingInst *RI) {
    *this << getIDAndType(RI->getBlock()) << " withoutEscaping "
          << getIDAndType(RI->getClosure());
  }
  void visitRefCountingInst(RefCountingInst *I) {
    if (I->isNonAtomic())
      *this << "[nonatomic] ";
    *this << getIDAndType(I->getOperand(0));
  }
  void visitIsUniqueInst(IsUniqueInst *CUI) {
    *this << getIDAndType(CUI->getOperand());
  }
  void visitIsEscapingClosureInst(IsEscapingClosureInst *CUI) {
    if (CUI->getVerificationType())
      *this << "[objc] ";
    *this << getIDAndType(CUI->getOperand());
  }
  void visitDeallocStackInst(DeallocStackInst *DI) {
    *this << getIDAndType(DI->getOperand());
  }
  void visitDeallocRefInst(DeallocRefInst *DI) {
    if (DI->canAllocOnStack())
      *this << "[stack] ";
    *this << getIDAndType(DI->getOperand());
  }
  void visitDeallocPartialRefInst(DeallocPartialRefInst *DPI) {
    *this << getIDAndType(DPI->getInstance());
    *this << ", ";
    *this << getIDAndType(DPI->getMetatype());
  }
  void visitDeallocValueBufferInst(DeallocValueBufferInst *DVBI) {
    *this << DVBI->getValueType() << " in " << getIDAndType(DVBI->getOperand());
  }
  void visitDeallocBoxInst(DeallocBoxInst *DI) {
    *this << getIDAndType(DI->getOperand());
  }
  void visitDestroyAddrInst(DestroyAddrInst *DI) {
    *this << getIDAndType(DI->getOperand());
  }
  void visitProjectValueBufferInst(ProjectValueBufferInst *PVBI) {
    *this << PVBI->getValueType() << " in " << getIDAndType(PVBI->getOperand());
  }
  void visitProjectBoxInst(ProjectBoxInst *PBI) {
    *this << getIDAndType(PBI->getOperand()) << ", " << PBI->getFieldIndex();
  }
  void visitProjectExistentialBoxInst(ProjectExistentialBoxInst *PEBI) {
    *this << PEBI->getType().getObjectType()
          << " in " << getIDAndType(PEBI->getOperand());
  }
  void visitBeginAccessInst(BeginAccessInst *BAI) {
    *this << '[' << getSILAccessKindName(BAI->getAccessKind()) << "] ["
          << getSILAccessEnforcementName(BAI->getEnforcement()) << "] "
          << (BAI->hasNoNestedConflict() ? "[no_nested_conflict] " : "")
          << (BAI->isFromBuiltin() ? "[builtin] " : "")
          << getIDAndType(BAI->getOperand());
  }
  void visitEndAccessInst(EndAccessInst *EAI) {
    *this << (EAI->isAborting() ? "[abort] " : "")
          << getIDAndType(EAI->getOperand());
  }
  void visitBeginUnpairedAccessInst(BeginUnpairedAccessInst *BAI) {
    *this << '[' << getSILAccessKindName(BAI->getAccessKind()) << "] ["
          << getSILAccessEnforcementName(BAI->getEnforcement()) << "] "
          << (BAI->hasNoNestedConflict() ? "[no_nested_conflict] " : "")
          << (BAI->isFromBuiltin() ? "[builtin] " : "")
          << getIDAndType(BAI->getSource()) << ", " 
          << getIDAndType(BAI->getBuffer());
  }
  void visitEndUnpairedAccessInst(EndUnpairedAccessInst *EAI) {
    *this << (EAI->isAborting() ? "[abort] " : "") << '['
          << getSILAccessEnforcementName(EAI->getEnforcement()) << "] "
          << (EAI->isFromBuiltin() ? "[builtin] " : "")
          << getIDAndType(EAI->getOperand());
  }

  void visitCondFailInst(CondFailInst *FI) {
    *this << getIDAndType(FI->getOperand());
  }
  
  void visitIndexAddrInst(IndexAddrInst *IAI) {
    *this << getIDAndType(IAI->getBase()) << ", "
          << getIDAndType(IAI->getIndex());
  }

  void visitTailAddrInst(TailAddrInst *TAI) {
    *this << getIDAndType(TAI->getBase()) << ", "
          << getIDAndType(TAI->getIndex()) << ", " << TAI->getTailType();
  }

  void visitIndexRawPointerInst(IndexRawPointerInst *IAI) {
    *this << getIDAndType(IAI->getBase()) << ", "
          << getIDAndType(IAI->getIndex());
  }

  void visitUnreachableInst(UnreachableInst *UI) {}

  void visitReturnInst(ReturnInst *RI) {
    *this << getIDAndType(RI->getOperand());
  }
  
  void visitThrowInst(ThrowInst *TI) {
    *this << getIDAndType(TI->getOperand());
  }

  void visitUnwindInst(UnwindInst *UI) {
    // no operands
  }

  void visitYieldInst(YieldInst *YI) {
    auto values = YI->getYieldedValues();
    if (values.size() != 1) *this << '(';
    interleave(values,
               [&](SILValue value) { *this << getIDAndType(value); },
               [&] { *this << ", "; });
    if (values.size() != 1) *this << ')';
    *this << ", resume " << Ctx.getID(YI->getResumeBB())
          << ", unwind " << Ctx.getID(YI->getUnwindBB());
  }

  void visitSwitchValueInst(SwitchValueInst *SII) {
    *this << getIDAndType(SII->getOperand());
    for (unsigned i = 0, e = SII->getNumCases(); i < e; ++i) {
      SILValue value;
      SILBasicBlock *dest;
      std::tie(value, dest) = SII->getCase(i);
      *this << ", case " << Ctx.getID(value) << ": " << Ctx.getID(dest);
    }
    if (SII->hasDefault())
      *this << ", default " << Ctx.getID(SII->getDefaultBB());
  }
  
  void printSwitchEnumInst(SwitchEnumInstBase *SOI) {
    *this << getIDAndType(SOI->getOperand());
    for (unsigned i = 0, e = SOI->getNumCases(); i < e; ++i) {
      EnumElementDecl *elt;
      SILBasicBlock *dest;
      std::tie(elt, dest) = SOI->getCase(i);
      *this << ", case " << SILDeclRef(elt, SILDeclRef::Kind::EnumElement)
            << ": " << Ctx.getID(dest);
      if (SOI->getCaseCount(i)) {
        *this << " !case_count(" << SOI->getCaseCount(i).getValue() << ")";
      }
    }
    if (SOI->hasDefault()) {
      *this << ", default " << Ctx.getID(SOI->getDefaultBB());
      if (SOI->getDefaultCount()) {
        *this << " !default_count(" << SOI->getDefaultCount().getValue() << ")";
      }
    }
  }
  
  void visitSwitchEnumInst(SwitchEnumInst *SOI) {
    printSwitchEnumInst(SOI);
  }
  void visitSwitchEnumAddrInst(SwitchEnumAddrInst *SOI) {
    printSwitchEnumInst(SOI);
  }
  
  void printSelectEnumInst(SelectEnumInstBase *SEI) {
    *this << getIDAndType(SEI->getEnumOperand());

    for (unsigned i = 0, e = SEI->getNumCases(); i < e; ++i) {
      EnumElementDecl *elt;
      SILValue result;
      std::tie(elt, result) = SEI->getCase(i);
      *this << ", case " << SILDeclRef(elt, SILDeclRef::Kind::EnumElement)
            << ": " << Ctx.getID(result);
    }
    if (SEI->hasDefault())
      *this << ", default " << Ctx.getID(SEI->getDefaultResult());

    *this << " : " << SEI->getType();
  }

  void visitSelectEnumInst(SelectEnumInst *SEI) {
    printSelectEnumInst(SEI);
  }
  void visitSelectEnumAddrInst(SelectEnumAddrInst *SEI) {
    printSelectEnumInst(SEI);
  }

  void visitSelectValueInst(SelectValueInst *SVI) {
    *this << getIDAndType(SVI->getOperand());

    for (unsigned i = 0, e = SVI->getNumCases(); i < e; ++i) {
      SILValue casevalue;
      SILValue result;
      std::tie(casevalue, result) = SVI->getCase(i);
      *this << ", case " << Ctx.getID(casevalue) << ": " << Ctx.getID(result);
    }
    if (SVI->hasDefault())
      *this << ", default " << Ctx.getID(SVI->getDefaultResult());

    *this << " : " << SVI->getType();
  }
  
  void visitDynamicMethodBranchInst(DynamicMethodBranchInst *DMBI) {
    *this << getIDAndType(DMBI->getOperand()) << ", " << DMBI->getMember()
          << ", " << Ctx.getID(DMBI->getHasMethodBB()) << ", "
          << Ctx.getID(DMBI->getNoMethodBB());
  }

  void printBranchArgs(OperandValueArrayRef args) {
    if (args.empty()) return;

    *this << '(';
    interleave(args,
               [&](SILValue v) { *this << getIDAndType(v); },
               [&] { *this << ", "; });
    *this << ')';
  }
  
  void visitBranchInst(BranchInst *UBI) {
    *this << Ctx.getID(UBI->getDestBB());
    printBranchArgs(UBI->getArgs());
  }

  void visitCondBranchInst(CondBranchInst *CBI) {
    *this << Ctx.getID(CBI->getCondition()) << ", "
          << Ctx.getID(CBI->getTrueBB());
    printBranchArgs(CBI->getTrueArgs());
    *this << ", " << Ctx.getID(CBI->getFalseBB());
    printBranchArgs(CBI->getFalseArgs());
    if (CBI->getTrueBBCount())
      *this << " !true_count(" << CBI->getTrueBBCount().getValue() << ")";
    if (CBI->getFalseBBCount())
      *this << " !false_count(" << CBI->getFalseBBCount().getValue() << ")";
  }
  
  void visitKeyPathInst(KeyPathInst *KPI) {
    *this << KPI->getType() << ", ";
    
    auto pattern = KPI->getPattern();
    
    if (pattern->getGenericSignature()) {
      pattern->getGenericSignature()->print(PrintState.OS);
      *this << ' ';
    }
    
    *this << "(";
    
    if (!pattern->getObjCString().empty())
      *this << "objc \"" << pattern->getObjCString() << "\"; ";
    
    *this << "root $" << KPI->getPattern()->getRootType();

    for (auto &component : pattern->getComponents()) {
      *this << "; ";

      printKeyPathPatternComponent(component);
    }
    
    *this << ')';
    if (!KPI->getSubstitutions().empty()) {
      *this << ' ';
      printSubstitutions(KPI->getSubstitutions());
    }
    if (!KPI->getAllOperands().empty()) {
      *this << " (";
      
      interleave(KPI->getAllOperands(),
        [&](const Operand &operand) {
          *this << Ctx.getID(operand.get());
        }, [&]{
          *this << ", ";
        });
      
      *this << ")";
    }
  }
  
  void
  printKeyPathPatternComponent(const KeyPathPatternComponent &component) {
    auto printComponentIndices =
      [&](ArrayRef<KeyPathPatternComponent::Index> indices) {
        *this << '[';
        interleave(indices,
          [&](const KeyPathPatternComponent::Index &i) {
            *this << "%$" << i.Operand << " : $"
                  << i.FormalType << " : "
                  << i.LoweredType;
          }, [&]{
            *this << ", ";
          });
        *this << ']';
      };

    switch (auto kind = component.getKind()) {
    case KeyPathPatternComponent::Kind::StoredProperty: {
      auto prop = component.getStoredPropertyDecl();
      *this << "stored_property #";
      printValueDecl(prop, PrintState.OS);
      *this << " : $" << component.getComponentType();
      break;
    }
    case KeyPathPatternComponent::Kind::GettableProperty:
    case KeyPathPatternComponent::Kind::SettableProperty: {
      *this << (kind == KeyPathPatternComponent::Kind::GettableProperty
                  ? "gettable_property $" : "settable_property $")
            << component.getComponentType() << ", "
            << " id ";
      auto id = component.getComputedPropertyId();
      switch (id.getKind()) {
      case KeyPathPatternComponent::ComputedPropertyId::DeclRef: {
        auto declRef = id.getDeclRef();
        *this << declRef << " : "
              << declRef.getDecl()->getInterfaceType();
        break;
      }
      case KeyPathPatternComponent::ComputedPropertyId::Function: {
        id.getFunction()->printName(PrintState.OS);
        *this << " : " << id.getFunction()->getLoweredType();
        break;
      }
      case KeyPathPatternComponent::ComputedPropertyId::Property: {
        *this << "##";
        printValueDecl(id.getProperty(), PrintState.OS);
        break;
      }
      }
      *this << ", getter ";
      component.getComputedPropertyGetter()->printName(PrintState.OS);
      *this << " : "
            << component.getComputedPropertyGetter()->getLoweredType();
      if (kind == KeyPathPatternComponent::Kind::SettableProperty) {
        *this << ", setter ";
        component.getComputedPropertySetter()->printName(PrintState.OS);
        *this << " : "
              << component.getComputedPropertySetter()->getLoweredType();
      }
      
      if (!component.getSubscriptIndices().empty()) {
        *this << ", indices ";
        printComponentIndices(component.getSubscriptIndices());
        *this << ", indices_equals ";
        component.getSubscriptIndexEquals()->printName(PrintState.OS);
        *this << " : "
              << component.getSubscriptIndexEquals()->getLoweredType();
        *this << ", indices_hash ";
        component.getSubscriptIndexHash()->printName(PrintState.OS);
        *this << " : "
              << component.getSubscriptIndexHash()->getLoweredType();
      }
      
      if (auto external = component.getExternalDecl()) {
        *this << ", external #";
        printValueDecl(external, PrintState.OS);
        auto subs = component.getExternalSubstitutions();
        if (!subs.empty()) {
          printSubstitutions(subs);
        }
      }
      
      break;
    }
    case KeyPathPatternComponent::Kind::OptionalWrap:
    case KeyPathPatternComponent::Kind::OptionalChain:
    case KeyPathPatternComponent::Kind::OptionalForce: {
      switch (kind) {
      case KeyPathPatternComponent::Kind::OptionalWrap:
        *this << "optional_wrap : $";
        break;
      case KeyPathPatternComponent::Kind::OptionalChain:
        *this << "optional_chain : $";
        break;
      case KeyPathPatternComponent::Kind::OptionalForce:
        *this << "optional_force : $";
        break;
      default:
        llvm_unreachable("out of sync");
      }
      *this << component.getComponentType();
      break;
    }
    }
  }
};
} // end anonymous namespace

static void printBlockID(raw_ostream &OS, SILBasicBlock *bb) {
  SILPrintContext Ctx(OS);
  OS << Ctx.getID(bb);
}

void SILBasicBlock::printAsOperand(raw_ostream &OS, bool PrintType) {
  printBlockID(OS, this);
}

//===----------------------------------------------------------------------===//
// Printing for SILInstruction, SILBasicBlock, SILFunction, and SILModule
//===----------------------------------------------------------------------===//

void SILNode::dump() const {
  print(llvm::errs());
}

void SILNode::print(raw_ostream &OS) const {
  SILPrintContext Ctx(OS);
  SILPrinter(Ctx).print(this);
}

void SILInstruction::dump() const {
  print(llvm::errs());
}

void SingleValueInstruction::dump() const {
  SILInstruction::dump();
}

void SILInstruction::print(raw_ostream &OS) const {
  SILPrintContext Ctx(OS);
  SILPrinter(Ctx).print(this);
}

/// Pretty-print the SILBasicBlock to errs.
void SILBasicBlock::dump() const {
  print(llvm::errs());
}

/// Pretty-print the SILBasicBlock to the designated stream.
void SILBasicBlock::print(raw_ostream &OS) const {
  SILPrintContext Ctx(OS);

  // Print the debug scope (and compute if we didn't do it already).
  auto &SM = this->getParent()->getModule().getASTContext().SourceMgr;
  for (auto &I : *this) {
    SILPrinter P(Ctx);
    P.printDebugScope(I.getDebugScope(), SM);
  }

  SILPrinter(Ctx).print(this);
}

void SILBasicBlock::print(raw_ostream &OS, SILPrintContext &Ctx) const {
  SILPrinter(Ctx).print(this);
}

/// Pretty-print the SILFunction to errs.
void SILFunction::dump(bool Verbose) const {
  SILPrintContext Ctx(llvm::errs(), Verbose);
  print(Ctx);
}

// This is out of line so the debugger can find it.
void SILFunction::dump() const {
  dump(false);
}

void SILFunction::dump(const char *FileName) const {
  std::error_code EC;
  llvm::raw_fd_ostream os(FileName, EC, llvm::sys::fs::OpenFlags::F_None);
  print(os);
}

static StringRef getLinkageString(SILLinkage linkage) {
  switch (linkage) {
  case SILLinkage::Public: return "public ";
  case SILLinkage::PublicNonABI: return "non_abi ";
  case SILLinkage::Hidden: return "hidden ";
  case SILLinkage::Shared: return "shared ";
  case SILLinkage::Private: return "private ";
  case SILLinkage::PublicExternal: return "public_external ";
  case SILLinkage::HiddenExternal: return "hidden_external ";
  case SILLinkage::SharedExternal: return "shared_external ";
  case SILLinkage::PrivateExternal: return "private_external ";
  }
  llvm_unreachable("bad linkage");
}

static void printLinkage(llvm::raw_ostream &OS, SILLinkage linkage,
                         bool isDefinition) {
  if ((isDefinition && linkage == SILLinkage::DefaultForDefinition) ||
      (!isDefinition && linkage == SILLinkage::DefaultForDeclaration))
    return;

  OS << getLinkageString(linkage);
}

/// Pretty-print the SILFunction to the designated stream.
void SILFunction::print(SILPrintContext &PrintCtx) const {
  llvm::raw_ostream &OS = PrintCtx.OS();
  if (PrintCtx.printDebugInfo()) {
    auto &SM = getModule().getASTContext().SourceMgr;
    for (auto &BB : *this)
      for (auto &I : BB) {
        SILPrinter P(PrintCtx);
        P.printDebugScope(I.getDebugScope(), SM);
      }
    OS << "\n";
  }

  if (SILPrintGenericSpecializationInfo) {
    if (isSpecialization()) {
      printGenericSpecializationInfo(OS, "function", getName(),
                                     getSpecializationInfo());
    }
  }

  OS << "// " << demangleSymbol(getName()) << '\n';
  OS << "sil ";
  printLinkage(OS, getLinkage(), isDefinition());

  if (isTransparent())
    OS << "[transparent] ";

  switch (isSerialized()) {
  case IsNotSerialized: break;
  case IsSerializable: OS << "[serializable] "; break;
  case IsSerialized: OS << "[serialized] "; break;
  }

  switch (isThunk()) {
  case IsNotThunk: break;
  case IsThunk: OS << "[thunk] "; break;
  case IsSignatureOptimizedThunk:
    OS << "[signature_optimized_thunk] ";
    break;
  case IsReabstractionThunk: OS << "[reabstraction_thunk] "; break;
  }
  if (isDynamicallyReplaceable()) {
    OS << "[dynamically_replacable] ";
  }
  if (isWithoutActuallyEscapingThunk())
    OS << "[without_actually_escaping] ";

  if (isGlobalInit())
    OS << "[global_init] ";
  if (isWeakLinked())
    OS << "[_weakLinked] ";

  switch (getInlineStrategy()) {
    case NoInline: OS << "[noinline] "; break;
    case AlwaysInline: OS << "[always_inline] "; break;
    case InlineDefault: break;
  }

  switch (getOptimizationMode()) {
    case OptimizationMode::NoOptimization: OS << "[Onone] "; break;
    case OptimizationMode::ForSpeed: OS << "[Ospeed] "; break;
    case OptimizationMode::ForSize: OS << "[Osize] "; break;
    default: break;
  }

  if (getEffectsKind() == EffectsKind::ReadOnly)
    OS << "[readonly] ";
  else if (getEffectsKind() == EffectsKind::ReadNone)
      OS << "[readnone] ";
  else if (getEffectsKind() == EffectsKind::ReadWrite)
    OS << "[readwrite] ";
  else if (getEffectsKind() == EffectsKind::ReleaseNone)
    OS << "[releasenone] ";

  if (auto *replacedFun = getDynamicallyReplacedFunction()) {
    OS << "[dynamic_replacement_for \"";
    OS << replacedFun->getName();
    OS << "\"] ";
  }

  if (hasObjCReplacement()) {
    OS << "[objc_replacement_for \"";
    OS << getObjCReplacement().str();
    OS << "\"] ";
  }

  for (auto &Attr : getSemanticsAttrs())
    OS << "[_semantics \"" << Attr << "\"] ";

  for (auto *Attr : getSpecializeAttrs()) {
    OS << "[_specialize "; Attr->print(OS); OS << "] ";
  }

  // TODO: Handle clang node owners which don't have a name.
  if (hasClangNode() && getClangNodeOwner()->hasName()) {
    OS << "[clang ";
    printValueDecl(getClangNodeOwner(), OS);
    OS << "] ";
  }

  // Handle functions that are deserialized from canonical SIL. Normally, we
  // should emit SIL with the correct SIL stage, so preserving this attribute
  // won't be necessary. But consider serializing raw SIL (either textual SIL or
  // SIB) after importing canonical SIL from another module. If the imported
  // functions are reserialized (e.g. shared linkage), then we must preserve
  // this attribute.
  if (WasDeserializedCanonical && getModule().getStage() == SILStage::Raw)
    OS << "[canonical] ";

  // If this function is not an external declaration /and/ is in ownership ssa
  // form, print [ossa].
  if (!isExternalDeclaration() && hasOwnership())
    OS << "[ossa] ";

  printName(OS);
  OS << " : $";
  
  // Print the type by substituting our context parameter names for the dependent
  // parameters. In SIL, we may end up with multiple generic parameters that
  // have the same name from different contexts, for instance, a generic
  // protocol requirement with a generic method parameter <T>, which is
  // witnessed by a generic type that has a generic type parameter also named
  // <T>, so we may need to introduce disambiguating aliases.
  llvm::DenseMap<CanType, Identifier> Aliases;
  llvm::DenseSet<Identifier> UsedNames;
  
  auto sig = getLoweredFunctionType()->getGenericSignature();
  auto *env = getGenericEnvironment();
  if (sig && env) {
    llvm::SmallString<16> disambiguatedNameBuf;
    unsigned disambiguatedNameCounter = 1;
    for (auto *paramTy : sig->getGenericParams()) {
      auto sugaredTy = env->getSugaredType(paramTy);
      Identifier name = sugaredTy->getName();
      while (!UsedNames.insert(name).second) {
        disambiguatedNameBuf.clear();
        {
          llvm::raw_svector_ostream names(disambiguatedNameBuf);
          names << sugaredTy->getName() << disambiguatedNameCounter++;
        }
        name = getASTContext().getIdentifier(disambiguatedNameBuf);
      }
      if (name != sugaredTy->getName()) {
        Aliases[paramTy->getCanonicalType()] = name;

        // Also for the archetype
        auto archetypeTy = env->mapTypeIntoContext(paramTy)
            ->getAs<ArchetypeType>();
        if (archetypeTy)
          Aliases[archetypeTy->getCanonicalType()] = name;
      }
    }
  }

  {
    PrintOptions withGenericEnvironment = PrintOptions::printSIL();
    withGenericEnvironment.GenericEnv = env;
    withGenericEnvironment.AlternativeTypeNames =
      Aliases.empty() ? nullptr : &Aliases;
    LoweredType->print(OS, withGenericEnvironment);
  }
  
  if (!isExternalDeclaration()) {
    if (auto eCount = getEntryCount()) {
      OS << " !function_entry_count(" << eCount.getValue() << ")";
    }
    OS << " {\n";

    SILPrinter(PrintCtx, (Aliases.empty() ? nullptr : &Aliases))
        .print(this);
    OS << "} // end sil function '" << getName() << '\'';
  }

  OS << "\n\n";
}
      
/// Pretty-print the SILFunction's name using SIL syntax,
/// '@function_mangled_name'.
void SILFunction::printName(raw_ostream &OS) const {
  OS << "@" << Name;  
}

/// Pretty-print a global variable to the designated stream.
void SILGlobalVariable::print(llvm::raw_ostream &OS, bool Verbose) const {
  OS << "// " << demangleSymbol(getName()) << '\n';
  
  OS << "sil_global ";
  printLinkage(OS, getLinkage(), isDefinition());

  if (isSerialized())
    OS << "[serialized] ";
  
  if (isLet())
    OS << "[let] ";

  printName(OS);
  OS << " : " << LoweredType;

  if (!StaticInitializerBlock.empty()) {
    OS << " = {\n";
    {
      SILPrintContext Ctx(OS);
      SILPrinter Printer(Ctx);
      for (const SILInstruction &I : StaticInitializerBlock) {
        Printer.print(&I);
      }
    }
    OS << "}\n";
  }

  OS << "\n\n";
}

void SILGlobalVariable::dump(bool Verbose) const {
  print(llvm::errs(), Verbose);
}
void SILGlobalVariable::dump() const {
   dump(false);
}

void SILGlobalVariable::printName(raw_ostream &OS) const {
  OS << "@" << Name;
}
      
/// Pretty-print the SILModule to errs.
void SILModule::dump(bool Verbose) const {
  SILPrintContext Ctx(llvm::errs(), Verbose);
  print(Ctx);
}

void SILModule::dump(const char *FileName, bool Verbose,
                     bool PrintASTDecls) const {
  std::error_code EC;
  llvm::raw_fd_ostream os(FileName, EC, llvm::sys::fs::OpenFlags::F_None);
  SILPrintContext Ctx(os, Verbose);
  print(Ctx, getSwiftModule(), PrintASTDecls);
}

static void printSILGlobals(SILPrintContext &Ctx,
                            const SILModule::GlobalListType &Globals) {
  if (!Ctx.sortSIL()) {
    for (const SILGlobalVariable &g : Globals)
      g.print(Ctx.OS(), Ctx.printVerbose());
    return;
  }

  std::vector<const SILGlobalVariable *> globals;
  globals.reserve(Globals.size());
  for (const SILGlobalVariable &g : Globals)
    globals.push_back(&g);
  std::sort(globals.begin(), globals.end(),
    [] (const SILGlobalVariable *g1, const SILGlobalVariable *g2) -> bool {
      return g1->getName().compare(g2->getName()) == -1;
    }
  );
  for (const SILGlobalVariable *g : globals)
    g->print(Ctx.OS(), Ctx.printVerbose());
}

static void printSILFunctions(SILPrintContext &Ctx,
                              const SILModule::FunctionListType &Functions) {
  if (!Ctx.sortSIL()) {
    for (const SILFunction &f : Functions)
      f.print(Ctx);
    return;
  }

  std::vector<const SILFunction *> functions;
  functions.reserve(Functions.size());
  for (const SILFunction &f : Functions)
    functions.push_back(&f);
  std::sort(functions.begin(), functions.end(),
    [] (const SILFunction *f1, const SILFunction *f2) -> bool {
      return f1->getName().compare(f2->getName()) == -1;
    }
  );
  for (const SILFunction *f : functions)
    f->print(Ctx);
}

static void printSILVTables(SILPrintContext &Ctx,
                            const SILModule::VTableListType &VTables) {
  if (!Ctx.sortSIL()) {
    for (const SILVTable &vt : VTables)
      vt.print(Ctx.OS(), Ctx.printVerbose());
    return;
  }

  std::vector<const SILVTable *> vtables;
  vtables.reserve(VTables.size());
  for (const SILVTable &vt : VTables)
    vtables.push_back(&vt);
  std::sort(vtables.begin(), vtables.end(),
    [] (const SILVTable *v1, const SILVTable *v2) -> bool {
      StringRef Name1 = v1->getClass()->getName().str();
      StringRef Name2 = v2->getClass()->getName().str();
      return Name1.compare(Name2) == -1;
    }
  );
  for (const SILVTable *vt : vtables)
    vt->print(Ctx.OS(), Ctx.printVerbose());
}

static void
printSILWitnessTables(SILPrintContext &Ctx,
                      const SILModule::WitnessTableListType &WTables) {
  if (!Ctx.sortSIL()) {
    for (const SILWitnessTable &wt : WTables)
      wt.print(Ctx.OS(), Ctx.printVerbose());
    return;
  }

  std::vector<const SILWitnessTable *> witnesstables;
  witnesstables.reserve(WTables.size());
  for (const SILWitnessTable &wt : WTables)
    witnesstables.push_back(&wt);
  std::sort(witnesstables.begin(), witnesstables.end(),
    [] (const SILWitnessTable *w1, const SILWitnessTable *w2) -> bool {
      return w1->getName().compare(w2->getName()) == -1;
    }
  );
  for (const SILWitnessTable *wt : witnesstables)
    wt->print(Ctx.OS(), Ctx.printVerbose());
}

static void
printSILDefaultWitnessTables(SILPrintContext &Ctx,
                        const SILModule::DefaultWitnessTableListType &WTables) {
  if (!Ctx.sortSIL()) {
    for (const SILDefaultWitnessTable &wt : WTables)
      wt.print(Ctx.OS(), Ctx.printVerbose());
    return;
  }

  std::vector<const SILDefaultWitnessTable *> witnesstables;
  witnesstables.reserve(WTables.size());
  for (const SILDefaultWitnessTable &wt : WTables)
    witnesstables.push_back(&wt);
  std::sort(witnesstables.begin(), witnesstables.end(),
    [] (const SILDefaultWitnessTable *w1,
        const SILDefaultWitnessTable *w2) -> bool {
      return w1->getProtocol()->getName()
          .compare(w2->getProtocol()->getName()) == -1;
    }
  );
  for (const SILDefaultWitnessTable *wt : witnesstables)
    wt->print(Ctx.OS(), Ctx.printVerbose());
}

static void
printSILCoverageMaps(SILPrintContext &Ctx,
                     const SILModule::CoverageMapCollectionType &CoverageMaps) {
  if (!Ctx.sortSIL()) {
    for (const auto &M : CoverageMaps)
      M.second->print(Ctx);
    return;
  }

  std::vector<const SILCoverageMap *> Maps;
  Maps.reserve(CoverageMaps.size());
  for (const auto &M : CoverageMaps)
    Maps.push_back(M.second);
  std::sort(Maps.begin(), Maps.end(),
            [](const SILCoverageMap *LHS, const SILCoverageMap *RHS) -> bool {
              return LHS->getName().compare(RHS->getName()) == -1;
            });
  for (const SILCoverageMap *M : Maps)
    M->print(Ctx);
}

void SILProperty::print(SILPrintContext &Ctx) const {
  PrintOptions Options = PrintOptions::printSIL();
  
  auto &OS = Ctx.OS();
  OS << "sil_property ";
  if (isSerialized())
    OS << "[serialized] ";
  
  OS << '#';
  printValueDecl(getDecl(), OS);
  if (auto sig = getDecl()->getInnermostDeclContext()
                          ->getGenericSignatureOfContext()) {
    sig->getCanonicalSignature()->print(OS, Options);
  }
  OS << " (";
  if (auto component = getComponent())
    SILPrinter(Ctx).printKeyPathPatternComponent(*component);
  OS << ")\n";
}

void SILProperty::dump() const {
  SILPrintContext context(llvm::errs());
  print(context);
}

static void printSILProperties(SILPrintContext &Ctx,
                               const SILModule::PropertyListType &Properties) {
  for (const SILProperty &P : Properties) {
    P.print(Ctx);
  }
}

/// Pretty-print the SILModule to the designated stream.
void SILModule::print(SILPrintContext &PrintCtx, ModuleDecl *M,
                      bool PrintASTDecls) const {
  llvm::raw_ostream &OS = PrintCtx.OS();
  OS << "sil_stage ";
  switch (Stage) {
  case SILStage::Raw:
    OS << "raw";
    break;
  case SILStage::Canonical:
    OS << "canonical";
    break;
  case SILStage::Lowered:
    OS << "lowered";
    break;
  }
  
  OS << "\n\nimport " << BUILTIN_NAME
     << "\nimport " << STDLIB_NAME
     << "\nimport " << SWIFT_SHIMS_NAME << "\n\n";

  // Print the declarations and types from the associated context (origin module or
  // current file).
  if (M && PrintASTDecls) {
    PrintOptions Options = PrintOptions::printSIL();
    Options.TypeDefinitions = true;
    Options.VarInitializers = true;
    // FIXME: ExplodePatternBindingDecls is incompatible with VarInitializers!
    Options.ExplodePatternBindingDecls = true;
    Options.SkipImplicit = false;
    Options.PrintGetSetOnRWProperties = true;
    Options.PrintInSILBody = false;
    bool WholeModuleMode = (M == AssociatedDeclContext);

    SmallVector<Decl *, 32> topLevelDecls;
    M->getTopLevelDecls(topLevelDecls);
    for (const Decl *D : topLevelDecls) {
      if (!WholeModuleMode && !(D->getDeclContext() == AssociatedDeclContext))
          continue;
      if ((isa<ValueDecl>(D) || isa<OperatorDecl>(D) ||
           isa<ExtensionDecl>(D) || isa<ImportDecl>(D)) &&
          !D->isImplicit()) {
        if (isa<AccessorDecl>(D))
          continue;

        // skip to visit ASTPrinter to avoid sil-opt prints duplicated import declarations
        if (auto importDecl = dyn_cast<ImportDecl>(D)) {
          StringRef importName = importDecl->getModule()->getName().str();
          if (importName == BUILTIN_NAME ||
              importName == STDLIB_NAME ||
              importName == SWIFT_SHIMS_NAME)
            continue;
        }
        D->print(OS, Options);
        OS << "\n\n";
      }
    }
  }

  printSILGlobals(PrintCtx, getSILGlobalList());
  printSILFunctions(PrintCtx, getFunctionList());
  printSILVTables(PrintCtx, getVTableList());
  printSILWitnessTables(PrintCtx, getWitnessTableList());
  printSILDefaultWitnessTables(PrintCtx, getDefaultWitnessTableList());
  printSILCoverageMaps(PrintCtx, getCoverageMaps());
  printSILProperties(PrintCtx, getPropertyList());
  
  OS << "\n\n";
}

void SILNode::dumpInContext() const {
  printInContext(llvm::errs());
}
void SILNode::printInContext(llvm::raw_ostream &OS) const {
  SILPrintContext Ctx(OS);
  SILPrinter(Ctx).printInContext(this);
}

void SILInstruction::dumpInContext() const {
  printInContext(llvm::errs());
}
void SILInstruction::printInContext(llvm::raw_ostream &OS) const {
  SILPrintContext Ctx(OS);
  SILPrinter(Ctx).printInContext(this);
}

void SILVTable::print(llvm::raw_ostream &OS, bool Verbose) const {
  OS << "sil_vtable ";
  if (isSerialized())
    OS << "[serialized] ";
  OS << getClass()->getName() << " {\n";

  PrintOptions QualifiedSILTypeOptions = PrintOptions::printQualifiedSILType();
  for (auto &entry : getEntries()) {
    OS << "  ";
    entry.Method.print(OS);
    OS << ": ";

    bool HasSingleImplementation = false;
    switch (entry.Method.kind) {
    default:
      break;
    case SILDeclRef::Kind::IVarDestroyer:
    case SILDeclRef::Kind::Destroyer:
    case SILDeclRef::Kind::Deallocator:
      HasSingleImplementation = true;
    }
    // No need to emit the signature for methods that may have only
    // single implementation, e.g. for destructors.
    if (!HasSingleImplementation) {
      QualifiedSILTypeOptions.CurrentModule =
          entry.Method.getDecl()->getDeclContext()->getParentModule();
      entry.Method.getDecl()->getInterfaceType().print(OS,
                                                       QualifiedSILTypeOptions);
      OS << " : ";
    }
    if (entry.Linkage !=
        stripExternalFromLinkage(entry.Implementation->getLinkage())) {
      OS << getLinkageString(entry.Linkage);
    }
    OS << '@' << entry.Implementation->getName();
    switch (entry.TheKind) {
    case SILVTable::Entry::Kind::Normal:
      break;
    case SILVTable::Entry::Kind::Inherited:
      OS << " [inherited]";
      break;
    case SILVTable::Entry::Kind::Override:
      OS << " [override]";
      break;
    }
    OS << "\t// " << demangleSymbol(entry.Implementation->getName());
    OS << "\n";
  }
  OS << "}\n\n";
}

void SILVTable::dump() const {
  print(llvm::errs());
}

/// Returns true if anything was printed.
static bool printAssociatedTypePath(llvm::raw_ostream &OS, CanType path) {
  if (auto memberType = dyn_cast<DependentMemberType>(path)) {
    if (printAssociatedTypePath(OS, memberType.getBase()))
      OS << '.';
    OS << memberType->getName().str();
    return true;
  } else {
    assert(isa<GenericTypeParamType>(path));
    return false;
  }
}

void SILWitnessTable::Entry::print(llvm::raw_ostream &out, bool verbose,
                                   const PrintOptions &options) const {
  PrintOptions QualifiedSILTypeOptions = PrintOptions::printQualifiedSILType();
  out << "  ";
  switch (getKind()) {
  case WitnessKind::Invalid:
    out << "no_default";
    break;
  case WitnessKind::Method: {
    // method #declref: @function
    auto &methodWitness = getMethodWitness();
    out << "method ";
    methodWitness.Requirement.print(out);
    out << ": ";
    QualifiedSILTypeOptions.CurrentModule =
        methodWitness.Requirement.getDecl()
            ->getDeclContext()
            ->getParentModule();
    methodWitness.Requirement.getDecl()->getInterfaceType().print(
        out, QualifiedSILTypeOptions);
    out << " : ";
    if (methodWitness.Witness) {
      methodWitness.Witness->printName(out);
      out << "\t// "
         << demangleSymbol(methodWitness.Witness->getName());
    } else {
      out << "nil";
    }
    break;
  }
  case WitnessKind::AssociatedType: {
    // associated_type AssociatedTypeName: ConformingType
    auto &assocWitness = getAssociatedTypeWitness();
    out << "associated_type ";
    out << assocWitness.Requirement->getName() << ": ";
    assocWitness.Witness->print(out, options);
    break;
  }
  case WitnessKind::AssociatedTypeProtocol: {
    // associated_type_protocol (AssociatedTypeName: Protocol): <conformance>
    auto &assocProtoWitness = getAssociatedTypeProtocolWitness();
    out << "associated_type_protocol (";
    (void) printAssociatedTypePath(out, assocProtoWitness.Requirement);
    out << ": " << assocProtoWitness.Protocol->getName() << "): ";
    if (assocProtoWitness.Witness.isConcrete())
      assocProtoWitness.Witness.getConcrete()->printName(out, options);
    else
      out << "dependent";
    break;
  }
  case WitnessKind::BaseProtocol: {
    // base_protocol Protocol: <conformance>
    auto &baseProtoWitness = getBaseProtocolWitness();
    out << "base_protocol "
        << baseProtoWitness.Requirement->getName() << ": ";
    baseProtoWitness.Witness->printName(out, options);
    break;
  }
  }
  out << '\n';
}

void SILWitnessTable::print(llvm::raw_ostream &OS, bool Verbose) const {
  PrintOptions Options = PrintOptions::printSIL();
  PrintOptions QualifiedSILTypeOptions = PrintOptions::printQualifiedSILType();
  OS << "sil_witness_table ";
  printLinkage(OS, getLinkage(), /*isDefinition*/ isDefinition());
  if (isSerialized())
    OS << "[serialized] ";

  getConformance()->printName(OS, Options);
  Options.GenericEnv =
    getConformance()->getDeclContext()->getGenericEnvironmentOfContext();

  if (isDeclaration()) {
    OS << "\n\n";
    return;
  }

  OS << " {\n";
  
  for (auto &witness : getEntries()) {
    witness.print(OS, Verbose, Options);
  }

  for (auto conditionalConformance : getConditionalConformances()) {
    // conditional_conformance (TypeName: Protocol):
    // <conformance>
    OS << "  conditional_conformance (";
    conditionalConformance.Requirement.print(OS, Options);
    OS << ": " << conditionalConformance.Conformance.getRequirement()->getName()
       << "): ";
    if (conditionalConformance.Conformance.isConcrete())
      conditionalConformance.Conformance.getConcrete()->printName(OS, Options);
    else
      OS << "dependent";

    OS << '\n';
  }

  OS << "}\n\n";
}

void SILWitnessTable::dump() const {
  print(llvm::errs());
}

void SILDefaultWitnessTable::print(llvm::raw_ostream &OS, bool Verbose) const {
  // sil_default_witness_table [<Linkage>] <Protocol> <MinSize>
  PrintOptions QualifiedSILTypeOptions = PrintOptions::printQualifiedSILType();
  OS << "sil_default_witness_table ";
  printLinkage(OS, getLinkage(), ForDefinition);
  OS << getProtocol()->getName() << " {\n";
  
  PrintOptions options = PrintOptions::printSIL();
  options.GenericEnv = Protocol->getGenericEnvironmentOfContext();

  for (auto &witness : getEntries()) {
    witness.print(OS, Verbose, options);
  }
  
  OS << "}\n\n";
}

void SILDefaultWitnessTable::dump() const {
  print(llvm::errs());
}

void SILCoverageMap::print(SILPrintContext &PrintCtx) const {
  llvm::raw_ostream &OS = PrintCtx.OS();
  OS << "sil_coverage_map " << QuotedString(getFile()) << " "
     << QuotedString(getName()) << " " << QuotedString(getPGOFuncName()) << " "
     << getHash() << " {\t// " << demangleSymbol(getName()) << "\n";
  if (PrintCtx.sortSIL())
    std::sort(MappedRegions.begin(), MappedRegions.end(),
              [](const MappedRegion &LHS, const MappedRegion &RHS) {
      return std::tie(LHS.StartLine, LHS.StartCol, LHS.EndLine, LHS.EndCol) <
             std::tie(RHS.StartLine, RHS.StartCol, RHS.EndLine, RHS.EndCol);
    });
  for (auto &MR : getMappedRegions()) {
    OS << "  " << MR.StartLine << ":" << MR.StartCol << " -> " << MR.EndLine
       << ":" << MR.EndCol << " : ";
    printCounter(OS, MR.Counter);
    OS << "\n";
  }
  OS << "}\n\n";
}

void SILCoverageMap::dump() const {
  print(llvm::errs());
}

#ifndef NDEBUG
void SILDebugScope::dump(SourceManager &SM, llvm::raw_ostream &OS,
                         unsigned Indent) const {
  OS << "{\n";
  OS.indent(Indent);
  if (Loc.isASTNode())
    Loc.getSourceLoc().print(OS, SM);
  OS << "\n";
  OS.indent(Indent + 2);
  OS << " parent: ";
  if (auto *P = Parent.dyn_cast<const SILDebugScope *>()) {
    P->dump(SM, OS, Indent + 2);
    OS.indent(Indent + 2);
  }
  else if (auto *F = Parent.dyn_cast<SILFunction *>())
    OS << "@" << F->getName();
  else
    OS << "nullptr";

  OS << "\n";
  OS.indent(Indent + 2);
  if (auto *CS = InlinedCallSite) {
    OS << "inlinedCallSite: ";
    CS->dump(SM, OS, Indent + 2);
    OS.indent(Indent + 2);
  }
  OS << "}\n";
}
#endif

void SILSpecializeAttr::print(llvm::raw_ostream &OS) const {
  SILPrintContext Ctx(OS);
  // Print other types as their Swift representation.
  PrintOptions SubPrinter = PrintOptions::printSIL();
  auto exported = isExported() ? "true" : "false";
  auto kind = isPartialSpecialization() ? "partial" : "full";

  OS << "exported: " << exported << ", ";
  OS << "kind: " << kind << ", ";

  if (!getRequirements().empty()) {
    OS << "where ";
    SILFunction *F = getFunction();
    assert(F);
    auto GenericEnv = F->getGenericEnvironment();
    interleave(getRequirements(),
               [&](Requirement req) {
                 if (!GenericEnv) {
                   req.print(OS, SubPrinter);
                   return;
                 }
                 // Use GenericEnvironment to produce user-friendly
                 // names instead of something like t_0_0.
                 auto FirstTy = GenericEnv->getSugaredType(req.getFirstType());
                 if (req.getKind() != RequirementKind::Layout) {
                   auto SecondTy =
                       GenericEnv->getSugaredType(req.getSecondType());
                   Requirement ReqWithDecls(req.getKind(), FirstTy, SecondTy);
                   ReqWithDecls.print(OS, SubPrinter);
                 } else {
                   Requirement ReqWithDecls(req.getKind(), FirstTy,
                                            req.getLayoutConstraint());
                   ReqWithDecls.print(OS, SubPrinter);
                 }
               },
               [&] { OS << ", "; });
  }
}

//===----------------------------------------------------------------------===//
// SILPrintContext members
//===----------------------------------------------------------------------===//

SILPrintContext::SILPrintContext(llvm::raw_ostream &OS, bool Verbose,
                bool SortedSIL) :
  OutStream(OS), Verbose(Verbose), SortedSIL(SortedSIL),
  DebugInfo(SILPrintDebugInfo) { }

SILPrintContext::SILPrintContext(llvm::raw_ostream &OS, bool Verbose,
                                 bool SortedSIL, bool DebugInfo) :
  OutStream(OS), Verbose(Verbose), SortedSIL(SortedSIL),
  DebugInfo(DebugInfo) { }

void SILPrintContext::setContext(const void *FunctionOrBlock) {
  if (FunctionOrBlock != ContextFunctionOrBlock) {
    BlocksToIDMap.clear();
    ValueToIDMap.clear();
    ContextFunctionOrBlock = FunctionOrBlock;
  }
}

SILPrintContext::~SILPrintContext() {
}

void SILPrintContext::printInstructionCallBack(const SILInstruction *I) {
}

void SILPrintContext::initBlockIDs(ArrayRef<const SILBasicBlock *> Blocks) {
  if (Blocks.empty())
    return;

  setContext(Blocks[0]->getParent());

  // Initialize IDs so our IDs are in RPOT as well. This is a hack.
  for (unsigned Index : indices(Blocks))
    BlocksToIDMap[Blocks[Index]] = Index;
}

ID SILPrintContext::getID(const SILBasicBlock *Block) {
  setContext(Block->getParent());

  // Lazily initialize the Blocks-to-IDs mapping.
  // If we are asked to emit sorted SIL, print out our BBs in RPOT order.
  if (BlocksToIDMap.empty()) {
    if (sortSIL()) {
      std::vector<SILBasicBlock *> RPOT;
      auto *UnsafeF = const_cast<SILFunction *>(Block->getParent());
      std::copy(po_begin(UnsafeF), po_end(UnsafeF), std::back_inserter(RPOT));
      std::reverse(RPOT.begin(), RPOT.end());
      // Initialize IDs so our IDs are in RPOT as well. This is a hack.
      for (unsigned Index : indices(RPOT))
        BlocksToIDMap[RPOT[Index]] = Index;
    } else {
      unsigned idx = 0;
      for (const SILBasicBlock &B : *Block->getParent())
        BlocksToIDMap[&B] = idx++;
    }
  }
  ID R = {ID::SILBasicBlock, BlocksToIDMap[Block]};
  return R;
}

ID SILPrintContext::getID(const SILNode *node) {
  if (node == nullptr)
    return {ID::Null, ~0U};

  if (isa<SILUndef>(node))
    return {ID::SILUndef, 0};
  
  SILBasicBlock *BB = node->getParentBlock();
  if (SILFunction *F = BB->getParent()) {
    setContext(F);
    // Lazily initialize the instruction -> ID mapping.
    if (ValueToIDMap.empty())
      F->numberValues(ValueToIDMap);
    ID R = {ID::SSAValue, ValueToIDMap[node]};
    return R;
  }

  setContext(BB);

  // Check if we have initialized our ValueToIDMap yet. If we have, just use
  // that.
  if (!ValueToIDMap.empty()) {
    ID R = {ID::SSAValue, ValueToIDMap[node]};
    return R;
  }

  // Otherwise, initialize the instruction -> ID mapping cache.
  unsigned idx = 0;
  for (auto &I : *BB) {
    // Give the instruction itself the next ID.
    ValueToIDMap[&I] = idx;

    // If there are no results, make sure we don't reuse that ID.
    auto results = I.getResults();
    if (results.empty()) {
      idx++;
      continue;
    }

    // Otherwise, assign all of the results an index.  Note that
    // we'll assign the same ID to both the instruction and the
    // first result.
    for (auto result : results) {
      ValueToIDMap[result] = idx++;
    }
  }

  ID R = {ID::SSAValue, ValueToIDMap[node]};
  return R;
}
