Go to the documentation of this file.
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");
31 cl::desc(
"Propagate attributes in index"));
35 cl::desc(
"Import constant global variables with references"));
43 bool HasProtected =
false;
57 return WithDSOLocalPropagation
62 [](
const std::unique_ptr<GlobalValueSummary> &Summary) {
63 return Summary->isDSOLocal();
71 [](
const std::unique_ptr<GlobalValueSummary> &Summary) {
72 return Summary->canAutoHide();
81 unsigned RORefCnt = 0, WORefCnt = 0;
83 for (
I = Refs.size() - 1;
I >= 0 && Refs[
I].isWriteOnly(); --
I)
85 for (;
I >= 0 && Refs[
I].isReadOnly(); --
I)
87 return {RORefCnt, WORefCnt};
114 assert(Flags <= 0xff &&
"Unexpected bits in flag");
154 for (
auto &GlobalList : *
this) {
155 auto GUID = GlobalList.first;
156 for (
auto &GlobSummary : GlobalList.second.SummaryList) {
157 auto *Summary = dyn_cast_or_null<FunctionSummary>(GlobSummary.get());
162 if (Summary->modulePath() != ModulePath)
164 GVSummaryMap[GUID] = Summary;
171 bool PerModuleIndex)
const {
173 assert(
VI &&
"GlobalValue not found in index");
174 assert((!PerModuleIndex ||
VI.getSummaryList().size() == 1) &&
175 "Expected a single entry per global value in per-module index");
176 auto &Summary =
VI.getSummaryList()[0];
177 return Summary.get();
184 const auto &SummaryList =
VI.getSummaryList();
185 if (SummaryList.empty())
187 for (
auto &
I : SummaryList)
204 for (
auto &
VI :
S->refs()) {
205 assert(
VI.getAccessSpecifier() == 0 || isa<FunctionSummary>(
S));
206 if (!
VI.getAccessSpecifier()) {
207 if (!MarkedNonReadWriteOnly.
insert(
VI).second)
209 }
else if (MarkedNonReadWriteOnly.
contains(
VI))
211 for (
auto &
Ref :
VI.getSummaryList())
214 if (
auto *GVS = dyn_cast<GlobalVarSummary>(
Ref->getBaseObject())) {
215 if (!
VI.isReadOnly())
216 GVS->setReadOnly(
false);
217 if (!
VI.isWriteOnly())
218 GVS->setWriteOnly(
false);
255 for (
auto &
P : *
this) {
256 bool IsDSOLocal =
true;
257 for (
auto &
S :
P.second.SummaryList) {
267 P.second.SummaryList,
268 [&](
const std::unique_ptr<GlobalValueSummary> &Summary) {
269 return isGlobalValueLive(Summary.get());
284 if (
auto *GVS = dyn_cast<GlobalVarSummary>(
S->getBaseObject()))
289 GUIDPreservedSymbols.
count(
P.first)) {
290 GVS->setReadOnly(
false);
291 GVS->setWriteOnly(
false);
296 IsDSOLocal &=
S->isDSOLocal();
301 for (
const std::unique_ptr<GlobalValueSummary> &Summary :
302 P.second.SummaryList)
303 Summary->setDSOLocal(
false);
308 for (
auto &
P : *
this)
309 if (
P.second.SummaryList.size())
310 if (
auto *GVS = dyn_cast<GlobalVarSummary>(
311 P.second.SummaryList[0]->getBaseObject()))
313 if (GVS->maybeReadOnly())
315 if (GVS->maybeWriteOnly())
316 WriteOnlyLiveGVars++;
321 bool AnalyzeRefs)
const {
340 auto *GVS = cast<GlobalVarSummary>(
S->getBaseObject());
348 !
S->notEligibleToImport() &&
349 (!AnalyzeRefs || !HasRefsPreventingImport(GVS));
357 scc_begin<ModuleSummaryIndex *>(
this);
359 O <<
"SCC (" << utostr(
I->size()) <<
" node" << (
I->size() == 1 ?
"" :
"s")
363 if (V.getSummaryList().size())
364 F = cast<FunctionSummary>(V.getSummaryList().front().get());
365 O <<
" " << (
F ==
nullptr ?
"External" :
"") <<
" " << utostr(V.getGUID())
366 << (
I.hasCycle() ?
" (has cycle)" :
"") <<
"\n";
376 void addComment(
const Twine &Comment);
377 std::string getAsString()
const;
379 std::vector<std::string>
Attrs;
380 std::string Comments;
392 const Twine &Comment) {
393 std::string
A =
Name.str();
401 void Attributes::addComment(
const Twine &Comment) {
402 if (!
Comment.isTriviallyEmpty()) {
403 if (Comments.empty())
411 std::string Attributes::getAsString()
const {
415 std::string
Ret =
"[";
416 for (
auto &A :
Attrs)
433 return "linkonce_odr";
445 return "extern_weak";
454 auto FlagValue = [](
unsigned V) {
return V ?
'1' :
'0'; };
455 char FlagRep[] = {FlagValue(
F.ReadNone),
456 FlagValue(
F.ReadOnly),
457 FlagValue(
F.NoRecurse),
458 FlagValue(
F.ReturnDoesNotAlias),
459 FlagValue(
F.NoInline),
460 FlagValue(
F.AlwaysInline),
461 FlagValue(
F.NoUnwind),
462 FlagValue(
F.MayThrow),
463 FlagValue(
F.HasUnknownCall),
464 FlagValue(
F.MustBeUnreachable),
472 auto *
FS = dyn_cast_or_null<FunctionSummary>(GVS);
489 if (isa<AliasSummary>(GVS))
496 Label += std::string(
" (") +
Attrs +
")";
508 OS <<
" " << StrId <<
" [label=\"";
515 OS <<
"\"]; // defined externally\n";
519 if (
auto *GVS = dyn_cast<GlobalVarSummary>(
S))
520 return GVS->maybeReadOnly();
525 if (
auto *GVS = dyn_cast<GlobalVarSummary>(
S))
526 return GVS->maybeWriteOnly();
531 if (
auto *GVS = dyn_cast<GlobalVarSummary>(
S))
532 return GVS->isConstant();
539 std::vector<Edge> CrossModuleEdges;
541 using GVSOrderedMapTy = std::map<GlobalValue::GUID, GlobalValueSummary *>;
542 std::map<StringRef, GVSOrderedMapTy> ModuleToDefinedGVS;
562 static const char *EdgeAttrs[] = {
563 " [style=dotted]; // alias",
564 " [style=dashed]; // ref",
565 " [style=dashed,color=forestgreen]; // const-ref",
566 " [style=dashed,color=violetred]; // writeOnly-ref",
567 " // call (hotness : Unknown)",
568 " [color=blue]; // call (hotness : Cold)",
569 " // call (hotness : None)",
570 " [color=brown]; // call (hotness : Hot)",
571 " [style=bold,color=red]; // call (hotness : Critical)"};
574 OS << Pfx <<
NodeId(SrcMod, SrcId) <<
" -> " <<
NodeId(DstMod, DstId)
575 << EdgeAttrs[TypeOrHotness] <<
"\n";
578 OS <<
"digraph Summary {\n";
579 for (
auto &ModIt : ModuleToDefinedGVS) {
581 OS <<
" // Module: " << ModIt.first <<
"\n";
583 OS <<
" style = filled;\n";
584 OS <<
" color = lightgrey;\n";
586 OS <<
" node [style=filled,fillcolor=lightblue];\n";
588 auto &GVSMap = ModIt.second;
590 if (!GVSMap.count(IdTo)) {
591 CrossModuleEdges.push_back({ModId, Hotness, IdFrom, IdTo});
594 DrawEdge(
" ", ModId, IdFrom, ModId, IdTo, Hotness);
597 for (
auto &SummaryIt : GVSMap) {
598 NodeMap[SummaryIt.first].push_back(ModId);
599 auto Flags = SummaryIt.second->flags();
601 if (isa<FunctionSummary>(SummaryIt.second)) {
602 A.add(
"shape",
"record",
"function");
603 }
else if (isa<AliasSummary>(SummaryIt.second)) {
604 A.add(
"style",
"dotted,filled",
"alias");
605 A.add(
"shape",
"box");
607 A.add(
"shape",
"Mrecord",
"variable");
609 A.addComment(
"immutable");
611 A.addComment(
"writeOnly");
613 A.addComment(
"constant");
615 if (Flags.Visibility)
616 A.addComment(
"visibility");
618 A.addComment(
"dsoLocal");
619 if (Flags.CanAutoHide)
620 A.addComment(
"canAutoHide");
621 if (GUIDPreservedSymbols.
count(SummaryIt.first))
622 A.addComment(
"preserved");
627 A.add(
"fillcolor",
"red",
"dead");
628 else if (Flags.NotEligibleToImport)
629 A.add(
"fillcolor",
"yellow",
"not eligible to import");
631 OS <<
" " <<
NodeId(ModId, SummaryIt.first) <<
" " << A.getAsString()
634 OS <<
" // Edges:\n";
636 for (
auto &SummaryIt : GVSMap) {
637 auto *GVS = SummaryIt.second;
638 for (
auto &R : GVS->refs())
639 Draw(SummaryIt.first, R.getGUID(),
640 R.isWriteOnly() ? -1 : (R.isReadOnly() ? -2 : -3));
642 if (
auto *AS = dyn_cast_or_null<AliasSummary>(SummaryIt.second)) {
643 Draw(SummaryIt.first, AS->getAliaseeGUID(), -4);
647 if (
auto *
FS = dyn_cast_or_null<FunctionSummary>(SummaryIt.second))
648 for (
auto &CGEdge :
FS->calls())
649 Draw(SummaryIt.first, CGEdge.first.getGUID(),
650 static_cast<int>(CGEdge.second.Hotness));
655 OS <<
" // Cross-module edges:\n";
656 for (
auto &
E : CrossModuleEdges) {
657 auto &ModList = NodeMap[
E.Dst];
658 if (ModList.empty()) {
662 ModList.push_back(-1);
664 for (
auto DstMod : ModList)
670 if (DstMod !=
E.SrcMod)
671 DrawEdge(
" ",
E.SrcMod,
E.Src, DstMod,
E.Dst,
E.Hotness);
uint64_t GUID
Declare a type to represent a global unique identifier for a global value.
ArrayRef< std::unique_ptr< GlobalValueSummary > > getSummaryList() const
bool hasSyntheticEntryCounts() const
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This is an optimization pass for GlobalISel generic memory operations.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
@ LinkOnceAnyLinkage
Keep one copy of function when linking (inline)
void setPartiallySplitLTOUnits()
bool isReadOnly(const GlobalVarSummary *GVS) const
void setEnableSplitLTOUnit()
@ HiddenVisibility
The GV is hidden.
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Global variable summary information to aid decisions and implementation of importing.
static cl::opt< bool > PropagateAttrs("propagate-attrs", cl::init(true), cl::Hidden, cl::desc("Propagate attributes in index"))
@ DefaultVisibility
The GV is visible.
bool isGlobalValueLive(const GlobalValueSummary *GVS) const
LinkageTypes
An enumeration for the kinds of linkage for global values.
void propagateAttributes(const DenseSet< GlobalValue::GUID > &PreservedSymbols)
Do the access attribute and DSOLocal propagation in combined index.
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
uint64_t getModuleId(const StringRef ModPath) const
Get the module ID recorded for the given module path.
bool isDSOLocal(bool WithDSOLocalPropagation=false) const
Checks if all summaries are DSO local (have the flag set).
ArrayRef< ValueInfo > refs() const
Return the list of values referenced by this global value definition.
static std::string getSummaryAttributes(GlobalValueSummary *GVS)
bool withDSOLocalPropagation() const
void setWithAttributePropagation()
Function and variable summary information to aid decisions and implementation of importing.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
static bool hasReadOnlyFlag(const GlobalValueSummary *S)
bool AreStatisticsEnabled()
Check if statistics are enabled.
VisibilityTypes
An enumeration for the kinds of visibility of global values.
@ Ref
The access may reference the value stored in memory.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
bool enableSplitLTOUnit() const
static std::string fflagsToString(FunctionSummary::FFlags F)
STATISTIC(NumFunctions, "Total number of functions")
This class implements an extremely fast bulk output stream that can only output to a stream.
uint64_t getFlags() const
bool withGlobalValueDeadStripping() const
@ InternalLinkage
Rename collisions when linking (static functions).
GlobalValue::VisibilityTypes getELFVisibility() const
Returns the most constraining visibility among summaries.
void setHasSyntheticEntryCounts()
static bool hasConstantFlag(const GlobalValueSummary *S)
Struct that holds a reference to a particular GUID in a global value summary.
bool canAutoHide() const
Checks if all copies are eligible for auto-hiding (have flag set).
Implements a dense probed hash-table based set.
bool isGUIDLive(GlobalValue::GUID GUID) const
gcc mainline compiles it x2(%rip)
GlobalValue::LinkageTypes linkage() const
Return linkage type recorded for this global value.
void dumpSCCs(raw_ostream &OS)
Print out strongly connected components for debugging.
Enumerate the SCCs of a directed graph in reverse topological order of the SCC DAG.
@ WeakAnyLinkage
Keep one copy of named function when linking (weak)
ValueInfo getValueInfo(const GlobalValueSummaryMapTy::value_type &R) const
Return a ValueInfo for the index value_type (convenient when iterating index).
static bool hasWriteOnlyFlag(const GlobalValueSummary *S)
initializer< Ty > init(const Ty &Val)
bool skipModuleByDistributedBackend() const
static FunctionSummary makeDummyFunctionSummary(std::vector< FunctionSummary::EdgeTy > Edges)
Create an empty FunctionSummary (with specified call edges).
iterator_range< pointee_iterator< WrappedIteratorT > > make_pointee_range(RangeT &&Range)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void setWithDSOLocalPropagation()
Flags specific to function summaries.
@ AppendingLinkage
Special purpose, only applies to global arrays.
bool partiallySplitLTOUnits() const
void exportToDot(raw_ostream &OS, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols) const
Export summary to dot file for GraphViz.
void setFlags(uint64_t Flags)
StringRef - Represent a constant reference to a string, i.e.
void setWithWholeProgramVisibility()
static cl::opt< bool > ImportConstantsWithRefs("import-constants-with-refs", cl::init(true), cl::Hidden, cl::desc("Import constant global variables with references"))
@ WeakODRLinkage
Same, but only replaced by something equivalent.
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
void collectDefinedGVSummariesPerModule(Map &ModuleToDefinedGVSummaries) const
Collect for each module the list of Summaries it defines (GUID -> Summary).
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
@ AvailableExternallyLinkage
Available for inspection, not emission.
@ CommonLinkage
Tentative definitions.
static void defineExternalNode(raw_ostream &OS, const char *Pfx, const ValueInfo &VI, GlobalValue::GUID Id)
bool canImportGlobalVar(GlobalValueSummary *S, bool AnalyzeRefs) const
Checks if we can import global variable from another module.
static FunctionSummary ExternalNode
A dummy node to reference external functions that aren't in the index.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Function summary information to aid decisions and implementation of importing.
void setWithGlobalValueDeadStripping()
static bool isInterposableLinkage(LinkageTypes Linkage)
Whether the definition of this global may be replaced by something non-equivalent at link time.
static constexpr uint32_t RangeWidth
static std::string linkageToString(GlobalValue::LinkageTypes LT)
GlobalValueSummary * getGlobalValueSummary(const GlobalValue &GV, bool PerModuleIndex=true) const
Returns the first GlobalValueSummary for GV, asserting that there is only one if PerModuleIndex.
@ ProtectedVisibility
The GV is protected.
std::pair< unsigned, unsigned > specialRefCounts() const
static constexpr uint64_t BitcodeSummaryVersion
@ ExternalLinkage
Externally visible function.
bool isWriteOnly(const GlobalVarSummary *GVS) const
void setSkipModuleByDistributedBackend()
@ PrivateLinkage
Like Internal, but omit from symbol table.
StringRef filename(StringRef path, Style style=Style::native)
Get filename.
std::string to_string(const T &Value)
static std::string getNodeLabel(const ValueInfo &VI, GlobalValueSummary *GVS)
static std::string getNodeVisualName(GlobalValue::GUID Id)
void collectDefinedFunctionsForModule(StringRef ModulePath, GVSummaryMapTy &GVSummaryMap) const
Collect for the given module the list of functions it defines (GUID -> Summary).
bool withAttributePropagation() const
static void propagateAttributesToRefs(GlobalValueSummary *S, DenseSet< ValueInfo > &MarkedNonReadWriteOnly)
@ ExternalWeakLinkage
ExternalWeak linkage description.
bool withWholeProgramVisibility() const
@ LinkOnceODRLinkage
Same, but only replaced by something equivalent.
LLVM Value Representation.