Skip to content

Commit 6262763

Browse files
[ThinLTO][Bitcode] Generate import type in bitcode (#87600)
For distributed ThinLTO, the LTO indexing step generates combined summary for each module, and postlink pipeline reads the combined summary which stores the information for link-time optimization. This patch populates the 'import type' of a summary in bitcode, and updates bitcode reader to parse the bit correctly.
1 parent 271eb06 commit 6262763

File tree

9 files changed

+119
-41
lines changed

9 files changed

+119
-41
lines changed

llvm/include/llvm/Bitcode/BitcodeWriter.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ class raw_ostream;
102102

103103
void writeIndex(
104104
const ModuleSummaryIndex *Index,
105-
const std::map<std::string, GVSummaryMapTy> *ModuleToSummariesForIndex);
105+
const std::map<std::string, GVSummaryMapTy> *ModuleToSummariesForIndex,
106+
const GVSummaryPtrSet *DecSummaries);
106107
};
107108

108109
/// Write the specified module to the specified raw output stream.
@@ -147,10 +148,12 @@ class raw_ostream;
147148
/// where it will be written in a new bitcode block. This is used when
148149
/// writing the combined index file for ThinLTO. When writing a subset of the
149150
/// index for a distributed backend, provide the \p ModuleToSummariesForIndex
150-
/// map.
151+
/// map. \p DecSummaries specifies the set of summaries for which the
152+
/// corresponding value should be imported as a declaration (prototype).
151153
void writeIndexToFile(const ModuleSummaryIndex &Index, raw_ostream &Out,
152154
const std::map<std::string, GVSummaryMapTy>
153-
*ModuleToSummariesForIndex = nullptr);
155+
*ModuleToSummariesForIndex = nullptr,
156+
const GVSummaryPtrSet *DecSummaries = nullptr);
154157

155158
/// If EmbedBitcode is set, save a copy of the llvm IR as data in the
156159
/// __LLVM,__bitcode section (.llvmbc on non-MacOS).

llvm/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,12 +271,13 @@ class ThinLTOCodeGenerator {
271271
const lto::InputFile &File);
272272

273273
/**
274-
* Compute the list of summaries needed for importing into module.
274+
* Compute the list of summaries and the subset of declaration summaries
275+
* needed for importing into module.
275276
*/
276277
void gatherImportedSummariesForModule(
277278
Module &Module, ModuleSummaryIndex &Index,
278279
std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex,
279-
const lto::InputFile &File);
280+
GVSummaryPtrSet &DecSummaries, const lto::InputFile &File);
280281

