llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lto Author: Konstantin Belochapka (kbelochapka) <details> <summary>Changes</summary> Serialize the serializable fields of lto::Config, TargetOptions, MCTargetOptions, and PassBuilder options as versioned module metadata. Preserve structured state such as optional values, string lists, and the basic-block sections profile buffer while omitting runtime-only callbacks, plugin pointers, and stream handles. Add APIs to round-trip the configuration through modules, standalone bitcode files, and ThinLTO summary indexes. Extend the bitcode writer to carry self-contained module metadata in summary-only output, embed the configuration in DTLTO index shards, and restore it in Clang's distributed ThinLTO backend while retaining the legacy fallback for indexes without metadata. Add unit and DTLTO integration coverage for module, file, and summary-index round trips. Add compile-time synchronization tests so new Config and TargetOptions fields require an explicit serialization update or omission. --- Patch is 86.13 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/219894.diff 22 Files Affected: - (modified) clang/lib/CodeGen/BackendUtil.cpp (+64-41) - (added) cross-project-tests/dtlto/config-serialization-sync.cpp (+21) - (added) cross-project-tests/dtlto/target-options-serialization-sync.cpp (+21) - (modified) cross-project-tests/lit.cfg.py (+1) - (modified) cross-project-tests/lit.site.cfg.py.in (+1) - (modified) llvm/include/llvm/Bitcode/BitcodeWriter.h (+7-2) - (modified) llvm/include/llvm/LTO/Config.h (+3-1) - (added) llvm/include/llvm/LTO/LTOConfigBitcode.h (+63) - (added) llvm/include/llvm/LTO/TargetOptionsBitcode.h (+49) - (modified) llvm/include/llvm/MC/MCTargetOptions.h (+2) - (modified) llvm/include/llvm/Target/TargetOptions.h (+2) - (modified) llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp (-1) - (modified) llvm/lib/Bitcode/Writer/BitcodeWriter.cpp (+32-6) - (added) llvm/lib/LTO/BitcodeMetadataUtils.h (+222) - (modified) llvm/lib/LTO/CMakeLists.txt (+2) - (modified) llvm/lib/LTO/LTO.cpp (+10-2) - (added) llvm/lib/LTO/LTOConfigBitcode.cpp (+486) - (added) llvm/lib/LTO/TargetOptionsBitcode.cpp (+522) - (modified) llvm/test/ThinLTO/X86/dtlto/summary.ll (+18-5) - (modified) llvm/unittests/CMakeLists.txt (+1) - (added) llvm/unittests/LTO/CMakeLists.txt (+13) - (added) llvm/unittests/LTO/LTOConfigBitcodeTest.cpp (+165) ``````````diff diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 6aa6bc1bd41e8..3ef228f932c9f 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -40,6 +40,7 @@ #include "llvm/IR/Verifier.h" #include "llvm/IRPrinter/IRPrintingPasses.h" #include "llvm/LTO/LTOBackend.h" +#include "llvm/LTO/LTOConfigBitcode.h" #include "llvm/MC/TargetRegistry.h" #include "llvm/Object/OffloadBinary.h" #include "llvm/Passes/PassBuilder.h" @@ -1395,7 +1396,28 @@ runThinLTOBackend(CompilerInstance &CI, ModuleSummaryIndex *CombinedIndex, return std::make_unique<CachedFileStream>(std::move(OS), CGOpts.ObjectFilenameForDebug); }; - lto::Config Conf; + + ErrorOr<std::unique_ptr<MemoryBuffer>> IndexBuffer = + CI.getVirtualFileSystem().getBufferForFile(CGOpts.ThinLTOIndexFile); + if (!IndexBuffer) { + errs() << "Error loading LTO config from index file '" + << CGOpts.ThinLTOIndexFile + << "': " << IndexBuffer.getError().message() << '\n'; + return; + } + Expected<std::optional<lto::Config>> SerializedConf = + lto::readLTOConfigFromSummaryIndexIfPresent( + (*IndexBuffer)->getMemBufferRef()); + if (!SerializedConf) { + logAllUnhandledErrors(SerializedConf.takeError(), errs(), + "Error loading LTO config from index file '" + + CGOpts.ThinLTOIndexFile + "': "); + return; + } + + bool HasSerializedConf = SerializedConf->has_value(); + lto::Config Conf = + HasSerializedConf ? std::move(**SerializedConf) : lto::Config(); if (CGOpts.SaveTempsFilePrefix != "") { if (Error E = Conf.addSaveTemps(CGOpts.SaveTempsFilePrefix + ".", /* UseInputModulePath */ false)) { @@ -1405,47 +1427,48 @@ runThinLTOBackend(CompilerInstance &CI, ModuleSummaryIndex *CombinedIndex, }); } } - Conf.CPU = TOpts.CPU; - Conf.CodeModel = getCodeModel(CGOpts); - Conf.MAttrs = TOpts.Features; - Conf.RelocModel = CGOpts.RelocationModel; - std::optional<CodeGenOptLevel> OptLevelOrNone = - CodeGenOpt::getLevel(CGOpts.OptimizationLevel); - assert(OptLevelOrNone && "Invalid optimization level!"); - Conf.CGOptLevel = *OptLevelOrNone; - Conf.OptLevel = CGOpts.OptimizationLevel; - initTargetOptions(CI, Diags, Conf.Options); - Conf.SampleProfile = std::move(SampleProfile); - Conf.PTO.LoopUnrolling = CGOpts.UnrollLoops; - Conf.PTO.LoopInterchange = CGOpts.InterchangeLoops; - Conf.PTO.LoopFusion = CGOpts.FuseLoops; - // For historical reasons, loop interleaving is set to mirror setting for loop - // unrolling. - Conf.PTO.LoopInterleaving = CGOpts.UnrollLoops; - Conf.PTO.LoopVectorization = CGOpts.VectorizeLoop; - Conf.PTO.SLPVectorization = CGOpts.VectorizeSLP; - // Only enable CGProfilePass when using integrated assembler, since - // non-integrated assemblers don't recognize .cgprofile section. - Conf.PTO.CallGraphProfile = !CGOpts.DisableIntegratedAS; - - // Context sensitive profile. - if (CGOpts.hasProfileCSIRInstr()) { - Conf.RunCSIRInstr = true; - Conf.CSIRProfile = getProfileGenName(CGOpts); - } else if (CGOpts.hasProfileCSIRUse()) { - Conf.RunCSIRInstr = false; - Conf.CSIRProfile = std::move(CGOpts.ProfileInstrumentUsePath); - } + if (!HasSerializedConf) { + Conf.CPU = TOpts.CPU; + Conf.CodeModel = getCodeModel(CGOpts); + Conf.MAttrs = TOpts.Features; + Conf.RelocModel = CGOpts.RelocationModel; + std::optional<CodeGenOptLevel> OptLevelOrNone = + CodeGenOpt::getLevel(CGOpts.OptimizationLevel); + assert(OptLevelOrNone && "Invalid optimization level!"); + Conf.CGOptLevel = *OptLevelOrNone; + Conf.OptLevel = CGOpts.OptimizationLevel; + initTargetOptions(CI, Diags, Conf.Options); + Conf.SampleProfile = std::move(SampleProfile); + Conf.PTO.LoopUnrolling = CGOpts.UnrollLoops; + Conf.PTO.LoopInterchange = CGOpts.InterchangeLoops; + Conf.PTO.LoopFusion = CGOpts.FuseLoops; + // For historical reasons, loop interleaving mirrors loop unrolling. + Conf.PTO.LoopInterleaving = CGOpts.UnrollLoops; + Conf.PTO.LoopVectorization = CGOpts.VectorizeLoop; + Conf.PTO.SLPVectorization = CGOpts.VectorizeSLP; + // Only enable CGProfilePass when using integrated assembler, since + // non-integrated assemblers don't recognize .cgprofile section. + Conf.PTO.CallGraphProfile = !CGOpts.DisableIntegratedAS; + + // Context sensitive profile. + if (CGOpts.hasProfileCSIRInstr()) { + Conf.RunCSIRInstr = true; + Conf.CSIRProfile = getProfileGenName(CGOpts); + } else if (CGOpts.hasProfileCSIRUse()) { + Conf.RunCSIRInstr = false; + Conf.CSIRProfile = std::move(CGOpts.ProfileInstrumentUsePath); + } - Conf.ProfileRemapping = std::move(ProfileRemapping); - Conf.DebugPassManager = CGOpts.DebugPassManager; - Conf.VerifyEach = CGOpts.VerifyEach; - Conf.RemarksWithHotness = CGOpts.DiagnosticsWithHotness; - Conf.RemarksFilename = CGOpts.OptRecordFile; - Conf.RemarksPasses = CGOpts.OptRecordPasses; - Conf.RemarksFormat = CGOpts.OptRecordFormat; - Conf.SplitDwarfFile = CGOpts.SplitDwarfFile; - Conf.SplitDwarfOutput = CGOpts.SplitDwarfOutput; + Conf.ProfileRemapping = std::move(ProfileRemapping); + Conf.DebugPassManager = CGOpts.DebugPassManager; + Conf.VerifyEach = CGOpts.VerifyEach; + Conf.RemarksWithHotness = CGOpts.DiagnosticsWithHotness; + Conf.RemarksFilename = CGOpts.OptRecordFile; + Conf.RemarksPasses = CGOpts.OptRecordPasses; + Conf.RemarksFormat = CGOpts.OptRecordFormat; + Conf.SplitDwarfFile = CGOpts.SplitDwarfFile; + Conf.SplitDwarfOutput = CGOpts.SplitDwarfOutput; + } for (auto &Plugin : CI.getPassPlugins()) Conf.LoadedPassPlugins.push_back(Plugin.get()); switch (Action) { diff --git a/cross-project-tests/dtlto/config-serialization-sync.cpp b/cross-project-tests/dtlto/config-serialization-sync.cpp new file mode 100644 index 0000000000000..5e7323e195e64 --- /dev/null +++ b/cross-project-tests/dtlto/config-serialization-sync.cpp @@ -0,0 +1,21 @@ +// Verify that adding an lto::Config field makes the real serialization guard +// fail to compile until the field is handled. +// +// REQUIRES: clang +// RUN: not %clangxx -std=c++17 -fsyntax-only \ +// RUN: -I%llvm_src_root/include -I%llvm_obj_root/include \ +// RUN: -I%llvm_src_root/lib/LTO %s 2>&1 | FileCheck %s + +// Inject an extra field at the final Config field declaration. Undefine the +// macro before including the implementation so its structured binding still +// contains the production field list. +#define GetCacheKeyOutputString \ + GetCacheKeyOutputString; \ + bool SerializationTestExtraField +#include "llvm/LTO/LTOConfigBitcode.h" +#undef GetCacheKeyOutputString + +#include "LTOConfigBitcode.cpp" + +// CHECK: type 'const Config' {{binds to|decomposes into}} 61 elements, +// CHECK-SAME: but only 60 names were provided diff --git a/cross-project-tests/dtlto/target-options-serialization-sync.cpp b/cross-project-tests/dtlto/target-options-serialization-sync.cpp new file mode 100644 index 0000000000000..6e2a798662415 --- /dev/null +++ b/cross-project-tests/dtlto/target-options-serialization-sync.cpp @@ -0,0 +1,21 @@ +// Verify that adding a TargetOptions field makes the real serialization guard +// fail to compile until the field is handled. +// +// REQUIRES: clang +// RUN: not %clangxx -std=c++17 -fsyntax-only \ +// RUN: -I%llvm_src_root/include -I%llvm_obj_root/include \ +// RUN: -I%llvm_src_root/lib/LTO %s 2>&1 | FileCheck %s + +// Inject an extra field at the final TargetOptions field declaration. Undefine +// the macro before including the implementation so its structured binding +// still contains the production field list. +#define ObjectFilenameForDebug \ + ObjectFilenameForDebug; \ + bool SerializationTestExtraField +#include "llvm/LTO/TargetOptionsBitcode.h" +#undef ObjectFilenameForDebug + +#include "TargetOptionsBitcode.cpp" + +// CHECK: type 'const TargetOptions' {{binds to|decomposes into}} 63 elements, +// CHECK-SAME: but only 62 names were provided diff --git a/cross-project-tests/lit.cfg.py b/cross-project-tests/lit.cfg.py index ae4647d33672e..94019275f5809 100644 --- a/cross-project-tests/lit.cfg.py +++ b/cross-project-tests/lit.cfg.py @@ -56,6 +56,7 @@ ), ), ToolSubst("%llvm_src_root", config.llvm_src_root), + ToolSubst("%llvm_obj_root", config.llvm_obj_root), ToolSubst("%llvm_tools_dir", config.llvm_tools_dir), ] diff --git a/cross-project-tests/lit.site.cfg.py.in b/cross-project-tests/lit.site.cfg.py.in index b8992b6dca45e..0f57041e6d752 100644 --- a/cross-project-tests/lit.site.cfg.py.in +++ b/cross-project-tests/lit.site.cfg.py.in @@ -6,6 +6,7 @@ from pathlib import Path config.targets_to_build = "@TARGETS_TO_BUILD@".split() config.llvm_src_root = "@LLVM_SOURCE_DIR@" +config.llvm_obj_root = "@LLVM_BINARY_DIR@" config.llvm_tools_dir = lit_config.substitute("@LLVM_TOOLS_DIR@") config.llvm_libs_dir = "@LLVM_LIBS_DIR@" config.llvm_shlib_dir = lit_config.substitute("@SHLIBDIR@") diff --git a/llvm/include/llvm/Bitcode/BitcodeWriter.h b/llvm/include/llvm/Bitcode/BitcodeWriter.h index d88e261f8c684..9ce577f4ca9ca 100644 --- a/llvm/include/llvm/Bitcode/BitcodeWriter.h +++ b/llvm/include/llvm/Bitcode/BitcodeWriter.h @@ -105,7 +105,8 @@ class BitcodeWriter { LLVM_ABI void writeIndex(const ModuleSummaryIndex *Index, const ModuleToSummariesForIndexTy *ModuleToSummariesForIndex, - const GVSummaryPtrSet *DecSummaries); + const GVSummaryPtrSet *DecSummaries, + const Module *ModuleMetadata = nullptr); }; /// Write the specified module to the specified raw output stream. @@ -152,10 +153,14 @@ LLVM_ABI void writeThinLinkBitcodeToFile(const Module &M, raw_ostream &Out, /// index for a distributed backend, provide the \p ModuleToSummariesForIndex /// map. \p DecSummaries specifies the set of summaries for which the /// corresponding value should be imported as a declaration (prototype). +/// If \p ModuleMetadata is provided, its module-level metadata is emitted into +/// the index module. The metadata must be self-contained and must not reference +/// globals or functions from \p ModuleMetadata. LLVM_ABI void writeIndexToFile( const ModuleSummaryIndex &Index, raw_ostream &Out, const ModuleToSummariesForIndexTy *ModuleToSummariesForIndex = nullptr, - const GVSummaryPtrSet *DecSummaries = nullptr); + const GVSummaryPtrSet *DecSummaries = nullptr, + const Module *ModuleMetadata = nullptr); /// If EmbedBitcode is set, save a copy of the llvm IR as data in the /// __LLVM,__bitcode section (.llvmbc on non-MacOS). diff --git a/llvm/include/llvm/LTO/Config.h b/llvm/include/llvm/LTO/Config.h index f322f753813ff..68c3bd8753660 100644 --- a/llvm/include/llvm/LTO/Config.h +++ b/llvm/include/llvm/LTO/Config.h @@ -46,7 +46,9 @@ struct Config { ELF, }; // Note: when adding fields here, consider whether they need to be added to - // computeLTOCacheKey in LTO.cpp. + // computeLTOCacheKey in LTO.cpp. The structured binding in + // LTOConfigBitcode.cpp will also require the field to be explicitly handled + // or documented as non-serializable. std::string CPU; TargetOptions Options; std::vector<std::string> MAttrs; diff --git a/llvm/include/llvm/LTO/LTOConfigBitcode.h b/llvm/include/llvm/LTO/LTOConfigBitcode.h new file mode 100644 index 0000000000000..6cbd68be1a94a --- /dev/null +++ b/llvm/include/llvm/LTO/LTOConfigBitcode.h @@ -0,0 +1,63 @@ +//===- LTOConfigBitcode.h - lto::Config in bitcode ------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// Utility for embedding serializable fields of lto::Config in LLVM IR bitcode +// via module metadata. Intended for LTO / DTLTO configuration transport. +// +// Non-serializable fields (callbacks, loaded plugin pointers, stream handles) +// are omitted. See encodeLTOConfigToModule() documentation in the .cpp file. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LTO_LTOCONFIG_BITCODE_H +#define LLVM_LTO_LTOCONFIG_BITCODE_H + +#include "llvm/IR/Module.h" +#include "llvm/IR/ModuleSummaryIndex.h" +#include "llvm/LTO/Config.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/MemoryBufferRef.h" + +#include <optional> + +namespace llvm { +namespace lto { + +inline constexpr StringLiteral LTOConfigMetadataName = "llvm.lto.config"; + +/// Serialize all serializable fields of \p Config into \p M. +LLVM_ABI Error encodeLTOConfigToModule(Module &M, const Config &Config); + +/// Deserialize lto::Config previously stored by encodeLTOConfigToModule. +LLVM_ABI Expected<Config> decodeLTOConfigFromModule(const Module &M); + +/// Serialize \p Config into a standalone LLVM bitcode file at \p Path. +LLVM_ABI Error writeLTOConfigToFile(StringRef Path, const Config &Config); + +/// Read a Config from a file written by writeLTOConfigToFile(). +LLVM_ABI Expected<Config> readLTOConfigFromFile(StringRef Path); + +/// Write a ThinLTO summary index containing serialized Config metadata. +LLVM_ABI Error writeIndexWithLTOConfigToFile( + const ModuleSummaryIndex &Index, const Config &Config, raw_ostream &Out, + const ModuleToSummariesForIndexTy *ModuleToSummariesForIndex = nullptr, + const GVSummaryPtrSet *DecSummaries = nullptr); + +/// Read Config metadata from a ThinLTO summary index. +LLVM_ABI Expected<Config> readLTOConfigFromSummaryIndex(MemoryBufferRef Buffer); + +/// Read Config metadata from a ThinLTO summary index, or return std::nullopt if +/// the index has no Config metadata. +LLVM_ABI Expected<std::optional<Config>> +readLTOConfigFromSummaryIndexIfPresent(MemoryBufferRef Buffer); + +/// Returns true if \p M contains serialized lto::Config metadata. +LLVM_ABI bool hasEncodedLTOConfig(const Module &M); + +} // namespace lto +} // namespace llvm + +#endif diff --git a/llvm/include/llvm/LTO/TargetOptionsBitcode.h b/llvm/include/llvm/LTO/TargetOptionsBitcode.h new file mode 100644 index 0000000000000..4f15c908ca477 --- /dev/null +++ b/llvm/include/llvm/LTO/TargetOptionsBitcode.h @@ -0,0 +1,49 @@ +//===- TargetOptionsBitcode.h - TargetOptions in bitcode --------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// Utility for embedding llvm::TargetOptions in LLVM IR bitcode via module +// metadata. Intended for LTO / DTLTO configuration transport. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LTO_TARGETOPTIONS_BITCODE_H +#define LLVM_LTO_TARGETOPTIONS_BITCODE_H + +#include "llvm/IR/Module.h" +#include "llvm/Support/Error.h" +#include "llvm/Target/TargetOptions.h" + +namespace llvm { +namespace lto { + +/// Metadata name written into the module and persisted in bitcode. +inline constexpr StringLiteral TargetOptionsMetadataName = + "llvm.lto.target_options"; + +/// Serialize \p Options into \p M as named module metadata. +/// Non-serializable fields are skipped. +LLVM_ABI Error encodeTargetOptionsToModule(Module &M, + const TargetOptions &Options); + +/// Deserialize TargetOptions previously stored by encodeTargetOptionsToModule. +/// Returns an error if metadata is missing or malformed. +LLVM_ABI Expected<TargetOptions> decodeTargetOptionsFromModule(const Module &M); + +/// Returns true if \p M contains serialized TargetOptions metadata. +LLVM_ABI bool hasEncodedTargetOptions(const Module &M); + +/// Encode TargetOptions as a standalone metadata node (for nesting). +LLVM_ABI MDNode *encodeTargetOptionsAsNode(LLVMContext &Ctx, + const TargetOptions &Options); + +/// Decode TargetOptions from a node produced by encodeTargetOptionsAsNode. +LLVM_ABI Expected<TargetOptions> +decodeTargetOptionsFromNode(const MDNode *Root); + +} // namespace lto +} // namespace llvm + +#endif diff --git a/llvm/include/llvm/MC/MCTargetOptions.h b/llvm/include/llvm/MC/MCTargetOptions.h index 1ef26da9afdbc..c7914e55545ed 100644 --- a/llvm/include/llvm/MC/MCTargetOptions.h +++ b/llvm/include/llvm/MC/MCTargetOptions.h @@ -37,6 +37,8 @@ class StringRef; class MCTargetOptions { public: + // When adding fields, update the structured binding and serialization in + // llvm/lib/LTO/TargetOptionsBitcode.cpp. enum AsmInstrumentation { AsmInstrumentationNone, AsmInstrumentationAddress diff --git a/llvm/include/llvm/Target/TargetOptions.h b/llvm/include/llvm/Target/TargetOptions.h index f6c862e99b98f..df5da377a99a0 100644 --- a/llvm/include/llvm/Target/TargetOptions.h +++ b/llvm/include/llvm/Target/TargetOptions.h @@ -118,6 +118,8 @@ enum CodeObjectVersionKind { class TargetOptions { public: + // When adding fields, update the structured binding and serialization in + // llvm/lib/LTO/TargetOptionsBitcode.cpp. TargetOptions() : NoTrappingFPMath(true), EnableAIXExtendedAltivecABI(false), HonorSignDependentRoundingFPMathOption(false), NoZerosInBSS(false), diff --git a/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp b/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp index 6574ab7a93c58..3e99d015434b8 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp @@ -1004,4 +1004,3 @@ Error BitcodeAnalyzer::parseBlock(unsigned BlockID, unsigned IndentLevel, return Skipped.takeError(); } } - diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 0b9b1bccb1fb8..d267115ebbedd 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -322,6 +322,10 @@ class ModuleBitcodeWriter : public ModuleBitcodeWriterBase { /// Emit the current module to the bitstream. void write(); + /// Emit the blocks required for module-level metadata into an already open + /// module block. + void writeModuleMetadataOnly(); + private: uint64_t bitcodeStartBit() { return BitcodeStartBit; } @@ -477,6 +481,9 @@ class IndexBitcodeWriter : public BitcodeWriterBase { /// provides a map of modules to the corresponding GUIDs/summaries to write. const ModuleToSummariesForIndexTy *ModuleToSummariesForIndex; + /// Optional module whose module-level metadata is emitted into the index. + const Module *ModuleMetadata; + /// Map that holds the correspondence between the GUID used in the combined /// index and a value id generated by this class to use in references. std::map<GlobalValue::GUID, unsigned> GUIDToValueIdMap; @@ -508,10 +515,12 @@ class IndexBitcodeWriter : public BitcodeWriterBase { BitstreamWriter &Stream, StringTableBuilder &StrtabBuilder, const ModuleSummaryIndex &Index, const GVSummaryPtrSet *DecSummaries = nullptr, - const ModuleToSummariesForIndexTy *ModuleToSummariesForIndex = nullptr) + const ModuleToSummariesForIndexTy *ModuleToSummariesForIndex = nullptr, + const Module *ModuleMetadata = nullptr) : BitcodeWriterBase(Stream, StrtabBuilder), Index(Index), DecSummaries(DecSummaries), - ModuleToSummariesForIndex(ModuleToSummariesForIndex) { + ModuleToSummariesForIndex(ModuleToSummariesForIndex), + ModuleMetadata(ModuleMetadata) { // See if the StackIdIndex was already added to the StackId map and // vector. If not, record it. @@ -5563,6 +5572,14 @@ void ModuleBitcodeWriter::write() { Stream.ExitBlock(); } +void ModuleBitcodeWriter::writeModuleMetadataOnly() { + writeBlockInfo(); + writeTypeTable(); + writeModuleConstants(); + writeModuleMetadataKinds(); + writeModuleMetadata(); +} + static void writeInt32ToBuffer(uint32_t Value, SmallVectorImpl<char> &Buffer, uint32_t &Position) { support::endian::write32le(&Buffer[Position], Value); @@ -5737,9 +5754,9 @@ vo... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/219894 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
