Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 40 additions & 4 deletions llvm/include/llvm/IR/ModuleSummaryIndex.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,11 @@ struct alignas(8) GlobalValueSummaryInfo {

/// Add a summary corresponding to a global value definition in a module with
/// the corresponding GUID.
void addSummary(std::unique_ptr<GlobalValueSummary> Summary) {
return SummaryList.push_back(std::move(Summary));
}
inline void addSummary(std::unique_ptr<GlobalValueSummary> Summary);

/// Verify that the HasLocal flag is consistent with the SummaryList. Should
/// only be called prior to index-based internalization and promotion.
inline void verifyLocal() const;

private:
/// List of global value summary structures for a particular value held
Expand All @@ -183,6 +185,22 @@ struct alignas(8) GlobalValueSummaryInfo {
/// compiling without sufficient distinguishing path, or (theoretically) hash
/// collisions. Each summary is from a different module.
GlobalValueSummaryList SummaryList;

/// True if the SummaryList contains at least one summary with local linkage.
/// In most cases there should be only one, unless translation units with
/// same-named locals were compiled without distinguishing path. And generally
/// there should not be a mix of local and non-local summaries, because the
/// GUID for a local is computed with the path prepended and a ';' delimiter.
/// In extremely rare cases there could be a GUID hash collision. Having the
/// flag saves having to walk through all summaries to prove the existence or
/// not of any locals.
/// NOTE: this flag is set when the index is built. It does not reflect
/// index-based internalization and promotion decisions. Generally most
/// index-based analysis occurs before then, but any users should assert that
/// the withInternalizeAndPromote() flag is not set on the index.
/// TODO: Replace checks in various ThinLTO analyses that loop through all
/// summaries to handle the local case with a check of the flag.
bool HasLocal : 1;
};

/// Map from global value GUID to corresponding summary structures. Use a
Expand Down Expand Up @@ -219,6 +237,8 @@ struct ValueInfo {
return getRef()->second.getSummaryList();
}

void verifyLocal() const { getRef()->second.verifyLocal(); }

// Even if the index is built with GVs available, we may not have one for
// summary entries synthesized for profiled indirect call targets.
bool hasName() const { return !haveGVs() || getValue(); }
Expand Down Expand Up @@ -649,7 +669,23 @@ class GlobalValueSummary {
friend class ModuleSummaryIndex;
};

GlobalValueSummaryInfo::GlobalValueSummaryInfo(bool HaveGVs) : U(HaveGVs) {}
GlobalValueSummaryInfo::GlobalValueSummaryInfo(bool HaveGVs)
: U(HaveGVs), HasLocal(false) {}

void GlobalValueSummaryInfo::addSummary(
std::unique_ptr<GlobalValueSummary> Summary) {
if (GlobalValue::isLocalLinkage(Summary->linkage()))
HasLocal = true;
return SummaryList.push_back(std::move(Summary));
}

void GlobalValueSummaryInfo::verifyLocal() const {
assert(HasLocal ==
llvm::any_of(SummaryList,
[](const std::unique_ptr<GlobalValueSummary> &Summary) {
return GlobalValue::isLocalLinkage(Summary->linkage());
}));
}

/// Alias summary information.
class AliasSummary : public GlobalValueSummary {
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/LTO/LTO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,10 @@ static void thinLTOInternalizeAndPromoteGUID(
return !GlobalValue::isLocalLinkage(Summary->linkage());
});

// Before performing index-based internalization and promotion for this GUID,
// the local flag should be consistent with the summary list linkage types.
VI.verifyLocal();

for (auto &S : VI.getSummaryList()) {
// First see if we need to promote an internal value because it is not
// exported.
Expand Down