mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-08 21:10:35 +00:00
(NFC) Track global summary liveness in GVFlags.
Replace GVFlags::LiveRoot with GVFlags::Live and use that instead of all the DeadSymbols sets. This is refactoring in order to make liveness information available in the RegularLTO pipeline. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@304466 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
cbf8bcc206
commit
ccb80b9c0f
@ -134,16 +134,18 @@ public:
|
||||
/// be renamed or references something that can't be renamed).
|
||||
unsigned NotEligibleToImport : 1;
|
||||
|
||||
/// Indicate that the global value must be considered a live root for
|
||||
/// index-based liveness analysis. Used for special LLVM values such as
|
||||
/// llvm.global_ctors that the linker does not know about.
|
||||
unsigned LiveRoot : 1;
|
||||
/// In per-module summary, indicate that the global value must be considered
|
||||
/// a live root for index-based liveness analysis. Used for special LLVM
|
||||
/// values such as llvm.global_ctors that the linker does not know about.
|
||||
///
|
||||
/// In combined summary, indicate that the global value is live.
|
||||
unsigned Live : 1;
|
||||
|
||||
/// Convenience Constructors
|
||||
explicit GVFlags(GlobalValue::LinkageTypes Linkage,
|
||||
bool NotEligibleToImport, bool LiveRoot)
|
||||
bool NotEligibleToImport, bool Live)
|
||||
: Linkage(Linkage), NotEligibleToImport(NotEligibleToImport),
|
||||
LiveRoot(LiveRoot) {}
|
||||
Live(Live) {}
|
||||
};
|
||||
|
||||
private:
|
||||
@ -172,6 +174,8 @@ private:
|
||||
/// are listed in the derived FunctionSummary object.
|
||||
std::vector<ValueInfo> RefEdgeList;
|
||||
|
||||
bool isLive() const { return Flags.Live; }
|
||||
|
||||
protected:
|
||||
GlobalValueSummary(SummaryKind K, GVFlags Flags, std::vector<ValueInfo> Refs)
|
||||
: Kind(K), Flags(Flags), RefEdgeList(std::move(Refs)) {}
|
||||
@ -213,19 +217,17 @@ public:
|
||||
/// Return true if this global value can't be imported.
|
||||
bool notEligibleToImport() const { return Flags.NotEligibleToImport; }
|
||||
|
||||
/// Return true if this global value must be considered a root for live
|
||||
/// value analysis on the index.
|
||||
bool liveRoot() const { return Flags.LiveRoot; }
|
||||
|
||||
/// Flag that this global value must be considered a root for live
|
||||
/// value analysis on the index.
|
||||
void setLiveRoot() { Flags.LiveRoot = true; }
|
||||
void setLive(bool Live) { Flags.Live = Live; }
|
||||
|
||||
/// Flag that this global value cannot be imported.
|
||||
void setNotEligibleToImport() { Flags.NotEligibleToImport = true; }
|
||||
|
||||
/// Return the list of values referenced by this global value definition.
|
||||
ArrayRef<ValueInfo> refs() const { return RefEdgeList; }
|
||||
|
||||
friend class ModuleSummaryIndex;
|
||||
friend void computeDeadSymbols(class ModuleSummaryIndex &,
|
||||
const DenseSet<GlobalValue::GUID> &);
|
||||
};
|
||||
|
||||
/// \brief Alias summary information.
|
||||
@ -535,6 +537,11 @@ private:
|
||||
/// GUIDs, it will be mapped to 0.
|
||||
std::map<GlobalValue::GUID, GlobalValue::GUID> OidGuidMap;
|
||||
|
||||
/// Indicates that summary-based GlobalValue GC has run, and values with
|
||||
/// GVFlags::Live==false are really dead. Otherwise, all values must be
|
||||
/// considered live.
|
||||
bool WithGlobalValueDeadStripping = false;
|
||||
|
||||
// YAML I/O support.
|
||||
friend yaml::MappingTraits<ModuleSummaryIndex>;
|
||||
|
||||
@ -550,6 +557,17 @@ public:
|
||||
const_gvsummary_iterator end() const { return GlobalValueMap.end(); }
|
||||
size_t size() const { return GlobalValueMap.size(); }
|
||||
|
||||
bool withGlobalValueDeadStripping() const {
|
||||
return WithGlobalValueDeadStripping;
|
||||
}
|
||||
void setWithGlobalValueDeadStripping() {
|
||||
WithGlobalValueDeadStripping = true;
|
||||
}
|
||||
|
||||
bool isGlobalValueLive(const GlobalValueSummary *GVS) const {
|
||||
return !WithGlobalValueDeadStripping || GVS->isLive();
|
||||
}
|
||||
|
||||
/// Return a ValueInfo for GUID if it exists, otherwise return ValueInfo().
|
||||
ValueInfo getValueInfo(GlobalValue::GUID GUID) const {
|
||||
auto I = GlobalValueMap.find(GUID);
|
||||
|
@ -81,15 +81,11 @@ public:
|
||||
/// \p ExportLists contains for each Module the set of globals (GUID) that will
|
||||
/// be imported by another module, or referenced by such a function. I.e. this
|
||||
/// is the set of globals that need to be promoted/renamed appropriately.
|
||||
///
|
||||
/// \p DeadSymbols (optional) contains a list of GUID that are deemed "dead" and
|
||||
/// will be ignored for the purpose of importing.
|
||||
void ComputeCrossModuleImport(
|
||||
const ModuleSummaryIndex &Index,
|
||||
const StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries,
|
||||
StringMap<FunctionImporter::ImportMapTy> &ImportLists,
|
||||
StringMap<FunctionImporter::ExportSetTy> &ExportLists,
|
||||
const DenseSet<GlobalValue::GUID> *DeadSymbols = nullptr);
|
||||
StringMap<FunctionImporter::ExportSetTy> &ExportLists);
|
||||
|
||||
/// Compute all the imports for the given module using the Index.
|
||||
///
|
||||
@ -102,9 +98,9 @@ void ComputeCrossModuleImportForModule(
|
||||
/// Compute all the symbols that are "dead": i.e these that can't be reached
|
||||
/// in the graph from any of the given symbols listed in
|
||||
/// \p GUIDPreservedSymbols.
|
||||
DenseSet<GlobalValue::GUID>
|
||||
computeDeadSymbols(const ModuleSummaryIndex &Index,
|
||||
const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols);
|
||||
void computeDeadSymbols(
|
||||
ModuleSummaryIndex &Index,
|
||||
const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols);
|
||||
|
||||
/// Compute the set of summaries needed for a ThinLTO backend compilation of
|
||||
/// \p ModulePath.
|
||||
|
@ -275,7 +275,7 @@ computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M,
|
||||
// FIXME: refactor this to use the same code that inliner is using.
|
||||
F.isVarArg();
|
||||
GlobalValueSummary::GVFlags Flags(F.getLinkage(), NotEligibleForImport,
|
||||
/* LiveRoot = */ false);
|
||||
/* Live = */ false);
|
||||
auto FuncSummary = llvm::make_unique<FunctionSummary>(
|
||||
Flags, NumInsts, RefEdges.takeVector(), CallGraphEdges.takeVector(),
|
||||
TypeTests.takeVector(), TypeTestAssumeVCalls.takeVector(),
|
||||
@ -295,7 +295,7 @@ computeVariableSummary(ModuleSummaryIndex &Index, const GlobalVariable &V,
|
||||
findRefEdges(Index, &V, RefEdges, Visited);
|
||||
bool NonRenamableLocal = isNonRenamableLocal(V);
|
||||
GlobalValueSummary::GVFlags Flags(V.getLinkage(), NonRenamableLocal,
|
||||
/* LiveRoot = */ false);
|
||||
/* Live = */ false);
|
||||
auto GVarSummary =
|
||||
llvm::make_unique<GlobalVarSummary>(Flags, RefEdges.takeVector());
|
||||
if (NonRenamableLocal)
|
||||
@ -308,7 +308,7 @@ computeAliasSummary(ModuleSummaryIndex &Index, const GlobalAlias &A,
|
||||
DenseSet<GlobalValue::GUID> &CantBePromoted) {
|
||||
bool NonRenamableLocal = isNonRenamableLocal(A);
|
||||
GlobalValueSummary::GVFlags Flags(A.getLinkage(), NonRenamableLocal,
|
||||
/* LiveRoot = */ false);
|
||||
/* Live = */ false);
|
||||
auto AS = llvm::make_unique<AliasSummary>(Flags, ArrayRef<ValueInfo>{});
|
||||
auto *Aliasee = A.getBaseObject();
|
||||
auto *AliaseeSummary = Index.getGlobalValueSummary(*Aliasee);
|
||||
@ -323,7 +323,7 @@ computeAliasSummary(ModuleSummaryIndex &Index, const GlobalAlias &A,
|
||||
static void setLiveRoot(ModuleSummaryIndex &Index, StringRef Name) {
|
||||
if (ValueInfo VI = Index.getValueInfo(GlobalValue::getGUID(Name)))
|
||||
for (auto &Summary : VI.getSummaryList())
|
||||
Summary->setLiveRoot();
|
||||
Summary->setLive(true);
|
||||
}
|
||||
|
||||
ModuleSummaryIndex llvm::buildModuleSummaryIndex(
|
||||
@ -423,8 +423,8 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex(
|
||||
return;
|
||||
assert(GV->isDeclaration() && "Def in module asm already has definition");
|
||||
GlobalValueSummary::GVFlags GVFlags(GlobalValue::InternalLinkage,
|
||||
/* NotEligibleToImport */ true,
|
||||
/* LiveRoot */ true);
|
||||
/* NotEligibleToImport = */ true,
|
||||
/* Live = */ true);
|
||||
CantBePromoted.insert(GlobalValue::getGUID(Name));
|
||||
// Create the appropriate summary type.
|
||||
if (isa<Function>(GV)) {
|
||||
|
@ -865,11 +865,11 @@ static GlobalValueSummary::GVFlags getDecodedGVSummaryFlags(uint64_t RawFlags,
|
||||
auto Linkage = GlobalValue::LinkageTypes(RawFlags & 0xF); // 4 bits
|
||||
RawFlags = RawFlags >> 4;
|
||||
bool NotEligibleToImport = (RawFlags & 0x1) || Version < 3;
|
||||
// The LiveRoot flag wasn't introduced until version 3. For dead stripping
|
||||
// The Live flag wasn't introduced until version 3. For dead stripping
|
||||
// to work correctly on earlier versions, we must conservatively treat all
|
||||
// values as live.
|
||||
bool LiveRoot = (RawFlags & 0x2) || Version < 3;
|
||||
return GlobalValueSummary::GVFlags(Linkage, NotEligibleToImport, LiveRoot);
|
||||
bool Live = (RawFlags & 0x2) || Version < 3;
|
||||
return GlobalValueSummary::GVFlags(Linkage, NotEligibleToImport, Live);
|
||||
}
|
||||
|
||||
static GlobalValue::VisibilityTypes getDecodedVisibility(unsigned Val) {
|
||||
|
@ -864,7 +864,7 @@ static uint64_t getEncodedGVSummaryFlags(GlobalValueSummary::GVFlags Flags) {
|
||||
uint64_t RawFlags = 0;
|
||||
|
||||
RawFlags |= Flags.NotEligibleToImport; // bool
|
||||
RawFlags |= (Flags.LiveRoot << 1);
|
||||
RawFlags |= (Flags.Live << 1);
|
||||
// Linkage don't need to be remapped at that time for the summary. Any future
|
||||
// change to the getEncodedLinkage() function will need to be taken into
|
||||
// account here as well.
|
||||
|
@ -930,6 +930,17 @@ ThinBackend lto::createWriteIndexesThinBackend(std::string OldPrefix,
|
||||
};
|
||||
}
|
||||
|
||||
static bool IsLiveByGUID(const ModuleSummaryIndex &Index,
|
||||
GlobalValue::GUID GUID) {
|
||||
auto VI = Index.getValueInfo(GUID);
|
||||
if (!VI)
|
||||
return false;
|
||||
for (auto &I : VI.getSummaryList())
|
||||
if (Index.isGlobalValueLive(I.get()))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
Error LTO::runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache,
|
||||
bool HasRegularLTO) {
|
||||
if (ThinLTO.ModuleMap.empty())
|
||||
@ -973,11 +984,10 @@ Error LTO::runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache,
|
||||
GlobalValue::dropLLVMManglingEscape(Res.second.IRName)));
|
||||
}
|
||||
|
||||
auto DeadSymbols =
|
||||
computeDeadSymbols(ThinLTO.CombinedIndex, GUIDPreservedSymbols);
|
||||
computeDeadSymbols(ThinLTO.CombinedIndex, GUIDPreservedSymbols);
|
||||
|
||||
ComputeCrossModuleImport(ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries,
|
||||
ImportLists, ExportLists, &DeadSymbols);
|
||||
ImportLists, ExportLists);
|
||||
|
||||
std::set<GlobalValue::GUID> ExportedGUIDs;
|
||||
for (auto &Res : GlobalResolutions) {
|
||||
@ -992,7 +1002,7 @@ Error LTO::runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache,
|
||||
auto GUID = GlobalValue::getGUID(
|
||||
GlobalValue::dropLLVMManglingEscape(Res.second.IRName));
|
||||
// Mark exported unless index-based analysis determined it to be dead.
|
||||
if (!DeadSymbols.count(GUID))
|
||||
if (IsLiveByGUID(ThinLTO.CombinedIndex, GUID))
|
||||
ExportedGUIDs.insert(GUID);
|
||||
}
|
||||
|
||||
|
@ -628,13 +628,13 @@ void ThinLTOCodeGenerator::promote(Module &TheModule,
|
||||
PreservedSymbols, Triple(TheModule.getTargetTriple()));
|
||||
|
||||
// Compute "dead" symbols, we don't want to import/export these!
|
||||
auto DeadSymbols = computeDeadSymbols(Index, GUIDPreservedSymbols);
|
||||
computeDeadSymbols(Index, GUIDPreservedSymbols);
|
||||
|
||||
// Generate import/export list
|
||||
StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
|
||||
StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
|
||||
ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries, ImportLists,
|
||||
ExportLists, &DeadSymbols);
|
||||
ExportLists);
|
||||
|
||||
// Resolve LinkOnce/Weak symbols.
|
||||
StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;
|
||||
@ -673,13 +673,13 @@ void ThinLTOCodeGenerator::crossModuleImport(Module &TheModule,
|
||||
PreservedSymbols, Triple(TheModule.getTargetTriple()));
|
||||
|
||||
// Compute "dead" symbols, we don't want to import/export these!
|
||||
auto DeadSymbols = computeDeadSymbols(Index, GUIDPreservedSymbols);
|
||||
computeDeadSymbols(Index, GUIDPreservedSymbols);
|
||||
|
||||
// Generate import/export list
|
||||
StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
|
||||
StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
|
||||
ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries, ImportLists,
|
||||
ExportLists, &DeadSymbols);
|
||||
ExportLists);
|
||||
auto &ImportList = ImportLists[TheModule.getModuleIdentifier()];
|
||||
|
||||
crossImportIntoModule(TheModule, Index, ModuleMap, ImportList);
|
||||
@ -750,13 +750,13 @@ void ThinLTOCodeGenerator::internalize(Module &TheModule,
|
||||
Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
|
||||
|
||||
// Compute "dead" symbols, we don't want to import/export these!
|
||||
auto DeadSymbols = computeDeadSymbols(Index, GUIDPreservedSymbols);
|
||||
computeDeadSymbols(Index, GUIDPreservedSymbols);
|
||||
|
||||
// Generate import/export list
|
||||
StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
|
||||
StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
|
||||
ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries, ImportLists,
|
||||
ExportLists, &DeadSymbols);
|
||||
ExportLists);
|
||||
auto &ExportList = ExportLists[ModuleIdentifier];
|
||||
|
||||
// Be friendly and don't nuke totally the module when the client didn't
|
||||
@ -902,14 +902,14 @@ void ThinLTOCodeGenerator::run() {
|
||||
computeGUIDPreservedSymbols(PreservedSymbols, TMBuilder.TheTriple);
|
||||
|
||||
// Compute "dead" symbols, we don't want to import/export these!
|
||||
auto DeadSymbols = computeDeadSymbols(*Index, GUIDPreservedSymbols);
|
||||
computeDeadSymbols(*Index, GUIDPreservedSymbols);
|
||||
|
||||
// Collect the import/export lists for all modules from the call-graph in the
|
||||
// combined index.
|
||||
StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
|
||||
StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
|
||||
ComputeCrossModuleImport(*Index, ModuleToDefinedGVSummaries, ImportLists,
|
||||
ExportLists, &DeadSymbols);
|
||||
ExportLists);
|
||||
|
||||
// We use a std::map here to be able to have a defined ordering when
|
||||
// producing a hash for the cache entry.
|
||||
|
@ -292,8 +292,7 @@ static void computeImportForFunction(
|
||||
static void ComputeImportForModule(
|
||||
const GVSummaryMapTy &DefinedGVSummaries, const ModuleSummaryIndex &Index,
|
||||
FunctionImporter::ImportMapTy &ImportList,
|
||||
StringMap<FunctionImporter::ExportSetTy> *ExportLists = nullptr,
|
||||
const DenseSet<GlobalValue::GUID> *DeadSymbols = nullptr) {
|
||||
StringMap<FunctionImporter::ExportSetTy> *ExportLists = nullptr) {
|
||||
// Worklist contains the list of function imported in this module, for which
|
||||
// we will analyse the callees and may import further down the callgraph.
|
||||
SmallVector<EdgeInfo, 128> Worklist;
|
||||
@ -301,7 +300,7 @@ static void ComputeImportForModule(
|
||||
// Populate the worklist with the import for the functions in the current
|
||||
// module
|
||||
for (auto &GVSummary : DefinedGVSummaries) {
|
||||
if (DeadSymbols && DeadSymbols->count(GVSummary.first)) {
|
||||
if (!Index.isGlobalValueLive(GVSummary.second)) {
|
||||
DEBUG(dbgs() << "Ignores Dead GUID: " << GVSummary.first << "\n");
|
||||
continue;
|
||||
}
|
||||
@ -344,15 +343,14 @@ void llvm::ComputeCrossModuleImport(
|
||||
const ModuleSummaryIndex &Index,
|
||||
const StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries,
|
||||
StringMap<FunctionImporter::ImportMapTy> &ImportLists,
|
||||
StringMap<FunctionImporter::ExportSetTy> &ExportLists,
|
||||
const DenseSet<GlobalValue::GUID> *DeadSymbols) {
|
||||
StringMap<FunctionImporter::ExportSetTy> &ExportLists) {
|
||||
// For each module that has function defined, compute the import/export lists.
|
||||
for (auto &DefinedGVSummaries : ModuleToDefinedGVSummaries) {
|
||||
auto &ImportList = ImportLists[DefinedGVSummaries.first()];
|
||||
DEBUG(dbgs() << "Computing import for Module '"
|
||||
<< DefinedGVSummaries.first() << "'\n");
|
||||
ComputeImportForModule(DefinedGVSummaries.second, Index, ImportList,
|
||||
&ExportLists, DeadSymbols);
|
||||
&ExportLists);
|
||||
}
|
||||
|
||||
// When computing imports we added all GUIDs referenced by anything
|
||||
@ -414,82 +412,71 @@ void llvm::ComputeCrossModuleImportForModule(
|
||||
#endif
|
||||
}
|
||||
|
||||
DenseSet<GlobalValue::GUID> llvm::computeDeadSymbols(
|
||||
const ModuleSummaryIndex &Index,
|
||||
void llvm::computeDeadSymbols(
|
||||
ModuleSummaryIndex &Index,
|
||||
const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols) {
|
||||
assert(!Index.withGlobalValueDeadStripping());
|
||||
if (!ComputeDead)
|
||||
return DenseSet<GlobalValue::GUID>();
|
||||
return;
|
||||
if (GUIDPreservedSymbols.empty())
|
||||
// Don't do anything when nothing is live, this is friendly with tests.
|
||||
return DenseSet<GlobalValue::GUID>();
|
||||
DenseSet<ValueInfo> LiveSymbols;
|
||||
return;
|
||||
unsigned LiveSymbols = 0;
|
||||
SmallVector<ValueInfo, 128> Worklist;
|
||||
Worklist.reserve(GUIDPreservedSymbols.size() * 2);
|
||||
for (auto GUID : GUIDPreservedSymbols) {
|
||||
ValueInfo VI = Index.getValueInfo(GUID);
|
||||
if (!VI)
|
||||
continue;
|
||||
DEBUG(dbgs() << "Live root: " << VI.getGUID() << "\n");
|
||||
LiveSymbols.insert(VI);
|
||||
Worklist.push_back(VI);
|
||||
for (auto &S : VI.getSummaryList())
|
||||
S->setLive(true);
|
||||
}
|
||||
|
||||
// Add values flagged in the index as live roots to the worklist.
|
||||
for (const auto &Entry : Index) {
|
||||
bool IsLiveRoot = llvm::any_of(
|
||||
Entry.second.SummaryList,
|
||||
[&](const std::unique_ptr<llvm::GlobalValueSummary> &Summary) {
|
||||
return Summary->liveRoot();
|
||||
});
|
||||
if (!IsLiveRoot)
|
||||
continue;
|
||||
DEBUG(dbgs() << "Live root (summary): " << Entry.first << "\n");
|
||||
Worklist.push_back(ValueInfo(&Entry));
|
||||
}
|
||||
for (const auto &Entry : Index)
|
||||
for (auto &S : Entry.second.SummaryList)
|
||||
if (S->isLive()) {
|
||||
DEBUG(dbgs() << "Live root: " << Entry.first << "\n");
|
||||
Worklist.push_back(ValueInfo(&Entry));
|
||||
++LiveSymbols;
|
||||
break;
|
||||
}
|
||||
|
||||
// Make value live and add it to the worklist if it was not live before.
|
||||
// FIXME: we should only make the prevailing copy live here
|
||||
auto visit = [&](ValueInfo VI) {
|
||||
for (auto &S : VI.getSummaryList())
|
||||
if (S->isLive())
|
||||
return;
|
||||
for (auto &S : VI.getSummaryList())
|
||||
S->setLive(true);
|
||||
++LiveSymbols;
|
||||
Worklist.push_back(VI);
|
||||
};
|
||||
|
||||
while (!Worklist.empty()) {
|
||||
auto VI = Worklist.pop_back_val();
|
||||
|
||||
// FIXME: we should only make the prevailing copy live here
|
||||
for (auto &Summary : VI.getSummaryList()) {
|
||||
for (auto Ref : Summary->refs()) {
|
||||
if (LiveSymbols.insert(Ref).second) {
|
||||
DEBUG(dbgs() << "Marking live (ref): " << Ref.getGUID() << "\n");
|
||||
Worklist.push_back(Ref);
|
||||
}
|
||||
}
|
||||
if (auto *FS = dyn_cast<FunctionSummary>(Summary.get())) {
|
||||
for (auto Call : FS->calls()) {
|
||||
if (LiveSymbols.insert(Call.first).second) {
|
||||
DEBUG(dbgs() << "Marking live (call): " << Call.first.getGUID()
|
||||
<< "\n");
|
||||
Worklist.push_back(Call.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto Ref : Summary->refs())
|
||||
visit(Ref);
|
||||
if (auto *FS = dyn_cast<FunctionSummary>(Summary.get()))
|
||||
for (auto Call : FS->calls())
|
||||
visit(Call.first);
|
||||
if (auto *AS = dyn_cast<AliasSummary>(Summary.get())) {
|
||||
auto AliaseeGUID = AS->getAliasee().getOriginalName();
|
||||
ValueInfo AliaseeVI = Index.getValueInfo(AliaseeGUID);
|
||||
if (AliaseeVI && LiveSymbols.insert(AliaseeVI).second) {
|
||||
DEBUG(dbgs() << "Marking live (alias): " << AliaseeGUID << "\n");
|
||||
Worklist.push_back(AliaseeVI);
|
||||
}
|
||||
if (AliaseeVI)
|
||||
visit(AliaseeVI);
|
||||
}
|
||||
}
|
||||
}
|
||||
DenseSet<GlobalValue::GUID> DeadSymbols;
|
||||
DeadSymbols.reserve(
|
||||
std::min(Index.size(), Index.size() - LiveSymbols.size()));
|
||||
for (auto &Entry : Index) {
|
||||
if (!LiveSymbols.count(ValueInfo(&Entry))) {
|
||||
DEBUG(dbgs() << "Marking dead: " << Entry.first << "\n");
|
||||
DeadSymbols.insert(Entry.first);
|
||||
}
|
||||
}
|
||||
DEBUG(dbgs() << LiveSymbols.size() << " symbols Live, and "
|
||||
<< DeadSymbols.size() << " symbols Dead \n");
|
||||
NumDeadSymbols += DeadSymbols.size();
|
||||
NumLiveSymbols += LiveSymbols.size();
|
||||
return DeadSymbols;
|
||||
Index.setWithGlobalValueDeadStripping();
|
||||
|
||||
unsigned DeadSymbols = Index.size() - LiveSymbols;
|
||||
DEBUG(dbgs() << LiveSymbols << " symbols Live, and " << DeadSymbols
|
||||
<< " symbols Dead \n");
|
||||
NumDeadSymbols += DeadSymbols;
|
||||
NumLiveSymbols += LiveSymbols;
|
||||
}
|
||||
|
||||
/// Compute the set of summaries needed for a ThinLTO backend compilation of
|
||||
|
Loading…
Reference in New Issue
Block a user