Skip to content

Commit

Permalink
Write summaries for merged modules when splitting modules for ThinLTO.
Browse files Browse the repository at this point in the history
This is to prepare to allow for dead stripping of globals in the
merged modules.

Differential Revision: https://reviews.llvm.org/D33921

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@305027 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
pcc committed Jun 8, 2017
1 parent be95f5e commit e74c64e
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 3 deletions.
2 changes: 2 additions & 0 deletions include/llvm/Bitcode/LLVMBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ enum BlockIDs {
METADATA_KIND_BLOCK_ID,

STRTAB_BLOCK_ID,

FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID,
};

/// Identification block contains a string that describes the producer details,
Expand Down
10 changes: 10 additions & 0 deletions lib/Analysis/ModuleSummaryAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,11 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex(
});
}

bool IsThinLTO = true;
if (auto *MD =
mdconst::extract_or_null<ConstantInt>(M.getModuleFlag("ThinLTO")))
IsThinLTO = MD->getZExtValue();

for (auto &GlobalList : Index) {
// Ignore entries for references that are undefined in the current module.
if (GlobalList.second.SummaryList.empty())
Expand All @@ -455,6 +460,11 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex(
assert(GlobalList.second.SummaryList.size() == 1 &&
"Expected module's index to have one summary per GUID");
auto &Summary = GlobalList.second.SummaryList[0];
if (!IsThinLTO) {
Summary->setNotEligibleToImport();
continue;
}

bool AllRefsCanBeExternallyReferenced =
llvm::all_of(Summary->refs(), [&](const ValueInfo &VI) {
return !CantBePromoted.count(VI.getGUID());
Expand Down
10 changes: 9 additions & 1 deletion lib/Bitcode/Writer/BitcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3305,7 +3305,15 @@ static const uint64_t INDEX_VERSION = 3;
/// Emit the per-module summary section alongside the rest of
/// the module's bitcode.
void ModuleBitcodeWriter::writePerModuleGlobalValueSummary() {
Stream.EnterSubblock(bitc::GLOBALVAL_SUMMARY_BLOCK_ID, 4);
// By default we compile with ThinLTO if the module has a summary, but the
// client can request full LTO with a module flag.
bool IsThinLTO = true;
if (auto *MD =
mdconst::extract_or_null<ConstantInt>(M.getModuleFlag("ThinLTO")))
IsThinLTO = MD->getZExtValue();
Stream.EnterSubblock(IsThinLTO ? bitc::GLOBALVAL_SUMMARY_BLOCK_ID
: bitc::FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID,
4);

Stream.EmitRecord(bitc::FS_VERSION, ArrayRef<uint64_t>{INDEX_VERSION});

Expand Down
12 changes: 10 additions & 2 deletions lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,12 @@ void splitAndWriteThinLTOBitcode(
ProfileSummaryInfo PSI(M);
ModuleSummaryIndex Index = buildModuleSummaryIndex(M, nullptr, &PSI);

// Mark the merged module as requiring full LTO. We still want an index for
// it though, so that it can participate in summary-based dead stripping.
MergedM->addModuleFlag(Module::Error, "ThinLTO", uint32_t(0));
ModuleSummaryIndex MergedMIndex =
buildModuleSummaryIndex(*MergedM, nullptr, &PSI);

SmallVector<char, 0> Buffer;

BitcodeWriter W(Buffer);
Expand All @@ -327,7 +333,8 @@ void splitAndWriteThinLTOBitcode(
ModuleHash ModHash = {{0}};
W.writeModule(&M, /*ShouldPreserveUseListOrder=*/false, &Index,
/*GenerateHash=*/true, &ModHash);
W.writeModule(MergedM.get());
W.writeModule(MergedM.get(), /*ShouldPreserveUseListOrder=*/false,
&MergedMIndex);
W.writeStrtab();
OS << Buffer;

Expand All @@ -340,7 +347,8 @@ void splitAndWriteThinLTOBitcode(
StripDebugInfo(M);
W2.writeModule(&M, /*ShouldPreserveUseListOrder=*/false, &Index,
/*GenerateHash=*/false, &ModHash);
W2.writeModule(MergedM.get());
W2.writeModule(MergedM.get(), /*ShouldPreserveUseListOrder=*/false,
&MergedMIndex);
W2.writeStrtab();
*ThinLinkOS << Buffer;
}
Expand Down
4 changes: 4 additions & 0 deletions test/Transforms/ThinLTOBitcodeWriter/split.ll
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
; ERROR: llvm-modextract: error: module index out of range; bitcode file contains 2 module(s)

; BCA0: <GLOBALVAL_SUMMARY_BLOCK
; BCA1: <FULL_LTO_GLOBALVAL_SUMMARY_BLOCK
; 16 = not eligible to import
; BCA1: <PERMODULE_GLOBALVAR_INIT_REFS {{.*}} op1=16
; BCA1-NOT: <GLOBALVAL_SUMMARY_BLOCK

$g = comdat any
Expand All @@ -47,5 +50,6 @@ define i8* @f() {
; NODEBUG-NOT: !llvm.dbg.cu
!llvm.dbg.cu = !{}

; M1: !{i32 1, !"ThinLTO", i32 0}
!1 = !{i32 2, !"Debug Info Version", i32 3}
!llvm.module.flags = !{!1}
3 changes: 3 additions & 0 deletions tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ static const char *GetBlockName(unsigned BlockID,
case bitc::USELIST_BLOCK_ID: return "USELIST_BLOCK_ID";
case bitc::GLOBALVAL_SUMMARY_BLOCK_ID:
return "GLOBALVAL_SUMMARY_BLOCK";
case bitc::FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID:
return "FULL_LTO_GLOBALVAL_SUMMARY_BLOCK";
case bitc::MODULE_STRTAB_BLOCK_ID: return "MODULE_STRTAB_BLOCK";
case bitc::STRTAB_BLOCK_ID: return "STRTAB_BLOCK";
}
Expand Down Expand Up @@ -298,6 +300,7 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID,
STRINGIFY_CODE(MST_CODE, HASH)
}
case bitc::GLOBALVAL_SUMMARY_BLOCK_ID:
case bitc::FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID:
switch (CodeID) {
default:
return nullptr;
Expand Down

0 comments on commit e74c64e

Please sign in to comment.