diff options
Diffstat (limited to 'llvm/lib/Bitcode')
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 79 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 11 |
2 files changed, 83 insertions, 7 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 2f3d2f3f032..fe051e7a912 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -5294,18 +5294,30 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { break; case bitc::FS_FLAGS: { // [flags] uint64_t Flags = Record[0]; - // Scan flags (set only on the combined index). - assert(Flags <= 0x3 && "Unexpected bits in flag"); + // Scan flags. + assert(Flags <= 0x1f && "Unexpected bits in flag"); // 1 bit: WithGlobalValueDeadStripping flag. + // Set on combined index only. if (Flags & 0x1) TheIndex.setWithGlobalValueDeadStripping(); // 1 bit: SkipModuleByDistributedBackend flag. + // Set on combined index only. if (Flags & 0x2) TheIndex.setSkipModuleByDistributedBackend(); // 1 bit: HasSyntheticEntryCounts flag. + // Set on combined index only. if (Flags & 0x4) TheIndex.setHasSyntheticEntryCounts(); + // 1 bit: DisableSplitLTOUnit flag. + // Set on per module indexes. It is up to the client to validate + // the consistency of this flag across modules being linked. + if (Flags & 0x8) + TheIndex.setEnableSplitLTOUnit(); + // 1 bit: PartiallySplitLTOUnits flag. + // Set on combined index only. + if (Flags & 0x10) + TheIndex.setPartiallySplitLTOUnits(); break; } case bitc::FS_VALUE_GUID: { // [valueid, refguid] @@ -5917,6 +5929,46 @@ Expected<std::unique_ptr<ModuleSummaryIndex>> BitcodeModule::getSummary() { return std::move(Index); } +static Expected<bool> getEnableSplitLTOUnitFlag(BitstreamCursor &Stream, + unsigned ID) { + if (Stream.EnterSubBlock(ID)) + return error("Invalid record"); + SmallVector<uint64_t, 64> Record; + + while (true) { + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + return error("Malformed block"); + case BitstreamEntry::EndBlock: + // If no flags record found, conservatively return true to mimic + // behavior before this flag was added. + return true; + case BitstreamEntry::Record: + // The interesting case. + break; + } + + // Look for the FS_FLAGS record. + Record.clear(); + auto BitCode = Stream.readRecord(Entry.ID, Record); + switch (BitCode) { + default: // Default behavior: ignore. + break; + case bitc::FS_FLAGS: { // [flags] + uint64_t Flags = Record[0]; + // Scan flags. + assert(Flags <= 0x1f && "Unexpected bits in flag"); + + return Flags & 0x8; + } + } + } + llvm_unreachable("Exit infinite loop"); +} + // Check if the given bitcode buffer contains a global value summary block. Expected<BitcodeLTOInfo> BitcodeModule::getLTOInfo() { BitstreamCursor Stream(Buffer); @@ -5932,14 +5984,27 @@ Expected<BitcodeLTOInfo> BitcodeModule::getLTOInfo() { case BitstreamEntry::Error: return error("Malformed block"); case BitstreamEntry::EndBlock: - return BitcodeLTOInfo{/*IsThinLTO=*/false, /*HasSummary=*/false}; + return BitcodeLTOInfo{/*IsThinLTO=*/false, /*HasSummary=*/false, + /*EnableSplitLTOUnit=*/false}; case BitstreamEntry::SubBlock: - if (Entry.ID == bitc::GLOBALVAL_SUMMARY_BLOCK_ID) - return BitcodeLTOInfo{/*IsThinLTO=*/true, /*HasSummary=*/true}; + if (Entry.ID == bitc::GLOBALVAL_SUMMARY_BLOCK_ID) { + Expected<bool> EnableSplitLTOUnit = + getEnableSplitLTOUnitFlag(Stream, Entry.ID); + if (!EnableSplitLTOUnit) + return EnableSplitLTOUnit.takeError(); + return BitcodeLTOInfo{/*IsThinLTO=*/true, /*HasSummary=*/true, + *EnableSplitLTOUnit}; + } - if (Entry.ID == bitc::FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID) - return BitcodeLTOInfo{/*IsThinLTO=*/false, /*HasSummary=*/true}; + if (Entry.ID == bitc::FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID) { + Expected<bool> EnableSplitLTOUnit = + getEnableSplitLTOUnitFlag(Stream, Entry.ID); + if (!EnableSplitLTOUnit) + return EnableSplitLTOUnit.takeError(); + return BitcodeLTOInfo{/*IsThinLTO=*/false, /*HasSummary=*/true, + *EnableSplitLTOUnit}; + } // Ignore other sub-blocks. if (Stream.SkipBlock()) diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 68d79edceaf..ba4f932e2e6 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -3618,6 +3618,13 @@ void ModuleBitcodeWriterBase::writePerModuleGlobalValueSummary() { Stream.EmitRecord(bitc::FS_VERSION, ArrayRef<uint64_t>{INDEX_VERSION}); + // Write the index flags. + uint64_t Flags = 0; + // Bits 1-3 are set only in the combined index, skip them. + if (Index->enableSplitLTOUnit()) + Flags |= 0x8; + Stream.EmitRecord(bitc::FS_FLAGS, ArrayRef<uint64_t>{Flags}); + if (Index->begin() == Index->end()) { Stream.ExitBlock(); return; @@ -3734,6 +3741,10 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() { Flags |= 0x2; if (Index.hasSyntheticEntryCounts()) Flags |= 0x4; + if (Index.enableSplitLTOUnit()) + Flags |= 0x8; + if (Index.partiallySplitLTOUnits()) + Flags |= 0x10; Stream.EmitRecord(bitc::FS_FLAGS, ArrayRef<uint64_t>{Flags}); for (const auto &GVI : valueIds()) { |