LCOV - code coverage report
Current view: top level - /usr/lib/llvm-19/include/llvm/IR - ModuleSummaryIndex.h (source / functions) Coverage Total Hit
Test: PostgreSQL 20devel Lines: 0.0 % 18 0
Test Date: 2026-07-03 19:57:34 Functions: 0.0 % 10 0
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 0.0 % 8 0

             Branch data     Line data    Source code
       1                 :             : //===- llvm/ModuleSummaryIndex.h - Module Summary Index ---------*- C++ -*-===//
       2                 :             : //
       3                 :             : // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
       4                 :             : // See https://llvm.org/LICENSE.txt for license information.
       5                 :             : // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
       6                 :             : //
       7                 :             : //===----------------------------------------------------------------------===//
       8                 :             : //
       9                 :             : /// @file
      10                 :             : /// ModuleSummaryIndex.h This file contains the declarations the classes that
      11                 :             : ///  hold the module index and summary for function importing.
      12                 :             : //
      13                 :             : //===----------------------------------------------------------------------===//
      14                 :             : 
      15                 :             : #ifndef LLVM_IR_MODULESUMMARYINDEX_H
      16                 :             : #define LLVM_IR_MODULESUMMARYINDEX_H
      17                 :             : 
      18                 :             : #include "llvm/ADT/ArrayRef.h"
      19                 :             : #include "llvm/ADT/DenseMap.h"
      20                 :             : #include "llvm/ADT/STLExtras.h"
      21                 :             : #include "llvm/ADT/SmallString.h"
      22                 :             : #include "llvm/ADT/SmallVector.h"
      23                 :             : #include "llvm/ADT/StringExtras.h"
      24                 :             : #include "llvm/ADT/StringMap.h"
      25                 :             : #include "llvm/ADT/StringRef.h"
      26                 :             : #include "llvm/IR/ConstantRange.h"
      27                 :             : #include "llvm/IR/GlobalValue.h"
      28                 :             : #include "llvm/IR/Module.h"
      29                 :             : #include "llvm/Support/Allocator.h"
      30                 :             : #include "llvm/Support/MathExtras.h"
      31                 :             : #include "llvm/Support/ScaledNumber.h"
      32                 :             : #include "llvm/Support/StringSaver.h"
      33                 :             : #include "llvm/Support/raw_ostream.h"
      34                 :             : #include <algorithm>
      35                 :             : #include <array>
      36                 :             : #include <cassert>
      37                 :             : #include <cstddef>
      38                 :             : #include <cstdint>
      39                 :             : #include <map>
      40                 :             : #include <memory>
      41                 :             : #include <optional>
      42                 :             : #include <set>
      43                 :             : #include <string>
      44                 :             : #include <unordered_set>
      45                 :             : #include <utility>
      46                 :             : #include <vector>
      47                 :             : 
      48                 :             : namespace llvm {
      49                 :             : 
      50                 :             : template <class GraphType> struct GraphTraits;
      51                 :             : 
      52                 :             : namespace yaml {
      53                 :             : 
      54                 :             : template <typename T> struct MappingTraits;
      55                 :             : 
      56                 :             : } // end namespace yaml
      57                 :             : 
      58                 :             : /// Class to accumulate and hold information about a callee.
      59                 :             : struct CalleeInfo {
      60                 :             :   enum class HotnessType : uint8_t {
      61                 :             :     Unknown = 0,
      62                 :             :     Cold = 1,
      63                 :             :     None = 2,
      64                 :             :     Hot = 3,
      65                 :             :     Critical = 4
      66                 :             :   };
      67                 :             : 
      68                 :             :   // The size of the bit-field might need to be adjusted if more values are
      69                 :             :   // added to HotnessType enum.
      70                 :             :   uint32_t Hotness : 3;
      71                 :             : 
      72                 :             :   // True if at least one of the calls to the callee is a tail call.
      73                 :             :   bool HasTailCall : 1;
      74                 :             : 
      75                 :             :   /// The value stored in RelBlockFreq has to be interpreted as the digits of
      76                 :             :   /// a scaled number with a scale of \p -ScaleShift.
      77                 :             :   static constexpr unsigned RelBlockFreqBits = 28;
      78                 :             :   uint32_t RelBlockFreq : RelBlockFreqBits;
      79                 :             :   static constexpr int32_t ScaleShift = 8;
      80                 :             :   static constexpr uint64_t MaxRelBlockFreq = (1 << RelBlockFreqBits) - 1;
      81                 :             : 
      82                 :             :   CalleeInfo()
      83                 :             :       : Hotness(static_cast<uint32_t>(HotnessType::Unknown)),
      84                 :             :         HasTailCall(false), RelBlockFreq(0) {}
      85                 :             :   explicit CalleeInfo(HotnessType Hotness, bool HasTC, uint64_t RelBF)
      86                 :             :       : Hotness(static_cast<uint32_t>(Hotness)), HasTailCall(HasTC),
      87                 :             :         RelBlockFreq(RelBF) {}
      88                 :             : 
      89                 :             :   void updateHotness(const HotnessType OtherHotness) {
      90                 :             :     Hotness = std::max(Hotness, static_cast<uint32_t>(OtherHotness));
      91                 :             :   }
      92                 :             : 
      93                 :             :   bool hasTailCall() const { return HasTailCall; }
      94                 :             : 
      95                 :             :   void setHasTailCall(const bool HasTC) { HasTailCall = HasTC; }
      96                 :             : 
      97                 :             :   HotnessType getHotness() const { return HotnessType(Hotness); }
      98                 :             : 
      99                 :             :   /// Update \p RelBlockFreq from \p BlockFreq and \p EntryFreq
     100                 :             :   ///
     101                 :             :   /// BlockFreq is divided by EntryFreq and added to RelBlockFreq. To represent
     102                 :             :   /// fractional values, the result is represented as a fixed point number with
     103                 :             :   /// scale of -ScaleShift.
     104                 :             :   void updateRelBlockFreq(uint64_t BlockFreq, uint64_t EntryFreq) {
     105                 :             :     if (EntryFreq == 0)
     106                 :             :       return;
     107                 :             :     using Scaled64 = ScaledNumber<uint64_t>;
     108                 :             :     Scaled64 Temp(BlockFreq, ScaleShift);
     109                 :             :     Temp /= Scaled64::get(EntryFreq);
     110                 :             : 
     111                 :             :     uint64_t Sum =
     112                 :             :         SaturatingAdd<uint64_t>(Temp.toInt<uint64_t>(), RelBlockFreq);
     113                 :             :     Sum = std::min(Sum, uint64_t(MaxRelBlockFreq));
     114                 :             :     RelBlockFreq = static_cast<uint32_t>(Sum);
     115                 :             :   }
     116                 :             : };
     117                 :             : 
     118                 :             : inline const char *getHotnessName(CalleeInfo::HotnessType HT) {
     119                 :             :   switch (HT) {
     120                 :             :   case CalleeInfo::HotnessType::Unknown:
     121                 :             :     return "unknown";
     122                 :             :   case CalleeInfo::HotnessType::Cold:
     123                 :             :     return "cold";
     124                 :             :   case CalleeInfo::HotnessType::None:
     125                 :             :     return "none";
     126                 :             :   case CalleeInfo::HotnessType::Hot:
     127                 :             :     return "hot";
     128                 :             :   case CalleeInfo::HotnessType::Critical:
     129                 :             :     return "critical";
     130                 :             :   }
     131                 :             :   llvm_unreachable("invalid hotness");
     132                 :             : }
     133                 :             : 
     134                 :             : class GlobalValueSummary;
     135                 :             : 
     136                 :             : using GlobalValueSummaryList = std::vector<std::unique_ptr<GlobalValueSummary>>;
     137                 :             : 
     138                 :             : struct alignas(8) GlobalValueSummaryInfo {
     139                 :             :   union NameOrGV {
     140                 :             :     NameOrGV(bool HaveGVs) {
     141                 :             :       if (HaveGVs)
     142                 :             :         GV = nullptr;
     143                 :             :       else
     144                 :             :         Name = "";
     145                 :             :     }
     146                 :             : 
     147                 :             :     /// The GlobalValue corresponding to this summary. This is only used in
     148                 :             :     /// per-module summaries and when the IR is available. E.g. when module
     149                 :             :     /// analysis is being run, or when parsing both the IR and the summary
     150                 :             :     /// from assembly.
     151                 :             :     const GlobalValue *GV;
     152                 :             : 
     153                 :             :     /// Summary string representation. This StringRef points to BC module
     154                 :             :     /// string table and is valid until module data is stored in memory.
     155                 :             :     /// This is guaranteed to happen until runThinLTOBackend function is
     156                 :             :     /// called, so it is safe to use this field during thin link. This field
     157                 :             :     /// is only valid if summary index was loaded from BC file.
     158                 :             :     StringRef Name;
     159                 :             :   } U;
     160                 :             : 
     161                 :             :   inline GlobalValueSummaryInfo(bool HaveGVs);
     162                 :             : 
     163                 :             :   /// List of global value summary structures for a particular value held
     164                 :             :   /// in the GlobalValueMap. Requires a vector in the case of multiple
     165                 :             :   /// COMDAT values of the same name.
     166                 :             :   GlobalValueSummaryList SummaryList;
     167                 :             : };
     168                 :             : 
     169                 :             : /// Map from global value GUID to corresponding summary structures. Use a
     170                 :             : /// std::map rather than a DenseMap so that pointers to the map's value_type
     171                 :             : /// (which are used by ValueInfo) are not invalidated by insertion. Also it will
     172                 :             : /// likely incur less overhead, as the value type is not very small and the size
     173                 :             : /// of the map is unknown, resulting in inefficiencies due to repeated
     174                 :             : /// insertions and resizing.
     175                 :             : using GlobalValueSummaryMapTy =
     176                 :             :     std::map<GlobalValue::GUID, GlobalValueSummaryInfo>;
     177                 :             : 
     178                 :             : /// Struct that holds a reference to a particular GUID in a global value
     179                 :             : /// summary.
     180                 :             : struct ValueInfo {
     181                 :             :   enum Flags { HaveGV = 1, ReadOnly = 2, WriteOnly = 4 };
     182                 :             :   PointerIntPair<const GlobalValueSummaryMapTy::value_type *, 3, int>
     183                 :             :       RefAndFlags;
     184                 :             : 
     185                 :             :   ValueInfo() = default;
     186                 :           0 :   ValueInfo(bool HaveGVs, const GlobalValueSummaryMapTy::value_type *R) {
     187                 :           0 :     RefAndFlags.setPointer(R);
     188                 :           0 :     RefAndFlags.setInt(HaveGVs);
     189                 :           0 :   }
     190                 :             : 
     191                 :           0 :   explicit operator bool() const { return getRef(); }
     192                 :             : 
     193                 :             :   GlobalValue::GUID getGUID() const { return getRef()->first; }
     194                 :             :   const GlobalValue *getValue() const {
     195                 :             :     assert(haveGVs());
     196                 :             :     return getRef()->second.U.GV;
     197                 :             :   }
     198                 :             : 
     199                 :           0 :   ArrayRef<std::unique_ptr<GlobalValueSummary>> getSummaryList() const {
     200         [ #  # ]:           0 :     return getRef()->second.SummaryList;
     201                 :             :   }
     202                 :             : 
     203                 :             :   StringRef name() const {
     204                 :             :     return haveGVs() ? getRef()->second.U.GV->getName()
     205                 :             :                      : getRef()->second.U.Name;
     206                 :             :   }
     207                 :             : 
     208                 :             :   bool haveGVs() const { return RefAndFlags.getInt() & HaveGV; }
     209                 :             :   bool isReadOnly() const {
     210                 :             :     assert(isValidAccessSpecifier());
     211                 :             :     return RefAndFlags.getInt() & ReadOnly;
     212                 :             :   }
     213                 :             :   bool isWriteOnly() const {
     214                 :             :     assert(isValidAccessSpecifier());
     215                 :             :     return RefAndFlags.getInt() & WriteOnly;
     216                 :             :   }
     217                 :             :   unsigned getAccessSpecifier() const {
     218                 :             :     assert(isValidAccessSpecifier());
     219                 :             :     return RefAndFlags.getInt() & (ReadOnly | WriteOnly);
     220                 :             :   }
     221                 :             :   bool isValidAccessSpecifier() const {
     222                 :             :     unsigned BadAccessMask = ReadOnly | WriteOnly;
     223                 :             :     return (RefAndFlags.getInt() & BadAccessMask) != BadAccessMask;
     224                 :             :   }
     225                 :             :   void setReadOnly() {
     226                 :             :     // We expect ro/wo attribute to set only once during
     227                 :             :     // ValueInfo lifetime.
     228                 :             :     assert(getAccessSpecifier() == 0);
     229                 :             :     RefAndFlags.setInt(RefAndFlags.getInt() | ReadOnly);
     230                 :             :   }
     231                 :             :   void setWriteOnly() {
     232                 :             :     assert(getAccessSpecifier() == 0);
     233                 :             :     RefAndFlags.setInt(RefAndFlags.getInt() | WriteOnly);
     234                 :             :   }
     235                 :             : 
     236                 :           0 :   const GlobalValueSummaryMapTy::value_type *getRef() const {
     237                 :           0 :     return RefAndFlags.getPointer();
     238                 :             :   }
     239                 :             : 
     240                 :             :   /// Returns the most constraining visibility among summaries. The
     241                 :             :   /// visibilities, ordered from least to most constraining, are: default,
     242                 :             :   /// protected and hidden.
     243                 :             :   GlobalValue::VisibilityTypes getELFVisibility() const;
     244                 :             : 
     245                 :             :   /// Checks if all summaries are DSO local (have the flag set). When DSOLocal
     246                 :             :   /// propagation has been done, set the parameter to enable fast check.
     247                 :             :   bool isDSOLocal(bool WithDSOLocalPropagation = false) const;
     248                 :             : 
     249                 :             :   /// Checks if all copies are eligible for auto-hiding (have flag set).
     250                 :             :   bool canAutoHide() const;
     251                 :             : };
     252                 :             : 
     253                 :             : inline raw_ostream &operator<<(raw_ostream &OS, const ValueInfo &VI) {
     254                 :             :   OS << VI.getGUID();
     255                 :             :   if (!VI.name().empty())
     256                 :             :     OS << " (" << VI.name() << ")";
     257                 :             :   return OS;
     258                 :             : }
     259                 :             : 
     260                 :             : inline bool operator==(const ValueInfo &A, const ValueInfo &B) {
     261                 :             :   assert(A.getRef() && B.getRef() &&
     262                 :             :          "Need ValueInfo with non-null Ref for comparison");
     263                 :             :   return A.getRef() == B.getRef();
     264                 :             : }
     265                 :             : 
     266                 :             : inline bool operator!=(const ValueInfo &A, const ValueInfo &B) {
     267                 :             :   assert(A.getRef() && B.getRef() &&
     268                 :             :          "Need ValueInfo with non-null Ref for comparison");
     269                 :             :   return A.getRef() != B.getRef();
     270                 :             : }
     271                 :             : 
     272                 :             : inline bool operator<(const ValueInfo &A, const ValueInfo &B) {
     273                 :             :   assert(A.getRef() && B.getRef() &&
     274                 :             :          "Need ValueInfo with non-null Ref to compare GUIDs");
     275                 :             :   return A.getGUID() < B.getGUID();
     276                 :             : }
     277                 :             : 
     278                 :             : template <> struct DenseMapInfo<ValueInfo> {
     279                 :             :   static inline ValueInfo getEmptyKey() {
     280                 :             :     return ValueInfo(false, (GlobalValueSummaryMapTy::value_type *)-8);
     281                 :             :   }
     282                 :             : 
     283                 :             :   static inline ValueInfo getTombstoneKey() {
     284                 :             :     return ValueInfo(false, (GlobalValueSummaryMapTy::value_type *)-16);
     285                 :             :   }
     286                 :             : 
     287                 :             :   static inline bool isSpecialKey(ValueInfo V) {
     288                 :             :     return V == getTombstoneKey() || V == getEmptyKey();
     289                 :             :   }
     290                 :             : 
     291                 :             :   static bool isEqual(ValueInfo L, ValueInfo R) {
     292                 :             :     // We are not supposed to mix ValueInfo(s) with different HaveGVs flag
     293                 :             :     // in a same container.
     294                 :             :     assert(isSpecialKey(L) || isSpecialKey(R) || (L.haveGVs() == R.haveGVs()));
     295                 :             :     return L.getRef() == R.getRef();
     296                 :             :   }
     297                 :             :   static unsigned getHashValue(ValueInfo I) { return (uintptr_t)I.getRef(); }
     298                 :             : };
     299                 :             : 
     300                 :             : /// Summary of memprof callsite metadata.
     301                 :             : struct CallsiteInfo {
     302                 :             :   // Actual callee function.
     303                 :             :   ValueInfo Callee;
     304                 :             : 
     305                 :             :   // Used to record whole program analysis cloning decisions.
     306                 :             :   // The ThinLTO backend will need to create as many clones as there are entries
     307                 :             :   // in the vector (it is expected and should be confirmed that all such
     308                 :             :   // summaries in the same FunctionSummary have the same number of entries).
     309                 :             :   // Each index records version info for the corresponding clone of this
     310                 :             :   // function. The value is the callee clone it calls (becomes the appended
     311                 :             :   // suffix id). Index 0 is the original version, and a value of 0 calls the
     312                 :             :   // original callee.
     313                 :             :   SmallVector<unsigned> Clones{0};
     314                 :             : 
     315                 :             :   // Represents stack ids in this context, recorded as indices into the
     316                 :             :   // StackIds vector in the summary index, which in turn holds the full 64-bit
     317                 :             :   // stack ids. This reduces memory as there are in practice far fewer unique
     318                 :             :   // stack ids than stack id references.
     319                 :             :   SmallVector<unsigned> StackIdIndices;
     320                 :             : 
     321                 :             :   CallsiteInfo(ValueInfo Callee, SmallVector<unsigned> StackIdIndices)
     322                 :             :       : Callee(Callee), StackIdIndices(std::move(StackIdIndices)) {}
     323                 :             :   CallsiteInfo(ValueInfo Callee, SmallVector<unsigned> Clones,
     324                 :             :                SmallVector<unsigned> StackIdIndices)
     325                 :             :       : Callee(Callee), Clones(std::move(Clones)),
     326                 :             :         StackIdIndices(std::move(StackIdIndices)) {}
     327                 :             : };
     328                 :             : 
     329                 :             : inline raw_ostream &operator<<(raw_ostream &OS, const CallsiteInfo &SNI) {
     330                 :             :   OS << "Callee: " << SNI.Callee;
     331                 :             :   bool First = true;
     332                 :             :   OS << " Clones: ";
     333                 :             :   for (auto V : SNI.Clones) {
     334                 :             :     if (!First)
     335                 :             :       OS << ", ";
     336                 :             :     First = false;
     337                 :             :     OS << V;
     338                 :             :   }
     339                 :             :   First = true;
     340                 :             :   OS << " StackIds: ";
     341                 :             :   for (auto Id : SNI.StackIdIndices) {
     342                 :             :     if (!First)
     343                 :             :       OS << ", ";
     344                 :             :     First = false;
     345                 :             :     OS << Id;
     346                 :             :   }
     347                 :             :   return OS;
     348                 :             : }
     349                 :             : 
     350                 :             : // Allocation type assigned to an allocation reached by a given context.
     351                 :             : // More can be added, now this is cold, notcold and hot.
     352                 :             : // Values should be powers of two so that they can be ORed, in particular to
     353                 :             : // track allocations that have different behavior with different calling
     354                 :             : // contexts.
     355                 :             : enum class AllocationType : uint8_t {
     356                 :             :   None = 0,
     357                 :             :   NotCold = 1,
     358                 :             :   Cold = 2,
     359                 :             :   Hot = 4,
     360                 :             :   All = 7 // This should always be set to the OR of all values.
     361                 :             : };
     362                 :             : 
     363                 :             : /// Summary of a single MIB in a memprof metadata on allocations.
     364                 :             : struct MIBInfo {
     365                 :             :   // The allocation type for this profiled context.
     366                 :             :   AllocationType AllocType;
     367                 :             : 
     368                 :             :   // Represents stack ids in this context, recorded as indices into the
     369                 :             :   // StackIds vector in the summary index, which in turn holds the full 64-bit
     370                 :             :   // stack ids. This reduces memory as there are in practice far fewer unique
     371                 :             :   // stack ids than stack id references.
     372                 :             :   SmallVector<unsigned> StackIdIndices;
     373                 :             : 
     374                 :             :   MIBInfo(AllocationType AllocType, SmallVector<unsigned> StackIdIndices)
     375                 :             :       : AllocType(AllocType), StackIdIndices(std::move(StackIdIndices)) {}
     376                 :             : };
     377                 :             : 
     378                 :             : inline raw_ostream &operator<<(raw_ostream &OS, const MIBInfo &MIB) {
     379                 :             :   OS << "AllocType " << (unsigned)MIB.AllocType;
     380                 :             :   bool First = true;
     381                 :             :   OS << " StackIds: ";
     382                 :             :   for (auto Id : MIB.StackIdIndices) {
     383                 :             :     if (!First)
     384                 :             :       OS << ", ";
     385                 :             :     First = false;
     386                 :             :     OS << Id;
     387                 :             :   }
     388                 :             :   return OS;
     389                 :             : }
     390                 :             : 
     391                 :             : /// Summary of memprof metadata on allocations.
     392                 :             : struct AllocInfo {
     393                 :             :   // Used to record whole program analysis cloning decisions.
     394                 :             :   // The ThinLTO backend will need to create as many clones as there are entries
     395                 :             :   // in the vector (it is expected and should be confirmed that all such
     396                 :             :   // summaries in the same FunctionSummary have the same number of entries).
     397                 :             :   // Each index records version info for the corresponding clone of this
     398                 :             :   // function. The value is the allocation type of the corresponding allocation.
     399                 :             :   // Index 0 is the original version. Before cloning, index 0 may have more than
     400                 :             :   // one allocation type.
     401                 :             :   SmallVector<uint8_t> Versions;
     402                 :             : 
     403                 :             :   // Vector of MIBs in this memprof metadata.
     404                 :             :   std::vector<MIBInfo> MIBs;
     405                 :             : 
     406                 :             :   // If requested, keep track of total profiled sizes for each MIB. This will be
     407                 :             :   // a vector of the same length and order as the MIBs vector, if non-empty.
     408                 :             :   std::vector<uint64_t> TotalSizes;
     409                 :             : 
     410                 :             :   AllocInfo(std::vector<MIBInfo> MIBs) : MIBs(std::move(MIBs)) {
     411                 :             :     Versions.push_back(0);
     412                 :             :   }
     413                 :             :   AllocInfo(SmallVector<uint8_t> Versions, std::vector<MIBInfo> MIBs)
     414                 :             :       : Versions(std::move(Versions)), MIBs(std::move(MIBs)) {}
     415                 :             : };
     416                 :             : 
     417                 :             : inline raw_ostream &operator<<(raw_ostream &OS, const AllocInfo &AE) {
     418                 :             :   bool First = true;
     419                 :             :   OS << "Versions: ";
     420                 :             :   for (auto V : AE.Versions) {
     421                 :             :     if (!First)
     422                 :             :       OS << ", ";
     423                 :             :     First = false;
     424                 :             :     OS << (unsigned)V;
     425                 :             :   }
     426                 :             :   OS << " MIB:\n";
     427                 :             :   for (auto &M : AE.MIBs) {
     428                 :             :     OS << "\t\t" << M << "\n";
     429                 :             :   }
     430                 :             :   if (!AE.TotalSizes.empty()) {
     431                 :             :     OS << " TotalSizes per MIB:\n\t\t";
     432                 :             :     First = true;
     433                 :             :     for (uint64_t TS : AE.TotalSizes) {
     434                 :             :       if (!First)
     435                 :             :         OS << ", ";
     436                 :             :       First = false;
     437                 :             :       OS << TS << "\n";
     438                 :             :     }
     439                 :             :   }
     440                 :             :   return OS;
     441                 :             : }
     442                 :             : 
     443                 :             : /// Function and variable summary information to aid decisions and
     444                 :             : /// implementation of importing.
     445                 :             : class GlobalValueSummary {
     446                 :             : public:
     447                 :             :   /// Sububclass discriminator (for dyn_cast<> et al.)
     448                 :             :   enum SummaryKind : unsigned { AliasKind, FunctionKind, GlobalVarKind };
     449                 :             : 
     450                 :             :   enum ImportKind : unsigned {
     451                 :             :     // The global value definition corresponding to the summary should be
     452                 :             :     // imported from source module
     453                 :             :     Definition = 0,
     454                 :             : 
     455                 :             :     // When its definition doesn't exist in the destination module and not
     456                 :             :     // imported (e.g., function is too large to be inlined), the global value
     457                 :             :     // declaration corresponding to the summary should be imported, or the
     458                 :             :     // attributes from summary should be annotated on the function declaration.
     459                 :             :     Declaration = 1,
     460                 :             :   };
     461                 :             : 
     462                 :             :   /// Group flags (Linkage, NotEligibleToImport, etc.) as a bitfield.
     463                 :             :   struct GVFlags {
     464                 :             :     /// The linkage type of the associated global value.
     465                 :             :     ///
     466                 :             :     /// One use is to flag values that have local linkage types and need to
     467                 :             :     /// have module identifier appended before placing into the combined
     468                 :             :     /// index, to disambiguate from other values with the same name.
     469                 :             :     /// In the future this will be used to update and optimize linkage
     470                 :             :     /// types based on global summary-based analysis.
     471                 :             :     unsigned Linkage : 4;
     472                 :             : 
     473                 :             :     /// Indicates the visibility.
     474                 :             :     unsigned Visibility : 2;
     475                 :             : 
     476                 :             :     /// Indicate if the global value cannot be imported (e.g. it cannot
     477                 :             :     /// be renamed or references something that can't be renamed).
     478                 :             :     unsigned NotEligibleToImport : 1;
     479                 :             : 
     480                 :             :     /// In per-module summary, indicate that the global value must be considered
     481                 :             :     /// a live root for index-based liveness analysis. Used for special LLVM
     482                 :             :     /// values such as llvm.global_ctors that the linker does not know about.
     483                 :             :     ///
     484                 :             :     /// In combined summary, indicate that the global value is live.
     485                 :             :     unsigned Live : 1;
     486                 :             : 
     487                 :             :     /// Indicates that the linker resolved the symbol to a definition from
     488                 :             :     /// within the same linkage unit.
     489                 :             :     unsigned DSOLocal : 1;
     490                 :             : 
     491                 :             :     /// In the per-module summary, indicates that the global value is
     492                 :             :     /// linkonce_odr and global unnamed addr (so eligible for auto-hiding
     493                 :             :     /// via hidden visibility). In the combined summary, indicates that the
     494                 :             :     /// prevailing linkonce_odr copy can be auto-hidden via hidden visibility
     495                 :             :     /// when it is upgraded to weak_odr in the backend. This is legal when
     496                 :             :     /// all copies are eligible for auto-hiding (i.e. all copies were
     497                 :             :     /// linkonce_odr global unnamed addr. If any copy is not (e.g. it was
     498                 :             :     /// originally weak_odr, we cannot auto-hide the prevailing copy as it
     499                 :             :     /// means the symbol was externally visible.
     500                 :             :     unsigned CanAutoHide : 1;
     501                 :             : 
     502                 :             :     /// This field is written by the ThinLTO indexing step to postlink combined
     503                 :             :     /// summary. The value is interpreted as 'ImportKind' enum defined above.
     504                 :             :     unsigned ImportType : 1;
     505                 :             : 
     506                 :             :     /// Convenience Constructors
     507                 :             :     explicit GVFlags(GlobalValue::LinkageTypes Linkage,
     508                 :             :                      GlobalValue::VisibilityTypes Visibility,
     509                 :             :                      bool NotEligibleToImport, bool Live, bool IsLocal,
     510                 :             :                      bool CanAutoHide, ImportKind ImportType)
     511                 :             :         : Linkage(Linkage), Visibility(Visibility),
     512                 :             :           NotEligibleToImport(NotEligibleToImport), Live(Live),
     513                 :             :           DSOLocal(IsLocal), CanAutoHide(CanAutoHide),
     514                 :             :           ImportType(static_cast<unsigned>(ImportType)) {}
     515                 :             :   };
     516                 :             : 
     517                 :             : private:
     518                 :             :   /// Kind of summary for use in dyn_cast<> et al.
     519                 :             :   SummaryKind Kind;
     520                 :             : 
     521                 :             :   GVFlags Flags;
     522                 :             : 
     523                 :             :   /// This is the hash of the name of the symbol in the original file. It is
     524                 :             :   /// identical to the GUID for global symbols, but differs for local since the
     525                 :             :   /// GUID includes the module level id in the hash.
     526                 :             :   GlobalValue::GUID OriginalName = 0;
     527                 :             : 
     528                 :             :   /// Path of module IR containing value's definition, used to locate
     529                 :             :   /// module during importing.
     530                 :             :   ///
     531                 :             :   /// This is only used during parsing of the combined index, or when
     532                 :             :   /// parsing the per-module index for creation of the combined summary index,
     533                 :             :   /// not during writing of the per-module index which doesn't contain a
     534                 :             :   /// module path string table.
     535                 :             :   StringRef ModulePath;
     536                 :             : 
     537                 :             :   /// List of values referenced by this global value's definition
     538                 :             :   /// (either by the initializer of a global variable, or referenced
     539                 :             :   /// from within a function). This does not include functions called, which
     540                 :             :   /// are listed in the derived FunctionSummary object.
     541                 :             :   std::vector<ValueInfo> RefEdgeList;
     542                 :             : 
     543                 :             : protected:
     544                 :             :   GlobalValueSummary(SummaryKind K, GVFlags Flags, std::vector<ValueInfo> Refs)
     545                 :             :       : Kind(K), Flags(Flags), RefEdgeList(std::move(Refs)) {
     546                 :             :     assert((K != AliasKind || Refs.empty()) &&
     547                 :             :            "Expect no references for AliasSummary");
     548                 :             :   }
     549                 :             : 
     550                 :             : public:
     551                 :             :   virtual ~GlobalValueSummary() = default;
     552                 :             : 
     553                 :             :   /// Returns the hash of the original name, it is identical to the GUID for
     554                 :             :   /// externally visible symbols, but not for local ones.
     555                 :             :   GlobalValue::GUID getOriginalName() const { return OriginalName; }
     556                 :             : 
     557                 :             :   /// Initialize the original name hash in this summary.
     558                 :             :   void setOriginalName(GlobalValue::GUID Name) { OriginalName = Name; }
     559                 :             : 
     560                 :             :   /// Which kind of summary subclass this is.
     561                 :           0 :   SummaryKind getSummaryKind() const { return Kind; }
     562                 :             : 
     563                 :             :   /// Set the path to the module containing this function, for use in
     564                 :             :   /// the combined index.
     565                 :             :   void setModulePath(StringRef ModPath) { ModulePath = ModPath; }
     566                 :             : 
     567                 :             :   /// Get the path to the module containing this function.
     568                 :           0 :   StringRef modulePath() const { return ModulePath; }
     569                 :             : 
     570                 :             :   /// Get the flags for this GlobalValue (see \p struct GVFlags).
     571                 :             :   GVFlags flags() const { return Flags; }
     572                 :             : 
     573                 :             :   /// Return linkage type recorded for this global value.
     574                 :             :   GlobalValue::LinkageTypes linkage() const {
     575                 :             :     return static_cast<GlobalValue::LinkageTypes>(Flags.Linkage);
     576                 :             :   }
     577                 :             : 
     578                 :             :   /// Sets the linkage to the value determined by global summary-based
     579                 :             :   /// optimization. Will be applied in the ThinLTO backends.
     580                 :             :   void setLinkage(GlobalValue::LinkageTypes Linkage) {
     581                 :             :     Flags.Linkage = Linkage;
     582                 :             :   }
     583                 :             : 
     584                 :             :   /// Return true if this global value can't be imported.
     585                 :           0 :   bool notEligibleToImport() const { return Flags.NotEligibleToImport; }
     586                 :             : 
     587                 :             :   bool isLive() const { return Flags.Live; }
     588                 :             : 
     589                 :             :   void setLive(bool Live) { Flags.Live = Live; }
     590                 :             : 
     591                 :             :   void setDSOLocal(bool Local) { Flags.DSOLocal = Local; }
     592                 :             : 
     593                 :             :   bool isDSOLocal() const { return Flags.DSOLocal; }
     594                 :             : 
     595                 :             :   void setCanAutoHide(bool CanAutoHide) { Flags.CanAutoHide = CanAutoHide; }
     596                 :             : 
     597                 :             :   bool canAutoHide() const { return Flags.CanAutoHide; }
     598                 :             : 
     599                 :             :   bool shouldImportAsDecl() const {
     600                 :             :     return Flags.ImportType == GlobalValueSummary::ImportKind::Declaration;
     601                 :             :   }
     602                 :             : 
     603                 :             :   void setImportKind(ImportKind IK) { Flags.ImportType = IK; }
     604                 :             : 
     605                 :             :   GlobalValueSummary::ImportKind importType() const {
     606                 :             :     return static_cast<ImportKind>(Flags.ImportType);
     607                 :             :   }
     608                 :             : 
     609                 :             :   GlobalValue::VisibilityTypes getVisibility() const {
     610                 :             :     return (GlobalValue::VisibilityTypes)Flags.Visibility;
     611                 :             :   }
     612                 :             :   void setVisibility(GlobalValue::VisibilityTypes Vis) {
     613                 :             :     Flags.Visibility = (unsigned)Vis;
     614                 :             :   }
     615                 :             : 
     616                 :             :   /// Flag that this global value cannot be imported.
     617                 :             :   void setNotEligibleToImport() { Flags.NotEligibleToImport = true; }
     618                 :             : 
     619                 :             :   /// Return the list of values referenced by this global value definition.
     620                 :             :   ArrayRef<ValueInfo> refs() const { return RefEdgeList; }
     621                 :             : 
     622                 :             :   /// If this is an alias summary, returns the summary of the aliased object (a
     623                 :             :   /// global variable or function), otherwise returns itself.
     624                 :             :   GlobalValueSummary *getBaseObject();
     625                 :             :   const GlobalValueSummary *getBaseObject() const;
     626                 :             : 
     627                 :             :   friend class ModuleSummaryIndex;
     628                 :             : };
     629                 :             : 
     630                 :             : GlobalValueSummaryInfo::GlobalValueSummaryInfo(bool HaveGVs) : U(HaveGVs) {}
     631                 :             : 
     632                 :             : /// Alias summary information.
     633                 :             : class AliasSummary : public GlobalValueSummary {
     634                 :             :   ValueInfo AliaseeValueInfo;
     635                 :             : 
     636                 :             :   /// This is the Aliasee in the same module as alias (could get from VI, trades
     637                 :             :   /// memory for time). Note that this pointer may be null (and the value info
     638                 :             :   /// empty) when we have a distributed index where the alias is being imported
     639                 :             :   /// (as a copy of the aliasee), but the aliasee is not.
     640                 :             :   GlobalValueSummary *AliaseeSummary;
     641                 :             : 
     642                 :             : public:
     643                 :             :   AliasSummary(GVFlags Flags)
     644                 :             :       : GlobalValueSummary(AliasKind, Flags, ArrayRef<ValueInfo>{}),
     645                 :             :         AliaseeSummary(nullptr) {}
     646                 :             : 
     647                 :             :   /// Check if this is an alias summary.
     648                 :             :   static bool classof(const GlobalValueSummary *GVS) {
     649                 :             :     return GVS->getSummaryKind() == AliasKind;
     650                 :             :   }
     651                 :             : 
     652                 :             :   void setAliasee(ValueInfo &AliaseeVI, GlobalValueSummary *Aliasee) {
     653                 :             :     AliaseeValueInfo = AliaseeVI;
     654                 :             :     AliaseeSummary = Aliasee;
     655                 :             :   }
     656                 :             : 
     657                 :             :   bool hasAliasee() const {
     658                 :             :     assert(!!AliaseeSummary == (AliaseeValueInfo &&
     659                 :             :                                 !AliaseeValueInfo.getSummaryList().empty()) &&
     660                 :             :            "Expect to have both aliasee summary and summary list or neither");
     661                 :             :     return !!AliaseeSummary;
     662                 :             :   }
     663                 :             : 
     664                 :             :   const GlobalValueSummary &getAliasee() const {
     665                 :             :     assert(AliaseeSummary && "Unexpected missing aliasee summary");
     666                 :             :     return *AliaseeSummary;
     667                 :             :   }
     668                 :             : 
     669                 :             :   GlobalValueSummary &getAliasee() {
     670                 :             :     return const_cast<GlobalValueSummary &>(
     671                 :             :                          static_cast<const AliasSummary *>(this)->getAliasee());
     672                 :             :   }
     673                 :             :   ValueInfo getAliaseeVI() const {
     674                 :             :     assert(AliaseeValueInfo && "Unexpected missing aliasee");
     675                 :             :     return AliaseeValueInfo;
     676                 :             :   }
     677                 :             :   GlobalValue::GUID getAliaseeGUID() const {
     678                 :             :     assert(AliaseeValueInfo && "Unexpected missing aliasee");
     679                 :             :     return AliaseeValueInfo.getGUID();
     680                 :             :   }
     681                 :             : };
     682                 :             : 
     683                 :             : const inline GlobalValueSummary *GlobalValueSummary::getBaseObject() const {
     684                 :             :   if (auto *AS = dyn_cast<AliasSummary>(this))
     685                 :             :     return &AS->getAliasee();
     686                 :             :   return this;
     687                 :             : }
     688                 :             : 
     689                 :             : inline GlobalValueSummary *GlobalValueSummary::getBaseObject() {
     690                 :             :   if (auto *AS = dyn_cast<AliasSummary>(this))
     691                 :             :     return &AS->getAliasee();
     692                 :             :   return this;
     693                 :             : }
     694                 :             : 
     695                 :             : /// Function summary information to aid decisions and implementation of
     696                 :             : /// importing.
     697                 :             : class FunctionSummary : public GlobalValueSummary {
     698                 :             : public:
     699                 :             :   /// <CalleeValueInfo, CalleeInfo> call edge pair.
     700                 :             :   using EdgeTy = std::pair<ValueInfo, CalleeInfo>;
     701                 :             : 
     702                 :             :   /// Types for -force-summary-edges-cold debugging option.
     703                 :             :   enum ForceSummaryHotnessType : unsigned {
     704                 :             :     FSHT_None,
     705                 :             :     FSHT_AllNonCritical,
     706                 :             :     FSHT_All
     707                 :             :   };
     708                 :             : 
     709                 :             :   /// An "identifier" for a virtual function. This contains the type identifier
     710                 :             :   /// represented as a GUID and the offset from the address point to the virtual
     711                 :             :   /// function pointer, where "address point" is as defined in the Itanium ABI:
     712                 :             :   /// https://itanium-cxx-abi.github.io/cxx-abi/abi.html#vtable-general
     713                 :             :   struct VFuncId {
     714                 :             :     GlobalValue::GUID GUID;
     715                 :             :     uint64_t Offset;
     716                 :             :   };
     717                 :             : 
     718                 :             :   /// A specification for a virtual function call with all constant integer
     719                 :             :   /// arguments. This is used to perform virtual constant propagation on the
     720                 :             :   /// summary.
     721                 :             :   struct ConstVCall {
     722                 :             :     VFuncId VFunc;
     723                 :             :     std::vector<uint64_t> Args;
     724                 :             :   };
     725                 :             : 
     726                 :             :   /// All type identifier related information. Because these fields are
     727                 :             :   /// relatively uncommon we only allocate space for them if necessary.
     728                 :             :   struct TypeIdInfo {
     729                 :             :     /// List of type identifiers used by this function in llvm.type.test
     730                 :             :     /// intrinsics referenced by something other than an llvm.assume intrinsic,
     731                 :             :     /// represented as GUIDs.
     732                 :             :     std::vector<GlobalValue::GUID> TypeTests;
     733                 :             : 
     734                 :             :     /// List of virtual calls made by this function using (respectively)
     735                 :             :     /// llvm.assume(llvm.type.test) or llvm.type.checked.load intrinsics that do
     736                 :             :     /// not have all constant integer arguments.
     737                 :             :     std::vector<VFuncId> TypeTestAssumeVCalls, TypeCheckedLoadVCalls;
     738                 :             : 
     739                 :             :     /// List of virtual calls made by this function using (respectively)
     740                 :             :     /// llvm.assume(llvm.type.test) or llvm.type.checked.load intrinsics with
     741                 :             :     /// all constant integer arguments.
     742                 :             :     std::vector<ConstVCall> TypeTestAssumeConstVCalls,
     743                 :             :         TypeCheckedLoadConstVCalls;
     744                 :             :   };
     745                 :             : 
     746                 :             :   /// Flags specific to function summaries.
     747                 :             :   struct FFlags {
     748                 :             :     // Function attribute flags. Used to track if a function accesses memory,
     749                 :             :     // recurses or aliases.
     750                 :             :     unsigned ReadNone : 1;
     751                 :             :     unsigned ReadOnly : 1;
     752                 :             :     unsigned NoRecurse : 1;
     753                 :             :     unsigned ReturnDoesNotAlias : 1;
     754                 :             : 
     755                 :             :     // Indicate if the global value cannot be inlined.
     756                 :             :     unsigned NoInline : 1;
     757                 :             :     // Indicate if function should be always inlined.
     758                 :             :     unsigned AlwaysInline : 1;
     759                 :             :     // Indicate if function never raises an exception. Can be modified during
     760                 :             :     // thinlink function attribute propagation
     761                 :             :     unsigned NoUnwind : 1;
     762                 :             :     // Indicate if function contains instructions that mayThrow
     763                 :             :     unsigned MayThrow : 1;
     764                 :             : 
     765                 :             :     // If there are calls to unknown targets (e.g. indirect)
     766                 :             :     unsigned HasUnknownCall : 1;
     767                 :             : 
     768                 :             :     // Indicate if a function must be an unreachable function.
     769                 :             :     //
     770                 :             :     // This bit is sufficient but not necessary;
     771                 :             :     // if this bit is on, the function must be regarded as unreachable;
     772                 :             :     // if this bit is off, the function might be reachable or unreachable.
     773                 :             :     unsigned MustBeUnreachable : 1;
     774                 :             : 
     775                 :             :     FFlags &operator&=(const FFlags &RHS) {
     776                 :             :       this->ReadNone &= RHS.ReadNone;
     777                 :             :       this->ReadOnly &= RHS.ReadOnly;
     778                 :             :       this->NoRecurse &= RHS.NoRecurse;
     779                 :             :       this->ReturnDoesNotAlias &= RHS.ReturnDoesNotAlias;
     780                 :             :       this->NoInline &= RHS.NoInline;
     781                 :             :       this->AlwaysInline &= RHS.AlwaysInline;
     782                 :             :       this->NoUnwind &= RHS.NoUnwind;
     783                 :             :       this->MayThrow &= RHS.MayThrow;
     784                 :             :       this->HasUnknownCall &= RHS.HasUnknownCall;
     785                 :             :       this->MustBeUnreachable &= RHS.MustBeUnreachable;
     786                 :             :       return *this;
     787                 :             :     }
     788                 :             : 
     789                 :             :     bool anyFlagSet() {
     790                 :             :       return this->ReadNone | this->ReadOnly | this->NoRecurse |
     791                 :             :              this->ReturnDoesNotAlias | this->NoInline | this->AlwaysInline |
     792                 :             :              this->NoUnwind | this->MayThrow | this->HasUnknownCall |
     793                 :             :              this->MustBeUnreachable;
     794                 :             :     }
     795                 :             : 
     796                 :             :     operator std::string() {
     797                 :             :       std::string Output;
     798                 :             :       raw_string_ostream OS(Output);
     799                 :             :       OS << "funcFlags: (";
     800                 :             :       OS << "readNone: " << this->ReadNone;
     801                 :             :       OS << ", readOnly: " << this->ReadOnly;
     802                 :             :       OS << ", noRecurse: " << this->NoRecurse;
     803                 :             :       OS << ", returnDoesNotAlias: " << this->ReturnDoesNotAlias;
     804                 :             :       OS << ", noInline: " << this->NoInline;
     805                 :             :       OS << ", alwaysInline: " << this->AlwaysInline;
     806                 :             :       OS << ", noUnwind: " << this->NoUnwind;
     807                 :             :       OS << ", mayThrow: " << this->MayThrow;
     808                 :             :       OS << ", hasUnknownCall: " << this->HasUnknownCall;
     809                 :             :       OS << ", mustBeUnreachable: " << this->MustBeUnreachable;
     810                 :             :       OS << ")";
     811                 :             :       return Output;
     812                 :             :     }
     813                 :             :   };
     814                 :             : 
     815                 :             :   /// Describes the uses of a parameter by the function.
     816                 :             :   struct ParamAccess {
     817                 :             :     static constexpr uint32_t RangeWidth = 64;
     818                 :             : 
     819                 :             :     /// Describes the use of a value in a call instruction, specifying the
     820                 :             :     /// call's target, the value's parameter number, and the possible range of
     821                 :             :     /// offsets from the beginning of the value that are passed.
     822                 :             :     struct Call {
     823                 :             :       uint64_t ParamNo = 0;
     824                 :             :       ValueInfo Callee;
     825                 :             :       ConstantRange Offsets{/*BitWidth=*/RangeWidth, /*isFullSet=*/true};
     826                 :             : 
     827                 :             :       Call() = default;
     828                 :             :       Call(uint64_t ParamNo, ValueInfo Callee, const ConstantRange &Offsets)
     829                 :             :           : ParamNo(ParamNo), Callee(Callee), Offsets(Offsets) {}
     830                 :             :     };
     831                 :             : 
     832                 :             :     uint64_t ParamNo = 0;
     833                 :             :     /// The range contains byte offsets from the parameter pointer which
     834                 :             :     /// accessed by the function. In the per-module summary, it only includes
     835                 :             :     /// accesses made by the function instructions. In the combined summary, it
     836                 :             :     /// also includes accesses by nested function calls.
     837                 :             :     ConstantRange Use{/*BitWidth=*/RangeWidth, /*isFullSet=*/true};
     838                 :             :     /// In the per-module summary, it summarizes the byte offset applied to each
     839                 :             :     /// pointer parameter before passing to each corresponding callee.
     840                 :             :     /// In the combined summary, it's empty and information is propagated by
     841                 :             :     /// inter-procedural analysis and applied to the Use field.
     842                 :             :     std::vector<Call> Calls;
     843                 :             : 
     844                 :             :     ParamAccess() = default;
     845                 :             :     ParamAccess(uint64_t ParamNo, const ConstantRange &Use)
     846                 :             :         : ParamNo(ParamNo), Use(Use) {}
     847                 :             :   };
     848                 :             : 
     849                 :             :   /// Create an empty FunctionSummary (with specified call edges).
     850                 :             :   /// Used to represent external nodes and the dummy root node.
     851                 :             :   static FunctionSummary
     852                 :             :   makeDummyFunctionSummary(std::vector<FunctionSummary::EdgeTy> Edges) {
     853                 :             :     return FunctionSummary(
     854                 :             :         FunctionSummary::GVFlags(
     855                 :             :             GlobalValue::LinkageTypes::AvailableExternallyLinkage,
     856                 :             :             GlobalValue::DefaultVisibility,
     857                 :             :             /*NotEligibleToImport=*/true, /*Live=*/true, /*IsLocal=*/false,
     858                 :             :             /*CanAutoHide=*/false, GlobalValueSummary::ImportKind::Definition),
     859                 :             :         /*NumInsts=*/0, FunctionSummary::FFlags{}, /*EntryCount=*/0,
     860                 :             :         std::vector<ValueInfo>(), std::move(Edges),
     861                 :             :         std::vector<GlobalValue::GUID>(),
     862                 :             :         std::vector<FunctionSummary::VFuncId>(),
     863                 :             :         std::vector<FunctionSummary::VFuncId>(),
     864                 :             :         std::vector<FunctionSummary::ConstVCall>(),
     865                 :             :         std::vector<FunctionSummary::ConstVCall>(),
     866                 :             :         std::vector<FunctionSummary::ParamAccess>(),
     867                 :             :         std::vector<CallsiteInfo>(), std::vector<AllocInfo>());
     868                 :             :   }
     869                 :             : 
     870                 :             :   /// A dummy node to reference external functions that aren't in the index
     871                 :             :   static FunctionSummary ExternalNode;
     872                 :             : 
     873                 :             : private:
     874                 :             :   /// Number of instructions (ignoring debug instructions, e.g.) computed
     875                 :             :   /// during the initial compile step when the summary index is first built.
     876                 :             :   unsigned InstCount;
     877                 :             : 
     878                 :             :   /// Function summary specific flags.
     879                 :             :   FFlags FunFlags;
     880                 :             : 
     881                 :             :   /// The synthesized entry count of the function.
     882                 :             :   /// This is only populated during ThinLink phase and remains unused while
     883                 :             :   /// generating per-module summaries.
     884                 :             :   uint64_t EntryCount = 0;
     885                 :             : 
     886                 :             :   /// List of <CalleeValueInfo, CalleeInfo> call edge pairs from this function.
     887                 :             :   std::vector<EdgeTy> CallGraphEdgeList;
     888                 :             : 
     889                 :             :   std::unique_ptr<TypeIdInfo> TIdInfo;
     890                 :             : 
     891                 :             :   /// Uses for every parameter to this function.
     892                 :             :   using ParamAccessesTy = std::vector<ParamAccess>;
     893                 :             :   std::unique_ptr<ParamAccessesTy> ParamAccesses;
     894                 :             : 
     895                 :             :   /// Optional list of memprof callsite metadata summaries. The correspondence
     896                 :             :   /// between the callsite summary and the callsites in the function is implied
     897                 :             :   /// by the order in the vector (and can be validated by comparing the stack
     898                 :             :   /// ids in the CallsiteInfo to those in the instruction callsite metadata).
     899                 :             :   /// As a memory savings optimization, we only create these for the prevailing
     900                 :             :   /// copy of a symbol when creating the combined index during LTO.
     901                 :             :   using CallsitesTy = std::vector<CallsiteInfo>;
     902                 :             :   std::unique_ptr<CallsitesTy> Callsites;
     903                 :             : 
     904                 :             :   /// Optional list of allocation memprof metadata summaries. The correspondence
     905                 :             :   /// between the alloc memprof summary and the allocation callsites in the
     906                 :             :   /// function is implied by the order in the vector (and can be validated by
     907                 :             :   /// comparing the stack ids in the AllocInfo to those in the instruction
     908                 :             :   /// memprof metadata).
     909                 :             :   /// As a memory savings optimization, we only create these for the prevailing
     910                 :             :   /// copy of a symbol when creating the combined index during LTO.
     911                 :             :   using AllocsTy = std::vector<AllocInfo>;
     912                 :             :   std::unique_ptr<AllocsTy> Allocs;
     913                 :             : 
     914                 :             : public:
     915                 :             :   FunctionSummary(GVFlags Flags, unsigned NumInsts, FFlags FunFlags,
     916                 :             :                   uint64_t EntryCount, std::vector<ValueInfo> Refs,
     917                 :             :                   std::vector<EdgeTy> CGEdges,
     918                 :             :                   std::vector<GlobalValue::GUID> TypeTests,
     919                 :             :                   std::vector<VFuncId> TypeTestAssumeVCalls,
     920                 :             :                   std::vector<VFuncId> TypeCheckedLoadVCalls,
     921                 :             :                   std::vector<ConstVCall> TypeTestAssumeConstVCalls,
     922                 :             :                   std::vector<ConstVCall> TypeCheckedLoadConstVCalls,
     923                 :             :                   std::vector<ParamAccess> Params, CallsitesTy CallsiteList,
     924                 :             :                   AllocsTy AllocList)
     925                 :             :       : GlobalValueSummary(FunctionKind, Flags, std::move(Refs)),
     926                 :             :         InstCount(NumInsts), FunFlags(FunFlags), EntryCount(EntryCount),
     927                 :             :         CallGraphEdgeList(std::move(CGEdges)) {
     928                 :             :     if (!TypeTests.empty() || !TypeTestAssumeVCalls.empty() ||
     929                 :             :         !TypeCheckedLoadVCalls.empty() || !TypeTestAssumeConstVCalls.empty() ||
     930                 :             :         !TypeCheckedLoadConstVCalls.empty())
     931                 :             :       TIdInfo = std::make_unique<TypeIdInfo>(
     932                 :             :           TypeIdInfo{std::move(TypeTests), std::move(TypeTestAssumeVCalls),
     933                 :             :                      std::move(TypeCheckedLoadVCalls),
     934                 :             :                      std::move(TypeTestAssumeConstVCalls),
     935                 :             :                      std::move(TypeCheckedLoadConstVCalls)});
     936                 :             :     if (!Params.empty())
     937                 :             :       ParamAccesses = std::make_unique<ParamAccessesTy>(std::move(Params));
     938                 :             :     if (!CallsiteList.empty())
     939                 :             :       Callsites = std::make_unique<CallsitesTy>(std::move(CallsiteList));
     940                 :             :     if (!AllocList.empty())
     941                 :             :       Allocs = std::make_unique<AllocsTy>(std::move(AllocList));
     942                 :             :   }
     943                 :             :   // Gets the number of readonly and writeonly refs in RefEdgeList
     944                 :             :   std::pair<unsigned, unsigned> specialRefCounts() const;
     945                 :             : 
     946                 :             :   /// Check if this is a function summary.
     947                 :           0 :   static bool classof(const GlobalValueSummary *GVS) {
     948                 :           0 :     return GVS->getSummaryKind() == FunctionKind;
     949                 :             :   }
     950                 :             : 
     951                 :             :   /// Get function summary flags.
     952                 :             :   FFlags fflags() const { return FunFlags; }
     953                 :             : 
     954                 :             :   void setNoRecurse() { FunFlags.NoRecurse = true; }
     955                 :             : 
     956                 :             :   void setNoUnwind() { FunFlags.NoUnwind = true; }
     957                 :             : 
     958                 :             :   /// Get the instruction count recorded for this function.
     959                 :           0 :   unsigned instCount() const { return InstCount; }
     960                 :             : 
     961                 :             :   /// Get the synthetic entry count for this function.
     962                 :             :   uint64_t entryCount() const { return EntryCount; }
     963                 :             : 
     964                 :             :   /// Set the synthetic entry count for this function.
     965                 :             :   void setEntryCount(uint64_t EC) { EntryCount = EC; }
     966                 :             : 
     967                 :             :   /// Return the list of <CalleeValueInfo, CalleeInfo> pairs.
     968                 :             :   ArrayRef<EdgeTy> calls() const { return CallGraphEdgeList; }
     969                 :             : 
     970                 :             :   std::vector<EdgeTy> &mutableCalls() { return CallGraphEdgeList; }
     971                 :             : 
     972                 :             :   void addCall(EdgeTy E) { CallGraphEdgeList.push_back(E); }
     973                 :             : 
     974                 :             :   /// Returns the list of type identifiers used by this function in
     975                 :             :   /// llvm.type.test intrinsics other than by an llvm.assume intrinsic,
     976                 :             :   /// represented as GUIDs.
     977                 :             :   ArrayRef<GlobalValue::GUID> type_tests() const {
     978                 :             :     if (TIdInfo)
     979                 :             :       return TIdInfo->TypeTests;
     980                 :             :     return {};
     981                 :             :   }
     982                 :             : 
     983                 :             :   /// Returns the list of virtual calls made by this function using
     984                 :             :   /// llvm.assume(llvm.type.test) intrinsics that do not have all constant
     985                 :             :   /// integer arguments.
     986                 :             :   ArrayRef<VFuncId> type_test_assume_vcalls() const {
     987                 :             :     if (TIdInfo)
     988                 :             :       return TIdInfo->TypeTestAssumeVCalls;
     989                 :             :     return {};
     990                 :             :   }
     991                 :             : 
     992                 :             :   /// Returns the list of virtual calls made by this function using
     993                 :             :   /// llvm.type.checked.load intrinsics that do not have all constant integer
     994                 :             :   /// arguments.
     995                 :             :   ArrayRef<VFuncId> type_checked_load_vcalls() const {
     996                 :             :     if (TIdInfo)
     997                 :             :       return TIdInfo->TypeCheckedLoadVCalls;
     998                 :             :     return {};
     999                 :             :   }
    1000                 :             : 
    1001                 :             :   /// Returns the list of virtual calls made by this function using
    1002                 :             :   /// llvm.assume(llvm.type.test) intrinsics with all constant integer
    1003                 :             :   /// arguments.
    1004                 :             :   ArrayRef<ConstVCall> type_test_assume_const_vcalls() const {
    1005                 :             :     if (TIdInfo)
    1006                 :             :       return TIdInfo->TypeTestAssumeConstVCalls;
    1007                 :             :     return {};
    1008                 :             :   }
    1009                 :             : 
    1010                 :             :   /// Returns the list of virtual calls made by this function using
    1011                 :             :   /// llvm.type.checked.load intrinsics with all constant integer arguments.
    1012                 :             :   ArrayRef<ConstVCall> type_checked_load_const_vcalls() const {
    1013                 :             :     if (TIdInfo)
    1014                 :             :       return TIdInfo->TypeCheckedLoadConstVCalls;
    1015                 :             :     return {};
    1016                 :             :   }
    1017                 :             : 
    1018                 :             :   /// Returns the list of known uses of pointer parameters.
    1019                 :             :   ArrayRef<ParamAccess> paramAccesses() const {
    1020                 :             :     if (ParamAccesses)
    1021                 :             :       return *ParamAccesses;
    1022                 :             :     return {};
    1023                 :             :   }
    1024                 :             : 
    1025                 :             :   /// Sets the list of known uses of pointer parameters.
    1026                 :             :   void setParamAccesses(std::vector<ParamAccess> NewParams) {
    1027                 :             :     if (NewParams.empty())
    1028                 :             :       ParamAccesses.reset();
    1029                 :             :     else if (ParamAccesses)
    1030                 :             :       *ParamAccesses = std::move(NewParams);
    1031                 :             :     else
    1032                 :             :       ParamAccesses = std::make_unique<ParamAccessesTy>(std::move(NewParams));
    1033                 :             :   }
    1034                 :             : 
    1035                 :             :   /// Add a type test to the summary. This is used by WholeProgramDevirt if we
    1036                 :             :   /// were unable to devirtualize a checked call.
    1037                 :             :   void addTypeTest(GlobalValue::GUID Guid) {
    1038                 :             :     if (!TIdInfo)
    1039                 :             :       TIdInfo = std::make_unique<TypeIdInfo>();
    1040                 :             :     TIdInfo->TypeTests.push_back(Guid);
    1041                 :             :   }
    1042                 :             : 
    1043                 :             :   const TypeIdInfo *getTypeIdInfo() const { return TIdInfo.get(); };
    1044                 :             : 
    1045                 :             :   ArrayRef<CallsiteInfo> callsites() const {
    1046                 :             :     if (Callsites)
    1047                 :             :       return *Callsites;
    1048                 :             :     return {};
    1049                 :             :   }
    1050                 :             : 
    1051                 :             :   CallsitesTy &mutableCallsites() {
    1052                 :             :     assert(Callsites);
    1053                 :             :     return *Callsites;
    1054                 :             :   }
    1055                 :             : 
    1056                 :             :   void addCallsite(CallsiteInfo &Callsite) {
    1057                 :             :     if (!Callsites)
    1058                 :             :       Callsites = std::make_unique<CallsitesTy>();
    1059                 :             :     Callsites->push_back(Callsite);
    1060                 :             :   }
    1061                 :             : 
    1062                 :             :   ArrayRef<AllocInfo> allocs() const {
    1063                 :             :     if (Allocs)
    1064                 :             :       return *Allocs;
    1065                 :             :     return {};
    1066                 :             :   }
    1067                 :             : 
    1068                 :             :   AllocsTy &mutableAllocs() {
    1069                 :             :     assert(Allocs);
    1070                 :             :     return *Allocs;
    1071                 :             :   }
    1072                 :             : 
    1073                 :             :   friend struct GraphTraits<ValueInfo>;
    1074                 :             : };
    1075                 :             : 
    1076                 :             : template <> struct DenseMapInfo<FunctionSummary::VFuncId> {
    1077                 :             :   static FunctionSummary::VFuncId getEmptyKey() { return {0, uint64_t(-1)}; }
    1078                 :             : 
    1079                 :             :   static FunctionSummary::VFuncId getTombstoneKey() {
    1080                 :             :     return {0, uint64_t(-2)};
    1081                 :             :   }
    1082                 :             : 
    1083                 :             :   static bool isEqual(FunctionSummary::VFuncId L, FunctionSummary::VFuncId R) {
    1084                 :             :     return L.GUID == R.GUID && L.Offset == R.Offset;
    1085                 :             :   }
    1086                 :             : 
    1087                 :             :   static unsigned getHashValue(FunctionSummary::VFuncId I) { return I.GUID; }
    1088                 :             : };
    1089                 :             : 
    1090                 :             : template <> struct DenseMapInfo<FunctionSummary::ConstVCall> {
    1091                 :             :   static FunctionSummary::ConstVCall getEmptyKey() {
    1092                 :             :     return {{0, uint64_t(-1)}, {}};
    1093                 :             :   }
    1094                 :             : 
    1095                 :             :   static FunctionSummary::ConstVCall getTombstoneKey() {
    1096                 :             :     return {{0, uint64_t(-2)}, {}};
    1097                 :             :   }
    1098                 :             : 
    1099                 :             :   static bool isEqual(FunctionSummary::ConstVCall L,
    1100                 :             :                       FunctionSummary::ConstVCall R) {
    1101                 :             :     return DenseMapInfo<FunctionSummary::VFuncId>::isEqual(L.VFunc, R.VFunc) &&
    1102                 :             :            L.Args == R.Args;
    1103                 :             :   }
    1104                 :             : 
    1105                 :             :   static unsigned getHashValue(FunctionSummary::ConstVCall I) {
    1106                 :             :     return I.VFunc.GUID;
    1107                 :             :   }
    1108                 :             : };
    1109                 :             : 
    1110                 :             : /// The ValueInfo and offset for a function within a vtable definition
    1111                 :             : /// initializer array.
    1112                 :             : struct VirtFuncOffset {
    1113                 :             :   VirtFuncOffset(ValueInfo VI, uint64_t Offset)
    1114                 :             :       : FuncVI(VI), VTableOffset(Offset) {}
    1115                 :             : 
    1116                 :             :   ValueInfo FuncVI;
    1117                 :             :   uint64_t VTableOffset;
    1118                 :             : };
    1119                 :             : /// List of functions referenced by a particular vtable definition.
    1120                 :             : using VTableFuncList = std::vector<VirtFuncOffset>;
    1121                 :             : 
    1122                 :             : /// Global variable summary information to aid decisions and
    1123                 :             : /// implementation of importing.
    1124                 :             : ///
    1125                 :             : /// Global variable summary has two extra flag, telling if it is
    1126                 :             : /// readonly or writeonly. Both readonly and writeonly variables
    1127                 :             : /// can be optimized in the backed: readonly variables can be
    1128                 :             : /// const-folded, while writeonly vars can be completely eliminated
    1129                 :             : /// together with corresponding stores. We let both things happen
    1130                 :             : /// by means of internalizing such variables after ThinLTO import.
    1131                 :             : class GlobalVarSummary : public GlobalValueSummary {
    1132                 :             : private:
    1133                 :             :   /// For vtable definitions this holds the list of functions and
    1134                 :             :   /// their corresponding offsets within the initializer array.
    1135                 :             :   std::unique_ptr<VTableFuncList> VTableFuncs;
    1136                 :             : 
    1137                 :             : public:
    1138                 :             :   struct GVarFlags {
    1139                 :             :     GVarFlags(bool ReadOnly, bool WriteOnly, bool Constant,
    1140                 :             :               GlobalObject::VCallVisibility Vis)
    1141                 :             :         : MaybeReadOnly(ReadOnly), MaybeWriteOnly(WriteOnly),
    1142                 :             :           Constant(Constant), VCallVisibility(Vis) {}
    1143                 :             : 
    1144                 :             :     // If true indicates that this global variable might be accessed
    1145                 :             :     // purely by non-volatile load instructions. This in turn means
    1146                 :             :     // it can be internalized in source and destination modules during
    1147                 :             :     // thin LTO import because it neither modified nor its address
    1148                 :             :     // is taken.
    1149                 :             :     unsigned MaybeReadOnly : 1;
    1150                 :             :     // If true indicates that variable is possibly only written to, so
    1151                 :             :     // its value isn't loaded and its address isn't taken anywhere.
    1152                 :             :     // False, when 'Constant' attribute is set.
    1153                 :             :     unsigned MaybeWriteOnly : 1;
    1154                 :             :     // Indicates that value is a compile-time constant. Global variable
    1155                 :             :     // can be 'Constant' while not being 'ReadOnly' on several occasions:
    1156                 :             :     // - it is volatile, (e.g mapped device address)
    1157                 :             :     // - its address is taken, meaning that unlike 'ReadOnly' vars we can't
    1158                 :             :     //   internalize it.
    1159                 :             :     // Constant variables are always imported thus giving compiler an
    1160                 :             :     // opportunity to make some extra optimizations. Readonly constants
    1161                 :             :     // are also internalized.
    1162                 :             :     unsigned Constant : 1;
    1163                 :             :     // Set from metadata on vtable definitions during the module summary
    1164                 :             :     // analysis.
    1165                 :             :     unsigned VCallVisibility : 2;
    1166                 :             :   } VarFlags;
    1167                 :             : 
    1168                 :             :   GlobalVarSummary(GVFlags Flags, GVarFlags VarFlags,
    1169                 :             :                    std::vector<ValueInfo> Refs)
    1170                 :             :       : GlobalValueSummary(GlobalVarKind, Flags, std::move(Refs)),
    1171                 :             :         VarFlags(VarFlags) {}
    1172                 :             : 
    1173                 :             :   /// Check if this is a global variable summary.
    1174                 :             :   static bool classof(const GlobalValueSummary *GVS) {
    1175                 :             :     return GVS->getSummaryKind() == GlobalVarKind;
    1176                 :             :   }
    1177                 :             : 
    1178                 :             :   GVarFlags varflags() const { return VarFlags; }
    1179                 :             :   void setReadOnly(bool RO) { VarFlags.MaybeReadOnly = RO; }
    1180                 :             :   void setWriteOnly(bool WO) { VarFlags.MaybeWriteOnly = WO; }
    1181                 :             :   bool maybeReadOnly() const { return VarFlags.MaybeReadOnly; }
    1182                 :             :   bool maybeWriteOnly() const { return VarFlags.MaybeWriteOnly; }
    1183                 :             :   bool isConstant() const { return VarFlags.Constant; }
    1184                 :             :   void setVCallVisibility(GlobalObject::VCallVisibility Vis) {
    1185                 :             :     VarFlags.VCallVisibility = Vis;
    1186                 :             :   }
    1187                 :             :   GlobalObject::VCallVisibility getVCallVisibility() const {
    1188                 :             :     return (GlobalObject::VCallVisibility)VarFlags.VCallVisibility;
    1189                 :             :   }
    1190                 :             : 
    1191                 :             :   void setVTableFuncs(VTableFuncList Funcs) {
    1192                 :             :     assert(!VTableFuncs);
    1193                 :             :     VTableFuncs = std::make_unique<VTableFuncList>(std::move(Funcs));
    1194                 :             :   }
    1195                 :             : 
    1196                 :             :   ArrayRef<VirtFuncOffset> vTableFuncs() const {
    1197                 :             :     if (VTableFuncs)
    1198                 :             :       return *VTableFuncs;
    1199                 :             :     return {};
    1200                 :             :   }
    1201                 :             : };
    1202                 :             : 
    1203                 :             : struct TypeTestResolution {
    1204                 :             :   /// Specifies which kind of type check we should emit for this byte array.
    1205                 :             :   /// See http://clang.llvm.org/docs/ControlFlowIntegrityDesign.html for full
    1206                 :             :   /// details on each kind of check; the enumerators are described with
    1207                 :             :   /// reference to that document.
    1208                 :             :   enum Kind {
    1209                 :             :     Unsat,     ///< Unsatisfiable type (i.e. no global has this type metadata)
    1210                 :             :     ByteArray, ///< Test a byte array (first example)
    1211                 :             :     Inline,    ///< Inlined bit vector ("Short Inline Bit Vectors")
    1212                 :             :     Single,    ///< Single element (last example in "Short Inline Bit Vectors")
    1213                 :             :     AllOnes,   ///< All-ones bit vector ("Eliminating Bit Vector Checks for
    1214                 :             :                ///  All-Ones Bit Vectors")
    1215                 :             :     Unknown,   ///< Unknown (analysis not performed, don't lower)
    1216                 :             :   } TheKind = Unknown;
    1217                 :             : 
    1218                 :             :   /// Range of size-1 expressed as a bit width. For example, if the size is in
    1219                 :             :   /// range [1,256], this number will be 8. This helps generate the most compact
    1220                 :             :   /// instruction sequences.
    1221                 :             :   unsigned SizeM1BitWidth = 0;
    1222                 :             : 
    1223                 :             :   // The following fields are only used if the target does not support the use
    1224                 :             :   // of absolute symbols to store constants. Their meanings are the same as the
    1225                 :             :   // corresponding fields in LowerTypeTestsModule::TypeIdLowering in
    1226                 :             :   // LowerTypeTests.cpp.
    1227                 :             : 
    1228                 :             :   uint64_t AlignLog2 = 0;
    1229                 :             :   uint64_t SizeM1 = 0;
    1230                 :             :   uint8_t BitMask = 0;
    1231                 :             :   uint64_t InlineBits = 0;
    1232                 :             : };
    1233                 :             : 
    1234                 :             : struct WholeProgramDevirtResolution {
    1235                 :             :   enum Kind {
    1236                 :             :     Indir,        ///< Just do a regular virtual call
    1237                 :             :     SingleImpl,   ///< Single implementation devirtualization
    1238                 :             :     BranchFunnel, ///< When retpoline mitigation is enabled, use a branch funnel
    1239                 :             :                   ///< that is defined in the merged module. Otherwise same as
    1240                 :             :                   ///< Indir.
    1241                 :             :   } TheKind = Indir;
    1242                 :             : 
    1243                 :             :   std::string SingleImplName;
    1244                 :             : 
    1245                 :             :   struct ByArg {
    1246                 :             :     enum Kind {
    1247                 :             :       Indir,            ///< Just do a regular virtual call
    1248                 :             :       UniformRetVal,    ///< Uniform return value optimization
    1249                 :             :       UniqueRetVal,     ///< Unique return value optimization
    1250                 :             :       VirtualConstProp, ///< Virtual constant propagation
    1251                 :             :     } TheKind = Indir;
    1252                 :             : 
    1253                 :             :     /// Additional information for the resolution:
    1254                 :             :     /// - UniformRetVal: the uniform return value.
    1255                 :             :     /// - UniqueRetVal: the return value associated with the unique vtable (0 or
    1256                 :             :     ///   1).
    1257                 :             :     uint64_t Info = 0;
    1258                 :             : 
    1259                 :             :     // The following fields are only used if the target does not support the use
    1260                 :             :     // of absolute symbols to store constants.
    1261                 :             : 
    1262                 :             :     uint32_t Byte = 0;
    1263                 :             :     uint32_t Bit = 0;
    1264                 :             :   };
    1265                 :             : 
    1266                 :             :   /// Resolutions for calls with all constant integer arguments (excluding the
    1267                 :             :   /// first argument, "this"), where the key is the argument vector.
    1268                 :             :   std::map<std::vector<uint64_t>, ByArg> ResByArg;
    1269                 :             : };
    1270                 :             : 
    1271                 :             : struct TypeIdSummary {
    1272                 :             :   TypeTestResolution TTRes;
    1273                 :             : 
    1274                 :             :   /// Mapping from byte offset to whole-program devirt resolution for that
    1275                 :             :   /// (typeid, byte offset) pair.
    1276                 :             :   std::map<uint64_t, WholeProgramDevirtResolution> WPDRes;
    1277                 :             : };
    1278                 :             : 
    1279                 :             : /// 160 bits SHA1
    1280                 :             : using ModuleHash = std::array<uint32_t, 5>;
    1281                 :             : 
    1282                 :             : /// Type used for iterating through the global value summary map.
    1283                 :             : using const_gvsummary_iterator = GlobalValueSummaryMapTy::const_iterator;
    1284                 :             : using gvsummary_iterator = GlobalValueSummaryMapTy::iterator;
    1285                 :             : 
    1286                 :             : /// String table to hold/own module path strings, as well as a hash
    1287                 :             : /// of the module. The StringMap makes a copy of and owns inserted strings.
    1288                 :             : using ModulePathStringTableTy = StringMap<ModuleHash>;
    1289                 :             : 
    1290                 :             : /// Map of global value GUID to its summary, used to identify values defined in
    1291                 :             : /// a particular module, and provide efficient access to their summary.
    1292                 :             : using GVSummaryMapTy = DenseMap<GlobalValue::GUID, GlobalValueSummary *>;
    1293                 :             : 
    1294                 :             : /// A set of global value summary pointers.
    1295                 :             : using GVSummaryPtrSet = std::unordered_set<GlobalValueSummary *>;
    1296                 :             : 
    1297                 :             : /// Map of a type GUID to type id string and summary (multimap used
    1298                 :             : /// in case of GUID conflicts).
    1299                 :             : using TypeIdSummaryMapTy =
    1300                 :             :     std::multimap<GlobalValue::GUID, std::pair<std::string, TypeIdSummary>>;
    1301                 :             : 
    1302                 :             : /// The following data structures summarize type metadata information.
    1303                 :             : /// For type metadata overview see https://llvm.org/docs/TypeMetadata.html.
    1304                 :             : /// Each type metadata includes both the type identifier and the offset of
    1305                 :             : /// the address point of the type (the address held by objects of that type
    1306                 :             : /// which may not be the beginning of the virtual table). Vtable definitions
    1307                 :             : /// are decorated with type metadata for the types they are compatible with.
    1308                 :             : ///
    1309                 :             : /// Holds information about vtable definitions decorated with type metadata:
    1310                 :             : /// the vtable definition value and its address point offset in a type
    1311                 :             : /// identifier metadata it is decorated (compatible) with.
    1312                 :             : struct TypeIdOffsetVtableInfo {
    1313                 :             :   TypeIdOffsetVtableInfo(uint64_t Offset, ValueInfo VI)
    1314                 :             :       : AddressPointOffset(Offset), VTableVI(VI) {}
    1315                 :             : 
    1316                 :             :   uint64_t AddressPointOffset;
    1317                 :             :   ValueInfo VTableVI;
    1318                 :             : };
    1319                 :             : /// List of vtable definitions decorated by a particular type identifier,
    1320                 :             : /// and their corresponding offsets in that type identifier's metadata.
    1321                 :             : /// Note that each type identifier may be compatible with multiple vtables, due
    1322                 :             : /// to inheritance, which is why this is a vector.
    1323                 :             : using TypeIdCompatibleVtableInfo = std::vector<TypeIdOffsetVtableInfo>;
    1324                 :             : 
    1325                 :             : /// Class to hold module path string table and global value map,
    1326                 :             : /// and encapsulate methods for operating on them.
    1327                 :             : class ModuleSummaryIndex {
    1328                 :             : private:
    1329                 :             :   /// Map from value name to list of summary instances for values of that
    1330                 :             :   /// name (may be duplicates in the COMDAT case, e.g.).
    1331                 :             :   GlobalValueSummaryMapTy GlobalValueMap;
    1332                 :             : 
    1333                 :             :   /// Holds strings for combined index, mapping to the corresponding module ID.
    1334                 :             :   ModulePathStringTableTy ModulePathStringTable;
    1335                 :             : 
    1336                 :             :   /// Mapping from type identifier GUIDs to type identifier and its summary
    1337                 :             :   /// information. Produced by thin link.
    1338                 :             :   TypeIdSummaryMapTy TypeIdMap;
    1339                 :             : 
    1340                 :             :   /// Mapping from type identifier to information about vtables decorated
    1341                 :             :   /// with that type identifier's metadata. Produced by per module summary
    1342                 :             :   /// analysis and consumed by thin link. For more information, see description
    1343                 :             :   /// above where TypeIdCompatibleVtableInfo is defined.
    1344                 :             :   std::map<std::string, TypeIdCompatibleVtableInfo, std::less<>>
    1345                 :             :       TypeIdCompatibleVtableMap;
    1346                 :             : 
    1347                 :             :   /// Mapping from original ID to GUID. If original ID can map to multiple
    1348                 :             :   /// GUIDs, it will be mapped to 0.
    1349                 :             :   std::map<GlobalValue::GUID, GlobalValue::GUID> OidGuidMap;
    1350                 :             : 
    1351                 :             :   /// Indicates that summary-based GlobalValue GC has run, and values with
    1352                 :             :   /// GVFlags::Live==false are really dead. Otherwise, all values must be
    1353                 :             :   /// considered live.
    1354                 :             :   bool WithGlobalValueDeadStripping = false;
    1355                 :             : 
    1356                 :             :   /// Indicates that summary-based attribute propagation has run and
    1357                 :             :   /// GVarFlags::MaybeReadonly / GVarFlags::MaybeWriteonly are really
    1358                 :             :   /// read/write only.
    1359                 :             :   bool WithAttributePropagation = false;
    1360                 :             : 
    1361                 :             :   /// Indicates that summary-based DSOLocal propagation has run and the flag in
    1362                 :             :   /// every summary of a GV is synchronized.
    1363                 :             :   bool WithDSOLocalPropagation = false;
    1364                 :             : 
    1365                 :             :   /// Indicates that we have whole program visibility.
    1366                 :             :   bool WithWholeProgramVisibility = false;
    1367                 :             : 
    1368                 :             :   /// Indicates that summary-based synthetic entry count propagation has run
    1369                 :             :   bool HasSyntheticEntryCounts = false;
    1370                 :             : 
    1371                 :             :   /// Indicates that we linked with allocator supporting hot/cold new operators.
    1372                 :             :   bool WithSupportsHotColdNew = false;
    1373                 :             : 
    1374                 :             :   /// Indicates that distributed backend should skip compilation of the
    1375                 :             :   /// module. Flag is suppose to be set by distributed ThinLTO indexing
    1376                 :             :   /// when it detected that the module is not needed during the final
    1377                 :             :   /// linking. As result distributed backend should just output a minimal
    1378                 :             :   /// valid object file.
    1379                 :             :   bool SkipModuleByDistributedBackend = false;
    1380                 :             : 
    1381                 :             :   /// If true then we're performing analysis of IR module, or parsing along with
    1382                 :             :   /// the IR from assembly. The value of 'false' means we're reading summary
    1383                 :             :   /// from BC or YAML source. Affects the type of value stored in NameOrGV
    1384                 :             :   /// union.
    1385                 :             :   bool HaveGVs;
    1386                 :             : 
    1387                 :             :   // True if the index was created for a module compiled with -fsplit-lto-unit.
    1388                 :             :   bool EnableSplitLTOUnit;
    1389                 :             : 
    1390                 :             :   // True if the index was created for a module compiled with -funified-lto
    1391                 :             :   bool UnifiedLTO;
    1392                 :             : 
    1393                 :             :   // True if some of the modules were compiled with -fsplit-lto-unit and
    1394                 :             :   // some were not. Set when the combined index is created during the thin link.
    1395                 :             :   bool PartiallySplitLTOUnits = false;
    1396                 :             : 
    1397                 :             :   /// True if some of the FunctionSummary contains a ParamAccess.
    1398                 :             :   bool HasParamAccess = false;
    1399                 :             : 
    1400                 :             :   std::set<std::string> CfiFunctionDefs;
    1401                 :             :   std::set<std::string> CfiFunctionDecls;
    1402                 :             : 
    1403                 :             :   // Used in cases where we want to record the name of a global, but
    1404                 :             :   // don't have the string owned elsewhere (e.g. the Strtab on a module).
    1405                 :             :   BumpPtrAllocator Alloc;
    1406                 :             :   StringSaver Saver;
    1407                 :             : 
    1408                 :             :   // The total number of basic blocks in the module in the per-module summary or
    1409                 :             :   // the total number of basic blocks in the LTO unit in the combined index.
    1410                 :             :   // FIXME: Putting this in the distributed ThinLTO index files breaks LTO
    1411                 :             :   // backend caching on any BB change to any linked file. It is currently not
    1412                 :             :   // used except in the case of a SamplePGO partial profile, and should be
    1413                 :             :   // reevaluated/redesigned to allow more effective incremental builds in that
    1414                 :             :   // case.
    1415                 :             :   uint64_t BlockCount;
    1416                 :             : 
    1417                 :             :   // List of unique stack ids (hashes). We use a 4B index of the id in the
    1418                 :             :   // stack id lists on the alloc and callsite summaries for memory savings,
    1419                 :             :   // since the number of unique ids is in practice much smaller than the
    1420                 :             :   // number of stack id references in the summaries.
    1421                 :             :   std::vector<uint64_t> StackIds;
    1422                 :             : 
    1423                 :             :   // Temporary map while building StackIds list. Clear when index is completely
    1424                 :             :   // built via releaseTemporaryMemory.
    1425                 :             :   DenseMap<uint64_t, unsigned> StackIdToIndex;
    1426                 :             : 
    1427                 :             :   // YAML I/O support.
    1428                 :             :   friend yaml::MappingTraits<ModuleSummaryIndex>;
    1429                 :             : 
    1430                 :             :   GlobalValueSummaryMapTy::value_type *
    1431                 :             :   getOrInsertValuePtr(GlobalValue::GUID GUID) {
    1432                 :             :     return &*GlobalValueMap.emplace(GUID, GlobalValueSummaryInfo(HaveGVs))
    1433                 :             :                  .first;
    1434                 :             :   }
    1435                 :             : 
    1436                 :             : public:
    1437                 :             :   // See HaveGVs variable comment.
    1438                 :             :   ModuleSummaryIndex(bool HaveGVs, bool EnableSplitLTOUnit = false,
    1439                 :             :                      bool UnifiedLTO = false)
    1440                 :             :       : HaveGVs(HaveGVs), EnableSplitLTOUnit(EnableSplitLTOUnit),
    1441                 :             :         UnifiedLTO(UnifiedLTO), Saver(Alloc), BlockCount(0) {}
    1442                 :             : 
    1443                 :             :   // Current version for the module summary in bitcode files.
    1444                 :             :   // The BitcodeSummaryVersion should be bumped whenever we introduce changes
    1445                 :             :   // in the way some record are interpreted, like flags for instance.
    1446                 :             :   // Note that incrementing this may require changes in both BitcodeReader.cpp
    1447                 :             :   // and BitcodeWriter.cpp.
    1448                 :             :   static constexpr uint64_t BitcodeSummaryVersion = 10;
    1449                 :             : 
    1450                 :             :   // Regular LTO module name for ASM writer
    1451                 :             :   static constexpr const char *getRegularLTOModuleName() {
    1452                 :             :     return "[Regular LTO]";
    1453                 :             :   }
    1454                 :             : 
    1455                 :             :   bool haveGVs() const { return HaveGVs; }
    1456                 :             : 
    1457                 :             :   uint64_t getFlags() const;
    1458                 :             :   void setFlags(uint64_t Flags);
    1459                 :             : 
    1460                 :             :   uint64_t getBlockCount() const { return BlockCount; }
    1461                 :             :   void addBlockCount(uint64_t C) { BlockCount += C; }
    1462                 :             :   void setBlockCount(uint64_t C) { BlockCount = C; }
    1463                 :             : 
    1464                 :             :   gvsummary_iterator begin() { return GlobalValueMap.begin(); }
    1465                 :             :   const_gvsummary_iterator begin() const { return GlobalValueMap.begin(); }
    1466                 :             :   gvsummary_iterator end() { return GlobalValueMap.end(); }
    1467                 :             :   const_gvsummary_iterator end() const { return GlobalValueMap.end(); }
    1468                 :             :   size_t size() const { return GlobalValueMap.size(); }
    1469                 :             : 
    1470                 :             :   const std::vector<uint64_t> &stackIds() const { return StackIds; }
    1471                 :             : 
    1472                 :             :   unsigned addOrGetStackIdIndex(uint64_t StackId) {
    1473                 :             :     auto Inserted = StackIdToIndex.insert({StackId, StackIds.size()});
    1474                 :             :     if (Inserted.second)
    1475                 :             :       StackIds.push_back(StackId);
    1476                 :             :     return Inserted.first->second;
    1477                 :             :   }
    1478                 :             : 
    1479                 :             :   uint64_t getStackIdAtIndex(unsigned Index) const {
    1480                 :             :     assert(StackIds.size() > Index);
    1481                 :             :     return StackIds[Index];
    1482                 :             :   }
    1483                 :             : 
    1484                 :             :   // Facility to release memory from data structures only needed during index
    1485                 :             :   // construction (including while building combined index). Currently this only
    1486                 :             :   // releases the temporary map used while constructing a correspondence between
    1487                 :             :   // stack ids and their index in the StackIds vector. Mostly impactful when
    1488                 :             :   // building a large combined index.
    1489                 :             :   void releaseTemporaryMemory() {
    1490                 :             :     assert(StackIdToIndex.size() == StackIds.size());
    1491                 :             :     StackIdToIndex.clear();
    1492                 :             :     StackIds.shrink_to_fit();
    1493                 :             :   }
    1494                 :             : 
    1495                 :             :   /// Convenience function for doing a DFS on a ValueInfo. Marks the function in
    1496                 :             :   /// the FunctionHasParent map.
    1497                 :             :   static void discoverNodes(ValueInfo V,
    1498                 :             :                             std::map<ValueInfo, bool> &FunctionHasParent) {
    1499                 :             :     if (!V.getSummaryList().size())
    1500                 :             :       return; // skip external functions that don't have summaries
    1501                 :             : 
    1502                 :             :     // Mark discovered if we haven't yet
    1503                 :             :     auto S = FunctionHasParent.emplace(V, false);
    1504                 :             : 
    1505                 :             :     // Stop if we've already discovered this node
    1506                 :             :     if (!S.second)
    1507                 :             :       return;
    1508                 :             : 
    1509                 :             :     FunctionSummary *F =
    1510                 :             :         dyn_cast<FunctionSummary>(V.getSummaryList().front().get());
    1511                 :             :     assert(F != nullptr && "Expected FunctionSummary node");
    1512                 :             : 
    1513                 :             :     for (const auto &C : F->calls()) {
    1514                 :             :       // Insert node if necessary
    1515                 :             :       auto S = FunctionHasParent.emplace(C.first, true);
    1516                 :             : 
    1517                 :             :       // Skip nodes that we're sure have parents
    1518                 :             :       if (!S.second && S.first->second)
    1519                 :             :         continue;
    1520                 :             : 
    1521                 :             :       if (S.second)
    1522                 :             :         discoverNodes(C.first, FunctionHasParent);
    1523                 :             :       else
    1524                 :             :         S.first->second = true;
    1525                 :             :     }
    1526                 :             :   }
    1527                 :             : 
    1528                 :             :   // Calculate the callgraph root
    1529                 :             :   FunctionSummary calculateCallGraphRoot() {
    1530                 :             :     // Functions that have a parent will be marked in FunctionHasParent pair.
    1531                 :             :     // Once we've marked all functions, the functions in the map that are false
    1532                 :             :     // have no parent (so they're the roots)
    1533                 :             :     std::map<ValueInfo, bool> FunctionHasParent;
    1534                 :             : 
    1535                 :             :     for (auto &S : *this) {
    1536                 :             :       // Skip external functions
    1537                 :             :       if (!S.second.SummaryList.size() ||
    1538                 :             :           !isa<FunctionSummary>(S.second.SummaryList.front().get()))
    1539                 :             :         continue;
    1540                 :             :       discoverNodes(ValueInfo(HaveGVs, &S), FunctionHasParent);
    1541                 :             :     }
    1542                 :             : 
    1543                 :             :     std::vector<FunctionSummary::EdgeTy> Edges;
    1544                 :             :     // create edges to all roots in the Index
    1545                 :             :     for (auto &P : FunctionHasParent) {
    1546                 :             :       if (P.second)
    1547                 :             :         continue; // skip over non-root nodes
    1548                 :             :       Edges.push_back(std::make_pair(P.first, CalleeInfo{}));
    1549                 :             :     }
    1550                 :             :     if (Edges.empty()) {
    1551                 :             :       // Failed to find root - return an empty node
    1552                 :             :       return FunctionSummary::makeDummyFunctionSummary({});
    1553                 :             :     }
    1554                 :             :     auto CallGraphRoot = FunctionSummary::makeDummyFunctionSummary(Edges);
    1555                 :             :     return CallGraphRoot;
    1556                 :             :   }
    1557                 :             : 
    1558                 :             :   bool withGlobalValueDeadStripping() const {
    1559                 :             :     return WithGlobalValueDeadStripping;
    1560                 :             :   }
    1561                 :             :   void setWithGlobalValueDeadStripping() {
    1562                 :             :     WithGlobalValueDeadStripping = true;
    1563                 :             :   }
    1564                 :             : 
    1565                 :             :   bool withAttributePropagation() const { return WithAttributePropagation; }
    1566                 :             :   void setWithAttributePropagation() {
    1567                 :             :     WithAttributePropagation = true;
    1568                 :             :   }
    1569                 :             : 
    1570                 :             :   bool withDSOLocalPropagation() const { return WithDSOLocalPropagation; }
    1571                 :             :   void setWithDSOLocalPropagation() { WithDSOLocalPropagation = true; }
    1572                 :             : 
    1573                 :             :   bool withWholeProgramVisibility() const { return WithWholeProgramVisibility; }
    1574                 :             :   void setWithWholeProgramVisibility() { WithWholeProgramVisibility = true; }
    1575                 :             : 
    1576                 :             :   bool isReadOnly(const GlobalVarSummary *GVS) const {
    1577                 :             :     return WithAttributePropagation && GVS->maybeReadOnly();
    1578                 :             :   }
    1579                 :             :   bool isWriteOnly(const GlobalVarSummary *GVS) const {
    1580                 :             :     return WithAttributePropagation && GVS->maybeWriteOnly();
    1581                 :             :   }
    1582                 :             : 
    1583                 :             :   bool hasSyntheticEntryCounts() const { return HasSyntheticEntryCounts; }
    1584                 :             :   void setHasSyntheticEntryCounts() { HasSyntheticEntryCounts = true; }
    1585                 :             : 
    1586                 :             :   bool withSupportsHotColdNew() const { return WithSupportsHotColdNew; }
    1587                 :             :   void setWithSupportsHotColdNew() { WithSupportsHotColdNew = true; }
    1588                 :             : 
    1589                 :             :   bool skipModuleByDistributedBackend() const {
    1590                 :             :     return SkipModuleByDistributedBackend;
    1591                 :             :   }
    1592                 :             :   void setSkipModuleByDistributedBackend() {
    1593                 :             :     SkipModuleByDistributedBackend = true;
    1594                 :             :   }
    1595                 :             : 
    1596                 :             :   bool enableSplitLTOUnit() const { return EnableSplitLTOUnit; }
    1597                 :             :   void setEnableSplitLTOUnit() { EnableSplitLTOUnit = true; }
    1598                 :             : 
    1599                 :             :   bool hasUnifiedLTO() const { return UnifiedLTO; }
    1600                 :             :   void setUnifiedLTO() { UnifiedLTO = true; }
    1601                 :             : 
    1602                 :             :   bool partiallySplitLTOUnits() const { return PartiallySplitLTOUnits; }
    1603                 :             :   void setPartiallySplitLTOUnits() { PartiallySplitLTOUnits = true; }
    1604                 :             : 
    1605                 :             :   bool hasParamAccess() const { return HasParamAccess; }
    1606                 :             : 
    1607                 :             :   bool isGlobalValueLive(const GlobalValueSummary *GVS) const {
    1608                 :             :     return !WithGlobalValueDeadStripping || GVS->isLive();
    1609                 :             :   }
    1610                 :             :   bool isGUIDLive(GlobalValue::GUID GUID) const;
    1611                 :             : 
    1612                 :             :   /// Return a ValueInfo for the index value_type (convenient when iterating
    1613                 :             :   /// index).
    1614                 :             :   ValueInfo getValueInfo(const GlobalValueSummaryMapTy::value_type &R) const {
    1615                 :             :     return ValueInfo(HaveGVs, &R);
    1616                 :             :   }
    1617                 :             : 
    1618                 :             :   /// Return a ValueInfo for GUID if it exists, otherwise return ValueInfo().
    1619                 :           0 :   ValueInfo getValueInfo(GlobalValue::GUID GUID) const {
    1620         [ #  # ]:           0 :     auto I = GlobalValueMap.find(GUID);
    1621   [ #  #  #  # ]:           0 :     return ValueInfo(HaveGVs, I == GlobalValueMap.end() ? nullptr : &*I);
    1622                 :             :   }
    1623                 :             : 
    1624                 :             :   /// Return a ValueInfo for \p GUID.
    1625                 :             :   ValueInfo getOrInsertValueInfo(GlobalValue::GUID GUID) {
    1626                 :             :     return ValueInfo(HaveGVs, getOrInsertValuePtr(GUID));
    1627                 :             :   }
    1628                 :             : 
    1629                 :             :   // Save a string in the Index. Use before passing Name to
    1630                 :             :   // getOrInsertValueInfo when the string isn't owned elsewhere (e.g. on the
    1631                 :             :   // module's Strtab).
    1632                 :             :   StringRef saveString(StringRef String) { return Saver.save(String); }
    1633                 :             : 
    1634                 :             :   /// Return a ValueInfo for \p GUID setting value \p Name.
    1635                 :             :   ValueInfo getOrInsertValueInfo(GlobalValue::GUID GUID, StringRef Name) {
    1636                 :             :     assert(!HaveGVs);
    1637                 :             :     auto VP = getOrInsertValuePtr(GUID);
    1638                 :             :     VP->second.U.Name = Name;
    1639                 :             :     return ValueInfo(HaveGVs, VP);
    1640                 :             :   }
    1641                 :             : 
    1642                 :             :   /// Return a ValueInfo for \p GV and mark it as belonging to GV.
    1643                 :             :   ValueInfo getOrInsertValueInfo(const GlobalValue *GV) {
    1644                 :             :     assert(HaveGVs);
    1645                 :             :     auto VP = getOrInsertValuePtr(GV->getGUID());
    1646                 :             :     VP->second.U.GV = GV;
    1647                 :             :     return ValueInfo(HaveGVs, VP);
    1648                 :             :   }
    1649                 :             : 
    1650                 :             :   /// Return the GUID for \p OriginalId in the OidGuidMap.
    1651                 :             :   GlobalValue::GUID getGUIDFromOriginalID(GlobalValue::GUID OriginalID) const {
    1652                 :             :     const auto I = OidGuidMap.find(OriginalID);
    1653                 :             :     return I == OidGuidMap.end() ? 0 : I->second;
    1654                 :             :   }
    1655                 :             : 
    1656                 :             :   std::set<std::string> &cfiFunctionDefs() { return CfiFunctionDefs; }
    1657                 :             :   const std::set<std::string> &cfiFunctionDefs() const { return CfiFunctionDefs; }
    1658                 :             : 
    1659                 :             :   std::set<std::string> &cfiFunctionDecls() { return CfiFunctionDecls; }
    1660                 :             :   const std::set<std::string> &cfiFunctionDecls() const { return CfiFunctionDecls; }
    1661                 :             : 
    1662                 :             :   /// Add a global value summary for a value.
    1663                 :             :   void addGlobalValueSummary(const GlobalValue &GV,
    1664                 :             :                              std::unique_ptr<GlobalValueSummary> Summary) {
    1665                 :             :     addGlobalValueSummary(getOrInsertValueInfo(&GV), std::move(Summary));
    1666                 :             :   }
    1667                 :             : 
    1668                 :             :   /// Add a global value summary for a value of the given name.
    1669                 :             :   void addGlobalValueSummary(StringRef ValueName,
    1670                 :             :                              std::unique_ptr<GlobalValueSummary> Summary) {
    1671                 :             :     addGlobalValueSummary(getOrInsertValueInfo(GlobalValue::getGUID(ValueName)),
    1672                 :             :                           std::move(Summary));
    1673                 :             :   }
    1674                 :             : 
    1675                 :             :   /// Add a global value summary for the given ValueInfo.
    1676                 :             :   void addGlobalValueSummary(ValueInfo VI,
    1677                 :             :                              std::unique_ptr<GlobalValueSummary> Summary) {
    1678                 :             :     if (const FunctionSummary *FS = dyn_cast<FunctionSummary>(Summary.get()))
    1679                 :             :       HasParamAccess |= !FS->paramAccesses().empty();
    1680                 :             :     addOriginalName(VI.getGUID(), Summary->getOriginalName());
    1681                 :             :     // Here we have a notionally const VI, but the value it points to is owned
    1682                 :             :     // by the non-const *this.
    1683                 :             :     const_cast<GlobalValueSummaryMapTy::value_type *>(VI.getRef())
    1684                 :             :         ->second.SummaryList.push_back(std::move(Summary));
    1685                 :             :   }
    1686                 :             : 
    1687                 :             :   /// Add an original name for the value of the given GUID.
    1688                 :             :   void addOriginalName(GlobalValue::GUID ValueGUID,
    1689                 :             :                        GlobalValue::GUID OrigGUID) {
    1690                 :             :     if (OrigGUID == 0 || ValueGUID == OrigGUID)
    1691                 :             :       return;
    1692                 :             :     if (OidGuidMap.count(OrigGUID) && OidGuidMap[OrigGUID] != ValueGUID)
    1693                 :             :       OidGuidMap[OrigGUID] = 0;
    1694                 :             :     else
    1695                 :             :       OidGuidMap[OrigGUID] = ValueGUID;
    1696                 :             :   }
    1697                 :             : 
    1698                 :             :   /// Find the summary for ValueInfo \p VI in module \p ModuleId, or nullptr if
    1699                 :             :   /// not found.
    1700                 :             :   GlobalValueSummary *findSummaryInModule(ValueInfo VI, StringRef ModuleId) const {
    1701                 :             :     auto SummaryList = VI.getSummaryList();
    1702                 :             :     auto Summary =
    1703                 :             :         llvm::find_if(SummaryList,
    1704                 :             :                       [&](const std::unique_ptr<GlobalValueSummary> &Summary) {
    1705                 :             :                         return Summary->modulePath() == ModuleId;
    1706                 :             :                       });
    1707                 :             :     if (Summary == SummaryList.end())
    1708                 :             :       return nullptr;
    1709                 :             :     return Summary->get();
    1710                 :             :   }
    1711                 :             : 
    1712                 :             :   /// Find the summary for global \p GUID in module \p ModuleId, or nullptr if
    1713                 :             :   /// not found.
    1714                 :             :   GlobalValueSummary *findSummaryInModule(GlobalValue::GUID ValueGUID,
    1715                 :             :                                           StringRef ModuleId) const {
    1716                 :             :     auto CalleeInfo = getValueInfo(ValueGUID);
    1717                 :             :     if (!CalleeInfo)
    1718                 :             :       return nullptr; // This function does not have a summary
    1719                 :             :     return findSummaryInModule(CalleeInfo, ModuleId);
    1720                 :             :   }
    1721                 :             : 
    1722                 :             :   /// Returns the first GlobalValueSummary for \p GV, asserting that there
    1723                 :             :   /// is only one if \p PerModuleIndex.
    1724                 :             :   GlobalValueSummary *getGlobalValueSummary(const GlobalValue &GV,
    1725                 :             :                                             bool PerModuleIndex = true) const {
    1726                 :             :     assert(GV.hasName() && "Can't get GlobalValueSummary for GV with no name");
    1727                 :             :     return getGlobalValueSummary(GV.getGUID(), PerModuleIndex);
    1728                 :             :   }
    1729                 :             : 
    1730                 :             :   /// Returns the first GlobalValueSummary for \p ValueGUID, asserting that
    1731                 :             :   /// there
    1732                 :             :   /// is only one if \p PerModuleIndex.
    1733                 :             :   GlobalValueSummary *getGlobalValueSummary(GlobalValue::GUID ValueGUID,
    1734                 :             :                                             bool PerModuleIndex = true) const;
    1735                 :             : 
    1736                 :             :   /// Table of modules, containing module hash and id.
    1737                 :             :   const StringMap<ModuleHash> &modulePaths() const {
    1738                 :             :     return ModulePathStringTable;
    1739                 :             :   }
    1740                 :             : 
    1741                 :             :   /// Table of modules, containing hash and id.
    1742                 :             :   StringMap<ModuleHash> &modulePaths() { return ModulePathStringTable; }
    1743                 :             : 
    1744                 :             :   /// Get the module SHA1 hash recorded for the given module path.
    1745                 :             :   const ModuleHash &getModuleHash(const StringRef ModPath) const {
    1746                 :             :     auto It = ModulePathStringTable.find(ModPath);
    1747                 :             :     assert(It != ModulePathStringTable.end() && "Module not registered");
    1748                 :             :     return It->second;
    1749                 :             :   }
    1750                 :             : 
    1751                 :             :   /// Convenience method for creating a promoted global name
    1752                 :             :   /// for the given value name of a local, and its original module's ID.
    1753                 :             :   static std::string getGlobalNameForLocal(StringRef Name, ModuleHash ModHash) {
    1754                 :             :     std::string Suffix = utostr((uint64_t(ModHash[0]) << 32) |
    1755                 :             :                                 ModHash[1]); // Take the first 64 bits
    1756                 :             :     return getGlobalNameForLocal(Name, Suffix);
    1757                 :             :   }
    1758                 :             : 
    1759                 :             :   static std::string getGlobalNameForLocal(StringRef Name, StringRef Suffix) {
    1760                 :             :     SmallString<256> NewName(Name);
    1761                 :             :     NewName += ".llvm.";
    1762                 :             :     NewName += Suffix;
    1763                 :             :     return std::string(NewName);
    1764                 :             :   }
    1765                 :             : 
    1766                 :             :   /// Helper to obtain the unpromoted name for a global value (or the original
    1767                 :             :   /// name if not promoted). Split off the rightmost ".llvm.${hash}" suffix,
    1768                 :             :   /// because it is possible in certain clients (not clang at the moment) for
    1769                 :             :   /// two rounds of ThinLTO optimization and therefore promotion to occur.
    1770                 :             :   static StringRef getOriginalNameBeforePromote(StringRef Name) {
    1771                 :             :     std::pair<StringRef, StringRef> Pair = Name.rsplit(".llvm.");
    1772                 :             :     return Pair.first;
    1773                 :             :   }
    1774                 :             : 
    1775                 :             :   typedef ModulePathStringTableTy::value_type ModuleInfo;
    1776                 :             : 
    1777                 :             :   /// Add a new module with the given \p Hash, mapped to the given \p
    1778                 :             :   /// ModID, and return a reference to the module.
    1779                 :             :   ModuleInfo *addModule(StringRef ModPath, ModuleHash Hash = ModuleHash{{0}}) {
    1780                 :             :     return &*ModulePathStringTable.insert({ModPath, Hash}).first;
    1781                 :             :   }
    1782                 :             : 
    1783                 :             :   /// Return module entry for module with the given \p ModPath.
    1784                 :             :   ModuleInfo *getModule(StringRef ModPath) {
    1785                 :             :     auto It = ModulePathStringTable.find(ModPath);
    1786                 :             :     assert(It != ModulePathStringTable.end() && "Module not registered");
    1787                 :             :     return &*It;
    1788                 :             :   }
    1789                 :             : 
    1790                 :             :   /// Return module entry for module with the given \p ModPath.
    1791                 :             :   const ModuleInfo *getModule(StringRef ModPath) const {
    1792                 :             :     auto It = ModulePathStringTable.find(ModPath);
    1793                 :             :     assert(It != ModulePathStringTable.end() && "Module not registered");
    1794                 :             :     return &*It;
    1795                 :             :   }
    1796                 :             : 
    1797                 :             :   /// Check if the given Module has any functions available for exporting
    1798                 :             :   /// in the index. We consider any module present in the ModulePathStringTable
    1799                 :             :   /// to have exported functions.
    1800                 :             :   bool hasExportedFunctions(const Module &M) const {
    1801                 :             :     return ModulePathStringTable.count(M.getModuleIdentifier());
    1802                 :             :   }
    1803                 :             : 
    1804                 :             :   const TypeIdSummaryMapTy &typeIds() const { return TypeIdMap; }
    1805                 :             : 
    1806                 :             :   /// Return an existing or new TypeIdSummary entry for \p TypeId.
    1807                 :             :   /// This accessor can mutate the map and therefore should not be used in
    1808                 :             :   /// the ThinLTO backends.
    1809                 :             :   TypeIdSummary &getOrInsertTypeIdSummary(StringRef TypeId) {
    1810                 :             :     auto TidIter = TypeIdMap.equal_range(GlobalValue::getGUID(TypeId));
    1811                 :             :     for (auto It = TidIter.first; It != TidIter.second; ++It)
    1812                 :             :       if (It->second.first == TypeId)
    1813                 :             :         return It->second.second;
    1814                 :             :     auto It = TypeIdMap.insert(
    1815                 :             :         {GlobalValue::getGUID(TypeId), {std::string(TypeId), TypeIdSummary()}});
    1816                 :             :     return It->second.second;
    1817                 :             :   }
    1818                 :             : 
    1819                 :             :   /// This returns either a pointer to the type id summary (if present in the
    1820                 :             :   /// summary map) or null (if not present). This may be used when importing.
    1821                 :             :   const TypeIdSummary *getTypeIdSummary(StringRef TypeId) const {
    1822                 :             :     auto TidIter = TypeIdMap.equal_range(GlobalValue::getGUID(TypeId));
    1823                 :             :     for (auto It = TidIter.first; It != TidIter.second; ++It)
    1824                 :             :       if (It->second.first == TypeId)
    1825                 :             :         return &It->second.second;
    1826                 :             :     return nullptr;
    1827                 :             :   }
    1828                 :             : 
    1829                 :             :   TypeIdSummary *getTypeIdSummary(StringRef TypeId) {
    1830                 :             :     return const_cast<TypeIdSummary *>(
    1831                 :             :         static_cast<const ModuleSummaryIndex *>(this)->getTypeIdSummary(
    1832                 :             :             TypeId));
    1833                 :             :   }
    1834                 :             : 
    1835                 :             :   const auto &typeIdCompatibleVtableMap() const {
    1836                 :             :     return TypeIdCompatibleVtableMap;
    1837                 :             :   }
    1838                 :             : 
    1839                 :             :   /// Return an existing or new TypeIdCompatibleVtableMap entry for \p TypeId.
    1840                 :             :   /// This accessor can mutate the map and therefore should not be used in
    1841                 :             :   /// the ThinLTO backends.
    1842                 :             :   TypeIdCompatibleVtableInfo &
    1843                 :             :   getOrInsertTypeIdCompatibleVtableSummary(StringRef TypeId) {
    1844                 :             :     return TypeIdCompatibleVtableMap[std::string(TypeId)];
    1845                 :             :   }
    1846                 :             : 
    1847                 :             :   /// For the given \p TypeId, this returns the TypeIdCompatibleVtableMap
    1848                 :             :   /// entry if present in the summary map. This may be used when importing.
    1849                 :             :   std::optional<TypeIdCompatibleVtableInfo>
    1850                 :             :   getTypeIdCompatibleVtableSummary(StringRef TypeId) const {
    1851                 :             :     auto I = TypeIdCompatibleVtableMap.find(TypeId);
    1852                 :             :     if (I == TypeIdCompatibleVtableMap.end())
    1853                 :             :       return std::nullopt;
    1854                 :             :     return I->second;
    1855                 :             :   }
    1856                 :             : 
    1857                 :             :   /// Collect for the given module the list of functions it defines
    1858                 :             :   /// (GUID -> Summary).
    1859                 :             :   void collectDefinedFunctionsForModule(StringRef ModulePath,
    1860                 :             :                                         GVSummaryMapTy &GVSummaryMap) const;
    1861                 :             : 
    1862                 :             :   /// Collect for each module the list of Summaries it defines (GUID ->
    1863                 :             :   /// Summary).
    1864                 :             :   template <class Map>
    1865                 :             :   void
    1866                 :             :   collectDefinedGVSummariesPerModule(Map &ModuleToDefinedGVSummaries) const {
    1867                 :             :     for (const auto &GlobalList : *this) {
    1868                 :             :       auto GUID = GlobalList.first;
    1869                 :             :       for (const auto &Summary : GlobalList.second.SummaryList) {
    1870                 :             :         ModuleToDefinedGVSummaries[Summary->modulePath()][GUID] = Summary.get();
    1871                 :             :       }
    1872                 :             :     }
    1873                 :             :   }
    1874                 :             : 
    1875                 :             :   /// Print to an output stream.
    1876                 :             :   void print(raw_ostream &OS, bool IsForDebug = false) const;
    1877                 :             : 
    1878                 :             :   /// Dump to stderr (for debugging).
    1879                 :             :   void dump() const;
    1880                 :             : 
    1881                 :             :   /// Export summary to dot file for GraphViz.
    1882                 :             :   void
    1883                 :             :   exportToDot(raw_ostream &OS,
    1884                 :             :               const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols) const;
    1885                 :             : 
    1886                 :             :   /// Print out strongly connected components for debugging.
    1887                 :             :   void dumpSCCs(raw_ostream &OS);
    1888                 :             : 
    1889                 :             :   /// Do the access attribute and DSOLocal propagation in combined index.
    1890                 :             :   void propagateAttributes(const DenseSet<GlobalValue::GUID> &PreservedSymbols);
    1891                 :             : 
    1892                 :             :   /// Checks if we can import global variable from another module.
    1893                 :             :   bool canImportGlobalVar(const GlobalValueSummary *S, bool AnalyzeRefs) const;
    1894                 :             : };
    1895                 :             : 
    1896                 :             : /// GraphTraits definition to build SCC for the index
    1897                 :             : template <> struct GraphTraits<ValueInfo> {
    1898                 :             :   typedef ValueInfo NodeRef;
    1899                 :             :   using EdgeRef = FunctionSummary::EdgeTy &;
    1900                 :             : 
    1901                 :             :   static NodeRef valueInfoFromEdge(FunctionSummary::EdgeTy &P) {
    1902                 :             :     return P.first;
    1903                 :             :   }
    1904                 :             :   using ChildIteratorType =
    1905                 :             :       mapped_iterator<std::vector<FunctionSummary::EdgeTy>::iterator,
    1906                 :             :                       decltype(&valueInfoFromEdge)>;
    1907                 :             : 
    1908                 :             :   using ChildEdgeIteratorType = std::vector<FunctionSummary::EdgeTy>::iterator;
    1909                 :             : 
    1910                 :             :   static NodeRef getEntryNode(ValueInfo V) { return V; }
    1911                 :             : 
    1912                 :             :   static ChildIteratorType child_begin(NodeRef N) {
    1913                 :             :     if (!N.getSummaryList().size()) // handle external function
    1914                 :             :       return ChildIteratorType(
    1915                 :             :           FunctionSummary::ExternalNode.CallGraphEdgeList.begin(),
    1916                 :             :           &valueInfoFromEdge);
    1917                 :             :     FunctionSummary *F =
    1918                 :             :         cast<FunctionSummary>(N.getSummaryList().front()->getBaseObject());
    1919                 :             :     return ChildIteratorType(F->CallGraphEdgeList.begin(), &valueInfoFromEdge);
    1920                 :             :   }
    1921                 :             : 
    1922                 :             :   static ChildIteratorType child_end(NodeRef N) {
    1923                 :             :     if (!N.getSummaryList().size()) // handle external function
    1924                 :             :       return ChildIteratorType(
    1925                 :             :           FunctionSummary::ExternalNode.CallGraphEdgeList.end(),
    1926                 :             :           &valueInfoFromEdge);
    1927                 :             :     FunctionSummary *F =
    1928                 :             :         cast<FunctionSummary>(N.getSummaryList().front()->getBaseObject());
    1929                 :             :     return ChildIteratorType(F->CallGraphEdgeList.end(), &valueInfoFromEdge);
    1930                 :             :   }
    1931                 :             : 
    1932                 :             :   static ChildEdgeIteratorType child_edge_begin(NodeRef N) {
    1933                 :             :     if (!N.getSummaryList().size()) // handle external function
    1934                 :             :       return FunctionSummary::ExternalNode.CallGraphEdgeList.begin();
    1935                 :             : 
    1936                 :             :     FunctionSummary *F =
    1937                 :             :         cast<FunctionSummary>(N.getSummaryList().front()->getBaseObject());
    1938                 :             :     return F->CallGraphEdgeList.begin();
    1939                 :             :   }
    1940                 :             : 
    1941                 :             :   static ChildEdgeIteratorType child_edge_end(NodeRef N) {
    1942                 :             :     if (!N.getSummaryList().size()) // handle external function
    1943                 :             :       return FunctionSummary::ExternalNode.CallGraphEdgeList.end();
    1944                 :             : 
    1945                 :             :     FunctionSummary *F =
    1946                 :             :         cast<FunctionSummary>(N.getSummaryList().front()->getBaseObject());
    1947                 :             :     return F->CallGraphEdgeList.end();
    1948                 :             :   }
    1949                 :             : 
    1950                 :             :   static NodeRef edge_dest(EdgeRef E) { return E.first; }
    1951                 :             : };
    1952                 :             : 
    1953                 :             : template <>
    1954                 :             : struct GraphTraits<ModuleSummaryIndex *> : public GraphTraits<ValueInfo> {
    1955                 :             :   static NodeRef getEntryNode(ModuleSummaryIndex *I) {
    1956                 :             :     std::unique_ptr<GlobalValueSummary> Root =
    1957                 :             :         std::make_unique<FunctionSummary>(I->calculateCallGraphRoot());
    1958                 :             :     GlobalValueSummaryInfo G(I->haveGVs());
    1959                 :             :     G.SummaryList.push_back(std::move(Root));
    1960                 :             :     static auto P =
    1961                 :             :         GlobalValueSummaryMapTy::value_type(GlobalValue::GUID(0), std::move(G));
    1962                 :             :     return ValueInfo(I->haveGVs(), &P);
    1963                 :             :   }
    1964                 :             : };
    1965                 :             : } // end namespace llvm
    1966                 :             : 
    1967                 :             : #endif // LLVM_IR_MODULESUMMARYINDEX_H
        

Generated by: LCOV version 2.0-1