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};
112 assert(Flags <= 0x7f &&
"Unexpected bits in flag");
148 for (
auto &GlobalList : *
this) {
149 auto GUID = GlobalList.first;
150 for (
auto &GlobSummary : GlobalList.second.SummaryList) {
151 auto *Summary = dyn_cast_or_null<FunctionSummary>(GlobSummary.get());
156 if (Summary->modulePath() != ModulePath)
158 GVSummaryMap[GUID] = Summary;
165 bool PerModuleIndex)
const {
167 assert(
VI &&
"GlobalValue not found in index");
168 assert((!PerModuleIndex ||
VI.getSummaryList().size() == 1) &&
169 "Expected a single entry per global value in per-module index");
170 auto &Summary =
VI.getSummaryList()[0];
171 return Summary.get();
178 const auto &SummaryList =
VI.getSummaryList();
179 if (SummaryList.empty())
181 for (
auto &
I : SummaryList)
198 for (
auto &
VI :
S->refs()) {
199 assert(
VI.getAccessSpecifier() == 0 || isa<FunctionSummary>(
S));
200 if (!
VI.getAccessSpecifier()) {
201 if (!MarkedNonReadWriteOnly.
insert(
VI).second)
203 }
else if (MarkedNonReadWriteOnly.
contains(
VI))
205 for (
auto &
Ref :
VI.getSummaryList())
208 if (
auto *GVS = dyn_cast<GlobalVarSummary>(
Ref->getBaseObject())) {
209 if (!
VI.isReadOnly())
210 GVS->setReadOnly(
false);
211 if (!
VI.isWriteOnly())
212 GVS->setWriteOnly(
false);
249 for (
auto &
P : *
this) {
250 bool IsDSOLocal =
true;
251 for (
auto &
S :
P.second.SummaryList) {
261 P.second.SummaryList,
262 [&](
const std::unique_ptr<GlobalValueSummary> &Summary) {
263 return isGlobalValueLive(Summary.get());
278 if (
auto *GVS = dyn_cast<GlobalVarSummary>(
S->getBaseObject()))
283 GUIDPreservedSymbols.
count(
P.first)) {
284 GVS->setReadOnly(
false);
285 GVS->setWriteOnly(
false);
290 IsDSOLocal &=
S->isDSOLocal();
295 for (
const std::unique_ptr<GlobalValueSummary> &Summary :
296 P.second.SummaryList)
297 Summary->setDSOLocal(
false);
302 for (
auto &
P : *
this)
303 if (
P.second.SummaryList.size())
304 if (
auto *GVS = dyn_cast<GlobalVarSummary>(
305 P.second.SummaryList[0]->getBaseObject()))
307 if (GVS->maybeReadOnly())
309 if (GVS->maybeWriteOnly())
310 WriteOnlyLiveGVars++;
315 bool AnalyzeRefs)
const {
334 auto *GVS = cast<GlobalVarSummary>(
S->getBaseObject());
342 !
S->notEligibleToImport() &&
343 (!AnalyzeRefs || !HasRefsPreventingImport(GVS));
351 scc_begin<ModuleSummaryIndex *>(
this);
353 O <<
"SCC (" << utostr(
I->size()) <<
" node" << (
I->size() == 1 ?
"" :
"s")
357 if (V.getSummaryList().size())
358 F = cast<FunctionSummary>(V.getSummaryList().front().get());
359 O <<
" " << (
F ==
nullptr ?
"External" :
"") <<
" " << utostr(V.getGUID())
360 << (
I.hasCycle() ?
" (has cycle)" :
"") <<
"\n";
370 void addComment(
const Twine &Comment);
371 std::string getAsString()
const;
373 std::vector<std::string>
Attrs;
374 std::string Comments;
386 const Twine &Comment) {
387 std::string
A =
Name.str();
395 void Attributes::addComment(
const Twine &Comment) {
396 if (!
Comment.isTriviallyEmpty()) {
397 if (Comments.empty())
405 std::string Attributes::getAsString()
const {
409 std::string
Ret =
"[";
410 for (
auto &A :
Attrs)
427 return "linkonce_odr";
439 return "extern_weak";
448 auto FlagValue = [](
unsigned V) {
return V ?
'1' :
'0'; };
449 char FlagRep[] = {FlagValue(
F.ReadNone),
450 FlagValue(
F.ReadOnly),
451 FlagValue(
F.NoRecurse),
452 FlagValue(
F.ReturnDoesNotAlias),
453 FlagValue(
F.NoInline),
454 FlagValue(
F.AlwaysInline),
455 FlagValue(
F.NoUnwind),
456 FlagValue(
F.MayThrow),
457 FlagValue(
F.HasUnknownCall),
458 FlagValue(
F.MustBeUnreachable),
466 auto *
FS = dyn_cast_or_null<FunctionSummary>(GVS);
483 if (isa<AliasSummary>(GVS))
490 Label += std::string(
" (") +
Attrs +
")";
502 OS <<
" " << StrId <<
" [label=\"";
509 OS <<
"\"]; // defined externally\n";
513 if (
auto *GVS = dyn_cast<GlobalVarSummary>(
S))
514 return GVS->maybeReadOnly();
519 if (
auto *GVS = dyn_cast<GlobalVarSummary>(
S))
520 return GVS->maybeWriteOnly();
525 if (
auto *GVS = dyn_cast<GlobalVarSummary>(
S))
526 return GVS->isConstant();
533 std::vector<Edge> CrossModuleEdges;
535 using GVSOrderedMapTy = std::map<GlobalValue::GUID, GlobalValueSummary *>;
536 std::map<StringRef, GVSOrderedMapTy> ModuleToDefinedGVS;
556 static const char *EdgeAttrs[] = {
557 " [style=dotted]; // alias",
558 " [style=dashed]; // ref",
559 " [style=dashed,color=forestgreen]; // const-ref",
560 " [style=dashed,color=violetred]; // writeOnly-ref",
561 " // call (hotness : Unknown)",
562 " [color=blue]; // call (hotness : Cold)",
563 " // call (hotness : None)",
564 " [color=brown]; // call (hotness : Hot)",
565 " [style=bold,color=red]; // call (hotness : Critical)"};
567 assert(
static_cast<size_t>(TypeOrHotness) <
568 sizeof(EdgeAttrs) /
sizeof(EdgeAttrs[0]));
569 OS << Pfx <<
NodeId(SrcMod, SrcId) <<
" -> " <<
NodeId(DstMod, DstId)
570 << EdgeAttrs[TypeOrHotness] <<
"\n";
573 OS <<
"digraph Summary {\n";
574 for (
auto &ModIt : ModuleToDefinedGVS) {
576 OS <<
" // Module: " << ModIt.first <<
"\n";
578 OS <<
" style = filled;\n";
579 OS <<
" color = lightgrey;\n";
581 OS <<
" node [style=filled,fillcolor=lightblue];\n";
583 auto &GVSMap = ModIt.second;
585 if (!GVSMap.count(IdTo)) {
586 CrossModuleEdges.push_back({ModId, Hotness, IdFrom, IdTo});
589 DrawEdge(
" ", ModId, IdFrom, ModId, IdTo, Hotness);
592 for (
auto &SummaryIt : GVSMap) {
593 NodeMap[SummaryIt.first].push_back(ModId);
594 auto Flags = SummaryIt.second->flags();
596 if (isa<FunctionSummary>(SummaryIt.second)) {
597 A.add(
"shape",
"record",
"function");
598 }
else if (isa<AliasSummary>(SummaryIt.second)) {
599 A.add(
"style",
"dotted,filled",
"alias");
600 A.add(
"shape",
"box");
602 A.add(
"shape",
"Mrecord",
"variable");
604 A.addComment(
"immutable");
606 A.addComment(
"writeOnly");
608 A.addComment(
"constant");
610 if (Flags.Visibility)
611 A.addComment(
"visibility");
613 A.addComment(
"dsoLocal");
614 if (Flags.CanAutoHide)
615 A.addComment(
"canAutoHide");
616 if (GUIDPreservedSymbols.
count(SummaryIt.first))
617 A.addComment(
"preserved");
622 A.add(
"fillcolor",
"red",
"dead");
623 else if (Flags.NotEligibleToImport)
624 A.add(
"fillcolor",
"yellow",
"not eligible to import");
626 OS <<
" " <<
NodeId(ModId, SummaryIt.first) <<
" " << A.getAsString()
629 OS <<
" // Edges:\n";
631 for (
auto &SummaryIt : GVSMap) {
632 auto *GVS = SummaryIt.second;
633 for (
auto &R : GVS->refs())
634 Draw(SummaryIt.first, R.getGUID(),
635 R.isWriteOnly() ? -1 : (R.isReadOnly() ? -2 : -3));
637 if (
auto *AS = dyn_cast_or_null<AliasSummary>(SummaryIt.second)) {
638 Draw(SummaryIt.first, AS->getAliaseeGUID(), -4);
642 if (
auto *
FS = dyn_cast_or_null<FunctionSummary>(SummaryIt.second))
643 for (
auto &CGEdge :
FS->calls())
644 Draw(SummaryIt.first, CGEdge.first.getGUID(),
645 static_cast<int>(CGEdge.second.Hotness));
650 OS <<
" // Cross-module edges:\n";
651 for (
auto &
E : CrossModuleEdges) {
652 auto &ModList = NodeMap[
E.Dst];
653 if (ModList.empty()) {
657 ModList.push_back(-1);
659 for (
auto DstMod : ModList)
665 if (DstMod !=
E.SrcMod)
666 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.
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.
@ LinkOnceODRLinkage
Same, but only replaced by something equivalent.
LLVM Value Representation.