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"));
 
   44  bool HasProtected = 
false;
 
 
   58  return WithDSOLocalPropagation
 
   63                       [](
const std::unique_ptr<GlobalValueSummary> &Summary) {
 
   64                         return Summary->isDSOLocal();
 
 
   72                      [](
const std::unique_ptr<GlobalValueSummary> &Summary) {
 
   73                        return Summary->canAutoHide();
 
 
   82  unsigned RORefCnt = 0, WORefCnt = 0;
 
   84  for (
I = Refs.size() - 1; 
I >= 0 && Refs[
I].isWriteOnly(); --
I)
 
   86  for (; 
I >= 0 && Refs[
I].isReadOnly(); --
I)
 
   88  return {RORefCnt, WORefCnt};
 
 
  120  assert(Flags <= 0x7ff && 
"Unexpected bits in flag");
 
 
  169  for (
auto &GlobalList : *
this) {
 
  170    auto GUID = GlobalList.first;
 
  171    for (
auto &GlobSummary : GlobalList.second.getSummaryList()) {
 
  177      if (Summary->modulePath() != ModulePath)
 
  179      GVSummaryMap[GUID] = Summary;
 
 
  186                                          bool PerModuleIndex)
 const {
 
  188  assert(VI && 
"GlobalValue not found in index");
 
  189  assert((!PerModuleIndex || VI.getSummaryList().size() == 1) &&
 
  190         "Expected a single entry per global value in per-module index");
 
  191  auto &Summary = VI.getSummaryList()[0];
 
  192  return Summary.get();
 
 
  199  const auto &SummaryList = VI.getSummaryList();
 
  200  if (SummaryList.empty())
 
  202  for (
auto &
I : SummaryList)
 
 
  219  for (
auto &VI : S->
refs()) {
 
  221    if (!VI.getAccessSpecifier()) {
 
  222      if (!MarkedNonReadWriteOnly.
insert(VI).second)
 
  224    } 
else if (MarkedNonReadWriteOnly.
contains(VI))
 
  226    for (
auto &
Ref : VI.getSummaryList())
 
  230        if (!VI.isReadOnly())
 
  231          GVS->setReadOnly(
false);
 
  232        if (!VI.isWriteOnly())
 
  233          GVS->setWriteOnly(
false);
 
 
  270  for (
auto &
P : *
this) {
 
  271    bool IsDSOLocal = 
true;
 
  272    for (
auto &S : 
P.second.getSummaryList()) {
 
  282            P.second.getSummaryList(),
 
  283            [&](
const std::unique_ptr<GlobalValueSummary> &Summary) {
 
  284              return isGlobalValueLive(Summary.get());
 
  304            GUIDPreservedSymbols.
count(
P.first)) {
 
  305          GVS->setReadOnly(
false);
 
  306          GVS->setWriteOnly(
false);
 
  311      IsDSOLocal &= S->isDSOLocal();
 
  316      for (
const std::unique_ptr<GlobalValueSummary> &Summary :
 
  317           P.second.getSummaryList())
 
  318        Summary->setDSOLocal(
false);
 
  323    for (
auto &
P : *
this)
 
  324      if (
P.second.getSummaryList().size())
 
  326                P.second.getSummaryList()[0]->getBaseObject()))
 
  328            if (GVS->maybeReadOnly())
 
  330            if (GVS->maybeWriteOnly())
 
  331              WriteOnlyLiveGVars++;
 
 
  336                                            bool AnalyzeRefs)
 const {
 
 
  343                                            bool &CanImportDecl)
 const {
 
  364  const bool nonInterposable =
 
  370  CanImportDecl = (nonInterposable && eligibleToImport);
 
  377  return nonInterposable && eligibleToImport &&
 
  378         (!AnalyzeRefs || !HasRefsPreventingImport(GVS));
 
 
  388    O << 
"SCC (" << 
utostr(
I->size()) << 
" node" << (
I->size() == 1 ? 
"" : 
"s")
 
  392      if (V.getSummaryList().size())
 
  394      O << 
" " << (
F == 
nullptr ? 
"External" : 
"") << 
" " << 
utostr(V.getGUID())
 
  395        << (
I.hasCycle() ? 
" (has cycle)" : 
"") << 
"\n";
 
 
  405  void addComment(
const Twine &Comment);
 
  406  std::string getAsString() 
const;
 
  408  std::vector<std::string> Attrs;
 
  409  std::string Comments;
 
  421                     const Twine &Comment) {
 
  422  std::string 
A = 
Name.str();
 
  430void Attributes::addComment(
const Twine &Comment) {
 
  431  if (!
Comment.isTriviallyEmpty()) {
 
  432    if (Comments.empty())
 
  440std::string Attributes::getAsString()
 const {
 
  444  std::string 
Ret = 
"[";
 
  445  for (
auto &
A : Attrs)
 
  462    return "linkonce_odr";
 
  474    return "extern_weak";
 
 
  483  auto FlagValue = [](
unsigned V) { 
return V ? 
'1' : 
'0'; };
 
  484  char FlagRep[] = {FlagValue(
F.ReadNone),
 
  485                    FlagValue(
F.ReadOnly),
 
  486                    FlagValue(
F.NoRecurse),
 
  487                    FlagValue(
F.ReturnDoesNotAlias),
 
  488                    FlagValue(
F.NoInline),
 
  489                    FlagValue(
F.AlwaysInline),
 
  490                    FlagValue(
F.NoUnwind),
 
  491                    FlagValue(
F.MayThrow),
 
  492                    FlagValue(
F.HasUnknownCall),
 
  493                    FlagValue(
F.MustBeUnreachable),
 
 
  505  return std::string(
"inst: ") + std::to_string(FS->instCount()) +
 
 
  510  return std::string(
"@") + std::to_string(Id);
 
 
  525    Label += std::string(
" (") + Attrs + 
")";
 
 
  536  auto StrId = std::to_string(Id);
 
  537  OS << 
"  " << StrId << 
" [label=\"";
 
  544  OS << 
"\"]; // defined externally\n";
 
 
  549    return GVS->maybeReadOnly();
 
 
  555    return GVS->maybeWriteOnly();
 
 
  561    return GVS->isConstant();
 
 
  568  std::vector<Edge> CrossModuleEdges;
 
  570  using GVSOrderedMapTy = std::map<GlobalValue::GUID, GlobalValueSummary *>;
 
  571  std::map<StringRef, GVSOrderedMapTy> ModuleToDefinedGVS;
 
  577  std::vector<StringRef> ModulePaths;
 
  579    ModulePaths.push_back(ModPath);
 
  582  for (
auto &ModPath : ModulePaths)
 
  588    return ModId == (
uint64_t)-1 ? std::to_string(Id)
 
  589                                 : std::string(
"M") + std::to_string(ModId) +
 
  590                                       "_" + std::to_string(Id);
 
  602    static const char *EdgeAttrs[] = {
 
  603        " [style=dotted]; // alias",
 
  604        " [style=dashed]; // ref",
 
  605        " [style=dashed,color=forestgreen]; // const-ref",
 
  606        " [style=dashed,color=violetred]; // writeOnly-ref",
 
  607        " // call (hotness : Unknown)",
 
  608        " [color=blue]; // call (hotness : Cold)",
 
  609        " // call (hotness : None)",
 
  610        " [color=brown]; // call (hotness : Hot)",
 
  611        " [style=bold,color=red]; // call (hotness : Critical)"};
 
  613    assert(
static_cast<size_t>(TypeOrHotness) < std::size(EdgeAttrs));
 
  614    OS << Pfx << NodeId(SrcMod, SrcId) << 
" -> " << NodeId(DstMod, DstId)
 
  615       << EdgeAttrs[TypeOrHotness] << 
"\n";
 
  618  OS << 
"digraph Summary {\n";
 
  619  for (
auto &ModIt : ModuleToDefinedGVS) {
 
  623    auto ModId = ModuleIdMap.
empty() ? 0 : ModuleIdMap[ModIt.first];
 
  624    OS << 
"  // Module: " << ModIt.first << 
"\n";
 
  625    OS << 
"  subgraph cluster_" << std::to_string(ModId) << 
" {\n";
 
  626    OS << 
"    style = filled;\n";
 
  627    OS << 
"    color = lightgrey;\n";
 
  629    OS << 
"    node [style=filled,fillcolor=lightblue];\n";
 
  631    auto &GVSMap = ModIt.second;
 
  633      if (!GVSMap.count(IdTo)) {
 
  634        CrossModuleEdges.push_back({ModId, Hotness, IdFrom, IdTo});
 
  637      DrawEdge(
"    ", ModId, IdFrom, ModId, IdTo, Hotness);
 
  640    for (
auto &SummaryIt : GVSMap) {
 
  641      NodeMap[SummaryIt.first].push_back(ModId);
 
  642      auto Flags = SummaryIt.second->flags();
 
  645        A.add(
"shape", 
"record", 
"function");
 
  647        A.add(
"style", 
"dotted,filled", 
"alias");
 
  648        A.add(
"shape", 
"box");
 
  650        A.add(
"shape", 
"Mrecord", 
"variable");
 
  652          A.addComment(
"immutable");
 
  654          A.addComment(
"writeOnly");
 
  656          A.addComment(
"constant");
 
  658      if (Flags.Visibility)
 
  659        A.addComment(
"visibility");
 
  661        A.addComment(
"dsoLocal");
 
  662      if (Flags.CanAutoHide)
 
  663        A.addComment(
"canAutoHide");
 
  665        A.addComment(
"definition");
 
  667        A.addComment(
"declaration");
 
  668      if (GUIDPreservedSymbols.
count(SummaryIt.first))
 
  669        A.addComment(
"preserved");
 
  674        A.add(
"fillcolor", 
"red", 
"dead");
 
  675      else if (Flags.NotEligibleToImport)
 
  676        A.add(
"fillcolor", 
"yellow", 
"not eligible to import");
 
  678      OS << 
"    " << NodeId(ModId, SummaryIt.first) << 
" " << 
A.getAsString()
 
  681    OS << 
"    // Edges:\n";
 
  683    for (
auto &SummaryIt : GVSMap) {
 
  684      auto *GVS = SummaryIt.second;
 
  685      for (
auto &R : GVS->refs())
 
  686        Draw(SummaryIt.first, R.getGUID(),
 
  687             R.isWriteOnly() ? -1 : (R.isReadOnly() ? -2 : -3));
 
  690        Draw(SummaryIt.first, AS->getAliaseeGUID(), -4);
 
  695        for (
auto &CGEdge : FS->calls())
 
  696          Draw(SummaryIt.first, CGEdge.first.getGUID(),
 
  697               static_cast<int>(CGEdge.second.Hotness));
 
  702  OS << 
"  // Cross-module edges:\n";
 
  703  for (
auto &E : CrossModuleEdges) {
 
  704    auto &ModList = NodeMap[E.Dst];
 
  705    if (ModList.empty()) {
 
  709      ModList.push_back(-1);
 
  711    for (
auto DstMod : ModList)
 
  717      if (DstMod != E.SrcMod)
 
  718        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).
static constexpr uint64_t BitcodeSummaryVersion
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)
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.
static constexpr uint32_t RangeWidth
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).