Skip to content
This repository has been archived by the owner on Apr 23, 2020. It is now read-only.

Commit

Permalink
(NFC) Track global summary liveness in GVFlags.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
eugenis committed Jun 1, 2017
1 parent cbf8bcc commit ccb80b9
Show file tree
Hide file tree
Showing 8 changed files with 114 additions and 103 deletions.
44 changes: 31 additions & 13 deletions include/llvm/IR/ModuleSummaryIndex.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,16 +134,18 @@ class GlobalValueSummary {
/// 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:
Expand Down Expand Up @@ -172,6 +174,8 @@ class GlobalValueSummary {
/// 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)) {}
Expand Down Expand Up @@ -213,19 +217,17 @@ class GlobalValueSummary {
/// 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.
Expand Down Expand Up @@ -535,6 +537,11 @@ class ModuleSummaryIndex {
/// 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>;

Expand All @@ -550,6 +557,17 @@ class ModuleSummaryIndex {
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);
Expand Down
12 changes: 4 additions & 8 deletions include/llvm/Transforms/IPO/FunctionImport.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,15 +81,11 @@ class FunctionImportPass : public PassInfoMixin<FunctionImportPass> {
/// \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.
///
Expand All @@ -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.
Expand Down
12 changes: 6 additions & 6 deletions lib/Analysis/ModuleSummaryAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand All @@ -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)
Expand All @@ -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);
Expand All @@ -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(
Expand Down Expand Up @@ -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)) {
Expand Down
6 changes: 3 additions & 3 deletions lib/Bitcode/Reader/BitcodeReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion lib/Bitcode/Writer/BitcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
18 changes: 14 additions & 4 deletions lib/LTO/LTO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down Expand Up @@ -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) {
Expand All @@ -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);
}

Expand Down
16 changes: 8 additions & 8 deletions lib/LTO/ThinLTOCodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down

0 comments on commit ccb80b9

Please sign in to comment.