281282
/**
282283
* Perform internalization. Index is updated to reflect linkage changes.

llvm/include/llvm/Transforms/IPO/FunctionImport.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,15 @@ bool convertToDeclaration(GlobalValue &GV);
212212
/// \p ModuleToSummariesForIndex will be populated with the needed summaries
213213
/// from each required module path. Use a std::map instead of StringMap to get
214214
/// stable order for bitcode emission.
215+
///
216+
/// \p DecSummaries will be popluated with the subset of of summary pointers
217+
/// that have 'declaration' import type among all summaries the module need.
215218
void gatherImportedSummariesForModule(
216219
StringRef ModulePath,
217220
const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
218221
const FunctionImporter::ImportMapTy &ImportList,
219-
std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex);
222+
std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex,
223+
GVSummaryPtrSet &DecSummaries);
220224

221225
/// Emit into \p OutputFilename the files module \p ModulePath will import from.
222226
std::error_code EmitImportsFiles(

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,11 @@ class IndexBitcodeWriter : public BitcodeWriterBase {
428428
/// The combined index to write to bitcode.
429429
const ModuleSummaryIndex &Index;
430430

431+
/// When writing combined summaries, provides the set of global value
432+
/// summaries for which the value (function, function alias, etc) should be
433+
/// imported as a declaration.
434+
const GVSummaryPtrSet *DecSummaries = nullptr;
435+
431436
/// When writing a subset of the index for distributed backends, client
432437
/// provides a map of modules to the corresponding GUIDs/summaries to write.
433438
const std::map<std::string, GVSummaryMapTy> *ModuleToSummariesForIndex;
@@ -452,11 +457,16 @@ class IndexBitcodeWriter : public BitcodeWriterBase {
452457
/// Constructs a IndexBitcodeWriter object for the given combined index,
453458
/// writing to the provided \p Buffer. When writing a subset of the index
454459
/// for a distributed backend, provide a \p ModuleToSummariesForIndex map.
460+
/// If provided, \p ModuleToDecSummaries specifies the set of summaries for
461+
/// which the corresponding functions or aliased functions should be imported
462+
/// as a declaration (but not definition) for each module.
455463
IndexBitcodeWriter(BitstreamWriter &Stream, StringTableBuilder &StrtabBuilder,
456464
const ModuleSummaryIndex &Index,
465+
const GVSummaryPtrSet *DecSummaries = nullptr,
457466
const std::map<std::string, GVSummaryMapTy>
458467
*ModuleToSummariesForIndex = nullptr)
459468
: BitcodeWriterBase(Stream, StrtabBuilder), Index(Index),
469+
DecSummaries(DecSummaries),
460470
ModuleToSummariesForIndex(ModuleToSummariesForIndex) {
461471
// Assign unique value ids to all summaries to be written, for use
462472
// in writing out the call graph edges. Save the mapping from GUID
@@ -1202,7 +1212,8 @@ static uint64_t getEncodedFFlags(FunctionSummary::FFlags Flags) {
12021212

12031213
// Decode the flags for GlobalValue in the summary. See getDecodedGVSummaryFlags
12041214
// in BitcodeReader.cpp.
1205-
static uint64_t getEncodedGVSummaryFlags(GlobalValueSummary::GVFlags Flags) {
1215+
static uint64_t getEncodedGVSummaryFlags(GlobalValueSummary::GVFlags Flags,
1216+
bool ImportAsDecl = false) {
12061217
uint64_t RawFlags = 0;
12071218

12081219
RawFlags |= Flags.NotEligibleToImport; // bool
@@ -1217,7 +1228,8 @@ static uint64_t getEncodedGVSummaryFlags(GlobalValueSummary::GVFlags Flags) {
12171228

12181229
RawFlags |= (Flags.Visibility << 8); // 2 bits
12191230

1220-
RawFlags |= (Flags.ImportType << 10); // 1 bit
1231+
unsigned ImportType = Flags.ImportType | ImportAsDecl;
1232+
RawFlags |= (ImportType << 10); // 1 bit
12211233

12221234
return RawFlags;
12231235
}
@@ -4543,6 +4555,12 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
45434555
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
45444556
unsigned AllocAbbrev = Stream.EmitAbbrev(std::move(Abbv));
45454557

4558+
auto shouldImportValueAsDecl = [&](GlobalValueSummary *GVS) -> bool {
4559+
if (DecSummaries == nullptr)
4560+
return false;
4561+
return DecSummaries->contains(GVS);
4562+
};
4563+
45464564
// The aliases are emitted as a post-pass, and will point to the value
45474565
// id of the aliasee. Save them in a vector for post-processing.
45484566
SmallVector<AliasSummary *, 64> Aliases;
@@ -4653,7 +4671,8 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
46534671
NameVals.push_back(*ValueId);
46544672
assert(ModuleIdMap.count(FS->modulePath()));
46554673
NameVals.push_back(ModuleIdMap[FS->modulePath()]);
4656-
NameVals.push_back(getEncodedGVSummaryFlags(FS->flags()));
4674+
NameVals.push_back(
4675+
getEncodedGVSummaryFlags(FS->flags(), shouldImportValueAsDecl(FS)));
46574676
NameVals.push_back(FS->instCount());
46584677
NameVals.push_back(getEncodedFFlags(FS->fflags()));
46594678
NameVals.push_back(FS->entryCount());
@@ -4702,7 +4721,8 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
47024721
NameVals.push_back(AliasValueId);
47034722
assert(ModuleIdMap.count(AS->modulePath()));
47044723
NameVals.push_back(ModuleIdMap[AS->modulePath()]);
4705-
NameVals.push_back(getEncodedGVSummaryFlags(AS->flags()));
4724+
NameVals.push_back(
4725+
getEncodedGVSummaryFlags(AS->flags(), shouldImportValueAsDecl(AS)));
47064726
auto AliaseeValueId = SummaryToValueIdMap[&AS->getAliasee()];
47074727
assert(AliaseeValueId);
47084728
NameVals.push_back(AliaseeValueId);
@@ -5036,8 +5056,9 @@ void BitcodeWriter::writeModule(const Module &M,
50365056

50375057
void BitcodeWriter::writeIndex(
50385058
const ModuleSummaryIndex *Index,
5039-
const std::map<std::string, GVSummaryMapTy> *ModuleToSummariesForIndex) {
5040-
IndexBitcodeWriter IndexWriter(*Stream, StrtabBuilder, *Index,
5059+
const std::map<std::string, GVSummaryMapTy> *ModuleToSummariesForIndex,
5060+
const GVSummaryPtrSet *DecSummaries) {
5061+
IndexBitcodeWriter IndexWriter(*Stream, StrtabBuilder, *Index, DecSummaries,
50415062
ModuleToSummariesForIndex);
50425063
IndexWriter.write();
50435064
}
@@ -5090,12 +5111,13 @@ void IndexBitcodeWriter::write() {
50905111
// index for a distributed backend, provide a \p ModuleToSummariesForIndex map.
50915112
void llvm::writeIndexToFile(
50925113
const ModuleSummaryIndex &Index, raw_ostream &Out,
5093-
const std::map<std::string, GVSummaryMapTy> *ModuleToSummariesForIndex) {
5114+
const std::map<std::string, GVSummaryMapTy> *ModuleToSummariesForIndex,
5115+
const GVSummaryPtrSet *DecSummaries) {
50945116
SmallVector<char, 0> Buffer;
50955117
Buffer.reserve(256 * 1024);
50965118

50975119
BitcodeWriter Writer(Buffer);
5098-
Writer.writeIndex(&Index, ModuleToSummariesForIndex);
5120+
Writer.writeIndex(&Index, ModuleToSummariesForIndex, DecSummaries);
50995121
Writer.writeStrtab();
51005122

51015123
Out.write((char *)&Buffer.front(), Buffer.size());

llvm/lib/LTO/LTO.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,18 +1400,20 @@ class lto::ThinBackendProc {
14001400
llvm::StringRef ModulePath,
14011401
const std::string &NewModulePath) {
14021402
std::map<std::string, GVSummaryMapTy> ModuleToSummariesForIndex;
1403+
GVSummaryPtrSet DeclarationSummaries;
14031404

14041405
std::error_code EC;
14051406
gatherImportedSummariesForModule(ModulePath, ModuleToDefinedGVSummaries,
1406-
ImportList, ModuleToSummariesForIndex);
1407+
ImportList, ModuleToSummariesForIndex,
1408+
DeclarationSummaries);
14071409

14081410
raw_fd_ostream OS(NewModulePath + ".thinlto.bc", EC,
14091411
sys::fs::OpenFlags::OF_None);
14101412
if (EC)
14111413
return errorCodeToError(EC);
14121414

1413-
// TODO: Serialize declaration bits to bitcode.
1414-
writeIndexToFile(CombinedIndex, OS, &ModuleToSummariesForIndex);
1415+
writeIndexToFile(CombinedIndex, OS, &ModuleToSummariesForIndex,
1416+
&DeclarationSummaries);
14151417

14161418
if (ShouldEmitImportsFiles) {
14171419
EC = EmitImportsFiles(ModulePath, NewModulePath + ".imports",

llvm/lib/LTO/ThinLTOCodeGenerator.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,7 @@ void ThinLTOCodeGenerator::crossModuleImport(Module &TheModule,
766766
void ThinLTOCodeGenerator::gatherImportedSummariesForModule(
767767
Module &TheModule, ModuleSummaryIndex &Index,
768768
std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex,
769-
const lto::InputFile &File) {
769+
GVSummaryPtrSet &DecSummaries, const lto::InputFile &File) {
770770
auto ModuleCount = Index.modulePaths().size();
771771
auto ModuleIdentifier = TheModule.getModuleIdentifier();
772772

@@ -796,7 +796,7 @@ void ThinLTOCodeGenerator::gatherImportedSummariesForModule(
796796

797797
llvm::gatherImportedSummariesForModule(
798798
ModuleIdentifier, ModuleToDefinedGVSummaries,
799-
ImportLists[ModuleIdentifier], ModuleToSummariesForIndex);
799+
ImportLists[ModuleIdentifier], ModuleToSummariesForIndex, DecSummaries);
800800
}
801801

802802
/**
@@ -832,10 +832,14 @@ void ThinLTOCodeGenerator::emitImports(Module &TheModule, StringRef OutputName,
832832
IsPrevailing(PrevailingCopy), ImportLists,
833833
ExportLists);
834834

835+
// 'EmitImportsFiles' emits the list of modules from which to import from, and
836+
// the set of keys in `ModuleToSummariesForIndex` should be a superset of keys
837+
// in `DecSummaries`, so no need to use `DecSummaries` in `EmitImportFiles`.
838+
GVSummaryPtrSet DecSummaries;
835839
std::map<std::string, GVSummaryMapTy> ModuleToSummariesForIndex;
836840
llvm::gatherImportedSummariesForModule(
837841
ModuleIdentifier, ModuleToDefinedGVSummaries,
838-
ImportLists[ModuleIdentifier], ModuleToSummariesForIndex);
842+
ImportLists[ModuleIdentifier], ModuleToSummariesForIndex, DecSummaries);
839843

840844
std::error_code EC;
841845
if ((EC = EmitImportsFiles(ModuleIdentifier, OutputName,

llvm/lib/Transforms/IPO/FunctionImport.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1435,7 +1435,8 @@ void llvm::gatherImportedSummariesForModule(
14351435
StringRef ModulePath,
14361436
const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
14371437
const FunctionImporter::ImportMapTy &ImportList,
1438-
std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex) {
1438+
std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex,
1439+
GVSummaryPtrSet &DecSummaries) {
14391440
// Include all summaries from the importing module.
14401441
ModuleToSummariesForIndex[std::string(ModulePath)] =
14411442
ModuleToDefinedGVSummaries.lookup(ModulePath);
@@ -1450,7 +1451,7 @@ void llvm::gatherImportedSummariesForModule(
14501451
assert(DS != DefinedGVSummaries.end() &&
14511452
"Expected a defined summary for imported global value");
14521453
if (Type == GlobalValueSummary::Declaration)
1453-
continue;
1454+
DecSummaries.insert(DS->second);
14541455

14551456
SummariesForIndex[GUID] = DS->second;
14561457
}

0 commit comments

Comments
 (0)