22#define DEBUG_TYPE "module-summary-index"
25 "Number of live global variables marked read only");
27 "Number of live global variables marked write only");
33 cl::desc(
"Always rename promoted locals."));
38 cl::desc(
"Propagate attributes in index"));
42 cl::desc(
"Import constant global variables with references"));
49 bool HasProtected =
false;
63 return WithDSOLocalPropagation
68 [](
const std::unique_ptr<GlobalValueSummary> &Summary) {
69 return Summary->isDSOLocal();
77 [](
const std::unique_ptr<GlobalValueSummary> &Summary) {
78 return Summary->canAutoHide();
87 unsigned RORefCnt = 0, WORefCnt = 0;
89 for (
I = Refs.size() - 1;
I >= 0 && Refs[
I].isWriteOnly(); --
I)
91 for (;
I >= 0 && Refs[
I].isReadOnly(); --
I)
93 return {RORefCnt, WORefCnt};
123 assert(Flags <= 0x7ff &&
"Unexpected bits in flag");
172 for (
auto &GlobalList : *
this) {
173 auto GUID = GlobalList.first;
174 for (
auto &GlobSummary : GlobalList.second.getSummaryList()) {
180 if (Summary->modulePath() != ModulePath)
182 GVSummaryMap[GUID] = Summary;
189 bool PerModuleIndex)
const {
191 assert(VI &&
"GlobalValue not found in index");
192 assert((!PerModuleIndex || VI.getSummaryList().size() == 1) &&
193 "Expected a single entry per global value in per-module index");
194 auto &Summary = VI.getSummaryList()[0];
195 return Summary.get();
202 const auto &SummaryList = VI.getSummaryList();
203 if (SummaryList.empty())
205 for (
auto &
I : SummaryList)
222 for (
auto &VI : S->
refs()) {
224 if (!VI.getAccessSpecifier()) {
225 if (!MarkedNonReadWriteOnly.
insert(VI).second)
227 }
else if (MarkedNonReadWriteOnly.
contains(VI))
229 bool HasNonGVar =
false;
230 for (
auto &
Ref : VI.getSummaryList()) {
234 if (!VI.isReadOnly())
235 GVS->setReadOnly(
false);
236 if (!VI.isWriteOnly())
237 GVS->setWriteOnly(
false);
252 for (
auto &
Ref : VI.getSummaryList()) {
256 GVS->setReadOnly(
false);
257 GVS->setWriteOnly(
false);
259 MarkedNonReadWriteOnly.
insert(VI);
298 for (
auto &
P : *
this) {
299 bool IsDSOLocal =
true;
300 for (
auto &S :
P.second.getSummaryList()) {
310 P.second.getSummaryList(),
311 [&](
const std::unique_ptr<GlobalValueSummary> &Summary) {
312 return isGlobalValueLive(Summary.get());
332 GUIDPreservedSymbols.
count(
P.first)) {
333 GVS->setReadOnly(
false);
334 GVS->setWriteOnly(
false);
339 IsDSOLocal &= S->isDSOLocal();
344 for (
const std::unique_ptr<GlobalValueSummary> &Summary :
345 P.second.getSummaryList())
346 Summary->setDSOLocal(
false);
351 for (
auto &
P : *
this)
352 if (
P.second.getSummaryList().size())
354 P.second.getSummaryList()[0]->getBaseObject()))
356 if (GVS->maybeReadOnly())
358 if (GVS->maybeWriteOnly())
359 WriteOnlyLiveGVars++;
364 bool AnalyzeRefs)
const {
371 bool &CanImportDecl)
const {
392 const bool nonInterposable =
398 CanImportDecl = (nonInterposable && eligibleToImport);
405 return nonInterposable && eligibleToImport &&
406 (!AnalyzeRefs || !HasRefsPreventingImport(GVS));
416 O <<
"SCC (" <<
utostr(
I->size()) <<
" node" << (
I->size() == 1 ?
"" :
"s")
420 if (V.getSummaryList().size())
422 O <<
" " << (
F ==
nullptr ?
"External" :
"") <<
" " <<
utostr(V.getGUID())
423 << (
I.hasCycle() ?
" (has cycle)" :
"") <<
"\n";
433 void addComment(
const Twine &Comment);
434 std::string getAsString()
const;
436 std::vector<std::string> Attrs;
437 std::string Comments;
449 const Twine &Comment) {
450 std::string
A =
Name.str();
458void Attributes::addComment(
const Twine &Comment) {
459 if (!
Comment.isTriviallyEmpty()) {
460 if (Comments.empty())
468std::string Attributes::getAsString()
const {
472 std::string Ret =
"[";
473 for (
auto &
A : Attrs)
490 return "linkonce_odr";
502 return "extern_weak";
511 auto FlagValue = [](
unsigned V) {
return V ?
'1' :
'0'; };
512 char FlagRep[] = {FlagValue(
F.ReadNone),
513 FlagValue(
F.ReadOnly),
514 FlagValue(
F.NoRecurse),
515 FlagValue(
F.ReturnDoesNotAlias),
516 FlagValue(
F.NoInline),
517 FlagValue(
F.AlwaysInline),
518 FlagValue(
F.NoUnwind),
519 FlagValue(
F.MayThrow),
520 FlagValue(
F.HasUnknownCall),
521 FlagValue(
F.MustBeUnreachable),
533 return std::string(
"inst: ") + std::to_string(FS->instCount()) +
538 return std::string(
"@") + std::to_string(Id);
553 Label += std::string(
" (") + Attrs +
")";
564 auto StrId = std::to_string(Id);
565 OS <<
" " << StrId <<
" [label=\"";
572 OS <<
"\"]; // defined externally\n";
577 return GVS->maybeReadOnly();
583 return GVS->maybeWriteOnly();
589 return GVS->isConstant();
596 std::vector<Edge> CrossModuleEdges;
598 using GVSOrderedMapTy = std::map<GlobalValue::GUID, GlobalValueSummary *>;
599 std::map<StringRef, GVSOrderedMapTy> ModuleToDefinedGVS;
605 std::vector<StringRef> ModulePaths;
607 ModulePaths.push_back(ModPath);
610 for (
auto &ModPath : ModulePaths)
616 return ModId == (
uint64_t)-1 ? std::to_string(Id)
617 : std::string(
"M") + std::to_string(ModId) +
618 "_" + std::to_string(Id);
630 static const char *EdgeAttrs[] = {
631 " [style=dotted]; // alias",
632 " [style=dashed]; // ref",
633 " [style=dashed,color=forestgreen]; // const-ref",
634 " [style=dashed,color=violetred]; // writeOnly-ref",
635 " // call (hotness : Unknown)",
636 " [color=blue]; // call (hotness : Cold)",
637 " // call (hotness : None)",
638 " [color=brown]; // call (hotness : Hot)",
639 " [style=bold,color=red]; // call (hotness : Critical)"};
641 assert(
static_cast<size_t>(TypeOrHotness) < std::size(EdgeAttrs));
642 OS << Pfx << NodeId(SrcMod, SrcId) <<
" -> " << NodeId(DstMod, DstId)
643 << EdgeAttrs[TypeOrHotness] <<
"\n";
646 OS <<
"digraph Summary {\n";
647 for (
auto &ModIt : ModuleToDefinedGVS) {
651 auto ModId = ModuleIdMap.
empty() ? 0 : ModuleIdMap[ModIt.first];
652 OS <<
" // Module: " << ModIt.first <<
"\n";
653 OS <<
" subgraph cluster_" << std::to_string(ModId) <<
" {\n";
654 OS <<
" style = filled;\n";
655 OS <<
" color = lightgrey;\n";
657 OS <<
" node [style=filled,fillcolor=lightblue];\n";
659 auto &GVSMap = ModIt.second;
661 if (!GVSMap.count(IdTo)) {
662 CrossModuleEdges.push_back({ModId, Hotness, IdFrom, IdTo});
665 DrawEdge(
" ", ModId, IdFrom, ModId, IdTo, Hotness);
668 for (
auto &SummaryIt : GVSMap) {
669 NodeMap[SummaryIt.first].push_back(ModId);
670 auto Flags = SummaryIt.second->flags();
673 A.add(
"shape",
"record",
"function");
675 A.add(
"style",
"dotted,filled",
"alias");
676 A.add(
"shape",
"box");
678 A.add(
"shape",
"Mrecord",
"variable");
680 A.addComment(
"immutable");
682 A.addComment(
"writeOnly");
684 A.addComment(
"constant");
686 if (Flags.Visibility)
687 A.addComment(
"visibility");
689 A.addComment(
"dsoLocal");
690 if (Flags.CanAutoHide)
691 A.addComment(
"canAutoHide");
693 A.addComment(
"definition");
695 A.addComment(
"declaration");
696 if (Flags.NoRenameOnPromotion)
697 A.addComment(
"noRenameOnPromotion");
698 if (GUIDPreservedSymbols.
count(SummaryIt.first))
699 A.addComment(
"preserved");
704 A.add(
"fillcolor",
"red",
"dead");
705 else if (Flags.NotEligibleToImport)
706 A.add(
"fillcolor",
"yellow",
"not eligible to import");
708 OS <<
" " << NodeId(ModId, SummaryIt.first) <<
" " <<
A.getAsString()
711 OS <<
" // Edges:\n";
713 for (
auto &SummaryIt : GVSMap) {
714 auto *GVS = SummaryIt.second;
715 for (
auto &R : GVS->refs())
716 Draw(SummaryIt.first, R.getGUID(),
717 R.isWriteOnly() ? -1 : (R.isReadOnly() ? -2 : -3));
720 Draw(SummaryIt.first, AS->getAliaseeGUID(), -4);
725 for (
auto &CGEdge : FS->calls())
726 Draw(SummaryIt.first, CGEdge.first.getGUID(),
727 static_cast<int>(CGEdge.second.Hotness));
732 OS <<
" // Cross-module edges:\n";
733 for (
auto &E : CrossModuleEdges) {
734 auto &ModList = NodeMap[E.Dst];
735 if (ModList.empty()) {
739 ModList.push_back(-1);
741 for (
auto DstMod : ModList)
747 if (DstMod != E.SrcMod)
748 DrawEdge(
" ", E.SrcMod, E.Src, DstMod, E.Dst, E.Hotness);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
static std::string getNodeVisualName(GlobalValue::GUID Id)
static std::string getNodeLabel(const ValueInfo &VI, GlobalValueSummary *GVS)
static std::string getSummaryAttributes(GlobalValueSummary *GVS)
static cl::opt< bool > ImportConstantsWithRefs("import-constants-with-refs", cl::init(true), cl::Hidden, cl::desc("Import constant global variables with references"))
static std::string fflagsToString(FunctionSummary::FFlags F)
static bool hasWriteOnlyFlag(const GlobalValueSummary *S)
static void propagateAttributesToRefs(GlobalValueSummary *S, DenseSet< ValueInfo > &MarkedNonReadWriteOnly)
static std::string linkageToString(GlobalValue::LinkageTypes LT)
static void defineExternalNode(raw_ostream &OS, const char *Pfx, const ValueInfo &VI, GlobalValue::GUID Id)
static cl::opt< bool > PropagateAttrs("propagate-attrs", cl::init(true), cl::Hidden, cl::desc("Propagate attributes in index"))
static bool hasReadOnlyFlag(const GlobalValueSummary *S)
static bool hasConstantFlag(const GlobalValueSummary *S)
ModuleSummaryIndex.h This file contains the declarations the classes that hold the module index and s...
This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected components (SCCs) of a ...
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Implements a dense probed hash-table based set.
Function summary information to aid decisions and implementation of importing.
static LLVM_ABI FunctionSummary ExternalNode
A dummy node to reference external functions that aren't in the index.
static FunctionSummary makeDummyFunctionSummary(SmallVectorImpl< FunctionSummary::EdgeTy > &&Edges)
Create an empty FunctionSummary (with specified call edges).
LLVM_ABI std::pair< unsigned, unsigned > specialRefCounts() const
Function and variable summary information to aid decisions and implementation of importing.
GlobalValueSummary * getBaseObject()
If this is an alias summary, returns the summary of the aliased object (a global variable or function...
ArrayRef< ValueInfo > refs() const
Return the list of values referenced by this global value definition.
GlobalValue::LinkageTypes linkage() const
Return linkage type recorded for this global value.
bool notEligibleToImport() const
Return true if this global value can't be imported.
uint64_t GUID
Declare a type to represent a global unique identifier for a global value.
VisibilityTypes
An enumeration for the kinds of visibility of global values.
@ DefaultVisibility
The GV is visible.
@ HiddenVisibility
The GV is hidden.
@ ProtectedVisibility
The GV is protected.
static bool isInterposableLinkage(LinkageTypes Linkage)
Whether the definition of this global may be replaced by something non-equivalent at link time.
LinkageTypes
An enumeration for the kinds of linkage for global values.
@ PrivateLinkage
Like Internal, but omit from symbol table.
@ CommonLinkage
Tentative definitions.
@ InternalLinkage
Rename collisions when linking (static functions).
@ LinkOnceAnyLinkage
Keep one copy of function when linking (inline)
@ WeakODRLinkage
Same, but only replaced by something equivalent.
@ ExternalLinkage
Externally visible function.
@ WeakAnyLinkage
Keep one copy of named function when linking (weak)
@ AppendingLinkage
Special purpose, only applies to global arrays.
@ AvailableExternallyLinkage
Available for inspection, not emission.
@ ExternalWeakLinkage
ExternalWeak linkage description.
@ LinkOnceODRLinkage
Same, but only replaced by something equivalent.
Global variable summary information to aid decisions and implementation of importing.
bool withAttributePropagation() const
bool withInternalizeAndPromote() const
bool withGlobalValueDeadStripping() const
bool withWholeProgramVisibility() const
LLVM_ABI bool isGUIDLive(GlobalValue::GUID GUID) const
bool isReadOnly(const GlobalVarSummary *GVS) const
LLVM_ABI void setFlags(uint64_t Flags)
bool isWriteOnly(const GlobalVarSummary *GVS) const
void setPartiallySplitLTOUnits()
ValueInfo getValueInfo(const GlobalValueSummaryMapTy::value_type &R) const
Return a ValueInfo for the index value_type (convenient when iterating index).
void setEnableSplitLTOUnit()
bool partiallySplitLTOUnits() const
LLVM_ABI void collectDefinedFunctionsForModule(StringRef ModulePath, GVSummaryMapTy &GVSummaryMap) const
Collect for the given module the list of functions it defines (GUID -> Summary).
LLVM_ABI void dumpSCCs(raw_ostream &OS)
Print out strongly connected components for debugging.
bool isGlobalValueLive(const GlobalValueSummary *GVS) const
bool enableSplitLTOUnit() const
void setWithSupportsHotColdNew()
LLVM_ABI void propagateAttributes(const DenseSet< GlobalValue::GUID > &PreservedSymbols)
Do the access attribute and DSOLocal propagation in combined index.
void setSkipModuleByDistributedBackend()
void setWithAttributePropagation()
const StringMap< ModuleHash > & modulePaths() const
Table of modules, containing module hash and id.
bool withSupportsHotColdNew() const
void collectDefinedGVSummariesPerModule(Map &ModuleToDefinedGVSummaries) const
Collect for each module the list of Summaries it defines (GUID -> Summary).
bool withDSOLocalPropagation() const
LLVM_ABI void exportToDot(raw_ostream &OS, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols) const
Export summary to dot file for GraphViz.
bool hasUnifiedLTO() const
void setWithDSOLocalPropagation()
void setWithInternalizeAndPromote()
bool skipModuleByDistributedBackend() const
LLVM_ABI uint64_t getFlags() const
GlobalValueSummary * getGlobalValueSummary(const GlobalValue &GV, bool PerModuleIndex=true) const
Returns the first GlobalValueSummary for GV, asserting that there is only one if PerModuleIndex.
void setWithGlobalValueDeadStripping()
void setWithWholeProgramVisibility()
LLVM_ABI bool canImportGlobalVar(const GlobalValueSummary *S, bool AnalyzeRefs) const
Checks if we can import global variable from another module.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM Value Representation.
std::pair< iterator, bool > insert(const ValueT &V)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
This class implements an extremely fast bulk output stream that can only output to a stream.
Enumerate the SCCs of a directed graph in reverse topological order of the SCC DAG.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
initializer< Ty > init(const Ty &Val)
LLVM_ABI StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
DenseMap< GlobalValue::GUID, GlobalValueSummary * > GVSummaryMapTy
Map of global value GUID to its summary, used to identify values defined in a particular module,...
scc_iterator< T > scc_begin(const T &G)
Construct the begin iterator for a deduced graph type T.
std::string utostr(uint64_t X, bool isNeg=false)
auto dyn_cast_or_null(const Y &Val)
iterator_range< pointee_iterator< WrappedIteratorT > > make_pointee_range(RangeT &&Range)
void sort(IteratorTy Start, IteratorTy End)
cl::opt< bool > AlwaysRenamePromotedLocals("always-rename-promoted-locals", cl::init(true), cl::Hidden, cl::desc("Always rename promoted locals."))
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool AreStatisticsEnabled()
Check if statistics are enabled.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ Ref
The access may reference the value stored in memory.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Flags specific to function summaries.
Struct that holds a reference to a particular GUID in a global value summary.
LLVM_ABI GlobalValue::VisibilityTypes getELFVisibility() const
Returns the most constraining visibility among summaries.
ArrayRef< std::unique_ptr< GlobalValueSummary > > getSummaryList() const
LLVM_ABI bool canAutoHide() const
Checks if all copies are eligible for auto-hiding (have flag set).
LLVM_ABI bool isDSOLocal(bool WithDSOLocalPropagation=false) const
Checks if all summaries are DSO local (have the flag set).