LCOV - code coverage report
Current view: top level - include/llvm/IR - ModuleSummaryIndex.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 189 219 86.3 %
Date: 2018-10-20 13:21:21 Functions: 27 53 50.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- llvm/ModuleSummaryIndex.h - Module Summary Index ---------*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : /// @file
      11             : /// ModuleSummaryIndex.h This file contains the declarations the classes that
      12             : ///  hold the module index and summary for function importing.
      13             : //
      14             : //===----------------------------------------------------------------------===//
      15             : 
      16             : #ifndef LLVM_IR_MODULESUMMARYINDEX_H
      17             : #define LLVM_IR_MODULESUMMARYINDEX_H
      18             : 
      19             : #include "llvm/ADT/ArrayRef.h"
      20             : #include "llvm/ADT/DenseMap.h"
      21             : #include "llvm/ADT/STLExtras.h"
      22             : #include "llvm/ADT/SmallString.h"
      23             : #include "llvm/ADT/StringExtras.h"
      24             : #include "llvm/ADT/StringMap.h"
      25             : #include "llvm/ADT/StringRef.h"
      26             : #include "llvm/ADT/TinyPtrVector.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 <algorithm>
      34             : #include <array>
      35             : #include <cassert>
      36             : #include <cstddef>
      37             : #include <cstdint>
      38             : #include <map>
      39             : #include <memory>
      40             : #include <set>
      41             : #include <string>
      42             : #include <utility>
      43             : #include <vector>
      44             : 
      45             : namespace llvm {
      46             : 
      47             : namespace yaml {
      48             : 
      49             : template <typename T> struct MappingTraits;
      50             : 
      51             : } // end namespace yaml
      52             : 
      53             : /// Class to accumulate and hold information about a callee.
      54             : struct CalleeInfo {
      55             :   enum class HotnessType : uint8_t {
      56             :     Unknown = 0,
      57             :     Cold = 1,
      58             :     None = 2,
      59             :     Hot = 3,
      60             :     Critical = 4
      61             :   };
      62             : 
      63             :   // The size of the bit-field might need to be adjusted if more values are
      64             :   // added to HotnessType enum.
      65             :   uint32_t Hotness : 3;
      66             : 
      67             :   /// The value stored in RelBlockFreq has to be interpreted as the digits of
      68             :   /// a scaled number with a scale of \p -ScaleShift.
      69             :   uint32_t RelBlockFreq : 29;
      70             :   static constexpr int32_t ScaleShift = 8;
      71             :   static constexpr uint64_t MaxRelBlockFreq = (1 << 29) - 1;
      72             : 
      73             :   CalleeInfo()
      74             :       : Hotness(static_cast<uint32_t>(HotnessType::Unknown)), RelBlockFreq(0) {}
      75             :   explicit CalleeInfo(HotnessType Hotness, uint64_t RelBF)
      76        1047 :       : Hotness(static_cast<uint32_t>(Hotness)), RelBlockFreq(RelBF) {}
      77             : 
      78             :   void updateHotness(const HotnessType OtherHotness) {
      79         374 :     Hotness = std::max(Hotness, static_cast<uint32_t>(OtherHotness));
      80             :   }
      81             : 
      82         863 :   HotnessType getHotness() const { return HotnessType(Hotness); }
      83             : 
      84             :   /// Update \p RelBlockFreq from \p BlockFreq and \p EntryFreq
      85             :   ///
      86             :   /// BlockFreq is divided by EntryFreq and added to RelBlockFreq. To represent
      87             :   /// fractional values, the result is represented as a fixed point number with
      88             :   /// scale of -ScaleShift.
      89         276 :   void updateRelBlockFreq(uint64_t BlockFreq, uint64_t EntryFreq) {
      90         276 :     if (EntryFreq == 0)
      91           0 :       return;
      92             :     using Scaled64 = ScaledNumber<uint64_t>;
      93             :     Scaled64 Temp(BlockFreq, ScaleShift);
      94         276 :     Temp /= Scaled64::get(EntryFreq);
      95             : 
      96             :     uint64_t Sum =
      97         276 :         SaturatingAdd<uint64_t>(Temp.toInt<uint64_t>(), RelBlockFreq);
      98         276 :     Sum = std::min(Sum, uint64_t(MaxRelBlockFreq));
      99         276 :     RelBlockFreq = static_cast<uint32_t>(Sum);
     100             :   }
     101             : };
     102             : 
     103             : inline const char *getHotnessName(CalleeInfo::HotnessType HT) {
     104          43 :   switch (HT) {
     105             :   case CalleeInfo::HotnessType::Unknown:
     106             :     return "unknown";
     107           8 :   case CalleeInfo::HotnessType::Cold:
     108             :     return "cold";
     109          16 :   case CalleeInfo::HotnessType::None:
     110             :     return "none";
     111          16 :   case CalleeInfo::HotnessType::Hot:
     112             :     return "hot";
     113           2 :   case CalleeInfo::HotnessType::Critical:
     114             :     return "critical";
     115             :   }
     116           0 :   llvm_unreachable("invalid hotness");
     117             : }
     118             : 
     119             : class GlobalValueSummary;
     120             : 
     121             : using GlobalValueSummaryList = std::vector<std::unique_ptr<GlobalValueSummary>>;
     122             : 
     123        8914 : struct GlobalValueSummaryInfo {
     124             :   union NameOrGV {
     125        4428 :     NameOrGV(bool HaveGVs) {
     126        4428 :       if (HaveGVs)
     127        1568 :         GV = nullptr;
     128             :       else
     129        2860 :         Name = "";
     130             :     }
     131             : 
     132             :     /// The GlobalValue corresponding to this summary. This is only used in
     133             :     /// per-module summaries and when the IR is available. E.g. when module
     134             :     /// analysis is being run, or when parsing both the IR and the summary
     135             :     /// from assembly.
     136             :     const GlobalValue *GV;
     137             : 
     138             :     /// Summary string representation. This StringRef points to BC module
     139             :     /// string table and is valid until module data is stored in memory.
     140             :     /// This is guaranteed to happen until runThinLTOBackend function is
     141             :     /// called, so it is safe to use this field during thin link. This field
     142             :     /// is only valid if summary index was loaded from BC file.
     143             :     StringRef Name;
     144             :   } U;
     145             : 
     146        4428 :   GlobalValueSummaryInfo(bool HaveGVs) : U(HaveGVs) {}
     147             : 
     148             :   /// List of global value summary structures for a particular value held
     149             :   /// in the GlobalValueMap. Requires a vector in the case of multiple
     150             :   /// COMDAT values of the same name.
     151             :   GlobalValueSummaryList SummaryList;
     152             : };
     153             : 
     154             : /// Map from global value GUID to corresponding summary structures. Use a
     155             : /// std::map rather than a DenseMap so that pointers to the map's value_type
     156             : /// (which are used by ValueInfo) are not invalidated by insertion. Also it will
     157             : /// likely incur less overhead, as the value type is not very small and the size
     158             : /// of the map is unknown, resulting in inefficiencies due to repeated
     159             : /// insertions and resizing.
     160             : using GlobalValueSummaryMapTy =
     161             :     std::map<GlobalValue::GUID, GlobalValueSummaryInfo>;
     162             : 
     163             : /// Struct that holds a reference to a particular GUID in a global value
     164             : /// summary.
     165             : struct ValueInfo {
     166             :   PointerIntPair<const GlobalValueSummaryMapTy::value_type *, 1, bool>
     167             :       RefAndFlag;
     168             : 
     169             :   ValueInfo() = default;
     170          21 :   ValueInfo(bool HaveGVs, const GlobalValueSummaryMapTy::value_type *R) {
     171             :     RefAndFlag.setPointer(R);
     172             :     RefAndFlag.setInt(HaveGVs);
     173             :   }
     174             : 
     175             :   operator bool() const { return getRef(); }
     176             : 
     177        5420 :   GlobalValue::GUID getGUID() const { return getRef()->first; }
     178             :   const GlobalValue *getValue() const {
     179             :     assert(haveGVs());
     180         811 :     return getRef()->second.U.GV;
     181             :   }
     182             : 
     183             :   ArrayRef<std::unique_ptr<GlobalValueSummary>> getSummaryList() const {
     184             :     return getRef()->second.SummaryList;
     185             :   }
     186             : 
     187        1390 :   StringRef name() const {
     188           0 :     return haveGVs() ? getRef()->second.U.GV->getName()
     189        1390 :                      : getRef()->second.U.Name;
     190             :   }
     191             : 
     192        1710 :   bool haveGVs() const { return RefAndFlag.getInt(); }
     193             : 
     194             :   const GlobalValueSummaryMapTy::value_type *getRef() const {
     195        5510 :     return RefAndFlag.getPointer();
     196             :   }
     197             : 
     198             :   bool isDSOLocal() const;
     199             : };
     200             : 
     201           1 : inline raw_ostream &operator<<(raw_ostream &OS, const ValueInfo &VI) {
     202           1 :   OS << VI.getGUID();
     203           1 :   if (!VI.name().empty())
     204           1 :     OS << " (" << VI.name() << ")";
     205           1 :   return OS;
     206             : }
     207             : 
     208             : inline bool operator==(const ValueInfo &A, const ValueInfo &B) {
     209             :   assert(A.getRef() && B.getRef() &&
     210             :          "Need ValueInfo with non-null Ref for comparison");
     211             :   return A.getRef() == B.getRef();
     212             : }
     213             : 
     214             : inline bool operator!=(const ValueInfo &A, const ValueInfo &B) {
     215             :   assert(A.getRef() && B.getRef() &&
     216             :          "Need ValueInfo with non-null Ref for comparison");
     217             :   return A.getRef() != B.getRef();
     218             : }
     219             : 
     220             : inline bool operator<(const ValueInfo &A, const ValueInfo &B) {
     221             :   assert(A.getRef() && B.getRef() &&
     222             :          "Need ValueInfo with non-null Ref to compare GUIDs");
     223          19 :   return A.getGUID() < B.getGUID();
     224             : }
     225             : 
     226             : template <> struct DenseMapInfo<ValueInfo> {
     227             :   static inline ValueInfo getEmptyKey() {
     228             :     return ValueInfo(false, (GlobalValueSummaryMapTy::value_type *)-8);
     229             :   }
     230             : 
     231             :   static inline ValueInfo getTombstoneKey() {
     232             :     return ValueInfo(false, (GlobalValueSummaryMapTy::value_type *)-16);
     233             :   }
     234             : 
     235             :   static inline bool isSpecialKey(ValueInfo V) {
     236             :     return V == getTombstoneKey() || V == getEmptyKey();
     237             :   }
     238             : 
     239             :   static bool isEqual(ValueInfo L, ValueInfo R) {
     240             :     // We are not supposed to mix ValueInfo(s) with different HaveGVs flag
     241             :     // in a same container.
     242             :     assert(isSpecialKey(L) || isSpecialKey(R) || (L.haveGVs() == R.haveGVs()));
     243         780 :     return L.getRef() == R.getRef();
     244             :   }
     245         574 :   static unsigned getHashValue(ValueInfo I) { return (uintptr_t)I.getRef(); }
     246             : };
     247             : 
     248             : /// Function and variable summary information to aid decisions and
     249             : /// implementation of importing.
     250             : class GlobalValueSummary {
     251             : public:
     252             :   /// Sububclass discriminator (for dyn_cast<> et al.)
     253             :   enum SummaryKind : unsigned { AliasKind, FunctionKind, GlobalVarKind };
     254             : 
     255             :   /// Group flags (Linkage, NotEligibleToImport, etc.) as a bitfield.
     256             :   struct GVFlags {
     257             :     /// The linkage type of the associated global value.
     258             :     ///
     259             :     /// One use is to flag values that have local linkage types and need to
     260             :     /// have module identifier appended before placing into the combined
     261             :     /// index, to disambiguate from other values with the same name.
     262             :     /// In the future this will be used to update and optimize linkage
     263             :     /// types based on global summary-based analysis.
     264             :     unsigned Linkage : 4;
     265             : 
     266             :     /// Indicate if the global value cannot be imported (e.g. it cannot
     267             :     /// be renamed or references something that can't be renamed).
     268             :     unsigned NotEligibleToImport : 1;
     269             : 
     270             :     /// In per-module summary, indicate that the global value must be considered
     271             :     /// a live root for index-based liveness analysis. Used for special LLVM
     272             :     /// values such as llvm.global_ctors that the linker does not know about.
     273             :     ///
     274             :     /// In combined summary, indicate that the global value is live.
     275             :     unsigned Live : 1;
     276             : 
     277             :     /// Indicates that the linker resolved the symbol to a definition from
     278             :     /// within the same linkage unit.
     279             :     unsigned DSOLocal : 1;
     280             : 
     281             :     /// Convenience Constructors
     282             :     explicit GVFlags(GlobalValue::LinkageTypes Linkage,
     283             :                      bool NotEligibleToImport, bool Live, bool IsLocal)
     284      114994 :         : Linkage(Linkage), NotEligibleToImport(NotEligibleToImport),
     285      117336 :           Live(Live), DSOLocal(IsLocal) {}
     286             :   };
     287             : 
     288             : private:
     289             :   /// Kind of summary for use in dyn_cast<> et al.
     290             :   SummaryKind Kind;
     291             : 
     292             :   GVFlags Flags;
     293             : 
     294             :   /// This is the hash of the name of the symbol in the original file. It is
     295             :   /// identical to the GUID for global symbols, but differs for local since the
     296             :   /// GUID includes the module level id in the hash.
     297             :   GlobalValue::GUID OriginalName = 0;
     298             : 
     299             :   /// Path of module IR containing value's definition, used to locate
     300             :   /// module during importing.
     301             :   ///
     302             :   /// This is only used during parsing of the combined index, or when
     303             :   /// parsing the per-module index for creation of the combined summary index,
     304             :   /// not during writing of the per-module index which doesn't contain a
     305             :   /// module path string table.
     306             :   StringRef ModulePath;
     307             : 
     308             :   /// List of values referenced by this global value's definition
     309             :   /// (either by the initializer of a global variable, or referenced
     310             :   /// from within a function). This does not include functions called, which
     311             :   /// are listed in the derived FunctionSummary object.
     312             :   std::vector<ValueInfo> RefEdgeList;
     313             : 
     314             : protected:
     315             :   GlobalValueSummary(SummaryKind K, GVFlags Flags, std::vector<ValueInfo> Refs)
     316      116300 :       : Kind(K), Flags(Flags), RefEdgeList(std::move(Refs)) {
     317             :     assert((K != AliasKind || Refs.empty()) &&
     318             :            "Expect no references for AliasSummary");
     319             :   }
     320             : 
     321             : public:
     322           0 :   virtual ~GlobalValueSummary() = default;
     323             : 
     324             :   /// Returns the hash of the original name, it is identical to the GUID for
     325             :   /// externally visible symbols, but not for local ones.
     326           0 :   GlobalValue::GUID getOriginalName() const { return OriginalName; }
     327             : 
     328             :   /// Initialize the original name hash in this summary.
     329        1219 :   void setOriginalName(GlobalValue::GUID Name) { OriginalName = Name; }
     330             : 
     331             :   /// Which kind of summary subclass this is.
     332           0 :   SummaryKind getSummaryKind() const { return Kind; }
     333             : 
     334             :   /// Set the path to the module containing this function, for use in
     335             :   /// the combined index.
     336        2417 :   void setModulePath(StringRef ModPath) { ModulePath = ModPath; }
     337             : 
     338             :   /// Get the path to the module containing this function.
     339           0 :   StringRef modulePath() const { return ModulePath; }
     340             : 
     341             :   /// Get the flags for this GlobalValue (see \p struct GVFlags).
     342        1597 :   GVFlags flags() const { return Flags; }
     343             : 
     344             :   /// Return linkage type recorded for this global value.
     345             :   GlobalValue::LinkageTypes linkage() const {
     346        2845 :     return static_cast<GlobalValue::LinkageTypes>(Flags.Linkage);
     347             :   }
     348             : 
     349             :   /// Sets the linkage to the value determined by global summary-based
     350             :   /// optimization. Will be applied in the ThinLTO backends.
     351             :   void setLinkage(GlobalValue::LinkageTypes Linkage) {
     352         563 :     Flags.Linkage = Linkage;
     353             :   }
     354             : 
     355             :   /// Return true if this global value can't be imported.
     356          42 :   bool notEligibleToImport() const { return Flags.NotEligibleToImport; }
     357             : 
     358        1767 :   bool isLive() const { return Flags.Live; }
     359             : 
     360         800 :   void setLive(bool Live) { Flags.Live = Live; }
     361             : 
     362         205 :   void setDSOLocal(bool Local) { Flags.DSOLocal = Local; }
     363             : 
     364           0 :   bool isDSOLocal() const { return Flags.DSOLocal; }
     365             : 
     366             :   /// Flag that this global value cannot be imported.
     367          72 :   void setNotEligibleToImport() { Flags.NotEligibleToImport = true; }
     368             : 
     369             :   /// Return the list of values referenced by this global value definition.
     370             :   ArrayRef<ValueInfo> refs() const { return RefEdgeList; }
     371             : 
     372             :   /// If this is an alias summary, returns the summary of the aliased object (a
     373             :   /// global variable or function), otherwise returns itself.
     374             :   GlobalValueSummary *getBaseObject();
     375             :   const GlobalValueSummary *getBaseObject() const;
     376             : 
     377             :   friend class ModuleSummaryIndex;
     378             : };
     379             : 
     380             : /// Alias summary information.
     381             : class AliasSummary : public GlobalValueSummary {
     382             :   GlobalValueSummary *AliaseeSummary;
     383             :   // AliaseeGUID is only set and accessed when we are building a combined index
     384             :   // via the BitcodeReader.
     385             :   GlobalValue::GUID AliaseeGUID;
     386             : 
     387             : public:
     388         528 :   AliasSummary(GVFlags Flags)
     389         528 :       : GlobalValueSummary(AliasKind, Flags, ArrayRef<ValueInfo>{}),
     390         528 :         AliaseeSummary(nullptr), AliaseeGUID(0) {}
     391             : 
     392             :   /// Check if this is an alias summary.
     393             :   static bool classof(const GlobalValueSummary *GVS) {
     394        3562 :     return GVS->getSummaryKind() == AliasKind;
     395             :   }
     396             : 
     397         528 :   void setAliasee(GlobalValueSummary *Aliasee) { AliaseeSummary = Aliasee; }
     398         393 :   void setAliaseeGUID(GlobalValue::GUID GUID) { AliaseeGUID = GUID; }
     399             : 
     400           0 :   bool hasAliasee() const { return !!AliaseeSummary; }
     401             : 
     402           0 :   const GlobalValueSummary &getAliasee() const {
     403             :     assert(AliaseeSummary && "Unexpected missing aliasee summary");
     404           0 :     return *AliaseeSummary;
     405             :   }
     406             : 
     407             :   GlobalValueSummary &getAliasee() {
     408             :     return const_cast<GlobalValueSummary &>(
     409         516 :                          static_cast<const AliasSummary *>(this)->getAliasee());
     410             :   }
     411             :   const GlobalValue::GUID &getAliaseeGUID() const {
     412             :     assert(AliaseeGUID && "Unexpected missing aliasee GUID");
     413             :     return AliaseeGUID;
     414             :   }
     415             : };
     416             : 
     417             : const inline GlobalValueSummary *GlobalValueSummary::getBaseObject() const {
     418             :   if (auto *AS = dyn_cast<AliasSummary>(this))
     419          47 :     return &AS->getAliasee();
     420             :   return this;
     421             : }
     422             : 
     423             : inline GlobalValueSummary *GlobalValueSummary::getBaseObject() {
     424             :   if (auto *AS = dyn_cast<AliasSummary>(this))
     425             :     return &AS->getAliasee();
     426             :   return this;
     427             : }
     428             : 
     429             : /// Function summary information to aid decisions and implementation of
     430             : /// importing.
     431             : class FunctionSummary : public GlobalValueSummary {
     432             : public:
     433             :   /// <CalleeValueInfo, CalleeInfo> call edge pair.
     434             :   using EdgeTy = std::pair<ValueInfo, CalleeInfo>;
     435             : 
     436             :   /// Types for -force-summary-edges-cold debugging option.
     437             :   enum ForceSummaryHotnessType : unsigned {
     438             :     FSHT_None,
     439             :     FSHT_AllNonCritical,
     440             :     FSHT_All
     441             :   };
     442             : 
     443             :   /// An "identifier" for a virtual function. This contains the type identifier
     444             :   /// represented as a GUID and the offset from the address point to the virtual
     445             :   /// function pointer, where "address point" is as defined in the Itanium ABI:
     446             :   /// https://itanium-cxx-abi.github.io/cxx-abi/abi.html#vtable-general
     447             :   struct VFuncId {
     448             :     GlobalValue::GUID GUID;
     449             :     uint64_t Offset;
     450             :   };
     451             : 
     452             :   /// A specification for a virtual function call with all constant integer
     453             :   /// arguments. This is used to perform virtual constant propagation on the
     454             :   /// summary.
     455        1615 :   struct ConstVCall {
     456             :     VFuncId VFunc;
     457             :     std::vector<uint64_t> Args;
     458             :   };
     459             : 
     460             :   /// All type identifier related information. Because these fields are
     461             :   /// relatively uncommon we only allocate space for them if necessary.
     462             :   struct TypeIdInfo {
     463             :     /// List of type identifiers used by this function in llvm.type.test
     464             :     /// intrinsics referenced by something other than an llvm.assume intrinsic,
     465             :     /// represented as GUIDs.
     466             :     std::vector<GlobalValue::GUID> TypeTests;
     467             : 
     468             :     /// List of virtual calls made by this function using (respectively)
     469             :     /// llvm.assume(llvm.type.test) or llvm.type.checked.load intrinsics that do
     470             :     /// not have all constant integer arguments.
     471             :     std::vector<VFuncId> TypeTestAssumeVCalls, TypeCheckedLoadVCalls;
     472             : 
     473             :     /// List of virtual calls made by this function using (respectively)
     474             :     /// llvm.assume(llvm.type.test) or llvm.type.checked.load intrinsics with
     475             :     /// all constant integer arguments.
     476             :     std::vector<ConstVCall> TypeTestAssumeConstVCalls,
     477             :         TypeCheckedLoadConstVCalls;
     478             :   };
     479             : 
     480             :   /// Function attribute flags. Used to track if a function accesses memory,
     481             :   /// recurses or aliases.
     482             :   struct FFlags {
     483             :     unsigned ReadNone : 1;
     484             :     unsigned ReadOnly : 1;
     485             :     unsigned NoRecurse : 1;
     486             :     unsigned ReturnDoesNotAlias : 1;
     487             :   };
     488             : 
     489             :   /// Create an empty FunctionSummary (with specified call edges).
     490             :   /// Used to represent external nodes and the dummy root node.
     491             :   static FunctionSummary
     492      113937 :   makeDummyFunctionSummary(std::vector<FunctionSummary::EdgeTy> Edges) {
     493             :     return FunctionSummary(
     494             :         FunctionSummary::GVFlags(
     495             :             GlobalValue::LinkageTypes::AvailableExternallyLinkage,
     496             :             /*NotEligibleToImport=*/true, /*Live=*/true, /*IsLocal=*/false),
     497      113937 :         0, FunctionSummary::FFlags{}, std::vector<ValueInfo>(),
     498      113937 :         std::move(Edges), std::vector<GlobalValue::GUID>(),
     499      113937 :         std::vector<FunctionSummary::VFuncId>(),
     500      113937 :         std::vector<FunctionSummary::VFuncId>(),
     501      113937 :         std::vector<FunctionSummary::ConstVCall>(),
     502      341811 :         std::vector<FunctionSummary::ConstVCall>());
     503             :   }
     504             : 
     505             :   /// A dummy node to reference external functions that aren't in the index
     506             :   static FunctionSummary ExternalNode;
     507             : 
     508             : private:
     509             :   /// Number of instructions (ignoring debug instructions, e.g.) computed
     510             :   /// during the initial compile step when the summary index is first built.
     511             :   unsigned InstCount;
     512             : 
     513             :   /// Function attribute flags. Used to track if a function accesses memory,
     514             :   /// recurses or aliases.
     515             :   FFlags FunFlags;
     516             : 
     517             :   /// List of <CalleeValueInfo, CalleeInfo> call edge pairs from this function.
     518             :   std::vector<EdgeTy> CallGraphEdgeList;
     519             : 
     520             :   std::unique_ptr<TypeIdInfo> TIdInfo;
     521             : 
     522             : public:
     523      116300 :   FunctionSummary(GVFlags Flags, unsigned NumInsts, FFlags FunFlags,
     524             :                   std::vector<ValueInfo> Refs, std::vector<EdgeTy> CGEdges,
     525             :                   std::vector<GlobalValue::GUID> TypeTests,
     526             :                   std::vector<VFuncId> TypeTestAssumeVCalls,
     527             :                   std::vector<VFuncId> TypeCheckedLoadVCalls,
     528             :                   std::vector<ConstVCall> TypeTestAssumeConstVCalls,
     529             :                   std::vector<ConstVCall> TypeCheckedLoadConstVCalls)
     530      116300 :       : GlobalValueSummary(FunctionKind, Flags, std::move(Refs)),
     531             :         InstCount(NumInsts), FunFlags(FunFlags),
     532      232600 :         CallGraphEdgeList(std::move(CGEdges)) {
     533      116188 :     if (!TypeTests.empty() || !TypeTestAssumeVCalls.empty() ||
     534      232435 :         !TypeCheckedLoadVCalls.empty() || !TypeTestAssumeConstVCalls.empty() ||
     535             :         !TypeCheckedLoadConstVCalls.empty())
     536         199 :       TIdInfo = llvm::make_unique<TypeIdInfo>(TypeIdInfo{
     537             :           std::move(TypeTests), std::move(TypeTestAssumeVCalls),
     538             :           std::move(TypeCheckedLoadVCalls),
     539             :           std::move(TypeTestAssumeConstVCalls),
     540         199 :           std::move(TypeCheckedLoadConstVCalls)});
     541      116300 :   }
     542             : 
     543             :   /// Check if this is a function summary.
     544             :   static bool classof(const GlobalValueSummary *GVS) {
     545        4662 :     return GVS->getSummaryKind() == FunctionKind;
     546             :   }
     547             : 
     548             :   /// Get function attribute flags.
     549         986 :   FFlags fflags() const { return FunFlags; }
     550             : 
     551             :   /// Get the instruction count recorded for this function.
     552           0 :   unsigned instCount() const { return InstCount; }
     553             : 
     554             :   /// Return the list of <CalleeValueInfo, CalleeInfo> pairs.
     555             :   ArrayRef<EdgeTy> calls() const { return CallGraphEdgeList; }
     556             : 
     557             :   /// Returns the list of type identifiers used by this function in
     558             :   /// llvm.type.test intrinsics other than by an llvm.assume intrinsic,
     559             :   /// represented as GUIDs.
     560             :   ArrayRef<GlobalValue::GUID> type_tests() const {
     561        2271 :     if (TIdInfo)
     562             :       return TIdInfo->TypeTests;
     563             :     return {};
     564             :   }
     565             : 
     566             :   /// Returns the list of virtual calls made by this function using
     567             :   /// llvm.assume(llvm.type.test) intrinsics that do not have all constant
     568             :   /// integer arguments.
     569             :   ArrayRef<VFuncId> type_test_assume_vcalls() const {
     570        1879 :     if (TIdInfo)
     571             :       return TIdInfo->TypeTestAssumeVCalls;
     572             :     return {};
     573             :   }
     574             : 
     575             :   /// Returns the list of virtual calls made by this function using
     576             :   /// llvm.type.checked.load intrinsics that do not have all constant integer
     577             :   /// arguments.
     578             :   ArrayRef<VFuncId> type_checked_load_vcalls() const {
     579        1879 :     if (TIdInfo)
     580             :       return TIdInfo->TypeCheckedLoadVCalls;
     581             :     return {};
     582             :   }
     583             : 
     584             :   /// Returns the list of virtual calls made by this function using
     585             :   /// llvm.assume(llvm.type.test) intrinsics with all constant integer
     586             :   /// arguments.
     587             :   ArrayRef<ConstVCall> type_test_assume_const_vcalls() const {
     588        1879 :     if (TIdInfo)
     589             :       return TIdInfo->TypeTestAssumeConstVCalls;
     590             :     return {};
     591             :   }
     592             : 
     593             :   /// Returns the list of virtual calls made by this function using
     594             :   /// llvm.type.checked.load intrinsics with all constant integer arguments.
     595             :   ArrayRef<ConstVCall> type_checked_load_const_vcalls() const {
     596        1879 :     if (TIdInfo)
     597             :       return TIdInfo->TypeCheckedLoadConstVCalls;
     598             :     return {};
     599             :   }
     600             : 
     601             :   /// Add a type test to the summary. This is used by WholeProgramDevirt if we
     602             :   /// were unable to devirtualize a checked call.
     603          10 :   void addTypeTest(GlobalValue::GUID Guid) {
     604          10 :     if (!TIdInfo)
     605           0 :       TIdInfo = llvm::make_unique<TypeIdInfo>();
     606          10 :     TIdInfo->TypeTests.push_back(Guid);
     607          10 :   }
     608             : 
     609             :   const TypeIdInfo *getTypeIdInfo() const { return TIdInfo.get(); };
     610             : 
     611             :   friend struct GraphTraits<ValueInfo>;
     612             : };
     613             : 
     614             : template <> struct DenseMapInfo<FunctionSummary::VFuncId> {
     615             :   static FunctionSummary::VFuncId getEmptyKey() { return {0, uint64_t(-1)}; }
     616             : 
     617             :   static FunctionSummary::VFuncId getTombstoneKey() {
     618             :     return {0, uint64_t(-2)};
     619             :   }
     620             : 
     621             :   static bool isEqual(FunctionSummary::VFuncId L, FunctionSummary::VFuncId R) {
     622         701 :     return L.GUID == R.GUID && L.Offset == R.Offset;
     623             :   }
     624             : 
     625          12 :   static unsigned getHashValue(FunctionSummary::VFuncId I) { return I.GUID; }
     626             : };
     627             : 
     628             : template <> struct DenseMapInfo<FunctionSummary::ConstVCall> {
     629             :   static FunctionSummary::ConstVCall getEmptyKey() {
     630          35 :     return {{0, uint64_t(-1)}, {}};
     631             :   }
     632             : 
     633             :   static FunctionSummary::ConstVCall getTombstoneKey() {
     634          20 :     return {{0, uint64_t(-2)}, {}};
     635             :   }
     636             : 
     637         679 :   static bool isEqual(FunctionSummary::ConstVCall L,
     638             :                       FunctionSummary::ConstVCall R) {
     639         650 :     return DenseMapInfo<FunctionSummary::VFuncId>::isEqual(L.VFunc, R.VFunc) &&
     640         650 :            L.Args == R.Args;
     641             :   }
     642             : 
     643           0 :   static unsigned getHashValue(FunctionSummary::ConstVCall I) {
     644          10 :     return I.VFunc.GUID;
     645             :   }
     646             : };
     647             : 
     648             : /// Global variable summary information to aid decisions and
     649             : /// implementation of importing.
     650             : ///
     651             : /// Currently this doesn't add anything to the base \p GlobalValueSummary,
     652             : /// but is a placeholder as additional info may be added to the summary
     653             : /// for variables.
     654             : class GlobalVarSummary : public GlobalValueSummary {
     655             : 
     656             : public:
     657             :   GlobalVarSummary(GVFlags Flags, std::vector<ValueInfo> Refs)
     658         509 :       : GlobalValueSummary(GlobalVarKind, Flags, std::move(Refs)) {}
     659             : 
     660             :   /// Check if this is a global variable summary.
     661             :   static bool classof(const GlobalValueSummary *GVS) {
     662           0 :     return GVS->getSummaryKind() == GlobalVarKind;
     663             :   }
     664             : };
     665             : 
     666          54 : struct TypeTestResolution {
     667             :   /// Specifies which kind of type check we should emit for this byte array.
     668             :   /// See http://clang.llvm.org/docs/ControlFlowIntegrityDesign.html for full
     669             :   /// details on each kind of check; the enumerators are described with
     670             :   /// reference to that document.
     671             :   enum Kind {
     672             :     Unsat,     ///< Unsatisfiable type (i.e. no global has this type metadata)
     673             :     ByteArray, ///< Test a byte array (first example)
     674             :     Inline,    ///< Inlined bit vector ("Short Inline Bit Vectors")
     675             :     Single,    ///< Single element (last example in "Short Inline Bit Vectors")
     676             :     AllOnes,   ///< All-ones bit vector ("Eliminating Bit Vector Checks for
     677             :                ///  All-Ones Bit Vectors")
     678             :   } TheKind = Unsat;
     679             : 
     680             :   /// Range of size-1 expressed as a bit width. For example, if the size is in
     681             :   /// range [1,256], this number will be 8. This helps generate the most compact
     682             :   /// instruction sequences.
     683             :   unsigned SizeM1BitWidth = 0;
     684             : 
     685             :   // The following fields are only used if the target does not support the use
     686             :   // of absolute symbols to store constants. Their meanings are the same as the
     687             :   // corresponding fields in LowerTypeTestsModule::TypeIdLowering in
     688             :   // LowerTypeTests.cpp.
     689             : 
     690             :   uint64_t AlignLog2 = 0;
     691             :   uint64_t SizeM1 = 0;
     692             :   uint8_t BitMask = 0;
     693             :   uint64_t InlineBits = 0;
     694             : };
     695             : 
     696          10 : struct WholeProgramDevirtResolution {
     697             :   enum Kind {
     698             :     Indir,        ///< Just do a regular virtual call
     699             :     SingleImpl,   ///< Single implementation devirtualization
     700             :     BranchFunnel, ///< When retpoline mitigation is enabled, use a branch funnel
     701             :                   ///< that is defined in the merged module. Otherwise same as
     702             :                   ///< Indir.
     703             :   } TheKind = Indir;
     704             : 
     705             :   std::string SingleImplName;
     706             : 
     707             :   struct ByArg {
     708             :     enum Kind {
     709             :       Indir,            ///< Just do a regular virtual call
     710             :       UniformRetVal,    ///< Uniform return value optimization
     711             :       UniqueRetVal,     ///< Unique return value optimization
     712             :       VirtualConstProp, ///< Virtual constant propagation
     713             :     } TheKind = Indir;
     714             : 
     715             :     /// Additional information for the resolution:
     716             :     /// - UniformRetVal: the uniform return value.
     717             :     /// - UniqueRetVal: the return value associated with the unique vtable (0 or
     718             :     ///   1).
     719             :     uint64_t Info = 0;
     720             : 
     721             :     // The following fields are only used if the target does not support the use
     722             :     // of absolute symbols to store constants.
     723             : 
     724             :     uint32_t Byte = 0;
     725             :     uint32_t Bit = 0;
     726             :   };
     727             : 
     728             :   /// Resolutions for calls with all constant integer arguments (excluding the
     729             :   /// first argument, "this"), where the key is the argument vector.
     730             :   std::map<std::vector<uint64_t>, ByArg> ResByArg;
     731             : };
     732             : 
     733         462 : struct TypeIdSummary {
     734             :   TypeTestResolution TTRes;
     735             : 
     736             :   /// Mapping from byte offset to whole-program devirt resolution for that
     737             :   /// (typeid, byte offset) pair.
     738             :   std::map<uint64_t, WholeProgramDevirtResolution> WPDRes;
     739             : };
     740             : 
     741             : /// 160 bits SHA1
     742             : using ModuleHash = std::array<uint32_t, 5>;
     743             : 
     744             : /// Type used for iterating through the global value summary map.
     745             : using const_gvsummary_iterator = GlobalValueSummaryMapTy::const_iterator;
     746             : using gvsummary_iterator = GlobalValueSummaryMapTy::iterator;
     747             : 
     748             : /// String table to hold/own module path strings, which additionally holds the
     749             : /// module ID assigned to each module during the plugin step, as well as a hash
     750             : /// of the module. The StringMap makes a copy of and owns inserted strings.
     751             : using ModulePathStringTableTy = StringMap<std::pair<uint64_t, ModuleHash>>;
     752             : 
     753             : /// Map of global value GUID to its summary, used to identify values defined in
     754             : /// a particular module, and provide efficient access to their summary.
     755             : using GVSummaryMapTy = DenseMap<GlobalValue::GUID, GlobalValueSummary *>;
     756             : 
     757             : /// Map of a type GUID to type id string and summary (multimap used
     758             : /// in case of GUID conflicts).
     759             : using TypeIdSummaryMapTy =
     760             :     std::multimap<GlobalValue::GUID, std::pair<std::string, TypeIdSummary>>;
     761             : 
     762             : /// Class to hold module path string table and global value map,
     763             : /// and encapsulate methods for operating on them.
     764             : class ModuleSummaryIndex {
     765             : private:
     766             :   /// Map from value name to list of summary instances for values of that
     767             :   /// name (may be duplicates in the COMDAT case, e.g.).
     768             :   GlobalValueSummaryMapTy GlobalValueMap;
     769             : 
     770             :   /// Holds strings for combined index, mapping to the corresponding module ID.
     771             :   ModulePathStringTableTy ModulePathStringTable;
     772             : 
     773             :   /// Mapping from type identifier GUIDs to type identifier and its summary
     774             :   /// information.
     775             :   TypeIdSummaryMapTy TypeIdMap;
     776             : 
     777             :   /// Mapping from original ID to GUID. If original ID can map to multiple
     778             :   /// GUIDs, it will be mapped to 0.
     779             :   std::map<GlobalValue::GUID, GlobalValue::GUID> OidGuidMap;
     780             : 
     781             :   /// Indicates that summary-based GlobalValue GC has run, and values with
     782             :   /// GVFlags::Live==false are really dead. Otherwise, all values must be
     783             :   /// considered live.
     784             :   bool WithGlobalValueDeadStripping = false;
     785             : 
     786             :   /// Indicates that distributed backend should skip compilation of the
     787             :   /// module. Flag is suppose to be set by distributed ThinLTO indexing
     788             :   /// when it detected that the module is not needed during the final
     789             :   /// linking. As result distributed backend should just output a minimal
     790             :   /// valid object file.
     791             :   bool SkipModuleByDistributedBackend = false;
     792             : 
     793             :   /// If true then we're performing analysis of IR module, or parsing along with
     794             :   /// the IR from assembly. The value of 'false' means we're reading summary
     795             :   /// from BC or YAML source. Affects the type of value stored in NameOrGV
     796             :   /// union.
     797             :   bool HaveGVs;
     798             : 
     799             :   std::set<std::string> CfiFunctionDefs;
     800             :   std::set<std::string> CfiFunctionDecls;
     801             : 
     802             :   // Used in cases where we want to record the name of a global, but
     803             :   // don't have the string owned elsewhere (e.g. the Strtab on a module).
     804             :   StringSaver Saver;
     805             :   BumpPtrAllocator Alloc;
     806             : 
     807             :   // YAML I/O support.
     808             :   friend yaml::MappingTraits<ModuleSummaryIndex>;
     809             : 
     810             :   GlobalValueSummaryMapTy::value_type *
     811        4427 :   getOrInsertValuePtr(GlobalValue::GUID GUID) {
     812        4427 :     return &*GlobalValueMap.emplace(GUID, GlobalValueSummaryInfo(HaveGVs))
     813        4427 :                  .first;
     814             :   }
     815             : 
     816             : public:
     817             :   // See HaveGVs variable comment.
     818       10188 :   ModuleSummaryIndex(bool HaveGVs) : HaveGVs(HaveGVs), Saver(Alloc) {}
     819             : 
     820           0 :   bool haveGVs() const { return HaveGVs; }
     821             : 
     822             :   gvsummary_iterator begin() { return GlobalValueMap.begin(); }
     823             :   const_gvsummary_iterator begin() const { return GlobalValueMap.begin(); }
     824             :   gvsummary_iterator end() { return GlobalValueMap.end(); }
     825             :   const_gvsummary_iterator end() const { return GlobalValueMap.end(); }
     826             :   size_t size() const { return GlobalValueMap.size(); }
     827             : 
     828             :   /// Convenience function for doing a DFS on a ValueInfo. Marks the function in
     829             :   /// the FunctionHasParent map.
     830           7 :   static void discoverNodes(ValueInfo V,
     831             :                             std::map<ValueInfo, bool> &FunctionHasParent) {
     832           7 :     if (!V.getSummaryList().size())
     833             :       return; // skip external functions that don't have summaries
     834             : 
     835             :     // Mark discovered if we haven't yet
     836           6 :     auto S = FunctionHasParent.emplace(V, false);
     837             : 
     838             :     // Stop if we've already discovered this node
     839           6 :     if (!S.second)
     840             :       return;
     841             : 
     842             :     FunctionSummary *F =
     843             :         dyn_cast<FunctionSummary>(V.getSummaryList().front().get());
     844             :     assert(F != nullptr && "Expected FunctionSummary node");
     845             : 
     846           6 :     for (auto &C : F->calls()) {
     847             :       // Insert node if necessary
     848           4 :       auto S = FunctionHasParent.emplace(C.first, true);
     849             : 
     850             :       // Skip nodes that we're sure have parents
     851           4 :       if (!S.second && S.first->second)
     852             :         continue;
     853             : 
     854           3 :       if (S.second)
     855           3 :         discoverNodes(C.first, FunctionHasParent);
     856             :       else
     857           0 :         S.first->second = true;
     858             :     }
     859             :   }
     860             : 
     861             :   // Calculate the callgraph root
     862           1 :   FunctionSummary calculateCallGraphRoot() {
     863             :     // Functions that have a parent will be marked in FunctionHasParent pair.
     864             :     // Once we've marked all functions, the functions in the map that are false
     865             :     // have no parent (so they're the roots)
     866             :     std::map<ValueInfo, bool> FunctionHasParent;
     867             : 
     868           6 :     for (auto &S : *this) {
     869             :       // Skip external functions
     870           5 :       if (!S.second.SummaryList.size() ||
     871             :           !isa<FunctionSummary>(S.second.SummaryList.front().get()))
     872             :         continue;
     873           8 :       discoverNodes(ValueInfo(HaveGVs, &S), FunctionHasParent);
     874             :     }
     875             : 
     876             :     std::vector<FunctionSummary::EdgeTy> Edges;
     877             :     // create edges to all roots in the Index
     878           6 :     for (auto &P : FunctionHasParent) {
     879           5 :       if (P.second)
     880             :         continue; // skip over non-root nodes
     881           2 :       Edges.push_back(std::make_pair(P.first, CalleeInfo{}));
     882             :     }
     883           1 :     if (Edges.empty()) {
     884             :       // Failed to find root - return an empty node
     885           0 :       return FunctionSummary::makeDummyFunctionSummary({});
     886             :     }
     887           2 :     auto CallGraphRoot = FunctionSummary::makeDummyFunctionSummary(Edges);
     888           1 :     return CallGraphRoot;
     889             :   }
     890             : 
     891           0 :   bool withGlobalValueDeadStripping() const {
     892           0 :     return WithGlobalValueDeadStripping;
     893             :   }
     894           0 :   void setWithGlobalValueDeadStripping() {
     895         486 :     WithGlobalValueDeadStripping = true;
     896           0 :   }
     897             : 
     898           0 :   bool skipModuleByDistributedBackend() const {
     899           0 :     return SkipModuleByDistributedBackend;
     900             :   }
     901           0 :   void setSkipModuleByDistributedBackend() {
     902           3 :     SkipModuleByDistributedBackend = true;
     903           0 :   }
     904             : 
     905           0 :   bool isGlobalValueLive(const GlobalValueSummary *GVS) const {
     906        2329 :     return !WithGlobalValueDeadStripping || GVS->isLive();
     907             :   }
     908             :   bool isGUIDLive(GlobalValue::GUID GUID) const;
     909             : 
     910             :   /// Return a ValueInfo for the index value_type (convenient when iterating
     911             :   /// index).
     912           0 :   ValueInfo getValueInfo(const GlobalValueSummaryMapTy::value_type &R) const {
     913           0 :     return ValueInfo(HaveGVs, &R);
     914             :   }
     915             : 
     916             :   /// Return a ValueInfo for GUID if it exists, otherwise return ValueInfo().
     917        7688 :   ValueInfo getValueInfo(GlobalValue::GUID GUID) const {
     918             :     auto I = GlobalValueMap.find(GUID);
     919        7688 :     return ValueInfo(HaveGVs, I == GlobalValueMap.end() ? nullptr : &*I);
     920             :   }
     921             : 
     922             :   /// Return a ValueInfo for \p GUID.
     923             :   ValueInfo getOrInsertValueInfo(GlobalValue::GUID GUID) {
     924        1275 :     return ValueInfo(HaveGVs, getOrInsertValuePtr(GUID));
     925             :   }
     926             : 
     927             :   // Save a string in the Index. Use before passing Name to
     928             :   // getOrInsertValueInfo when the string isn't owned elsewhere (e.g. on the
     929             :   // module's Strtab).
     930          13 :   StringRef saveString(std::string String) { return Saver.save(String); }
     931             : 
     932             :   /// Return a ValueInfo for \p GUID setting value \p Name.
     933             :   ValueInfo getOrInsertValueInfo(GlobalValue::GUID GUID, StringRef Name) {
     934             :     assert(!HaveGVs);
     935        1647 :     auto VP = getOrInsertValuePtr(GUID);
     936        1647 :     VP->second.U.Name = Name;
     937        1647 :     return ValueInfo(HaveGVs, VP);
     938             :   }
     939             : 
     940             :   /// Return a ValueInfo for \p GV and mark it as belonging to GV.
     941        1505 :   ValueInfo getOrInsertValueInfo(const GlobalValue *GV) {
     942             :     assert(HaveGVs);
     943        1505 :     auto VP = getOrInsertValuePtr(GV->getGUID());
     944        1505 :     VP->second.U.GV = GV;
     945        3010 :     return ValueInfo(HaveGVs, VP);
     946             :   }
     947             : 
     948             :   /// Return the GUID for \p OriginalId in the OidGuidMap.
     949             :   GlobalValue::GUID getGUIDFromOriginalID(GlobalValue::GUID OriginalID) const {
     950             :     const auto I = OidGuidMap.find(OriginalID);
     951          92 :     return I == OidGuidMap.end() ? 0 : I->second;
     952             :   }
     953             : 
     954             :   std::set<std::string> &cfiFunctionDefs() { return CfiFunctionDefs; }
     955             :   const std::set<std::string> &cfiFunctionDefs() const { return CfiFunctionDefs; }
     956             : 
     957             :   std::set<std::string> &cfiFunctionDecls() { return CfiFunctionDecls; }
     958             :   const std::set<std::string> &cfiFunctionDecls() const { return CfiFunctionDecls; }
     959             : 
     960             :   /// Add a global value summary for a value.
     961         923 :   void addGlobalValueSummary(const GlobalValue &GV,
     962             :                              std::unique_ptr<GlobalValueSummary> Summary) {
     963         923 :     addGlobalValueSummary(getOrInsertValueInfo(&GV), std::move(Summary));
     964         923 :   }
     965             : 
     966             :   /// Add a global value summary for a value of the given name.
     967             :   void addGlobalValueSummary(StringRef ValueName,
     968             :                              std::unique_ptr<GlobalValueSummary> Summary) {
     969             :     addGlobalValueSummary(getOrInsertValueInfo(GlobalValue::getGUID(ValueName)),
     970             :                           std::move(Summary));
     971             :   }
     972             : 
     973             :   /// Add a global value summary for the given ValueInfo.
     974        3340 :   void addGlobalValueSummary(ValueInfo VI,
     975             :                              std::unique_ptr<GlobalValueSummary> Summary) {
     976        6680 :     addOriginalName(VI.getGUID(), Summary->getOriginalName());
     977             :     // Here we have a notionally const VI, but the value it points to is owned
     978             :     // by the non-const *this.
     979             :     const_cast<GlobalValueSummaryMapTy::value_type *>(VI.getRef())
     980        3340 :         ->second.SummaryList.push_back(std::move(Summary));
     981        3340 :   }
     982             : 
     983             :   /// Add an original name for the value of the given GUID.
     984        3509 :   void addOriginalName(GlobalValue::GUID ValueGUID,
     985             :                        GlobalValue::GUID OrigGUID) {
     986        3509 :     if (OrigGUID == 0 || ValueGUID == OrigGUID)
     987             :       return;
     988           8 :     if (OidGuidMap.count(OrigGUID) && OidGuidMap[OrigGUID] != ValueGUID)
     989           0 :       OidGuidMap[OrigGUID] = 0;
     990             :     else
     991         246 :       OidGuidMap[OrigGUID] = ValueGUID;
     992             :   }
     993             : 
     994             :   /// Find the summary for global \p GUID in module \p ModuleId, or nullptr if
     995             :   /// not found.
     996         787 :   GlobalValueSummary *findSummaryInModule(GlobalValue::GUID ValueGUID,
     997             :                                           StringRef ModuleId) const {
     998         787 :     auto CalleeInfo = getValueInfo(ValueGUID);
     999         787 :     if (!CalleeInfo) {
    1000             :       return nullptr; // This function does not have a summary
    1001             :     }
    1002             :     auto Summary =
    1003             :         llvm::find_if(CalleeInfo.getSummaryList(),
    1004             :                       [&](const std::unique_ptr<GlobalValueSummary> &Summary) {
    1005             :                         return Summary->modulePath() == ModuleId;
    1006             :                       });
    1007         785 :     if (Summary == CalleeInfo.getSummaryList().end())
    1008             :       return nullptr;
    1009         694 :     return Summary->get();
    1010             :   }
    1011             : 
    1012             :   /// Returns the first GlobalValueSummary for \p GV, asserting that there
    1013             :   /// is only one if \p PerModuleIndex.
    1014             :   GlobalValueSummary *getGlobalValueSummary(const GlobalValue &GV,
    1015             :                                             bool PerModuleIndex = true) const {
    1016             :     assert(GV.hasName() && "Can't get GlobalValueSummary for GV with no name");
    1017         259 :     return getGlobalValueSummary(GV.getGUID(), PerModuleIndex);
    1018             :   }
    1019             : 
    1020             :   /// Returns the first GlobalValueSummary for \p ValueGUID, asserting that
    1021             :   /// there
    1022             :   /// is only one if \p PerModuleIndex.
    1023             :   GlobalValueSummary *getGlobalValueSummary(GlobalValue::GUID ValueGUID,
    1024             :                                             bool PerModuleIndex = true) const;
    1025             : 
    1026             :   /// Table of modules, containing module hash and id.
    1027             :   const StringMap<std::pair<uint64_t, ModuleHash>> &modulePaths() const {
    1028          30 :     return ModulePathStringTable;
    1029             :   }
    1030             : 
    1031             :   /// Table of modules, containing hash and id.
    1032             :   StringMap<std::pair<uint64_t, ModuleHash>> &modulePaths() {
    1033          87 :     return ModulePathStringTable;
    1034             :   }
    1035             : 
    1036             :   /// Get the module ID recorded for the given module path.
    1037             :   uint64_t getModuleId(const StringRef ModPath) const {
    1038         249 :     return ModulePathStringTable.lookup(ModPath).first;
    1039             :   }
    1040             : 
    1041             :   /// Get the module SHA1 hash recorded for the given module path.
    1042             :   const ModuleHash &getModuleHash(const StringRef ModPath) const {
    1043         348 :     auto It = ModulePathStringTable.find(ModPath);
    1044             :     assert(It != ModulePathStringTable.end() && "Module not registered");
    1045         121 :     return It->second.second;
    1046             :   }
    1047             : 
    1048             :   /// Convenience method for creating a promoted global name
    1049             :   /// for the given value name of a local, and its original module's ID.
    1050         121 :   static std::string getGlobalNameForLocal(StringRef Name, ModuleHash ModHash) {
    1051             :     SmallString<256> NewName(Name);
    1052             :     NewName += ".llvm.";
    1053         242 :     NewName += utostr((uint64_t(ModHash[0]) << 32) |
    1054             :                       ModHash[1]); // Take the first 64 bits
    1055         121 :     return NewName.str();
    1056             :   }
    1057             : 
    1058             :   /// Helper to obtain the unpromoted name for a global value (or the original
    1059             :   /// name if not promoted).
    1060             :   static StringRef getOriginalNameBeforePromote(StringRef Name) {
    1061             :     std::pair<StringRef, StringRef> Pair = Name.split(".llvm.");
    1062             :     return Pair.first;
    1063             :   }
    1064             : 
    1065             :   typedef ModulePathStringTableTy::value_type ModuleInfo;
    1066             : 
    1067             :   /// Add a new module with the given \p Hash, mapped to the given \p
    1068             :   /// ModID, and return a reference to the module.
    1069         833 :   ModuleInfo *addModule(StringRef ModPath, uint64_t ModId,
    1070             :                         ModuleHash Hash = ModuleHash{{0}}) {
    1071         833 :     return &*ModulePathStringTable.insert({ModPath, {ModId, Hash}}).first;
    1072             :   }
    1073             : 
    1074             :   /// Return module entry for module with the given \p ModPath.
    1075             :   ModuleInfo *getModule(StringRef ModPath) {
    1076        1222 :     auto It = ModulePathStringTable.find(ModPath);
    1077             :     assert(It != ModulePathStringTable.end() && "Module not registered");
    1078        1222 :     return &*It;
    1079             :   }
    1080             : 
    1081             :   /// Check if the given Module has any functions available for exporting
    1082             :   /// in the index. We consider any module present in the ModulePathStringTable
    1083             :   /// to have exported functions.
    1084         357 :   bool hasExportedFunctions(const Module &M) const {
    1085         357 :     return ModulePathStringTable.count(M.getModuleIdentifier());
    1086             :   }
    1087             : 
    1088             :   const TypeIdSummaryMapTy &typeIds() const { return TypeIdMap; }
    1089             : 
    1090             :   /// Return an existing or new TypeIdSummary entry for \p TypeId.
    1091             :   /// This accessor can mutate the map and therefore should not be used in
    1092             :   /// the ThinLTO backends.
    1093         108 :   TypeIdSummary &getOrInsertTypeIdSummary(StringRef TypeId) {
    1094         108 :     auto TidIter = TypeIdMap.equal_range(GlobalValue::getGUID(TypeId));
    1095         108 :     for (auto It = TidIter.first; It != TidIter.second; ++It)
    1096             :       if (It->second.first == TypeId)
    1097           8 :         return It->second.second;
    1098             :     auto It = TypeIdMap.insert(
    1099         300 :         {GlobalValue::getGUID(TypeId), {TypeId, TypeIdSummary()}});
    1100         100 :     return It->second.second;
    1101             :   }
    1102             : 
    1103             :   /// This returns either a pointer to the type id summary (if present in the
    1104             :   /// summary map) or null (if not present). This may be used when importing.
    1105          85 :   const TypeIdSummary *getTypeIdSummary(StringRef TypeId) const {
    1106          85 :     auto TidIter = TypeIdMap.equal_range(GlobalValue::getGUID(TypeId));
    1107          85 :     for (auto It = TidIter.first; It != TidIter.second; ++It)
    1108             :       if (It->second.first == TypeId)
    1109          67 :         return &It->second.second;
    1110             :     return nullptr;
    1111             :   }
    1112             : 
    1113             :   /// Collect for the given module the list of functions it defines
    1114             :   /// (GUID -> Summary).
    1115             :   void collectDefinedFunctionsForModule(StringRef ModulePath,
    1116             :                                         GVSummaryMapTy &GVSummaryMap) const;
    1117             : 
    1118             :   /// Collect for each module the list of Summaries it defines (GUID ->
    1119             :   /// Summary).
    1120             :   void collectDefinedGVSummariesPerModule(
    1121             :       StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries) const;
    1122             : 
    1123             :   /// Print to an output stream.
    1124             :   void print(raw_ostream &OS, bool IsForDebug = false) const;
    1125             : 
    1126             :   /// Dump to stderr (for debugging).
    1127             :   void dump() const;
    1128             : 
    1129             :   /// Export summary to dot file for GraphViz.
    1130             :   void exportToDot(raw_ostream& OS) const;
    1131             : 
    1132             :   /// Print out strongly connected components for debugging.
    1133             :   void dumpSCCs(raw_ostream &OS);
    1134             : };
    1135             : 
    1136             : /// GraphTraits definition to build SCC for the index
    1137             : template <> struct GraphTraits<ValueInfo> {
    1138             :   typedef ValueInfo NodeRef;
    1139             : 
    1140          12 :   static NodeRef valueInfoFromEdge(FunctionSummary::EdgeTy &P) {
    1141          12 :     return P.first;
    1142             :   }
    1143             :   using ChildIteratorType =
    1144             :       mapped_iterator<std::vector<FunctionSummary::EdgeTy>::iterator,
    1145             :                       decltype(&valueInfoFromEdge)>;
    1146             : 
    1147             :   static NodeRef getEntryNode(ValueInfo V) { return V; }
    1148             : 
    1149          10 :   static ChildIteratorType child_begin(NodeRef N) {
    1150          10 :     if (!N.getSummaryList().size()) // handle external function
    1151             :       return ChildIteratorType(
    1152             :           FunctionSummary::ExternalNode.CallGraphEdgeList.begin(),
    1153           2 :           &valueInfoFromEdge);
    1154             :     FunctionSummary *F =
    1155             :         cast<FunctionSummary>(N.getSummaryList().front()->getBaseObject());
    1156           8 :     return ChildIteratorType(F->CallGraphEdgeList.begin(), &valueInfoFromEdge);
    1157             :   }
    1158             : 
    1159          17 :   static ChildIteratorType child_end(NodeRef N) {
    1160          17 :     if (!N.getSummaryList().size()) // handle external function
    1161             :       return ChildIteratorType(
    1162             :           FunctionSummary::ExternalNode.CallGraphEdgeList.end(),
    1163           2 :           &valueInfoFromEdge);
    1164             :     FunctionSummary *F =
    1165             :         cast<FunctionSummary>(N.getSummaryList().front()->getBaseObject());
    1166          15 :     return ChildIteratorType(F->CallGraphEdgeList.end(), &valueInfoFromEdge);
    1167             :   }
    1168             : };
    1169             : 
    1170             : template <>
    1171             : struct GraphTraits<ModuleSummaryIndex *> : public GraphTraits<ValueInfo> {
    1172           1 :   static NodeRef getEntryNode(ModuleSummaryIndex *I) {
    1173             :     std::unique_ptr<GlobalValueSummary> Root =
    1174           1 :         make_unique<FunctionSummary>(I->calculateCallGraphRoot());
    1175           1 :     GlobalValueSummaryInfo G(I->haveGVs());
    1176             :     G.SummaryList.push_back(std::move(Root));
    1177             :     static auto P =
    1178           1 :         GlobalValueSummaryMapTy::value_type(GlobalValue::GUID(0), std::move(G));
    1179           2 :     return ValueInfo(I->haveGVs(), &P);
    1180             :   }
    1181             : };
    1182             : 
    1183             : } // end namespace llvm
    1184             : 
    1185             : #endif // LLVM_IR_MODULESUMMARYINDEX_H

Generated by: LCOV version 1.13