diff options
Diffstat (limited to 'lib/Bitcode/Writer')
| -rw-r--r-- | lib/Bitcode/Writer/BitWriter.cpp | 6 | ||||
| -rw-r--r-- | lib/Bitcode/Writer/BitcodeWriter.cpp | 228 | ||||
| -rw-r--r-- | lib/Bitcode/Writer/BitcodeWriterPass.cpp | 8 | ||||
| -rw-r--r-- | lib/Bitcode/Writer/ValueEnumerator.cpp | 7 | 
4 files changed, 189 insertions, 60 deletions
| diff --git a/lib/Bitcode/Writer/BitWriter.cpp b/lib/Bitcode/Writer/BitWriter.cpp index e0388418a3d9..763cd12aa2d7 100644 --- a/lib/Bitcode/Writer/BitWriter.cpp +++ b/lib/Bitcode/Writer/BitWriter.cpp @@ -25,7 +25,7 @@ int LLVMWriteBitcodeToFile(LLVMModuleRef M, const char *Path) {    if (EC)      return -1; -  WriteBitcodeToFile(unwrap(M), OS); +  WriteBitcodeToFile(*unwrap(M), OS);    return 0;  } @@ -33,7 +33,7 @@ int LLVMWriteBitcodeToFD(LLVMModuleRef M, int FD, int ShouldClose,                           int Unbuffered) {    raw_fd_ostream OS(FD, ShouldClose, Unbuffered); -  WriteBitcodeToFile(unwrap(M), OS); +  WriteBitcodeToFile(*unwrap(M), OS);    return 0;  } @@ -45,6 +45,6 @@ LLVMMemoryBufferRef LLVMWriteBitcodeToMemoryBuffer(LLVMModuleRef M) {    std::string Data;    raw_string_ostream OS(Data); -  WriteBitcodeToFile(unwrap(M), OS); +  WriteBitcodeToFile(*unwrap(M), OS);    return wrap(MemoryBuffer::getMemBufferCopy(OS.str()).release());  } diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index a7201ed97350..be75df0820d9 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -28,6 +28,7 @@  #include "llvm/Bitcode/BitCodes.h"  #include "llvm/Bitcode/BitstreamWriter.h"  #include "llvm/Bitcode/LLVMBitCodes.h" +#include "llvm/Config/llvm-config.h"  #include "llvm/IR/Attributes.h"  #include "llvm/IR/BasicBlock.h"  #include "llvm/IR/CallSite.h" @@ -86,6 +87,12 @@ static cl::opt<unsigned>                     cl::desc("Number of metadatas above which we emit an index "                              "to enable lazy-loading")); +cl::opt<bool> WriteRelBFToSummary( +    "write-relbf-to-summary", cl::Hidden, cl::init(false), +    cl::desc("Write relative block frequency to function summary ")); + +extern FunctionSummary::ForceSummaryHotnessType ForceSummaryEdgesCold; +  namespace {  /// These are manifest constants used by the bitcode writer. They do not need to @@ -167,12 +174,12 @@ protected:  public:    /// Constructs a ModuleBitcodeWriterBase object for the given Module,    /// writing to the provided \p Buffer. -  ModuleBitcodeWriterBase(const Module *M, StringTableBuilder &StrtabBuilder, +  ModuleBitcodeWriterBase(const Module &M, StringTableBuilder &StrtabBuilder,                            BitstreamWriter &Stream,                            bool ShouldPreserveUseListOrder,                            const ModuleSummaryIndex *Index) -      : BitcodeWriterBase(Stream, StrtabBuilder), M(*M), -        VE(*M, ShouldPreserveUseListOrder), Index(Index) { +      : BitcodeWriterBase(Stream, StrtabBuilder), M(M), +        VE(M, ShouldPreserveUseListOrder), Index(Index) {      // Assign ValueIds to any callee values in the index that came from      // indirect call profiles and were recorded as a GUID not a Value*      // (which would have been assigned an ID by the ValueEnumerator). @@ -190,7 +197,7 @@ public:            // otherwise we would have a Value for it). If so, synthesize            // a value id.            for (auto &CallEdge : FS->calls()) -            if (!CallEdge.first.getValue()) +            if (!CallEdge.first.haveGVs() || !CallEdge.first.getValue())                assignValueId(CallEdge.first.getGUID());    } @@ -223,7 +230,7 @@ private:    // Helper to get the valueId for the type of value recorded in VI.    unsigned getValueId(ValueInfo VI) { -    if (!VI.getValue()) +    if (!VI.haveGVs() || !VI.getValue())        return getValueId(VI.getGUID());      return VE.getValueID(VI.getValue());    } @@ -251,7 +258,7 @@ class ModuleBitcodeWriter : public ModuleBitcodeWriterBase {  public:    /// Constructs a ModuleBitcodeWriter object for the given Module,    /// writing to the provided \p Buffer. -  ModuleBitcodeWriter(const Module *M, SmallVectorImpl<char> &Buffer, +  ModuleBitcodeWriter(const Module &M, SmallVectorImpl<char> &Buffer,                        StringTableBuilder &StrtabBuilder,                        BitstreamWriter &Stream, bool ShouldPreserveUseListOrder,                        const ModuleSummaryIndex *Index, bool GenerateHash, @@ -328,6 +335,8 @@ private:                               unsigned Abbrev);    void writeDILocalVariable(const DILocalVariable *N,                              SmallVectorImpl<uint64_t> &Record, unsigned Abbrev); +  void writeDILabel(const DILabel *N, +                    SmallVectorImpl<uint64_t> &Record, unsigned Abbrev);    void writeDIExpression(const DIExpression *N,                           SmallVectorImpl<uint64_t> &Record, unsigned Abbrev);    void writeDIGlobalVariableExpression(const DIGlobalVariableExpression *N, @@ -635,8 +644,12 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {      return bitc::ATTR_KIND_NO_RED_ZONE;    case Attribute::NoReturn:      return bitc::ATTR_KIND_NO_RETURN; +  case Attribute::NoCfCheck: +    return bitc::ATTR_KIND_NOCF_CHECK;    case Attribute::NoUnwind:      return bitc::ATTR_KIND_NO_UNWIND; +  case Attribute::OptForFuzzing: +    return bitc::ATTR_KIND_OPT_FOR_FUZZING;    case Attribute::OptimizeForSize:      return bitc::ATTR_KIND_OPTIMIZE_FOR_SIZE;    case Attribute::OptimizeNone: @@ -663,6 +676,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {      return bitc::ATTR_KIND_STACK_PROTECT_STRONG;    case Attribute::SafeStack:      return bitc::ATTR_KIND_SAFESTACK; +  case Attribute::ShadowCallStack: +    return bitc::ATTR_KIND_SHADOWCALLSTACK;    case Attribute::StrictFP:      return bitc::ATTR_KIND_STRICT_FP;    case Attribute::StructRet: @@ -1302,7 +1317,7 @@ void ModuleBitcodeWriter::writeModuleInfo() {    // Emit the ifunc information.    for (const GlobalIFunc &I : M.ifuncs()) {      // IFUNC: [strtab offset, strtab size, ifunc type, address space, resolver -    //         val#, linkage, visibility] +    //         val#, linkage, visibility, DSO_Local]      Vals.push_back(addToStrtab(I.getName()));      Vals.push_back(I.getName().size());      Vals.push_back(VE.getTypeID(I.getValueType())); @@ -1310,6 +1325,7 @@ void ModuleBitcodeWriter::writeModuleInfo() {      Vals.push_back(VE.getValueID(I.getResolver()));      Vals.push_back(getEncodedLinkage(I));      Vals.push_back(getEncodedVisibility(I)); +    Vals.push_back(I.isDSOLocal());      Stream.EmitRecord(bitc::MODULE_CODE_IFUNC, Vals);      Vals.clear();    } @@ -1330,19 +1346,19 @@ static uint64_t getOptimizationFlags(const Value *V) {        Flags |= 1 << bitc::PEO_EXACT;    } else if (const auto *FPMO = dyn_cast<FPMathOperator>(V)) {      if (FPMO->hasAllowReassoc()) -      Flags |= FastMathFlags::AllowReassoc; +      Flags |= bitc::AllowReassoc;      if (FPMO->hasNoNaNs()) -      Flags |= FastMathFlags::NoNaNs; +      Flags |= bitc::NoNaNs;      if (FPMO->hasNoInfs()) -      Flags |= FastMathFlags::NoInfs; +      Flags |= bitc::NoInfs;      if (FPMO->hasNoSignedZeros()) -      Flags |= FastMathFlags::NoSignedZeros; +      Flags |= bitc::NoSignedZeros;      if (FPMO->hasAllowReciprocal()) -      Flags |= FastMathFlags::AllowReciprocal; +      Flags |= bitc::AllowReciprocal;      if (FPMO->hasAllowContract()) -      Flags |= FastMathFlags::AllowContract; +      Flags |= bitc::AllowContract;      if (FPMO->hasApproxFunc()) -      Flags |= FastMathFlags::ApproxFunc; +      Flags |= bitc::ApproxFunc;    }    return Flags; @@ -1441,8 +1457,9 @@ static uint64_t rotateSign(int64_t I) {  void ModuleBitcodeWriter::writeDISubrange(const DISubrange *N,                                            SmallVectorImpl<uint64_t> &Record,                                            unsigned Abbrev) { -  Record.push_back(N->isDistinct()); -  Record.push_back(N->getCount()); +  const uint64_t Version = 1 << 1; +  Record.push_back((uint64_t)N->isDistinct() | Version); +  Record.push_back(VE.getMetadataOrNullID(N->getRawCountNode()));    Record.push_back(rotateSign(N->getLowerBound()));    Stream.EmitRecord(bitc::METADATA_SUBRANGE, Record, Abbrev); @@ -1452,7 +1469,7 @@ void ModuleBitcodeWriter::writeDISubrange(const DISubrange *N,  void ModuleBitcodeWriter::writeDIEnumerator(const DIEnumerator *N,                                              SmallVectorImpl<uint64_t> &Record,                                              unsigned Abbrev) { -  Record.push_back(N->isDistinct()); +  Record.push_back((N->isUnsigned() << 1) | N->isDistinct());    Record.push_back(rotateSign(N->getValue()));    Record.push_back(VE.getMetadataOrNullID(N->getRawName())); @@ -1521,6 +1538,7 @@ void ModuleBitcodeWriter::writeDICompositeType(    Record.push_back(VE.getMetadataOrNullID(N->getVTableHolder()));    Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams().get()));    Record.push_back(VE.getMetadataOrNullID(N->getRawIdentifier())); +  Record.push_back(VE.getMetadataOrNullID(N->getDiscriminator()));    Stream.EmitRecord(bitc::METADATA_COMPOSITE_TYPE, Record, Abbrev);    Record.clear(); @@ -1545,8 +1563,18 @@ void ModuleBitcodeWriter::writeDIFile(const DIFile *N,    Record.push_back(N->isDistinct());    Record.push_back(VE.getMetadataOrNullID(N->getRawFilename()));    Record.push_back(VE.getMetadataOrNullID(N->getRawDirectory())); -  Record.push_back(N->getChecksumKind()); -  Record.push_back(VE.getMetadataOrNullID(N->getRawChecksum())); +  if (N->getRawChecksum()) { +    Record.push_back(N->getRawChecksum()->Kind); +    Record.push_back(VE.getMetadataOrNullID(N->getRawChecksum()->Value)); +  } else { +    // Maintain backwards compatibility with the old internal representation of +    // CSK_None in ChecksumKind by writing nulls here when Checksum is None. +    Record.push_back(0); +    Record.push_back(VE.getMetadataOrNullID(nullptr)); +  } +  auto Source = N->getRawSource(); +  if (Source) +    Record.push_back(VE.getMetadataOrNullID(*Source));    Stream.EmitRecord(bitc::METADATA_FILE, Record, Abbrev);    Record.clear(); @@ -1602,7 +1630,7 @@ void ModuleBitcodeWriter::writeDISubprogram(const DISubprogram *N,    Record.push_back(VE.getMetadataOrNullID(N->getRawUnit()));    Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams().get()));    Record.push_back(VE.getMetadataOrNullID(N->getDeclaration())); -  Record.push_back(VE.getMetadataOrNullID(N->getVariables().get())); +  Record.push_back(VE.getMetadataOrNullID(N->getRetainedNodes().get()));    Record.push_back(N->getThisAdjustment());    Record.push_back(VE.getMetadataOrNullID(N->getThrownTypes().get())); @@ -1759,6 +1787,19 @@ void ModuleBitcodeWriter::writeDILocalVariable(    Record.clear();  } +void ModuleBitcodeWriter::writeDILabel( +    const DILabel *N, SmallVectorImpl<uint64_t> &Record, +    unsigned Abbrev) { +  Record.push_back((uint64_t)N->isDistinct()); +  Record.push_back(VE.getMetadataOrNullID(N->getScope())); +  Record.push_back(VE.getMetadataOrNullID(N->getRawName())); +  Record.push_back(VE.getMetadataOrNullID(N->getFile())); +  Record.push_back(N->getLine()); + +  Stream.EmitRecord(bitc::METADATA_LABEL, Record, Abbrev); +  Record.clear(); +} +  void ModuleBitcodeWriter::writeDIExpression(const DIExpression *N,                                              SmallVectorImpl<uint64_t> &Record,                                              unsigned Abbrev) { @@ -3183,7 +3224,7 @@ void ModuleBitcodeWriter::writeBlockInfo() {      Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LHS      Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // RHS      Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // opc -    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7)); // flags +    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8)); // flags      if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, Abbv) !=          FUNCTION_INST_BINOP_FLAGS_ABBREV)        llvm_unreachable("Unexpected abbrev ordering!"); @@ -3312,10 +3353,14 @@ void IndexBitcodeWriter::writeModStrings() {  /// Write the function type metadata related records that need to appear before  /// a function summary entry (whether per-module or combined). -static void writeFunctionTypeMetadataRecords(BitstreamWriter &Stream, -                                             FunctionSummary *FS) { -  if (!FS->type_tests().empty()) +static void writeFunctionTypeMetadataRecords( +    BitstreamWriter &Stream, FunctionSummary *FS, +    std::set<GlobalValue::GUID> &ReferencedTypeIds) { +  if (!FS->type_tests().empty()) {      Stream.EmitRecord(bitc::FS_TYPE_TESTS, FS->type_tests()); +    for (auto &TT : FS->type_tests()) +      ReferencedTypeIds.insert(TT); +  }    SmallVector<uint64_t, 64> Record; @@ -3327,6 +3372,7 @@ static void writeFunctionTypeMetadataRecords(BitstreamWriter &Stream,      for (auto &VF : VFs) {        Record.push_back(VF.GUID);        Record.push_back(VF.Offset); +      ReferencedTypeIds.insert(VF.GUID);      }      Stream.EmitRecord(Ty, Record);    }; @@ -3341,6 +3387,7 @@ static void writeFunctionTypeMetadataRecords(BitstreamWriter &Stream,      for (auto &VC : VCs) {        Record.clear();        Record.push_back(VC.VFunc.GUID); +      ReferencedTypeIds.insert(VC.VFunc.GUID);        Record.push_back(VC.VFunc.Offset);        Record.insert(Record.end(), VC.Args.begin(), VC.Args.end());        Stream.EmitRecord(Ty, Record); @@ -3353,6 +3400,51 @@ static void writeFunctionTypeMetadataRecords(BitstreamWriter &Stream,                       FS->type_checked_load_const_vcalls());  } +static void writeWholeProgramDevirtResolutionByArg( +    SmallVector<uint64_t, 64> &NameVals, const std::vector<uint64_t> &args, +    const WholeProgramDevirtResolution::ByArg &ByArg) { +  NameVals.push_back(args.size()); +  NameVals.insert(NameVals.end(), args.begin(), args.end()); + +  NameVals.push_back(ByArg.TheKind); +  NameVals.push_back(ByArg.Info); +  NameVals.push_back(ByArg.Byte); +  NameVals.push_back(ByArg.Bit); +} + +static void writeWholeProgramDevirtResolution( +    SmallVector<uint64_t, 64> &NameVals, StringTableBuilder &StrtabBuilder, +    uint64_t Id, const WholeProgramDevirtResolution &Wpd) { +  NameVals.push_back(Id); + +  NameVals.push_back(Wpd.TheKind); +  NameVals.push_back(StrtabBuilder.add(Wpd.SingleImplName)); +  NameVals.push_back(Wpd.SingleImplName.size()); + +  NameVals.push_back(Wpd.ResByArg.size()); +  for (auto &A : Wpd.ResByArg) +    writeWholeProgramDevirtResolutionByArg(NameVals, A.first, A.second); +} + +static void writeTypeIdSummaryRecord(SmallVector<uint64_t, 64> &NameVals, +                                     StringTableBuilder &StrtabBuilder, +                                     const std::string &Id, +                                     const TypeIdSummary &Summary) { +  NameVals.push_back(StrtabBuilder.add(Id)); +  NameVals.push_back(Id.size()); + +  NameVals.push_back(Summary.TTRes.TheKind); +  NameVals.push_back(Summary.TTRes.SizeM1BitWidth); +  NameVals.push_back(Summary.TTRes.AlignLog2); +  NameVals.push_back(Summary.TTRes.SizeM1); +  NameVals.push_back(Summary.TTRes.BitMask); +  NameVals.push_back(Summary.TTRes.InlineBits); + +  for (auto &W : Summary.WPDRes) +    writeWholeProgramDevirtResolution(NameVals, StrtabBuilder, W.first, +                                      W.second); +} +  // Helper to emit a single function summary record.  void ModuleBitcodeWriterBase::writePerModuleFunctionSummaryRecord(      SmallVector<uint64_t, 64> &NameVals, GlobalValueSummary *Summary, @@ -3361,7 +3453,8 @@ void ModuleBitcodeWriterBase::writePerModuleFunctionSummaryRecord(    NameVals.push_back(ValueID);    FunctionSummary *FS = cast<FunctionSummary>(Summary); -  writeFunctionTypeMetadataRecords(Stream, FS); +  std::set<GlobalValue::GUID> ReferencedTypeIds; +  writeFunctionTypeMetadataRecords(Stream, FS, ReferencedTypeIds);    NameVals.push_back(getEncodedGVSummaryFlags(FS->flags()));    NameVals.push_back(FS->instCount()); @@ -3371,16 +3464,21 @@ void ModuleBitcodeWriterBase::writePerModuleFunctionSummaryRecord(    for (auto &RI : FS->refs())      NameVals.push_back(VE.getValueID(RI.getValue())); -  bool HasProfileData = F.hasProfileData(); +  bool HasProfileData = +      F.hasProfileData() || ForceSummaryEdgesCold != FunctionSummary::FSHT_None;    for (auto &ECI : FS->calls()) {      NameVals.push_back(getValueId(ECI.first));      if (HasProfileData)        NameVals.push_back(static_cast<uint8_t>(ECI.second.Hotness)); +    else if (WriteRelBFToSummary) +      NameVals.push_back(ECI.second.RelBlockFreq);    }    unsigned FSAbbrev = (HasProfileData ? FSCallsProfileAbbrev : FSCallsAbbrev);    unsigned Code = -      (HasProfileData ? bitc::FS_PERMODULE_PROFILE : bitc::FS_PERMODULE); +      (HasProfileData ? bitc::FS_PERMODULE_PROFILE +                      : (WriteRelBFToSummary ? bitc::FS_PERMODULE_RELBF +                                             : bitc::FS_PERMODULE));    // Emit the finished record.    Stream.EmitRecord(Code, NameVals, FSAbbrev); @@ -3392,7 +3490,7 @@ void ModuleBitcodeWriterBase::writePerModuleFunctionSummaryRecord(  void ModuleBitcodeWriterBase::writeModuleLevelReferences(      const GlobalVariable &V, SmallVector<uint64_t, 64> &NameVals,      unsigned FSModRefsAbbrev) { -  auto VI = Index->getValueInfo(GlobalValue::getGUID(V.getName())); +  auto VI = Index->getValueInfo(V.getGUID());    if (!VI || VI.getSummaryList().empty()) {      // Only declarations should not have a summary (a declaration might however      // have a summary if the def was in module level asm). @@ -3409,7 +3507,7 @@ void ModuleBitcodeWriterBase::writeModuleLevelReferences(      NameVals.push_back(VE.getValueID(RI.getValue()));    // Sort the refs for determinism output, the vector returned by FS->refs() has    // been initialized from a DenseSet. -  std::sort(NameVals.begin() + SizeBeforeRefs, NameVals.end()); +  llvm::sort(NameVals.begin() + SizeBeforeRefs, NameVals.end());    Stream.EmitRecord(bitc::FS_PERMODULE_GLOBALVAR_INIT_REFS, NameVals,                      FSModRefsAbbrev); @@ -3446,31 +3544,34 @@ void ModuleBitcodeWriterBase::writePerModuleGlobalValueSummary() {                        ArrayRef<uint64_t>{GVI.second, GVI.first});    } -  // Abbrev for FS_PERMODULE. +  // Abbrev for FS_PERMODULE_PROFILE.    auto Abbv = std::make_shared<BitCodeAbbrev>(); -  Abbv->Add(BitCodeAbbrevOp(bitc::FS_PERMODULE)); +  Abbv->Add(BitCodeAbbrevOp(bitc::FS_PERMODULE_PROFILE));    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));   // valueid    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // flags    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));   // instcount    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4));   // fflags    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4));   // numrefs -  // numrefs x valueid, n x (valueid) +  // numrefs x valueid, n x (valueid, hotness)    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); -  unsigned FSCallsAbbrev = Stream.EmitAbbrev(std::move(Abbv)); +  unsigned FSCallsProfileAbbrev = Stream.EmitAbbrev(std::move(Abbv)); -  // Abbrev for FS_PERMODULE_PROFILE. +  // Abbrev for FS_PERMODULE or FS_PERMODULE_RELBF.    Abbv = std::make_shared<BitCodeAbbrev>(); -  Abbv->Add(BitCodeAbbrevOp(bitc::FS_PERMODULE_PROFILE)); +  if (WriteRelBFToSummary) +    Abbv->Add(BitCodeAbbrevOp(bitc::FS_PERMODULE_RELBF)); +  else +    Abbv->Add(BitCodeAbbrevOp(bitc::FS_PERMODULE));    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));   // valueid    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // flags    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));   // instcount    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4));   // fflags    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4));   // numrefs -  // numrefs x valueid, n x (valueid, hotness) +  // numrefs x valueid, n x (valueid [, rel_block_freq])    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); -  unsigned FSCallsProfileAbbrev = Stream.EmitAbbrev(std::move(Abbv)); +  unsigned FSCallsAbbrev = Stream.EmitAbbrev(std::move(Abbv));    // Abbrev for FS_PERMODULE_GLOBALVAR_INIT_REFS.    Abbv = std::make_shared<BitCodeAbbrev>(); @@ -3498,7 +3599,7 @@ void ModuleBitcodeWriterBase::writePerModuleGlobalValueSummary() {      if (!F.hasName())        report_fatal_error("Unexpected anonymous function when writing summary"); -    ValueInfo VI = Index->getValueInfo(GlobalValue::getGUID(F.getName())); +    ValueInfo VI = Index->getValueInfo(F.getGUID());      if (!VI || VI.getSummaryList().empty()) {        // Only declarations should not have a summary (a declaration might        // however have a summary if the def was in module level asm). @@ -3539,6 +3640,14 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {    Stream.EnterSubblock(bitc::GLOBALVAL_SUMMARY_BLOCK_ID, 3);    Stream.EmitRecord(bitc::FS_VERSION, ArrayRef<uint64_t>{INDEX_VERSION}); +  // Write the index flags. +  uint64_t Flags = 0; +  if (Index.withGlobalValueDeadStripping()) +    Flags |= 0x1; +  if (Index.skipModuleByDistributedBackend()) +    Flags |= 0x2; +  Stream.EmitRecord(bitc::FS_FLAGS, ArrayRef<uint64_t>{Flags}); +    for (const auto &GVI : valueIds()) {      Stream.EmitRecord(bitc::FS_VALUE_GUID,                        ArrayRef<uint64_t>{GVI.second, GVI.first}); @@ -3600,6 +3709,10 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {    SmallVector<uint64_t, 64> NameVals; +  // Set that will be populated during call to writeFunctionTypeMetadataRecords +  // with the type ids referenced by this index file. +  std::set<GlobalValue::GUID> ReferencedTypeIds; +    // For local linkage, we also emit the original name separately    // immediately after the record.    auto MaybeEmitOriginalName = [&](GlobalValueSummary &S) { @@ -3651,7 +3764,7 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {      }      auto *FS = cast<FunctionSummary>(S); -    writeFunctionTypeMetadataRecords(Stream, FS); +    writeFunctionTypeMetadataRecords(Stream, FS, ReferencedTypeIds);      NameVals.push_back(*ValueId);      NameVals.push_back(Index.getModuleId(FS->modulePath())); @@ -3673,7 +3786,8 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {      bool HasProfileData = false;      for (auto &EI : FS->calls()) { -      HasProfileData |= EI.second.Hotness != CalleeInfo::HotnessType::Unknown; +      HasProfileData |= +          EI.second.getHotness() != CalleeInfo::HotnessType::Unknown;        if (HasProfileData)          break;      } @@ -3757,6 +3871,17 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {      NameVals.clear();    } +  if (!Index.typeIds().empty()) { +    for (auto &S : Index.typeIds()) { +      // Skip if not referenced in any GV summary within this index file. +      if (!ReferencedTypeIds.count(GlobalValue::getGUID(S.first))) +        continue; +      writeTypeIdSummaryRecord(NameVals, StrtabBuilder, S.first, S.second); +      Stream.EmitRecord(bitc::FS_TYPE_ID, NameVals); +      NameVals.clear(); +    } +  } +    Stream.ExitBlock();  } @@ -4012,7 +4137,7 @@ void BitcodeWriter::copyStrtab(StringRef Strtab) {    WroteStrtab = true;  } -void BitcodeWriter::writeModule(const Module *M, +void BitcodeWriter::writeModule(const Module &M,                                  bool ShouldPreserveUseListOrder,                                  const ModuleSummaryIndex *Index,                                  bool GenerateHash, ModuleHash *ModHash) { @@ -4022,8 +4147,8 @@ void BitcodeWriter::writeModule(const Module *M,    // Modules in case it needs to materialize metadata. But the bitcode writer    // requires that the module is materialized, so we can cast to non-const here,    // after checking that it is in fact materialized. -  assert(M->isMaterialized()); -  Mods.push_back(const_cast<Module *>(M)); +  assert(M.isMaterialized()); +  Mods.push_back(const_cast<Module *>(&M));    ModuleBitcodeWriter ModuleWriter(M, Buffer, StrtabBuilder, *Stream,                                     ShouldPreserveUseListOrder, Index, @@ -4039,9 +4164,8 @@ void BitcodeWriter::writeIndex(    IndexWriter.write();  } -/// WriteBitcodeToFile - Write the specified module to the specified output -/// stream. -void llvm::WriteBitcodeToFile(const Module *M, raw_ostream &Out, +/// Write the specified module to the specified output stream. +void llvm::WriteBitcodeToFile(const Module &M, raw_ostream &Out,                                bool ShouldPreserveUseListOrder,                                const ModuleSummaryIndex *Index,                                bool GenerateHash, ModuleHash *ModHash) { @@ -4050,7 +4174,7 @@ void llvm::WriteBitcodeToFile(const Module *M, raw_ostream &Out,    // If this is darwin or another generic macho target, reserve space for the    // header. -  Triple TT(M->getTargetTriple()); +  Triple TT(M.getTargetTriple());    if (TT.isOSDarwin() || TT.isOSBinFormatMachO())      Buffer.insert(Buffer.begin(), BWH_HeaderSize, 0); @@ -4107,7 +4231,7 @@ class ThinLinkBitcodeWriter : public ModuleBitcodeWriterBase {    const ModuleHash *ModHash;  public: -  ThinLinkBitcodeWriter(const Module *M, StringTableBuilder &StrtabBuilder, +  ThinLinkBitcodeWriter(const Module &M, StringTableBuilder &StrtabBuilder,                          BitstreamWriter &Stream,                          const ModuleSummaryIndex &Index,                          const ModuleHash &ModHash) @@ -4225,7 +4349,7 @@ void ThinLinkBitcodeWriter::write() {    Stream.ExitBlock();  } -void BitcodeWriter::writeThinLinkBitcode(const Module *M, +void BitcodeWriter::writeThinLinkBitcode(const Module &M,                                           const ModuleSummaryIndex &Index,                                           const ModuleHash &ModHash) {    assert(!WroteStrtab); @@ -4234,8 +4358,8 @@ void BitcodeWriter::writeThinLinkBitcode(const Module *M,    // Modules in case it needs to materialize metadata. But the bitcode writer    // requires that the module is materialized, so we can cast to non-const here,    // after checking that it is in fact materialized. -  assert(M->isMaterialized()); -  Mods.push_back(const_cast<Module *>(M)); +  assert(M.isMaterialized()); +  Mods.push_back(const_cast<Module *>(&M));    ThinLinkBitcodeWriter ThinLinkWriter(M, StrtabBuilder, *Stream, Index,                                         ModHash); @@ -4245,7 +4369,7 @@ void BitcodeWriter::writeThinLinkBitcode(const Module *M,  // Write the specified thin link bitcode file to the given raw output stream,  // where it will be written in a new bitcode block. This is used when  // writing the per-module index file for ThinLTO. -void llvm::WriteThinLinkBitcodeToFile(const Module *M, raw_ostream &Out, +void llvm::WriteThinLinkBitcodeToFile(const Module &M, raw_ostream &Out,                                        const ModuleSummaryIndex &Index,                                        const ModuleHash &ModHash) {    SmallVector<char, 0> Buffer; diff --git a/lib/Bitcode/Writer/BitcodeWriterPass.cpp b/lib/Bitcode/Writer/BitcodeWriterPass.cpp index 80cab762a68c..41212e575f8e 100644 --- a/lib/Bitcode/Writer/BitcodeWriterPass.cpp +++ b/lib/Bitcode/Writer/BitcodeWriterPass.cpp @@ -23,7 +23,7 @@ PreservedAnalyses BitcodeWriterPass::run(Module &M, ModuleAnalysisManager &AM) {    const ModuleSummaryIndex *Index =        EmitSummaryIndex ? &(AM.getResult<ModuleSummaryIndexAnalysis>(M))                         : nullptr; -  WriteBitcodeToFile(&M, OS, ShouldPreserveUseListOrder, Index, EmitModuleHash); +  WriteBitcodeToFile(M, OS, ShouldPreserveUseListOrder, Index, EmitModuleHash);    return PreservedAnalyses::all();  } @@ -55,7 +55,7 @@ namespace {            EmitSummaryIndex                ? &(getAnalysis<ModuleSummaryIndexWrapperPass>().getIndex())                : nullptr; -      WriteBitcodeToFile(&M, OS, ShouldPreserveUseListOrder, Index, +      WriteBitcodeToFile(M, OS, ShouldPreserveUseListOrder, Index,                           EmitModuleHash);        return false;      } @@ -80,3 +80,7 @@ ModulePass *llvm::createBitcodeWriterPass(raw_ostream &Str,    return new WriteBitcodePass(Str, ShouldPreserveUseListOrder,                                EmitSummaryIndex, EmitModuleHash);  } + +bool llvm::isBitcodeWriterPass(Pass *P) { +  return P->getPassID() == (llvm::AnalysisID)&WriteBitcodePass::ID; +} diff --git a/lib/Bitcode/Writer/ValueEnumerator.cpp b/lib/Bitcode/Writer/ValueEnumerator.cpp index d99befcdaeae..d473741e8ceb 100644 --- a/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -14,6 +14,7 @@  #include "ValueEnumerator.h"  #include "llvm/ADT/DenseMap.h"  #include "llvm/ADT/SmallVector.h" +#include "llvm/Config/llvm-config.h"  #include "llvm/IR/Argument.h"  #include "llvm/IR/Attributes.h"  #include "llvm/IR/BasicBlock.h" @@ -183,7 +184,7 @@ static void predictValueUseListOrderImpl(const Value *V, const Function *F,      return;    bool IsGlobalValue = OM.isGlobalValue(ID); -  std::sort(List.begin(), List.end(), [&](const Entry &L, const Entry &R) { +  llvm::sort(List.begin(), List.end(), [&](const Entry &L, const Entry &R) {      const Use *LU = L.first;      const Use *RU = R.first;      if (LU == RU) @@ -488,7 +489,7 @@ void ValueEnumerator::print(raw_ostream &OS, const ValueMapType &Map,      V->print(errs());      errs() << '\n'; -    OS << " Uses(" << std::distance(V->use_begin(),V->use_end()) << "):"; +    OS << " Uses(" << V->getNumUses() << "):";      for (const Use &U : V->uses()) {        if (&U != &*V->use_begin())          OS << ","; @@ -744,7 +745,7 @@ void ValueEnumerator::organizeMetadata() {    // and then sort by the original/current ID.  Since the IDs are guaranteed to    // be unique, the result of std::sort will be deterministic.  There's no need    // for std::stable_sort. -  std::sort(Order.begin(), Order.end(), [this](MDIndex LHS, MDIndex RHS) { +  llvm::sort(Order.begin(), Order.end(), [this](MDIndex LHS, MDIndex RHS) {      return std::make_tuple(LHS.F, getMetadataTypeOrder(LHS.get(MDs)), LHS.ID) <             std::make_tuple(RHS.F, getMetadataTypeOrder(RHS.get(MDs)), RHS.ID);    }); | 
