diff options
Diffstat (limited to 'lib/Bitcode/Writer/BitcodeWriter.cpp')
| -rw-r--r-- | lib/Bitcode/Writer/BitcodeWriter.cpp | 741 | 
1 files changed, 675 insertions, 66 deletions
diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 1a70ba5ac127..a1f87863757b 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -13,14 +13,18 @@  #include "llvm/Bitcode/ReaderWriter.h"  #include "ValueEnumerator.h" +#include "llvm/ADT/STLExtras.h"  #include "llvm/ADT/Triple.h"  #include "llvm/Bitcode/BitstreamWriter.h"  #include "llvm/Bitcode/LLVMBitCodes.h" +#include "llvm/IR/CallSite.h"  #include "llvm/IR/Constants.h"  #include "llvm/IR/DebugInfoMetadata.h"  #include "llvm/IR/DerivedTypes.h"  #include "llvm/IR/InlineAsm.h"  #include "llvm/IR/Instructions.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/IntrinsicInst.h"  #include "llvm/IR/Module.h"  #include "llvm/IR/Operator.h"  #include "llvm/IR/UseListOrder.h" @@ -174,6 +178,10 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {      return bitc::ATTR_KIND_IN_ALLOCA;    case Attribute::Cold:      return bitc::ATTR_KIND_COLD; +  case Attribute::InaccessibleMemOnly: +    return bitc::ATTR_KIND_INACCESSIBLEMEM_ONLY; +  case Attribute::InaccessibleMemOrArgMemOnly: +    return bitc::ATTR_KIND_INACCESSIBLEMEM_OR_ARGMEMONLY;    case Attribute::InlineHint:      return bitc::ATTR_KIND_INLINE_HINT;    case Attribute::InReg: @@ -198,6 +206,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {      return bitc::ATTR_KIND_NO_IMPLICIT_FLOAT;    case Attribute::NoInline:      return bitc::ATTR_KIND_NO_INLINE; +  case Attribute::NoRecurse: +    return bitc::ATTR_KIND_NO_RECURSE;    case Attribute::NonLazyBind:      return bitc::ATTR_KIND_NON_LAZY_BIND;    case Attribute::NonNull: @@ -405,6 +415,7 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {      case Type::LabelTyID:     Code = bitc::TYPE_CODE_LABEL;     break;      case Type::MetadataTyID:  Code = bitc::TYPE_CODE_METADATA;  break;      case Type::X86_MMXTyID:   Code = bitc::TYPE_CODE_X86_MMX;   break; +    case Type::TokenTyID:     Code = bitc::TYPE_CODE_TOKEN;     break;      case Type::IntegerTyID:        // INTEGER: [width]        Code = bitc::TYPE_CODE_INTEGER; @@ -573,10 +584,41 @@ static void writeComdats(const ValueEnumerator &VE, BitstreamWriter &Stream) {    }  } -// Emit top-level description of module, including target triple, inline asm, -// descriptors for global variables, and function prototype info. -static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, -                            BitstreamWriter &Stream) { +/// Write a record that will eventually hold the word offset of the +/// module-level VST. For now the offset is 0, which will be backpatched +/// after the real VST is written. Returns the bit offset to backpatch. +static uint64_t WriteValueSymbolTableForwardDecl(const ValueSymbolTable &VST, +                                                 BitstreamWriter &Stream) { +  if (VST.empty()) +    return 0; + +  // Write a placeholder value in for the offset of the real VST, +  // which is written after the function blocks so that it can include +  // the offset of each function. The placeholder offset will be +  // updated when the real VST is written. +  BitCodeAbbrev *Abbv = new BitCodeAbbrev(); +  Abbv->Add(BitCodeAbbrevOp(bitc::MODULE_CODE_VSTOFFSET)); +  // Blocks are 32-bit aligned, so we can use a 32-bit word offset to +  // hold the real VST offset. Must use fixed instead of VBR as we don't +  // know how many VBR chunks to reserve ahead of time. +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); +  unsigned VSTOffsetAbbrev = Stream.EmitAbbrev(Abbv); + +  // Emit the placeholder +  uint64_t Vals[] = {bitc::MODULE_CODE_VSTOFFSET, 0}; +  Stream.EmitRecordWithAbbrev(VSTOffsetAbbrev, Vals); + +  // Compute and return the bit offset to the placeholder, which will be +  // patched when the real VST is written. We can simply subtract the 32-bit +  // fixed size from the current bit number to get the location to backpatch. +  return Stream.GetCurrentBitNo() - 32; +} + +/// Emit top-level description of module, including target triple, inline asm, +/// descriptors for global variables, and function prototype info. +/// Returns the bit offset to backpatch with the location of the real VST. +static uint64_t WriteModuleInfo(const Module *M, const ValueEnumerator &VE, +                                BitstreamWriter &Stream) {    // Emit various pieces of data attached to a module.    if (!M->getTargetTriple().empty())      WriteStringRecord(bitc::MODULE_CODE_TRIPLE, M->getTargetTriple(), @@ -725,7 +767,8 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE,    // Emit the alias information.    for (const GlobalAlias &A : M->aliases()) {      // ALIAS: [alias type, aliasee val#, linkage, visibility] -    Vals.push_back(VE.getTypeID(A.getType())); +    Vals.push_back(VE.getTypeID(A.getValueType())); +    Vals.push_back(A.getType()->getAddressSpace());      Vals.push_back(VE.getValueID(A.getAliasee()));      Vals.push_back(getEncodedLinkage(A));      Vals.push_back(getEncodedVisibility(A)); @@ -736,6 +779,25 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE,      Stream.EmitRecord(bitc::MODULE_CODE_ALIAS, Vals, AbbrevToUse);      Vals.clear();    } + +  // Write a record indicating the number of module-level metadata IDs +  // This is needed because the ids of metadata are assigned implicitly +  // based on their ordering in the bitcode, with the function-level +  // metadata ids starting after the module-level metadata ids. For +  // function importing where we lazy load the metadata as a postpass, +  // we want to avoid parsing the module-level metadata before parsing +  // the imported functions. +  BitCodeAbbrev *Abbv = new BitCodeAbbrev(); +  Abbv->Add(BitCodeAbbrevOp(bitc::MODULE_CODE_METADATA_VALUES)); +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); +  unsigned MDValsAbbrev = Stream.EmitAbbrev(Abbv); +  Vals.push_back(VE.numMDs()); +  Stream.EmitRecord(bitc::MODULE_CODE_METADATA_VALUES, Vals, MDValsAbbrev); +  Vals.clear(); + +  uint64_t VSTOffsetPlaceholder = +      WriteValueSymbolTableForwardDecl(M->getValueSymbolTable(), Stream); +  return VSTOffsetPlaceholder;  }  static uint64_t GetOptimizationFlags(const Value *V) { @@ -943,7 +1005,8 @@ static void WriteDICompileUnit(const DICompileUnit *N,                                 BitstreamWriter &Stream,                                 SmallVectorImpl<uint64_t> &Record,                                 unsigned Abbrev) { -  Record.push_back(N->isDistinct()); +  assert(N->isDistinct() && "Expected distinct compile units"); +  Record.push_back(/* IsDistinct */ true);    Record.push_back(N->getSourceLanguage());    Record.push_back(VE.getMetadataOrNullID(N->getFile()));    Record.push_back(VE.getMetadataOrNullID(N->getRawProducer())); @@ -958,6 +1021,7 @@ static void WriteDICompileUnit(const DICompileUnit *N,    Record.push_back(VE.getMetadataOrNullID(N->getGlobalVariables().get()));    Record.push_back(VE.getMetadataOrNullID(N->getImportedEntities().get()));    Record.push_back(N->getDWOId()); +  Record.push_back(VE.getMetadataOrNullID(N->getMacros().get()));    Stream.EmitRecord(bitc::METADATA_COMPILE_UNIT, Record, Abbrev);    Record.clear(); @@ -982,7 +1046,6 @@ static void WriteDISubprogram(const DISubprogram *N, const ValueEnumerator &VE,    Record.push_back(N->getVirtualIndex());    Record.push_back(N->getFlags());    Record.push_back(N->isOptimized()); -  Record.push_back(VE.getMetadataOrNullID(N->getRawFunction()));    Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams().get()));    Record.push_back(VE.getMetadataOrNullID(N->getDeclaration()));    Record.push_back(VE.getMetadataOrNullID(N->getVariables().get())); @@ -1034,6 +1097,33 @@ static void WriteDINamespace(const DINamespace *N, const ValueEnumerator &VE,    Record.clear();  } +static void WriteDIMacro(const DIMacro *N, const ValueEnumerator &VE, +                         BitstreamWriter &Stream, +                         SmallVectorImpl<uint64_t> &Record, unsigned Abbrev) { +  Record.push_back(N->isDistinct()); +  Record.push_back(N->getMacinfoType()); +  Record.push_back(N->getLine()); +  Record.push_back(VE.getMetadataOrNullID(N->getRawName())); +  Record.push_back(VE.getMetadataOrNullID(N->getRawValue())); + +  Stream.EmitRecord(bitc::METADATA_MACRO, Record, Abbrev); +  Record.clear(); +} + +static void WriteDIMacroFile(const DIMacroFile *N, const ValueEnumerator &VE, +                             BitstreamWriter &Stream, +                             SmallVectorImpl<uint64_t> &Record, +                             unsigned Abbrev) { +  Record.push_back(N->isDistinct()); +  Record.push_back(N->getMacinfoType()); +  Record.push_back(N->getLine()); +  Record.push_back(VE.getMetadataOrNullID(N->getFile())); +  Record.push_back(VE.getMetadataOrNullID(N->getElements().get())); + +  Stream.EmitRecord(bitc::METADATA_MACRO_FILE, Record, Abbrev); +  Record.clear(); +} +  static void WriteDIModule(const DIModule *N, const ValueEnumerator &VE,                            BitstreamWriter &Stream,                            SmallVectorImpl<uint64_t> &Record, unsigned Abbrev) { @@ -1100,7 +1190,6 @@ static void WriteDILocalVariable(const DILocalVariable *N,                                   SmallVectorImpl<uint64_t> &Record,                                   unsigned Abbrev) {    Record.push_back(N->isDistinct()); -  Record.push_back(N->getTag());    Record.push_back(VE.getMetadataOrNullID(N->getScope()));    Record.push_back(VE.getMetadataOrNullID(N->getRawName()));    Record.push_back(VE.getMetadataOrNullID(N->getFile())); @@ -1310,16 +1399,15 @@ static void WriteMetadataAttachment(const Function &F,      Record.clear();    } -  for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) -    for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); -         I != E; ++I) { +  for (const BasicBlock &BB : F) +    for (const Instruction &I : BB) {        MDs.clear(); -      I->getAllMetadataOtherThanDebugLoc(MDs); +      I.getAllMetadataOtherThanDebugLoc(MDs);        // If no metadata, ignore instruction.        if (MDs.empty()) continue; -      Record.push_back(VE.getInstructionID(I)); +      Record.push_back(VE.getInstructionID(&I));        for (unsigned i = 0, e = MDs.size(); i != e; ++i) {          Record.push_back(MDs[i].first); @@ -1342,7 +1430,7 @@ static void WriteModuleMetadataStore(const Module *M, BitstreamWriter &Stream) {    if (Names.empty()) return; -  Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3); +  Stream.EnterSubblock(bitc::METADATA_KIND_BLOCK_ID, 3);    for (unsigned MDKindID = 0, e = Names.size(); MDKindID != e; ++MDKindID) {      Record.push_back(MDKindID); @@ -1356,6 +1444,33 @@ static void WriteModuleMetadataStore(const Module *M, BitstreamWriter &Stream) {    Stream.ExitBlock();  } +static void WriteOperandBundleTags(const Module *M, BitstreamWriter &Stream) { +  // Write metadata kinds +  // +  // OPERAND_BUNDLE_TAGS_BLOCK_ID : N x OPERAND_BUNDLE_TAG +  // +  // OPERAND_BUNDLE_TAG - [strchr x N] + +  SmallVector<StringRef, 8> Tags; +  M->getOperandBundleTags(Tags); + +  if (Tags.empty()) +    return; + +  Stream.EnterSubblock(bitc::OPERAND_BUNDLE_TAGS_BLOCK_ID, 3); + +  SmallVector<uint64_t, 64> Record; + +  for (auto Tag : Tags) { +    Record.append(Tag.begin(), Tag.end()); + +    Stream.EmitRecord(bitc::OPERAND_BUNDLE_TAG, Record, 0); +    Record.clear(); +  } + +  Stream.ExitBlock(); +} +  static void emitSignedInt64(SmallVectorImpl<uint64_t> &Vals, uint64_t V) {    if ((int64_t)V >= 0)      Vals.push_back(V << 1); @@ -1664,6 +1779,23 @@ static bool PushValueAndType(const Value *V, unsigned InstID,    return false;  } +static void WriteOperandBundles(BitstreamWriter &Stream, ImmutableCallSite CS, +                                unsigned InstID, ValueEnumerator &VE) { +  SmallVector<unsigned, 64> Record; +  LLVMContext &C = CS.getInstruction()->getContext(); + +  for (unsigned i = 0, e = CS.getNumOperandBundles(); i != e; ++i) { +    const auto &Bundle = CS.getOperandBundleAt(i); +    Record.push_back(C.getOperandBundleTagID(Bundle.getTagName())); + +    for (auto &Input : Bundle.Inputs) +      PushValueAndType(Input, InstID, Record, VE); + +    Stream.EmitRecord(bitc::FUNC_CODE_OPERAND_BUNDLE, Record); +    Record.clear(); +  } +} +  /// pushValue - Like PushValueAndType, but where the type of the value is  /// omitted (perhaps it was already encoded in an earlier operand).  static void pushValue(const Value *V, unsigned InstID, @@ -1806,10 +1938,9 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,        Vals.push_back(VE.getTypeID(SI.getCondition()->getType()));        pushValue(SI.getCondition(), InstID, Vals, VE);        Vals.push_back(VE.getValueID(SI.getDefaultDest())); -      for (SwitchInst::ConstCaseIt i = SI.case_begin(), e = SI.case_end(); -           i != e; ++i) { -        Vals.push_back(VE.getValueID(i.getCaseValue())); -        Vals.push_back(VE.getValueID(i.getCaseSuccessor())); +      for (SwitchInst::ConstCaseIt Case : SI.cases()) { +        Vals.push_back(VE.getValueID(Case.getCaseValue())); +        Vals.push_back(VE.getValueID(Case.getCaseSuccessor()));        }      }      break; @@ -1826,6 +1957,10 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,      const InvokeInst *II = cast<InvokeInst>(&I);      const Value *Callee = II->getCalledValue();      FunctionType *FTy = II->getFunctionType(); + +    if (II->hasOperandBundles()) +      WriteOperandBundles(Stream, II, InstID, VE); +      Code = bitc::FUNC_CODE_INST_INVOKE;      Vals.push_back(VE.getAttributeID(II->getAttributes())); @@ -1851,6 +1986,49 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,      Code = bitc::FUNC_CODE_INST_RESUME;      PushValueAndType(I.getOperand(0), InstID, Vals, VE);      break; +  case Instruction::CleanupRet: { +    Code = bitc::FUNC_CODE_INST_CLEANUPRET; +    const auto &CRI = cast<CleanupReturnInst>(I); +    pushValue(CRI.getCleanupPad(), InstID, Vals, VE); +    if (CRI.hasUnwindDest()) +      Vals.push_back(VE.getValueID(CRI.getUnwindDest())); +    break; +  } +  case Instruction::CatchRet: { +    Code = bitc::FUNC_CODE_INST_CATCHRET; +    const auto &CRI = cast<CatchReturnInst>(I); +    pushValue(CRI.getCatchPad(), InstID, Vals, VE); +    Vals.push_back(VE.getValueID(CRI.getSuccessor())); +    break; +  } +  case Instruction::CleanupPad: +  case Instruction::CatchPad: { +    const auto &FuncletPad = cast<FuncletPadInst>(I); +    Code = isa<CatchPadInst>(FuncletPad) ? bitc::FUNC_CODE_INST_CATCHPAD +                                         : bitc::FUNC_CODE_INST_CLEANUPPAD; +    pushValue(FuncletPad.getParentPad(), InstID, Vals, VE); + +    unsigned NumArgOperands = FuncletPad.getNumArgOperands(); +    Vals.push_back(NumArgOperands); +    for (unsigned Op = 0; Op != NumArgOperands; ++Op) +      PushValueAndType(FuncletPad.getArgOperand(Op), InstID, Vals, VE); +    break; +  } +  case Instruction::CatchSwitch: { +    Code = bitc::FUNC_CODE_INST_CATCHSWITCH; +    const auto &CatchSwitch = cast<CatchSwitchInst>(I); + +    pushValue(CatchSwitch.getParentPad(), InstID, Vals, VE); + +    unsigned NumHandlers = CatchSwitch.getNumHandlers(); +    Vals.push_back(NumHandlers); +    for (const BasicBlock *CatchPadBB : CatchSwitch.handlers()) +      Vals.push_back(VE.getValueID(CatchPadBB)); + +    if (CatchSwitch.hasUnwindDest()) +      Vals.push_back(VE.getValueID(CatchSwitch.getUnwindDest())); +    break; +  }    case Instruction::Unreachable:      Code = bitc::FUNC_CODE_INST_UNREACHABLE;      AbbrevToUse = FUNCTION_INST_UNREACHABLE_ABBREV; @@ -1902,6 +2080,8 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,      assert(AlignRecord < 1 << 5 && "alignment greater than 1 << 64");      AlignRecord |= AI.isUsedWithInAlloca() << 5;      AlignRecord |= 1 << 6; +    // Reserve bit 7 for SwiftError flag. +    // AlignRecord |= AI.isSwiftError() << 7;      Vals.push_back(AlignRecord);      break;    } @@ -1971,11 +2151,23 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,      const CallInst &CI = cast<CallInst>(I);      FunctionType *FTy = CI.getFunctionType(); +    if (CI.hasOperandBundles()) +      WriteOperandBundles(Stream, &CI, InstID, VE); +      Code = bitc::FUNC_CODE_INST_CALL;      Vals.push_back(VE.getAttributeID(CI.getAttributes())); -    Vals.push_back((CI.getCallingConv() << 1) | unsigned(CI.isTailCall()) | -                   unsigned(CI.isMustTailCall()) << 14 | 1 << 15); + +    unsigned Flags = GetOptimizationFlags(&I); +    Vals.push_back(CI.getCallingConv() << bitc::CALL_CCONV | +                   unsigned(CI.isTailCall()) << bitc::CALL_TAIL | +                   unsigned(CI.isMustTailCall()) << bitc::CALL_MUSTTAIL | +                   1 << bitc::CALL_EXPLICIT_TYPE | +                   unsigned(CI.isNoTailCall()) << bitc::CALL_NOTAIL | +                   unsigned(Flags != 0) << bitc::CALL_FMF); +    if (Flags != 0) +      Vals.push_back(Flags); +      Vals.push_back(VE.getTypeID(FTy));      PushValueAndType(CI.getCalledValue(), InstID, Vals, VE);  // Callee @@ -2008,56 +2200,149 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,    Vals.clear();  } -// Emit names for globals/functions etc. -static void WriteValueSymbolTable(const ValueSymbolTable &VST, -                                  const ValueEnumerator &VE, -                                  BitstreamWriter &Stream) { -  if (VST.empty()) return; +enum StringEncoding { SE_Char6, SE_Fixed7, SE_Fixed8 }; + +/// Determine the encoding to use for the given string name and length. +static StringEncoding getStringEncoding(const char *Str, unsigned StrLen) { +  bool isChar6 = true; +  for (const char *C = Str, *E = C + StrLen; C != E; ++C) { +    if (isChar6) +      isChar6 = BitCodeAbbrevOp::isChar6(*C); +    if ((unsigned char)*C & 128) +      // don't bother scanning the rest. +      return SE_Fixed8; +  } +  if (isChar6) +    return SE_Char6; +  else +    return SE_Fixed7; +} + +/// Emit names for globals/functions etc. The VSTOffsetPlaceholder, +/// BitcodeStartBit and FunctionIndex are only passed for the module-level +/// VST, where we are including a function bitcode index and need to +/// backpatch the VST forward declaration record. +static void WriteValueSymbolTable( +    const ValueSymbolTable &VST, const ValueEnumerator &VE, +    BitstreamWriter &Stream, uint64_t VSTOffsetPlaceholder = 0, +    uint64_t BitcodeStartBit = 0, +    DenseMap<const Function *, std::unique_ptr<FunctionInfo>> *FunctionIndex = +        nullptr) { +  if (VST.empty()) { +    // WriteValueSymbolTableForwardDecl should have returned early as +    // well. Ensure this handling remains in sync by asserting that +    // the placeholder offset is not set. +    assert(VSTOffsetPlaceholder == 0); +    return; +  } + +  if (VSTOffsetPlaceholder > 0) { +    // Get the offset of the VST we are writing, and backpatch it into +    // the VST forward declaration record. +    uint64_t VSTOffset = Stream.GetCurrentBitNo(); +    // The BitcodeStartBit was the stream offset of the actual bitcode +    // (e.g. excluding any initial darwin header). +    VSTOffset -= BitcodeStartBit; +    assert((VSTOffset & 31) == 0 && "VST block not 32-bit aligned"); +    Stream.BackpatchWord(VSTOffsetPlaceholder, VSTOffset / 32); +  } +    Stream.EnterSubblock(bitc::VALUE_SYMTAB_BLOCK_ID, 4); +  // For the module-level VST, add abbrev Ids for the VST_CODE_FNENTRY +  // records, which are not used in the per-function VSTs. +  unsigned FnEntry8BitAbbrev; +  unsigned FnEntry7BitAbbrev; +  unsigned FnEntry6BitAbbrev; +  if (VSTOffsetPlaceholder > 0) { +    // 8-bit fixed-width VST_FNENTRY function strings. +    BitCodeAbbrev *Abbv = new BitCodeAbbrev(); +    Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_FNENTRY)); +    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // value id +    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // funcoffset +    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); +    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8)); +    FnEntry8BitAbbrev = Stream.EmitAbbrev(Abbv); + +    // 7-bit fixed width VST_FNENTRY function strings. +    Abbv = new BitCodeAbbrev(); +    Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_FNENTRY)); +    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // value id +    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // funcoffset +    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); +    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7)); +    FnEntry7BitAbbrev = Stream.EmitAbbrev(Abbv); + +    // 6-bit char6 VST_FNENTRY function strings. +    Abbv = new BitCodeAbbrev(); +    Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_FNENTRY)); +    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // value id +    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // funcoffset +    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); +    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6)); +    FnEntry6BitAbbrev = Stream.EmitAbbrev(Abbv); +  } +    // FIXME: Set up the abbrev, we know how many values there are!    // FIXME: We know if the type names can use 7-bit ascii.    SmallVector<unsigned, 64> NameVals; -  for (ValueSymbolTable::const_iterator SI = VST.begin(), SE = VST.end(); -       SI != SE; ++SI) { - -    const ValueName &Name = *SI; - +  for (const ValueName &Name : VST) {      // Figure out the encoding to use for the name. -    bool is7Bit = true; -    bool isChar6 = true; -    for (const char *C = Name.getKeyData(), *E = C+Name.getKeyLength(); -         C != E; ++C) { -      if (isChar6) -        isChar6 = BitCodeAbbrevOp::isChar6(*C); -      if ((unsigned char)*C & 128) { -        is7Bit = false; -        break;  // don't bother scanning the rest. -      } -    } +    StringEncoding Bits = +        getStringEncoding(Name.getKeyData(), Name.getKeyLength());      unsigned AbbrevToUse = VST_ENTRY_8_ABBREV; +    NameVals.push_back(VE.getValueID(Name.getValue())); + +    Function *F = dyn_cast<Function>(Name.getValue()); +    if (!F) { +      // If value is an alias, need to get the aliased base object to +      // see if it is a function. +      auto *GA = dyn_cast<GlobalAlias>(Name.getValue()); +      if (GA && GA->getBaseObject()) +        F = dyn_cast<Function>(GA->getBaseObject()); +    }      // VST_ENTRY:   [valueid, namechar x N] +    // VST_FNENTRY: [valueid, funcoffset, namechar x N]      // VST_BBENTRY: [bbid, namechar x N]      unsigned Code; -    if (isa<BasicBlock>(SI->getValue())) { +    if (isa<BasicBlock>(Name.getValue())) {        Code = bitc::VST_CODE_BBENTRY; -      if (isChar6) +      if (Bits == SE_Char6)          AbbrevToUse = VST_BBENTRY_6_ABBREV; +    } else if (F && !F->isDeclaration()) { +      // Must be the module-level VST, where we pass in the Index and +      // have a VSTOffsetPlaceholder. The function-level VST should not +      // contain any Function symbols. +      assert(FunctionIndex); +      assert(VSTOffsetPlaceholder > 0); + +      // Save the word offset of the function (from the start of the +      // actual bitcode written to the stream). +      assert(FunctionIndex->count(F) == 1); +      uint64_t BitcodeIndex = +          (*FunctionIndex)[F]->bitcodeIndex() - BitcodeStartBit; +      assert((BitcodeIndex & 31) == 0 && "function block not 32-bit aligned"); +      NameVals.push_back(BitcodeIndex / 32); + +      Code = bitc::VST_CODE_FNENTRY; +      AbbrevToUse = FnEntry8BitAbbrev; +      if (Bits == SE_Char6) +        AbbrevToUse = FnEntry6BitAbbrev; +      else if (Bits == SE_Fixed7) +        AbbrevToUse = FnEntry7BitAbbrev;      } else {        Code = bitc::VST_CODE_ENTRY; -      if (isChar6) +      if (Bits == SE_Char6)          AbbrevToUse = VST_ENTRY_6_ABBREV; -      else if (is7Bit) +      else if (Bits == SE_Fixed7)          AbbrevToUse = VST_ENTRY_7_ABBREV;      } -    NameVals.push_back(VE.getValueID(SI->getValue())); -    for (const char *P = Name.getKeyData(), -         *E = Name.getKeyData()+Name.getKeyLength(); P != E; ++P) -      NameVals.push_back((unsigned char)*P); +    for (const auto P : Name.getKey()) +      NameVals.push_back((unsigned char)P);      // Emit the finished record.      Stream.EmitRecord(Code, NameVals, AbbrevToUse); @@ -2066,6 +2351,66 @@ static void WriteValueSymbolTable(const ValueSymbolTable &VST,    Stream.ExitBlock();  } +/// Emit function names and summary offsets for the combined index +/// used by ThinLTO. +static void WriteCombinedValueSymbolTable(const FunctionInfoIndex &Index, +                                          BitstreamWriter &Stream) { +  Stream.EnterSubblock(bitc::VALUE_SYMTAB_BLOCK_ID, 4); + +  // 8-bit fixed-width VST_COMBINED_FNENTRY function strings. +  BitCodeAbbrev *Abbv = new BitCodeAbbrev(); +  Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_COMBINED_FNENTRY)); +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // funcoffset +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8)); +  unsigned FnEntry8BitAbbrev = Stream.EmitAbbrev(Abbv); + +  // 7-bit fixed width VST_COMBINED_FNENTRY function strings. +  Abbv = new BitCodeAbbrev(); +  Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_COMBINED_FNENTRY)); +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // funcoffset +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7)); +  unsigned FnEntry7BitAbbrev = Stream.EmitAbbrev(Abbv); + +  // 6-bit char6 VST_COMBINED_FNENTRY function strings. +  Abbv = new BitCodeAbbrev(); +  Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_COMBINED_FNENTRY)); +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // funcoffset +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6)); +  unsigned FnEntry6BitAbbrev = Stream.EmitAbbrev(Abbv); + +  // FIXME: We know if the type names can use 7-bit ascii. +  SmallVector<unsigned, 64> NameVals; + +  for (const auto &FII : Index) { +    for (const auto &FI : FII.getValue()) { +      NameVals.push_back(FI->bitcodeIndex()); + +      StringRef FuncName = FII.first(); + +      // Figure out the encoding to use for the name. +      StringEncoding Bits = getStringEncoding(FuncName.data(), FuncName.size()); + +      // VST_COMBINED_FNENTRY: [funcsumoffset, namechar x N] +      unsigned AbbrevToUse = FnEntry8BitAbbrev; +      if (Bits == SE_Char6) +        AbbrevToUse = FnEntry6BitAbbrev; +      else if (Bits == SE_Fixed7) +        AbbrevToUse = FnEntry7BitAbbrev; + +      for (const auto P : FuncName) +        NameVals.push_back((unsigned char)P); + +      // Emit the finished record. +      Stream.EmitRecord(bitc::VST_CODE_COMBINED_FNENTRY, NameVals, AbbrevToUse); +      NameVals.clear(); +    } +  } +  Stream.ExitBlock(); +} +  static void WriteUseList(ValueEnumerator &VE, UseListOrder &&Order,                           BitstreamWriter &Stream) {    assert(Order.Shuffle.size() >= 2 && "Shuffle too small"); @@ -2100,9 +2445,34 @@ static void WriteUseListBlock(const Function *F, ValueEnumerator &VE,    Stream.ExitBlock();  } -/// WriteFunction - Emit a function body to the module stream. -static void WriteFunction(const Function &F, ValueEnumerator &VE, -                          BitstreamWriter &Stream) { +/// \brief Save information for the given function into the function index. +/// +/// At a minimum this saves the bitcode index of the function record that +/// was just written. However, if we are emitting function summary information, +/// for example for ThinLTO, then a \a FunctionSummary object is created +/// to hold the provided summary information. +static void SaveFunctionInfo( +    const Function &F, +    DenseMap<const Function *, std::unique_ptr<FunctionInfo>> &FunctionIndex, +    unsigned NumInsts, uint64_t BitcodeIndex, bool EmitFunctionSummary) { +  std::unique_ptr<FunctionSummary> FuncSummary; +  if (EmitFunctionSummary) { +    FuncSummary = llvm::make_unique<FunctionSummary>(NumInsts); +    FuncSummary->setLocalFunction(F.hasLocalLinkage()); +  } +  FunctionIndex[&F] = +      llvm::make_unique<FunctionInfo>(BitcodeIndex, std::move(FuncSummary)); +} + +/// Emit a function body to the module stream. +static void WriteFunction( +    const Function &F, ValueEnumerator &VE, BitstreamWriter &Stream, +    DenseMap<const Function *, std::unique_ptr<FunctionInfo>> &FunctionIndex, +    bool EmitFunctionSummary) { +  // Save the bitcode index of the start of this function block for recording +  // in the VST. +  uint64_t BitcodeIndex = Stream.GetCurrentBitNo(); +    Stream.EnterSubblock(bitc::FUNCTION_BLOCK_ID, 4);    VE.incorporateFunction(F); @@ -2128,6 +2498,7 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE,    bool NeedsMetadataAttachment = F.hasMetadata();    DILocation *LastDL = nullptr; +  unsigned NumInsts = 0;    // Finally, emit all the instructions, in order.    for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) @@ -2135,6 +2506,9 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE,           I != E; ++I) {        WriteInstruction(*I, InstID, VE, Stream, Vals); +      if (!isa<DbgInfoIntrinsic>(I)) +        ++NumInsts; +        if (!I->getType()->isVoidTy())          ++InstID; @@ -2171,6 +2545,9 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE,      WriteUseListBlock(&F, VE, Stream);    VE.purgeFunction();    Stream.ExitBlock(); + +  SaveFunctionInfo(F, FunctionIndex, NumInsts, BitcodeIndex, +                   EmitFunctionSummary);  }  // Emit blockinfo, which defines the standard abbreviations etc. @@ -2348,9 +2725,183 @@ static void WriteBlockInfo(const ValueEnumerator &VE, BitstreamWriter &Stream) {    Stream.ExitBlock();  } +/// Write the module path strings, currently only used when generating +/// a combined index file. +static void WriteModStrings(const FunctionInfoIndex &I, +                            BitstreamWriter &Stream) { +  Stream.EnterSubblock(bitc::MODULE_STRTAB_BLOCK_ID, 3); + +  // TODO: See which abbrev sizes we actually need to emit + +  // 8-bit fixed-width MST_ENTRY strings. +  BitCodeAbbrev *Abbv = new BitCodeAbbrev(); +  Abbv->Add(BitCodeAbbrevOp(bitc::MST_CODE_ENTRY)); +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8)); +  unsigned Abbrev8Bit = Stream.EmitAbbrev(Abbv); + +  // 7-bit fixed width MST_ENTRY strings. +  Abbv = new BitCodeAbbrev(); +  Abbv->Add(BitCodeAbbrevOp(bitc::MST_CODE_ENTRY)); +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7)); +  unsigned Abbrev7Bit = Stream.EmitAbbrev(Abbv); + +  // 6-bit char6 MST_ENTRY strings. +  Abbv = new BitCodeAbbrev(); +  Abbv->Add(BitCodeAbbrevOp(bitc::MST_CODE_ENTRY)); +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6)); +  unsigned Abbrev6Bit = Stream.EmitAbbrev(Abbv); + +  SmallVector<unsigned, 64> NameVals; +  for (const StringMapEntry<uint64_t> &MPSE : I.modPathStringEntries()) { +    StringEncoding Bits = +        getStringEncoding(MPSE.getKey().data(), MPSE.getKey().size()); +    unsigned AbbrevToUse = Abbrev8Bit; +    if (Bits == SE_Char6) +      AbbrevToUse = Abbrev6Bit; +    else if (Bits == SE_Fixed7) +      AbbrevToUse = Abbrev7Bit; + +    NameVals.push_back(MPSE.getValue()); + +    for (const auto P : MPSE.getKey()) +      NameVals.push_back((unsigned char)P); + +    // Emit the finished record. +    Stream.EmitRecord(bitc::MST_CODE_ENTRY, NameVals, AbbrevToUse); +    NameVals.clear(); +  } +  Stream.ExitBlock(); +} + +// Helper to emit a single function summary record. +static void WritePerModuleFunctionSummaryRecord( +    SmallVector<unsigned, 64> &NameVals, FunctionSummary *FS, unsigned ValueID, +    unsigned FSAbbrev, BitstreamWriter &Stream) { +  assert(FS); +  NameVals.push_back(ValueID); +  NameVals.push_back(FS->isLocalFunction()); +  NameVals.push_back(FS->instCount()); + +  // Emit the finished record. +  Stream.EmitRecord(bitc::FS_CODE_PERMODULE_ENTRY, NameVals, FSAbbrev); +  NameVals.clear(); +} + +/// Emit the per-module function summary section alongside the rest of +/// the module's bitcode. +static void WritePerModuleFunctionSummary( +    DenseMap<const Function *, std::unique_ptr<FunctionInfo>> &FunctionIndex, +    const Module *M, const ValueEnumerator &VE, BitstreamWriter &Stream) { +  Stream.EnterSubblock(bitc::FUNCTION_SUMMARY_BLOCK_ID, 3); + +  // Abbrev for FS_CODE_PERMODULE_ENTRY. +  BitCodeAbbrev *Abbv = new BitCodeAbbrev(); +  Abbv->Add(BitCodeAbbrevOp(bitc::FS_CODE_PERMODULE_ENTRY)); +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));   // valueid +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // islocal +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));   // instcount +  unsigned FSAbbrev = Stream.EmitAbbrev(Abbv); + +  SmallVector<unsigned, 64> NameVals; +  for (auto &I : FunctionIndex) { +    // Skip anonymous functions. We will emit a function summary for +    // any aliases below. +    if (!I.first->hasName()) +      continue; + +    WritePerModuleFunctionSummaryRecord( +        NameVals, I.second->functionSummary(), +        VE.getValueID(M->getValueSymbolTable().lookup(I.first->getName())), +        FSAbbrev, Stream); +  } + +  for (const GlobalAlias &A : M->aliases()) { +    if (!A.getBaseObject()) +      continue; +    const Function *F = dyn_cast<Function>(A.getBaseObject()); +    if (!F || F->isDeclaration()) +      continue; + +    assert(FunctionIndex.count(F) == 1); +    WritePerModuleFunctionSummaryRecord( +        NameVals, FunctionIndex[F]->functionSummary(), +        VE.getValueID(M->getValueSymbolTable().lookup(A.getName())), FSAbbrev, +        Stream); +  } + +  Stream.ExitBlock(); +} + +/// Emit the combined function summary section into the combined index +/// file. +static void WriteCombinedFunctionSummary(const FunctionInfoIndex &I, +                                         BitstreamWriter &Stream) { +  Stream.EnterSubblock(bitc::FUNCTION_SUMMARY_BLOCK_ID, 3); + +  // Abbrev for FS_CODE_COMBINED_ENTRY. +  BitCodeAbbrev *Abbv = new BitCodeAbbrev(); +  Abbv->Add(BitCodeAbbrevOp(bitc::FS_CODE_COMBINED_ENTRY)); +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // modid +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // instcount +  unsigned FSAbbrev = Stream.EmitAbbrev(Abbv); + +  SmallVector<unsigned, 64> NameVals; +  for (const auto &FII : I) { +    for (auto &FI : FII.getValue()) { +      FunctionSummary *FS = FI->functionSummary(); +      assert(FS); + +      NameVals.push_back(I.getModuleId(FS->modulePath())); +      NameVals.push_back(FS->instCount()); + +      // Record the starting offset of this summary entry for use +      // in the VST entry. Add the current code size since the +      // reader will invoke readRecord after the abbrev id read. +      FI->setBitcodeIndex(Stream.GetCurrentBitNo() + Stream.GetAbbrevIDWidth()); + +      // Emit the finished record. +      Stream.EmitRecord(bitc::FS_CODE_COMBINED_ENTRY, NameVals, FSAbbrev); +      NameVals.clear(); +    } +  } + +  Stream.ExitBlock(); +} + +// Create the "IDENTIFICATION_BLOCK_ID" containing a single string with the +// current llvm version, and a record for the epoch number. +static void WriteIdentificationBlock(const Module *M, BitstreamWriter &Stream) { +  Stream.EnterSubblock(bitc::IDENTIFICATION_BLOCK_ID, 5); + +  // Write the "user readable" string identifying the bitcode producer +  BitCodeAbbrev *Abbv = new BitCodeAbbrev(); +  Abbv->Add(BitCodeAbbrevOp(bitc::IDENTIFICATION_CODE_STRING)); +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6)); +  auto StringAbbrev = Stream.EmitAbbrev(Abbv); +  WriteStringRecord(bitc::IDENTIFICATION_CODE_STRING, +                    "LLVM" LLVM_VERSION_STRING, StringAbbrev, Stream); + +  // Write the epoch version +  Abbv = new BitCodeAbbrev(); +  Abbv->Add(BitCodeAbbrevOp(bitc::IDENTIFICATION_CODE_EPOCH)); +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); +  auto EpochAbbrev = Stream.EmitAbbrev(Abbv); +  SmallVector<unsigned, 1> Vals = {bitc::BITCODE_CURRENT_EPOCH}; +  Stream.EmitRecord(bitc::IDENTIFICATION_CODE_EPOCH, Vals, EpochAbbrev); +  Stream.ExitBlock(); +} +  /// WriteModule - Emit the specified module to the bitstream.  static void WriteModule(const Module *M, BitstreamWriter &Stream, -                        bool ShouldPreserveUseListOrder) { +                        bool ShouldPreserveUseListOrder, +                        uint64_t BitcodeStartBit, bool EmitFunctionSummary) {    Stream.EnterSubblock(bitc::MODULE_BLOCK_ID, 3);    SmallVector<unsigned, 1> Vals; @@ -2377,7 +2928,7 @@ static void WriteModule(const Module *M, BitstreamWriter &Stream,    // Emit top-level description of module, including target triple, inline asm,    // descriptors for global variables, and function prototype info. -  WriteModuleInfo(M, VE, Stream); +  uint64_t VSTOffsetPlaceholder = WriteModuleInfo(M, VE, Stream);    // Emit constants.    WriteModuleConstants(VE, Stream); @@ -2388,17 +2939,25 @@ static void WriteModule(const Module *M, BitstreamWriter &Stream,    // Emit metadata.    WriteModuleMetadataStore(M, Stream); -  // Emit names for globals/functions etc. -  WriteValueSymbolTable(M->getValueSymbolTable(), VE, Stream); -    // Emit module-level use-lists.    if (VE.shouldPreserveUseListOrder())      WriteUseListBlock(nullptr, VE, Stream); +  WriteOperandBundleTags(M, Stream); +    // Emit function bodies. +  DenseMap<const Function *, std::unique_ptr<FunctionInfo>> FunctionIndex;    for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F)      if (!F->isDeclaration()) -      WriteFunction(*F, VE, Stream); +      WriteFunction(*F, VE, Stream, FunctionIndex, EmitFunctionSummary); + +  // Need to write after the above call to WriteFunction which populates +  // the summary information in the index. +  if (EmitFunctionSummary) +    WritePerModuleFunctionSummary(FunctionIndex, M, VE, Stream); + +  WriteValueSymbolTable(M->getValueSymbolTable(), VE, Stream, +                        VSTOffsetPlaceholder, BitcodeStartBit, &FunctionIndex);    Stream.ExitBlock();  } @@ -2473,10 +3032,22 @@ static void EmitDarwinBCHeaderAndTrailer(SmallVectorImpl<char> &Buffer,      Buffer.push_back(0);  } +/// Helper to write the header common to all bitcode files. +static void WriteBitcodeHeader(BitstreamWriter &Stream) { +  // Emit the file header. +  Stream.Emit((unsigned)'B', 8); +  Stream.Emit((unsigned)'C', 8); +  Stream.Emit(0x0, 4); +  Stream.Emit(0xC, 4); +  Stream.Emit(0xE, 4); +  Stream.Emit(0xD, 4); +} +  /// WriteBitcodeToFile - Write the specified module to the specified output  /// stream.  void llvm::WriteBitcodeToFile(const Module *M, raw_ostream &Out, -                              bool ShouldPreserveUseListOrder) { +                              bool ShouldPreserveUseListOrder, +                              bool EmitFunctionSummary) {    SmallVector<char, 0> Buffer;    Buffer.reserve(256*1024); @@ -2489,17 +3060,20 @@ void llvm::WriteBitcodeToFile(const Module *M, raw_ostream &Out,    // Emit the module into the buffer.    {      BitstreamWriter Stream(Buffer); +    // Save the start bit of the actual bitcode, in case there is space +    // saved at the start for the darwin header above. The reader stream +    // will start at the bitcode, and we need the offset of the VST +    // to line up. +    uint64_t BitcodeStartBit = Stream.GetCurrentBitNo();      // Emit the file header. -    Stream.Emit((unsigned)'B', 8); -    Stream.Emit((unsigned)'C', 8); -    Stream.Emit(0x0, 4); -    Stream.Emit(0xC, 4); -    Stream.Emit(0xE, 4); -    Stream.Emit(0xD, 4); +    WriteBitcodeHeader(Stream); + +    WriteIdentificationBlock(M, Stream);      // Emit the module. -    WriteModule(M, Stream, ShouldPreserveUseListOrder); +    WriteModule(M, Stream, ShouldPreserveUseListOrder, BitcodeStartBit, +                EmitFunctionSummary);    }    if (TT.isOSDarwin()) @@ -2508,3 +3082,38 @@ void llvm::WriteBitcodeToFile(const Module *M, raw_ostream &Out,    // Write the generated bitstream to "Out".    Out.write((char*)&Buffer.front(), Buffer.size());  } + +// Write the specified function summary index to the given raw output stream, +// where it will be written in a new bitcode block. This is used when +// writing the combined index file for ThinLTO. +void llvm::WriteFunctionSummaryToFile(const FunctionInfoIndex &Index, +                                      raw_ostream &Out) { +  SmallVector<char, 0> Buffer; +  Buffer.reserve(256 * 1024); + +  BitstreamWriter Stream(Buffer); + +  // Emit the bitcode header. +  WriteBitcodeHeader(Stream); + +  Stream.EnterSubblock(bitc::MODULE_BLOCK_ID, 3); + +  SmallVector<unsigned, 1> Vals; +  unsigned CurVersion = 1; +  Vals.push_back(CurVersion); +  Stream.EmitRecord(bitc::MODULE_CODE_VERSION, Vals); + +  // Write the module paths in the combined index. +  WriteModStrings(Index, Stream); + +  // Write the function summary combined index records. +  WriteCombinedFunctionSummary(Index, Stream); + +  // Need a special VST writer for the combined index (we don't have a +  // real VST and real values when this is invoked). +  WriteCombinedValueSymbolTable(Index, Stream); + +  Stream.ExitBlock(); + +  Out.write((char *)&Buffer.front(), Buffer.size()); +}  | 
