mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-19 06:46:43 +00:00
Reland "[ThinLTO][Bitcode] Generate import type in bitcode" (#97253)
https://github.com/llvm/llvm-project/pull/87600 was reverted in order to revert6262763341
. Now https://github.com/llvm/llvm-project/pull/95482 is fix forward for6262763341
. This patch is a reland for https://github.com/llvm/llvm-project/pull/87600 **Changes on top of original patch** In `llvm/include/llvm/IR/ModuleSummaryIndex.h`, make the type of `GVSummaryPtrSet` an `unordered_set` which is more memory efficient when the number of elements is smaller than 128 [1] **Original commit message** 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]393eff4e02/llvm/lib/Support/SmallPtrSet.cpp (L43)
This commit is contained in:
parent
84741940f2
commit
50fea9943f
@ -102,7 +102,8 @@ public:
|
||||
|
||||
void writeIndex(
|
||||
const ModuleSummaryIndex *Index,
|
||||
const std::map<std::string, GVSummaryMapTy> *ModuleToSummariesForIndex);
|
||||
const std::map<std::string, GVSummaryMapTy> *ModuleToSummariesForIndex,
|
||||
const GVSummaryPtrSet *DecSummaries);
|
||||
};
|
||||
|
||||
/// Write the specified module to the specified raw output stream.
|
||||
@ -147,10 +148,12 @@ void writeThinLinkBitcodeToFile(const Module &M, raw_ostream &Out,
|
||||
/// where it will be written in a new bitcode block. This is used when
|
||||
/// writing the combined index file for ThinLTO. When writing a subset of the
|
||||
/// index for a distributed backend, provide the \p ModuleToSummariesForIndex
|
||||
/// map.
|
||||
/// map. \p DecSummaries specifies the set of summaries for which the
|
||||
/// corresponding value should be imported as a declaration (prototype).
|
||||
void writeIndexToFile(const ModuleSummaryIndex &Index, raw_ostream &Out,
|
||||
const std::map<std::string, GVSummaryMapTy>
|
||||
*ModuleToSummariesForIndex = nullptr);
|
||||
*ModuleToSummariesForIndex = nullptr,
|
||||
const GVSummaryPtrSet *DecSummaries = nullptr);
|
||||
|
||||
/// If EmbedBitcode is set, save a copy of the llvm IR as data in the
|
||||
/// __LLVM,__bitcode section (.llvmbc on non-MacOS).
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@ -1277,7 +1278,7 @@ using ModulePathStringTableTy = StringMap<ModuleHash>;
|
||||
using GVSummaryMapTy = DenseMap<GlobalValue::GUID, GlobalValueSummary *>;
|
||||
|
||||
/// A set of global value summary pointers.
|
||||
using GVSummaryPtrSet = SmallPtrSet<GlobalValueSummary *, 4>;
|
||||
using GVSummaryPtrSet = std::unordered_set<GlobalValueSummary *>;
|
||||
|
||||
/// Map of a type GUID to type id string and summary (multimap used
|
||||
/// in case of GUID conflicts).
|
||||
|
@ -271,12 +271,13 @@ public:
|
||||
const lto::InputFile &File);
|
||||
|
||||
/**
|
||||
* Compute the list of summaries needed for importing into module.
|
||||
* Compute the list of summaries and the subset of declaration summaries
|
||||
* needed for importing into module.
|
||||
*/
|
||||
void gatherImportedSummariesForModule(
|
||||
Module &Module, ModuleSummaryIndex &Index,
|
||||
std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex,
|
||||
const lto::InputFile &File);
|
||||
GVSummaryPtrSet &DecSummaries, const lto::InputFile &File);
|
||||
|
||||
/**
|
||||
* Perform internalization. Index is updated to reflect linkage changes.
|
||||
|
@ -214,11 +214,15 @@ bool convertToDeclaration(GlobalValue &GV);
|
||||
/// \p ModuleToSummariesForIndex will be populated with the needed summaries
|
||||
/// from each required module path. Use a std::map instead of StringMap to get
|
||||
/// stable order for bitcode emission.
|
||||
///
|
||||
/// \p DecSummaries will be popluated with the subset of of summary pointers
|
||||
/// that have 'declaration' import type among all summaries the module need.
|
||||
void gatherImportedSummariesForModule(
|
||||
StringRef ModulePath,
|
||||
const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
|
||||
const FunctionImporter::ImportMapTy &ImportList,
|
||||
std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex);
|
||||
std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex,
|
||||
GVSummaryPtrSet &DecSummaries);
|
||||
|
||||
/// Emit into \p OutputFilename the files module \p ModulePath will import from.
|
||||
std::error_code EmitImportsFiles(
|
||||
|
@ -425,6 +425,11 @@ class IndexBitcodeWriter : public BitcodeWriterBase {
|
||||
/// The combined index to write to bitcode.
|
||||
const ModuleSummaryIndex &Index;
|
||||
|
||||
/// When writing combined summaries, provides the set of global value
|
||||
/// summaries for which the value (function, function alias, etc) should be
|
||||
/// imported as a declaration.
|
||||
const GVSummaryPtrSet *DecSummaries = nullptr;
|
||||
|
||||
/// When writing a subset of the index for distributed backends, client
|
||||
/// provides a map of modules to the corresponding GUIDs/summaries to write.
|
||||
const std::map<std::string, GVSummaryMapTy> *ModuleToSummariesForIndex;
|
||||
@ -453,11 +458,16 @@ public:
|
||||
/// Constructs a IndexBitcodeWriter object for the given combined index,
|
||||
/// writing to the provided \p Buffer. When writing a subset of the index
|
||||
/// for a distributed backend, provide a \p ModuleToSummariesForIndex map.
|
||||
/// If provided, \p DecSummaries specifies the set of summaries for which
|
||||
/// the corresponding functions or aliased functions should be imported as a
|
||||
/// declaration (but not definition) for each module.
|
||||
IndexBitcodeWriter(BitstreamWriter &Stream, StringTableBuilder &StrtabBuilder,
|
||||
const ModuleSummaryIndex &Index,
|
||||
const GVSummaryPtrSet *DecSummaries = nullptr,
|
||||
const std::map<std::string, GVSummaryMapTy>
|
||||
*ModuleToSummariesForIndex = nullptr)
|
||||
: BitcodeWriterBase(Stream, StrtabBuilder), Index(Index),
|
||||
DecSummaries(DecSummaries),
|
||||
ModuleToSummariesForIndex(ModuleToSummariesForIndex) {
|
||||
|
||||
// See if the StackIdIndex was already added to the StackId map and
|
||||
@ -1226,7 +1236,8 @@ static uint64_t getEncodedFFlags(FunctionSummary::FFlags Flags) {
|
||||
|
||||
// Decode the flags for GlobalValue in the summary. See getDecodedGVSummaryFlags
|
||||
// in BitcodeReader.cpp.
|
||||
static uint64_t getEncodedGVSummaryFlags(GlobalValueSummary::GVFlags Flags) {
|
||||
static uint64_t getEncodedGVSummaryFlags(GlobalValueSummary::GVFlags Flags,
|
||||
bool ImportAsDecl = false) {
|
||||
uint64_t RawFlags = 0;
|
||||
|
||||
RawFlags |= Flags.NotEligibleToImport; // bool
|
||||
@ -1241,7 +1252,8 @@ static uint64_t getEncodedGVSummaryFlags(GlobalValueSummary::GVFlags Flags) {
|
||||
|
||||
RawFlags |= (Flags.Visibility << 8); // 2 bits
|
||||
|
||||
RawFlags |= (Flags.ImportType << 10); // 1 bit
|
||||
unsigned ImportType = Flags.ImportType | ImportAsDecl;
|
||||
RawFlags |= (ImportType << 10); // 1 bit
|
||||
|
||||
return RawFlags;
|
||||
}
|
||||
@ -4568,6 +4580,12 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
|
||||
unsigned AllocAbbrev = Stream.EmitAbbrev(std::move(Abbv));
|
||||
|
||||
auto shouldImportValueAsDecl = [&](GlobalValueSummary *GVS) -> bool {
|
||||
if (DecSummaries == nullptr)
|
||||
return false;
|
||||
return DecSummaries->count(GVS);
|
||||
};
|
||||
|
||||
// The aliases are emitted as a post-pass, and will point to the value
|
||||
// id of the aliasee. Save them in a vector for post-processing.
|
||||
SmallVector<AliasSummary *, 64> Aliases;
|
||||
@ -4678,7 +4696,8 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
|
||||
NameVals.push_back(*ValueId);
|
||||
assert(ModuleIdMap.count(FS->modulePath()));
|
||||
NameVals.push_back(ModuleIdMap[FS->modulePath()]);
|
||||
NameVals.push_back(getEncodedGVSummaryFlags(FS->flags()));
|
||||
NameVals.push_back(
|
||||
getEncodedGVSummaryFlags(FS->flags(), shouldImportValueAsDecl(FS)));
|
||||
NameVals.push_back(FS->instCount());
|
||||
NameVals.push_back(getEncodedFFlags(FS->fflags()));
|
||||
NameVals.push_back(FS->entryCount());
|
||||
@ -4727,7 +4746,8 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
|
||||
NameVals.push_back(AliasValueId);
|
||||
assert(ModuleIdMap.count(AS->modulePath()));
|
||||
NameVals.push_back(ModuleIdMap[AS->modulePath()]);
|
||||
NameVals.push_back(getEncodedGVSummaryFlags(AS->flags()));
|
||||
NameVals.push_back(
|
||||
getEncodedGVSummaryFlags(AS->flags(), shouldImportValueAsDecl(AS)));
|
||||
auto AliaseeValueId = SummaryToValueIdMap[&AS->getAliasee()];
|
||||
assert(AliaseeValueId);
|
||||
NameVals.push_back(AliaseeValueId);
|
||||
@ -5068,8 +5088,9 @@ void BitcodeWriter::writeModule(const Module &M,
|
||||
|
||||
void BitcodeWriter::writeIndex(
|
||||
const ModuleSummaryIndex *Index,
|
||||
const std::map<std::string, GVSummaryMapTy> *ModuleToSummariesForIndex) {
|
||||
IndexBitcodeWriter IndexWriter(*Stream, StrtabBuilder, *Index,
|
||||
const std::map<std::string, GVSummaryMapTy> *ModuleToSummariesForIndex,
|
||||
const GVSummaryPtrSet *DecSummaries) {
|
||||
IndexBitcodeWriter IndexWriter(*Stream, StrtabBuilder, *Index, DecSummaries,
|
||||
ModuleToSummariesForIndex);
|
||||
IndexWriter.write();
|
||||
}
|
||||
@ -5124,12 +5145,13 @@ void IndexBitcodeWriter::write() {
|
||||
// index for a distributed backend, provide a \p ModuleToSummariesForIndex map.
|
||||
void llvm::writeIndexToFile(
|
||||
const ModuleSummaryIndex &Index, raw_ostream &Out,
|
||||
const std::map<std::string, GVSummaryMapTy> *ModuleToSummariesForIndex) {
|
||||
const std::map<std::string, GVSummaryMapTy> *ModuleToSummariesForIndex,
|
||||
const GVSummaryPtrSet *DecSummaries) {
|
||||
SmallVector<char, 0> Buffer;
|
||||
Buffer.reserve(256 * 1024);
|
||||
|
||||
BitcodeWriter Writer(Buffer);
|
||||
Writer.writeIndex(&Index, ModuleToSummariesForIndex);
|
||||
Writer.writeIndex(&Index, ModuleToSummariesForIndex, DecSummaries);
|
||||
Writer.writeStrtab();
|
||||
|
||||
Out.write((char *)&Buffer.front(), Buffer.size());
|
||||
|
@ -1400,18 +1400,20 @@ public:
|
||||
llvm::StringRef ModulePath,
|
||||
const std::string &NewModulePath) {
|
||||
std::map<std::string, GVSummaryMapTy> ModuleToSummariesForIndex;
|
||||
GVSummaryPtrSet DeclarationSummaries;
|
||||
|
||||
std::error_code EC;
|
||||
gatherImportedSummariesForModule(ModulePath, ModuleToDefinedGVSummaries,
|
||||
ImportList, ModuleToSummariesForIndex);
|
||||
ImportList, ModuleToSummariesForIndex,
|
||||
DeclarationSummaries);
|
||||
|
||||
raw_fd_ostream OS(NewModulePath + ".thinlto.bc", EC,
|
||||
sys::fs::OpenFlags::OF_None);
|
||||
if (EC)
|
||||
return errorCodeToError(EC);
|
||||
|
||||
// TODO: Serialize declaration bits to bitcode.
|
||||
writeIndexToFile(CombinedIndex, OS, &ModuleToSummariesForIndex);
|
||||
writeIndexToFile(CombinedIndex, OS, &ModuleToSummariesForIndex,
|
||||
&DeclarationSummaries);
|
||||
|
||||
if (ShouldEmitImportsFiles) {
|
||||
EC = EmitImportsFiles(ModulePath, NewModulePath + ".imports",
|
||||
|
@ -767,7 +767,7 @@ void ThinLTOCodeGenerator::crossModuleImport(Module &TheModule,
|
||||
void ThinLTOCodeGenerator::gatherImportedSummariesForModule(
|
||||
Module &TheModule, ModuleSummaryIndex &Index,
|
||||
std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex,
|
||||
const lto::InputFile &File) {
|
||||
GVSummaryPtrSet &DecSummaries, const lto::InputFile &File) {
|
||||
auto ModuleCount = Index.modulePaths().size();
|
||||
auto ModuleIdentifier = TheModule.getModuleIdentifier();
|
||||
|
||||
@ -797,7 +797,7 @@ void ThinLTOCodeGenerator::gatherImportedSummariesForModule(
|
||||
|
||||
llvm::gatherImportedSummariesForModule(
|
||||
ModuleIdentifier, ModuleToDefinedGVSummaries,
|
||||
ImportLists[ModuleIdentifier], ModuleToSummariesForIndex);
|
||||
ImportLists[ModuleIdentifier], ModuleToSummariesForIndex, DecSummaries);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -833,10 +833,14 @@ void ThinLTOCodeGenerator::emitImports(Module &TheModule, StringRef OutputName,
|
||||
IsPrevailing(PrevailingCopy), ImportLists,
|
||||
ExportLists);
|
||||
|
||||
// 'EmitImportsFiles' emits the list of modules from which to import from, and
|
||||
// the set of keys in `ModuleToSummariesForIndex` should be a superset of keys
|
||||
// in `DecSummaries`, so no need to use `DecSummaries` in `EmitImportFiles`.
|
||||
GVSummaryPtrSet DecSummaries;
|
||||
std::map<std::string, GVSummaryMapTy> ModuleToSummariesForIndex;
|
||||
llvm::gatherImportedSummariesForModule(
|
||||
ModuleIdentifier, ModuleToDefinedGVSummaries,
|
||||
ImportLists[ModuleIdentifier], ModuleToSummariesForIndex);
|
||||
ImportLists[ModuleIdentifier], ModuleToSummariesForIndex, DecSummaries);
|
||||
|
||||
std::error_code EC;
|
||||
if ((EC = EmitImportsFiles(ModuleIdentifier, OutputName,
|
||||
|
@ -1421,7 +1421,8 @@ void llvm::gatherImportedSummariesForModule(
|
||||
StringRef ModulePath,
|
||||
const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
|
||||
const FunctionImporter::ImportMapTy &ImportList,
|
||||
std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex) {
|
||||
std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex,
|
||||
GVSummaryPtrSet &DecSummaries) {
|
||||
// Include all summaries from the importing module.
|
||||
ModuleToSummariesForIndex[std::string(ModulePath)] =
|
||||
ModuleToDefinedGVSummaries.lookup(ModulePath);
|
||||
@ -1436,7 +1437,7 @@ void llvm::gatherImportedSummariesForModule(
|
||||
assert(DS != DefinedGVSummaries.end() &&
|
||||
"Expected a defined summary for imported global value");
|
||||
if (Type == GlobalValueSummary::Declaration)
|
||||
continue;
|
||||
DecSummaries.insert(DS->second);
|
||||
|
||||
SummariesForIndex[GUID] = DS->second;
|
||||
}
|
||||
|
@ -15,16 +15,20 @@
|
||||
; and the other one is larger. Both callees of 'small_func' are defined in lib.ll.
|
||||
; - Given the import limit, in main's combined summary, the import type of 'small_func'
|
||||
; and 'small_indirect_callee' will be 'definition', and the import type of
|
||||
; 'large_func' and 'large_indirect_callee' will be 'declaration'.
|
||||
; large* functions and their aliasees will be 'declaration'.
|
||||
;
|
||||
; The test will disassemble combined summaries and check the import type is
|
||||
; correct. Right now postlink optimizer pipeline doesn't do anything (e.g.,
|
||||
; import the declaration or de-serialize summary attributes yet) so there is
|
||||
; nothing to test more than the summary content.
|
||||
;
|
||||
; TODO: Extend this test case to test IR once postlink optimizer makes use of
|
||||
; the import type for declarations.
|
||||
;
|
||||
; RUN: llvm-lto2 run \
|
||||
; RUN: -debug-only=function-import \
|
||||
; RUN: -import-instr-limit=7 \
|
||||
; RUN: -import-instr-evolution-factor=1.0 \
|
||||
; RUN: -import-declaration \
|
||||
; RUN: -thinlto-distributed-indexes \
|
||||
; RUN: -r=main.bc,main,px \
|
||||
@ -32,36 +36,45 @@
|
||||
; RUN: -r=main.bc,large_func, \
|
||||
; RUN: -r=lib.bc,callee,pl \
|
||||
; RUN: -r=lib.bc,large_indirect_callee,px \
|
||||
; RUN: -r=lib.bc,large_indirect_bar,px \
|
||||
; RUN: -r=lib.bc,small_func,px \
|
||||
; RUN: -r=lib.bc,large_func,px \
|
||||
; RUN: -r=lib.bc,large_indirect_callee_alias,px \
|
||||
; RUN: -r=lib.bc,calleeAddrs,px -o summary main.bc lib.bc 2>&1 | FileCheck %s --check-prefix=DUMP
|
||||
; RUN: -r=lib.bc,large_indirect_bar_alias,px \
|
||||
; RUN: -r=lib.bc,calleeAddrs,px -r=lib.bc,calleeAddrs2,px -o summary main.bc lib.bc 2>&1 | FileCheck %s --check-prefix=DUMP
|
||||
;
|
||||
; RUN: llvm-lto -thinlto-action=thinlink -import-declaration -import-instr-limit=7 -o combined.index.bc main.bc lib.bc
|
||||
; RUN: llvm-lto -thinlto-action=distributedindexes -debug-only=function-import -import-declaration -import-instr-limit=7 -thinlto-index combined.index.bc main.bc lib.bc 2>&1 | FileCheck %s --check-prefix=DUMP
|
||||
; RUN: llvm-lto -thinlto-action=thinlink -import-declaration -import-instr-limit=7 -import-instr-evolution-factor=1.0 -o combined.index.bc main.bc lib.bc
|
||||
; RUN: llvm-lto -thinlto-action=distributedindexes -debug-only=function-import -import-declaration -import-instr-limit=7 -import-instr-evolution-factor=1.0 -thinlto-index combined.index.bc main.bc lib.bc 2>&1 | FileCheck %s --check-prefix=DUMP
|
||||
|
||||
; DUMP: - 2 function definitions and 3 function declarations imported from lib.bc
|
||||
; DUMP: - 2 function definitions and 4 function declarations imported from lib.bc
|
||||
|
||||
; First disassemble per-module summary and find out the GUID for {large_func, large_indirect_callee}.
|
||||
;
|
||||
; RUN: llvm-dis lib.bc -o - | FileCheck %s --check-prefix=LIB-DIS
|
||||
; LIB-DIS: [[LARGEFUNC:\^[0-9]+]] = gv: (name: "large_func", summaries: {{.*}}) ; guid = 2418497564662708935
|
||||
; LIB-DIS: module: (path: "lib.bc", hash: (0, 0, 0, 0, 0))
|
||||
; LIB-DIS: gv: (name: "large_func", summaries: {{.*}}) ; guid = 2418497564662708935
|
||||
; LIB-DIS: gv: (name: "large_indirect_bar_alias", summaries: {{.*}}, aliasee: [[LARGEINDIRECT_BAR:\^[0-9]+]]{{.*}}guid = 13590951773474913315
|
||||
; LIB-DIS: [[LARGEINDIRECT_BAR]] = gv: (name: "large_indirect_bar", summaries: {{.*}}) ; guid = 13770917885399536773
|
||||
; LIB-DIS: [[LARGEINDIRECT:\^[0-9]+]] = gv: (name: "large_indirect_callee", summaries: {{.*}}) ; guid = 14343440786664691134
|
||||
; LIB-DIS: [[LARGEINDIRECTALIAS:\^[0-9]+]] = gv: (name: "large_indirect_callee_alias", summaries: {{.*}}, aliasee: [[LARGEINDIRECT]]
|
||||
; LIB-DIS: gv: (name: "large_indirect_callee_alias", summaries: {{.*}}, aliasee: [[LARGEINDIRECT]]{{.*}}guid = 16730173943625350469
|
||||
;
|
||||
; Secondly disassemble main's combined summary and test that large callees are
|
||||
; not imported as declarations yet.
|
||||
; Secondly disassemble main's combined summary and verify the import type of
|
||||
; these two GUIDs are declaration.
|
||||
;
|
||||
; RUN: llvm-dis main.bc.thinlto.bc -o - | FileCheck %s --check-prefix=MAIN-DIS
|
||||
;
|
||||
; MAIN-DIS: [[LIBMOD:\^[0-9]+]] = module: (path: "lib.bc", hash: (0, 0, 0, 0, 0))
|
||||
; MAIN-DIS-NOT: [[LARGEFUNC:\^[0-9]+]] = gv: (guid: 2418497564662708935, summaries: (function: (module: [[LIBMOD]], flags: ({{.*}} importType: declaration), insts: 8, {{.*}})))
|
||||
; MAIN-DIS-NOT: [[LARGEINDIRECT:\^[0-9]+]] = gv: (guid: 14343440786664691134, summaries: (function: (module: [[LIBMOD]], flags: ({{.*}} importType: declaration), insts: 8, {{.*}})))
|
||||
; MAIN-DIS-NOT: [[LARGEINDIRECTALIAS:\^[0-9]+]] = gv: (guid: 16730173943625350469, summaries: (alias: (module: [[LIBMOD]], flags: ({{.*}} importType: declaration)
|
||||
; MAIN-DIS: gv: (guid: 2418497564662708935, summaries: (function: (module: [[LIBMOD]], flags: ({{.*}} importType: declaration), insts: 8, {{.*}})))
|
||||
; When alias is imported as a copy of the aliasee, but the aliasee is not being
|
||||
; imported by itself, the aliasee should be null.
|
||||
; MAIN-DIS: gv: (guid: 13590951773474913315, summaries: (alias: (module: [[LIBMOD]], flags: ({{.*}} importType: declaration), aliasee: null)))
|
||||
; MAIN-DIS: [[LARGEINDIRECT:\^[0-9]+]] = gv: (guid: 14343440786664691134, summaries: (function: (module: [[LIBMOD]], flags: ({{.*}} importType: declaration), insts: 8, {{.*}})))
|
||||
; MAIN-DIS: gv: (guid: 16730173943625350469, summaries: (alias: (module: [[LIBMOD]], flags: ({{.*}} importType: declaration), aliasee: [[LARGEINDIRECT]])))
|
||||
|
||||
; Run in-process ThinLTO and tests that
|
||||
; 1. `callee` remains internalized even if the symbols of its callers
|
||||
; (large_func and large_indirect_callee) are exported as declarations and visible to main module.
|
||||
; (large_func, large_indirect_callee, large_indirect_bar) are exported as
|
||||
; declarations and visible to main module.
|
||||
; 2. the debugging logs from `function-import` pass are expected.
|
||||
|
||||
; RUN: llvm-lto2 run \
|
||||
@ -69,20 +82,21 @@
|
||||
; RUN: -save-temps \
|
||||
; RUN: -thinlto-threads=1 \
|
||||
; RUN: -import-instr-limit=7 \
|
||||
; RUN: -import-instr-evolution-factor=1.0 \
|
||||
; RUN: -import-declaration \
|
||||
; RUN: -r=main.bc,main,px \
|
||||
; RUN: -r=main.bc,small_func, \
|
||||
; RUN: -r=main.bc,large_func, \
|
||||
; RUN: -r=lib.bc,callee,pl \
|
||||
; RUN: -r=lib.bc,large_indirect_callee,px \
|
||||
; RUN: -r=lib.bc,large_indirect_bar,px \
|
||||
; RUN: -r=lib.bc,small_func,px \
|
||||
; RUN: -r=lib.bc,large_func,px \
|
||||
; RUN: -r=lib.bc,large_indirect_callee_alias,px \
|
||||
; RUN: -r=lib.bc,calleeAddrs,px -o in-process main.bc lib.bc 2>&1 | FileCheck %s --check-prefix=IMPORTDUMP
|
||||
; RUN: -r=lib.bc,large_indirect_bar_alias,px \
|
||||
; RUN: -r=lib.bc,calleeAddrs,px -r=lib.bc,calleeAddrs2,px -o in-process main.bc lib.bc 2>&1 | FileCheck %s --check-prefix=IMPORTDUMP
|
||||
|
||||
; Test import status from debugging logs.
|
||||
; TODO: Serialize declaration bit and test declaration bits are correctly set,
|
||||
; and extend this test case to test IR once postlink optimizer makes use of
|
||||
; TODO: Extend this test case to test IR once postlink optimizer makes use of
|
||||
; the import type for declarations.
|
||||
; IMPORTDUMP-DAG: Not importing function 11825436545918268459 callee from lib.cc
|
||||
; IMPORTDUMP-DAG: Is importing function declaration 14343440786664691134 large_indirect_callee from lib.cc
|
||||
@ -91,6 +105,8 @@
|
||||
; IMPORTDUMP-DAG: Is importing function declaration 2418497564662708935 large_func from lib.cc
|
||||
; IMPORTDUMP-DAG: Not importing global 7680325410415171624 calleeAddrs from lib.cc
|
||||
; IMPORTDUMP-DAG: Is importing alias declaration 16730173943625350469 large_indirect_callee_alias from lib.cc
|
||||
; IMPORTDUMP-DAG: Is importing alias declaration 13590951773474913315 large_indirect_bar_alias from lib.cc
|
||||
; IMPORTDUMP-DAG: Not importing function 13770917885399536773 large_indirect_bar
|
||||
|
||||
; RUN: llvm-dis in-process.1.3.import.bc -o - | FileCheck %s --check-prefix=IMPORT
|
||||
|
||||
@ -101,6 +117,8 @@
|
||||
; IMPORT-DAG: declare void @large_func
|
||||
; IMPORT-NOT: large_indirect_callee
|
||||
; IMPORT-NOT: large_indirect_callee_alias
|
||||
; IMPORT-NOT: large_indirect_bar
|
||||
; IMPORT-NOT: large_indirect_bar_alias
|
||||
|
||||
; INTERNALIZE: define internal void @callee()
|
||||
|
||||
@ -124,8 +142,13 @@ source_filename = "lib.cc"
|
||||
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
; Both large_indirect_callee and large_indirect_callee_alias are referenced
|
||||
; and visible to main.ll.
|
||||
@calleeAddrs = global [3 x ptr] [ptr @large_indirect_callee, ptr @small_indirect_callee, ptr @large_indirect_callee_alias]
|
||||
|
||||
; large_indirect_bar_alias is visible to main.ll but its aliasee isn't.
|
||||
@calleeAddrs2 = global [1 x ptr] [ptr @large_indirect_bar_alias]
|
||||
|
||||
define void @callee() #1 {
|
||||
ret void
|
||||
}
|
||||
@ -141,12 +164,28 @@ define void @large_indirect_callee()#2 {
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @large_indirect_bar()#2 {
|
||||
call void @callee()
|
||||
call void @callee()
|
||||
call void @callee()
|
||||
call void @callee()
|
||||
call void @callee()
|
||||
call void @callee()
|
||||
call void @callee()
|
||||
ret void
|
||||
}
|
||||
|
||||
define internal void @small_indirect_callee() #0 {
|
||||
entry:
|
||||
%0 = load ptr, ptr @calleeAddrs2
|
||||
call void %0(), !prof !3
|
||||
ret void
|
||||
}
|
||||
|
||||
@large_indirect_callee_alias = alias void(), ptr @large_indirect_callee
|
||||
|
||||
@large_indirect_bar_alias = alias void(), ptr @large_indirect_bar
|
||||
|
||||
define void @small_func() {
|
||||
entry:
|
||||
%0 = load ptr, ptr @calleeAddrs
|
||||
@ -179,3 +218,4 @@ attributes #2 = { norecurse }
|
||||
!0 = !{!"VP", i32 0, i64 1, i64 14343440786664691134, i64 1}
|
||||
!1 = !{!"VP", i32 0, i64 1, i64 13568239288960714650, i64 1}
|
||||
!2 = !{!"VP", i32 0, i64 1, i64 16730173943625350469, i64 1}
|
||||
!3 = !{!"VP", i32 0, i64 1, i64 13590951773474913315, i64 1}
|
||||
|
@ -692,8 +692,9 @@ private:
|
||||
// Build a map of module to the GUIDs and summary objects that should
|
||||
// be written to its index.
|
||||
std::map<std::string, GVSummaryMapTy> ModuleToSummariesForIndex;
|
||||
GVSummaryPtrSet DecSummaries;
|
||||
ThinGenerator.gatherImportedSummariesForModule(
|
||||
*TheModule, *Index, ModuleToSummariesForIndex, *Input);
|
||||
*TheModule, *Index, ModuleToSummariesForIndex, DecSummaries, *Input);
|
||||
|
||||
std::string OutputName = OutputFilename;
|
||||
if (OutputName.empty()) {
|
||||
@ -703,7 +704,7 @@ private:
|
||||
std::error_code EC;
|
||||
raw_fd_ostream OS(OutputName, EC, sys::fs::OpenFlags::OF_None);
|
||||
error(EC, "error opening the file '" + OutputName + "'");
|
||||
writeIndexToFile(*Index, OS, &ModuleToSummariesForIndex);
|
||||
writeIndexToFile(*Index, OS, &ModuleToSummariesForIndex, &DecSummaries);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user