- //===- llvm/ModuleSummaryIndex.h - Module Summary Index ---------*- C++ -*-===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
- // 
- /// @file 
- /// ModuleSummaryIndex.h This file contains the declarations the classes that 
- ///  hold the module index and summary for function importing. 
- // 
- //===----------------------------------------------------------------------===// 
-   
- #ifndef LLVM_IR_MODULESUMMARYINDEX_H 
- #define LLVM_IR_MODULESUMMARYINDEX_H 
-   
- #include "llvm/ADT/ArrayRef.h" 
- #include "llvm/ADT/DenseMap.h" 
- #include "llvm/ADT/STLExtras.h" 
- #include "llvm/ADT/SmallString.h" 
- #include "llvm/ADT/SmallVector.h" 
- #include "llvm/ADT/StringExtras.h" 
- #include "llvm/ADT/StringMap.h" 
- #include "llvm/ADT/StringRef.h" 
- #include "llvm/IR/ConstantRange.h" 
- #include "llvm/IR/GlobalValue.h" 
- #include "llvm/IR/Module.h" 
- #include "llvm/Support/Allocator.h" 
- #include "llvm/Support/MathExtras.h" 
- #include "llvm/Support/ScaledNumber.h" 
- #include "llvm/Support/StringSaver.h" 
- #include "llvm/Support/raw_ostream.h" 
- #include <algorithm> 
- #include <array> 
- #include <cassert> 
- #include <cstddef> 
- #include <cstdint> 
- #include <map> 
- #include <memory> 
- #include <optional> 
- #include <set> 
- #include <string> 
- #include <utility> 
- #include <vector> 
-   
- namespace llvm { 
-   
- template <class GraphType> struct GraphTraits; 
-   
- namespace yaml { 
-   
- template <typename T> struct MappingTraits; 
-   
- } // end namespace yaml 
-   
- /// Class to accumulate and hold information about a callee. 
- struct CalleeInfo { 
-   enum class HotnessType : uint8_t { 
-     Unknown = 0, 
-     Cold = 1, 
-     None = 2, 
-     Hot = 3, 
-     Critical = 4 
-   }; 
-   
-   // The size of the bit-field might need to be adjusted if more values are 
-   // added to HotnessType enum. 
-   uint32_t Hotness : 3; 
-   
-   /// The value stored in RelBlockFreq has to be interpreted as the digits of 
-   /// a scaled number with a scale of \p -ScaleShift. 
-   uint32_t RelBlockFreq : 29; 
-   static constexpr int32_t ScaleShift = 8; 
-   static constexpr uint64_t MaxRelBlockFreq = (1 << 29) - 1; 
-   
-   CalleeInfo() 
-       : Hotness(static_cast<uint32_t>(HotnessType::Unknown)), RelBlockFreq(0) {} 
-   explicit CalleeInfo(HotnessType Hotness, uint64_t RelBF) 
-       : Hotness(static_cast<uint32_t>(Hotness)), RelBlockFreq(RelBF) {} 
-   
-   void updateHotness(const HotnessType OtherHotness) { 
-     Hotness = std::max(Hotness, static_cast<uint32_t>(OtherHotness)); 
-   } 
-   
-   HotnessType getHotness() const { return HotnessType(Hotness); } 
-   
-   /// Update \p RelBlockFreq from \p BlockFreq and \p EntryFreq 
-   /// 
-   /// BlockFreq is divided by EntryFreq and added to RelBlockFreq. To represent 
-   /// fractional values, the result is represented as a fixed point number with 
-   /// scale of -ScaleShift. 
-   void updateRelBlockFreq(uint64_t BlockFreq, uint64_t EntryFreq) { 
-     if (EntryFreq == 0) 
-       return; 
-     using Scaled64 = ScaledNumber<uint64_t>; 
-     Scaled64 Temp(BlockFreq, ScaleShift); 
-     Temp /= Scaled64::get(EntryFreq); 
-   
-     uint64_t Sum = 
-         SaturatingAdd<uint64_t>(Temp.toInt<uint64_t>(), RelBlockFreq); 
-     Sum = std::min(Sum, uint64_t(MaxRelBlockFreq)); 
-     RelBlockFreq = static_cast<uint32_t>(Sum); 
-   } 
- }; 
-   
- inline const char *getHotnessName(CalleeInfo::HotnessType HT) { 
-   switch (HT) { 
-   case CalleeInfo::HotnessType::Unknown: 
-     return "unknown"; 
-   case CalleeInfo::HotnessType::Cold: 
-     return "cold"; 
-   case CalleeInfo::HotnessType::None: 
-     return "none"; 
-   case CalleeInfo::HotnessType::Hot: 
-     return "hot"; 
-   case CalleeInfo::HotnessType::Critical: 
-     return "critical"; 
-   } 
-   llvm_unreachable("invalid hotness"); 
- } 
-   
- class GlobalValueSummary; 
-   
- using GlobalValueSummaryList = std::vector<std::unique_ptr<GlobalValueSummary>>; 
-   
- struct alignas(8) GlobalValueSummaryInfo { 
-   union NameOrGV { 
-     NameOrGV(bool HaveGVs) { 
-       if (HaveGVs) 
-         GV = nullptr; 
-       else 
-         Name = ""; 
-     } 
-   
-     /// The GlobalValue corresponding to this summary. This is only used in 
-     /// per-module summaries and when the IR is available. E.g. when module 
-     /// analysis is being run, or when parsing both the IR and the summary 
-     /// from assembly. 
-     const GlobalValue *GV; 
-   
-     /// Summary string representation. This StringRef points to BC module 
-     /// string table and is valid until module data is stored in memory. 
-     /// This is guaranteed to happen until runThinLTOBackend function is 
-     /// called, so it is safe to use this field during thin link. This field 
-     /// is only valid if summary index was loaded from BC file. 
-     StringRef Name; 
-   } U; 
-   
-   GlobalValueSummaryInfo(bool HaveGVs) : U(HaveGVs) {} 
-   
-   /// List of global value summary structures for a particular value held 
-   /// in the GlobalValueMap. Requires a vector in the case of multiple 
-   /// COMDAT values of the same name. 
-   GlobalValueSummaryList SummaryList; 
- }; 
-   
- /// Map from global value GUID to corresponding summary structures. Use a 
- /// std::map rather than a DenseMap so that pointers to the map's value_type 
- /// (which are used by ValueInfo) are not invalidated by insertion. Also it will 
- /// likely incur less overhead, as the value type is not very small and the size 
- /// of the map is unknown, resulting in inefficiencies due to repeated 
- /// insertions and resizing. 
- using GlobalValueSummaryMapTy = 
-     std::map<GlobalValue::GUID, GlobalValueSummaryInfo>; 
-   
- /// Struct that holds a reference to a particular GUID in a global value 
- /// summary. 
- struct ValueInfo { 
-   enum Flags { HaveGV = 1, ReadOnly = 2, WriteOnly = 4 }; 
-   PointerIntPair<const GlobalValueSummaryMapTy::value_type *, 3, int> 
-       RefAndFlags; 
-   
-   ValueInfo() = default; 
-   ValueInfo(bool HaveGVs, const GlobalValueSummaryMapTy::value_type *R) { 
-     RefAndFlags.setPointer(R); 
-     RefAndFlags.setInt(HaveGVs); 
-   } 
-   
-   explicit operator bool() const { return getRef(); } 
-   
-   GlobalValue::GUID getGUID() const { return getRef()->first; } 
-   const GlobalValue *getValue() const { 
-     assert(haveGVs()); 
-     return getRef()->second.U.GV; 
-   } 
-   
-   ArrayRef<std::unique_ptr<GlobalValueSummary>> getSummaryList() const { 
-     return getRef()->second.SummaryList; 
-   } 
-   
-   StringRef name() const { 
-     return haveGVs() ? getRef()->second.U.GV->getName() 
-                      : getRef()->second.U.Name; 
-   } 
-   
-   bool haveGVs() const { return RefAndFlags.getInt() & HaveGV; } 
-   bool isReadOnly() const { 
-     assert(isValidAccessSpecifier()); 
-     return RefAndFlags.getInt() & ReadOnly; 
-   } 
-   bool isWriteOnly() const { 
-     assert(isValidAccessSpecifier()); 
-     return RefAndFlags.getInt() & WriteOnly; 
-   } 
-   unsigned getAccessSpecifier() const { 
-     assert(isValidAccessSpecifier()); 
-     return RefAndFlags.getInt() & (ReadOnly | WriteOnly); 
-   } 
-   bool isValidAccessSpecifier() const { 
-     unsigned BadAccessMask = ReadOnly | WriteOnly; 
-     return (RefAndFlags.getInt() & BadAccessMask) != BadAccessMask; 
-   } 
-   void setReadOnly() { 
-     // We expect ro/wo attribute to set only once during 
-     // ValueInfo lifetime. 
-     assert(getAccessSpecifier() == 0); 
-     RefAndFlags.setInt(RefAndFlags.getInt() | ReadOnly); 
-   } 
-   void setWriteOnly() { 
-     assert(getAccessSpecifier() == 0); 
-     RefAndFlags.setInt(RefAndFlags.getInt() | WriteOnly); 
-   } 
-   
-   const GlobalValueSummaryMapTy::value_type *getRef() const { 
-     return RefAndFlags.getPointer(); 
-   } 
-   
-   /// Returns the most constraining visibility among summaries. The 
-   /// visibilities, ordered from least to most constraining, are: default, 
-   /// protected and hidden. 
-   GlobalValue::VisibilityTypes getELFVisibility() const; 
-   
-   /// Checks if all summaries are DSO local (have the flag set). When DSOLocal 
-   /// propagation has been done, set the parameter to enable fast check. 
-   bool isDSOLocal(bool WithDSOLocalPropagation = false) const; 
-   
-   /// Checks if all copies are eligible for auto-hiding (have flag set). 
-   bool canAutoHide() const; 
- }; 
-   
- inline raw_ostream &operator<<(raw_ostream &OS, const ValueInfo &VI) { 
-   OS << VI.getGUID(); 
-   if (!VI.name().empty()) 
-     OS << " (" << VI.name() << ")"; 
-   return OS; 
- } 
-   
- inline bool operator==(const ValueInfo &A, const ValueInfo &B) { 
-   assert(A.getRef() && B.getRef() && 
-          "Need ValueInfo with non-null Ref for comparison"); 
-   return A.getRef() == B.getRef(); 
- } 
-   
- inline bool operator!=(const ValueInfo &A, const ValueInfo &B) { 
-   assert(A.getRef() && B.getRef() && 
-          "Need ValueInfo with non-null Ref for comparison"); 
-   return A.getRef() != B.getRef(); 
- } 
-   
- inline bool operator<(const ValueInfo &A, const ValueInfo &B) { 
-   assert(A.getRef() && B.getRef() && 
-          "Need ValueInfo with non-null Ref to compare GUIDs"); 
-   return A.getGUID() < B.getGUID(); 
- } 
-   
- template <> struct DenseMapInfo<ValueInfo> { 
-   static inline ValueInfo getEmptyKey() { 
-     return ValueInfo(false, (GlobalValueSummaryMapTy::value_type *)-8); 
-   } 
-   
-   static inline ValueInfo getTombstoneKey() { 
-     return ValueInfo(false, (GlobalValueSummaryMapTy::value_type *)-16); 
-   } 
-   
-   static inline bool isSpecialKey(ValueInfo V) { 
-     return V == getTombstoneKey() || V == getEmptyKey(); 
-   } 
-   
-   static bool isEqual(ValueInfo L, ValueInfo R) { 
-     // We are not supposed to mix ValueInfo(s) with different HaveGVs flag 
-     // in a same container. 
-     assert(isSpecialKey(L) || isSpecialKey(R) || (L.haveGVs() == R.haveGVs())); 
-     return L.getRef() == R.getRef(); 
-   } 
-   static unsigned getHashValue(ValueInfo I) { return (uintptr_t)I.getRef(); } 
- }; 
-   
- /// Summary of memprof callsite metadata. 
- struct CallsiteInfo { 
-   // Actual callee function. 
-   ValueInfo Callee; 
-   
-   // Used to record whole program analysis cloning decisions. 
-   // The ThinLTO backend will need to create as many clones as there are entries 
-   // in the vector (it is expected and should be confirmed that all such 
-   // summaries in the same FunctionSummary have the same number of entries). 
-   // Each index records version info for the corresponding clone of this 
-   // function. The value is the callee clone it calls (becomes the appended 
-   // suffix id). Index 0 is the original version, and a value of 0 calls the 
-   // original callee. 
-   SmallVector<unsigned> Clones{0}; 
-   
-   // Represents stack ids in this context, recorded as indices into the 
-   // StackIds vector in the summary index, which in turn holds the full 64-bit 
-   // stack ids. This reduces memory as there are in practice far fewer unique 
-   // stack ids than stack id references. 
-   SmallVector<unsigned> StackIdIndices; 
-   
-   CallsiteInfo(ValueInfo Callee, SmallVector<unsigned> StackIdIndices) 
-       : Callee(Callee), StackIdIndices(std::move(StackIdIndices)) {} 
-   CallsiteInfo(ValueInfo Callee, SmallVector<unsigned> Clones, 
-                SmallVector<unsigned> StackIdIndices) 
-       : Callee(Callee), Clones(std::move(Clones)), 
-         StackIdIndices(std::move(StackIdIndices)) {} 
- }; 
-   
- // Allocation type assigned to an allocation reached by a given context. 
- // More can be added but initially this is just noncold and cold. 
- // Values should be powers of two so that they can be ORed, in particular to 
- // track allocations that have different behavior with different calling 
- // contexts. 
- enum class AllocationType : uint8_t { None = 0, NotCold = 1, Cold = 2 }; 
-   
- /// Summary of a single MIB in a memprof metadata on allocations. 
- struct MIBInfo { 
-   // The allocation type for this profiled context. 
-   AllocationType AllocType; 
-   
-   // Represents stack ids in this context, recorded as indices into the 
-   // StackIds vector in the summary index, which in turn holds the full 64-bit 
-   // stack ids. This reduces memory as there are in practice far fewer unique 
-   // stack ids than stack id references. 
-   SmallVector<unsigned> StackIdIndices; 
-   
-   MIBInfo(AllocationType AllocType, SmallVector<unsigned> StackIdIndices) 
-       : AllocType(AllocType), StackIdIndices(std::move(StackIdIndices)) {} 
- }; 
-   
- /// Summary of memprof metadata on allocations. 
- struct AllocInfo { 
-   // Used to record whole program analysis cloning decisions. 
-   // The ThinLTO backend will need to create as many clones as there are entries 
-   // in the vector (it is expected and should be confirmed that all such 
-   // summaries in the same FunctionSummary have the same number of entries). 
-   // Each index records version info for the corresponding clone of this 
-   // function. The value is the allocation type of the corresponding allocation. 
-   // Index 0 is the original version. Before cloning, index 0 may have more than 
-   // one allocation type. 
-   SmallVector<uint8_t> Versions; 
-   
-   // Vector of MIBs in this memprof metadata. 
-   std::vector<MIBInfo> MIBs; 
-   
-   AllocInfo(std::vector<MIBInfo> MIBs) : MIBs(std::move(MIBs)) { 
-     Versions.push_back(0); 
-   } 
-   AllocInfo(SmallVector<uint8_t> Versions, std::vector<MIBInfo> MIBs) 
-       : Versions(std::move(Versions)), MIBs(std::move(MIBs)) {} 
- }; 
-   
- /// Function and variable summary information to aid decisions and 
- /// implementation of importing. 
- class GlobalValueSummary { 
- public: 
-   /// Sububclass discriminator (for dyn_cast<> et al.) 
-   enum SummaryKind : unsigned { AliasKind, FunctionKind, GlobalVarKind }; 
-   
-   /// Group flags (Linkage, NotEligibleToImport, etc.) as a bitfield. 
-   struct GVFlags { 
-     /// The linkage type of the associated global value. 
-     /// 
-     /// One use is to flag values that have local linkage types and need to 
-     /// have module identifier appended before placing into the combined 
-     /// index, to disambiguate from other values with the same name. 
-     /// In the future this will be used to update and optimize linkage 
-     /// types based on global summary-based analysis. 
-     unsigned Linkage : 4; 
-   
-     /// Indicates the visibility. 
-     unsigned Visibility : 2; 
-   
-     /// Indicate if the global value cannot be imported (e.g. it cannot 
-     /// be renamed or references something that can't be renamed). 
-     unsigned NotEligibleToImport : 1; 
-   
-     /// In per-module summary, indicate that the global value must be considered 
-     /// a live root for index-based liveness analysis. Used for special LLVM 
-     /// values such as llvm.global_ctors that the linker does not know about. 
-     /// 
-     /// In combined summary, indicate that the global value is live. 
-     unsigned Live : 1; 
-   
-     /// Indicates that the linker resolved the symbol to a definition from 
-     /// within the same linkage unit. 
-     unsigned DSOLocal : 1; 
-   
-     /// In the per-module summary, indicates that the global value is 
-     /// linkonce_odr and global unnamed addr (so eligible for auto-hiding 
-     /// via hidden visibility). In the combined summary, indicates that the 
-     /// prevailing linkonce_odr copy can be auto-hidden via hidden visibility 
-     /// when it is upgraded to weak_odr in the backend. This is legal when 
-     /// all copies are eligible for auto-hiding (i.e. all copies were 
-     /// linkonce_odr global unnamed addr. If any copy is not (e.g. it was 
-     /// originally weak_odr, we cannot auto-hide the prevailing copy as it 
-     /// means the symbol was externally visible. 
-     unsigned CanAutoHide : 1; 
-   
-     /// Convenience Constructors 
-     explicit GVFlags(GlobalValue::LinkageTypes Linkage, 
-                      GlobalValue::VisibilityTypes Visibility, 
-                      bool NotEligibleToImport, bool Live, bool IsLocal, 
-                      bool CanAutoHide) 
-         : Linkage(Linkage), Visibility(Visibility), 
-           NotEligibleToImport(NotEligibleToImport), Live(Live), 
-           DSOLocal(IsLocal), CanAutoHide(CanAutoHide) {} 
-   }; 
-   
- private: 
-   /// Kind of summary for use in dyn_cast<> et al. 
-   SummaryKind Kind; 
-   
-   GVFlags Flags; 
-   
-   /// This is the hash of the name of the symbol in the original file. It is 
-   /// identical to the GUID for global symbols, but differs for local since the 
-   /// GUID includes the module level id in the hash. 
-   GlobalValue::GUID OriginalName = 0; 
-   
-   /// Path of module IR containing value's definition, used to locate 
-   /// module during importing. 
-   /// 
-   /// This is only used during parsing of the combined index, or when 
-   /// parsing the per-module index for creation of the combined summary index, 
-   /// not during writing of the per-module index which doesn't contain a 
-   /// module path string table. 
-   StringRef ModulePath; 
-   
-   /// List of values referenced by this global value's definition 
-   /// (either by the initializer of a global variable, or referenced 
-   /// from within a function). This does not include functions called, which 
-   /// are listed in the derived FunctionSummary object. 
-   std::vector<ValueInfo> RefEdgeList; 
-   
- protected: 
-   GlobalValueSummary(SummaryKind K, GVFlags Flags, std::vector<ValueInfo> Refs) 
-       : Kind(K), Flags(Flags), RefEdgeList(std::move(Refs)) { 
-     assert((K != AliasKind || Refs.empty()) && 
-            "Expect no references for AliasSummary"); 
-   } 
-   
- public: 
-   virtual ~GlobalValueSummary() = default; 
-   
-   /// Returns the hash of the original name, it is identical to the GUID for 
-   /// externally visible symbols, but not for local ones. 
-   GlobalValue::GUID getOriginalName() const { return OriginalName; } 
-   
-   /// Initialize the original name hash in this summary. 
-   void setOriginalName(GlobalValue::GUID Name) { OriginalName = Name; } 
-   
-   /// Which kind of summary subclass this is. 
-   SummaryKind getSummaryKind() const { return Kind; } 
-   
-   /// Set the path to the module containing this function, for use in 
-   /// the combined index. 
-   void setModulePath(StringRef ModPath) { ModulePath = ModPath; } 
-   
-   /// Get the path to the module containing this function. 
-   StringRef modulePath() const { return ModulePath; } 
-   
-   /// Get the flags for this GlobalValue (see \p struct GVFlags). 
-   GVFlags flags() const { return Flags; } 
-   
-   /// Return linkage type recorded for this global value. 
-   GlobalValue::LinkageTypes linkage() const { 
-     return static_cast<GlobalValue::LinkageTypes>(Flags.Linkage); 
-   } 
-   
-   /// Sets the linkage to the value determined by global summary-based 
-   /// optimization. Will be applied in the ThinLTO backends. 
-   void setLinkage(GlobalValue::LinkageTypes Linkage) { 
-     Flags.Linkage = Linkage; 
-   } 
-   
-   /// Return true if this global value can't be imported. 
-   bool notEligibleToImport() const { return Flags.NotEligibleToImport; } 
-   
-   bool isLive() const { return Flags.Live; } 
-   
-   void setLive(bool Live) { Flags.Live = Live; } 
-   
-   void setDSOLocal(bool Local) { Flags.DSOLocal = Local; } 
-   
-   bool isDSOLocal() const { return Flags.DSOLocal; } 
-   
-   void setCanAutoHide(bool CanAutoHide) { Flags.CanAutoHide = CanAutoHide; } 
-   
-   bool canAutoHide() const { return Flags.CanAutoHide; } 
-   
-   GlobalValue::VisibilityTypes getVisibility() const { 
-     return (GlobalValue::VisibilityTypes)Flags.Visibility; 
-   } 
-   void setVisibility(GlobalValue::VisibilityTypes Vis) { 
-     Flags.Visibility = (unsigned)Vis; 
-   } 
-   
-   /// Flag that this global value cannot be imported. 
-   void setNotEligibleToImport() { Flags.NotEligibleToImport = true; } 
-   
-   /// Return the list of values referenced by this global value definition. 
-   ArrayRef<ValueInfo> refs() const { return RefEdgeList; } 
-   
-   /// If this is an alias summary, returns the summary of the aliased object (a 
-   /// global variable or function), otherwise returns itself. 
-   GlobalValueSummary *getBaseObject(); 
-   const GlobalValueSummary *getBaseObject() const; 
-   
-   friend class ModuleSummaryIndex; 
- }; 
-   
- /// Alias summary information. 
- class AliasSummary : public GlobalValueSummary { 
-   ValueInfo AliaseeValueInfo; 
-   
-   /// This is the Aliasee in the same module as alias (could get from VI, trades 
-   /// memory for time). Note that this pointer may be null (and the value info 
-   /// empty) when we have a distributed index where the alias is being imported 
-   /// (as a copy of the aliasee), but the aliasee is not. 
-   GlobalValueSummary *AliaseeSummary; 
-   
- public: 
-   AliasSummary(GVFlags Flags) 
-       : GlobalValueSummary(AliasKind, Flags, ArrayRef<ValueInfo>{}), 
-         AliaseeSummary(nullptr) {} 
-   
-   /// Check if this is an alias summary. 
-   static bool classof(const GlobalValueSummary *GVS) { 
-     return GVS->getSummaryKind() == AliasKind; 
-   } 
-   
-   void setAliasee(ValueInfo &AliaseeVI, GlobalValueSummary *Aliasee) { 
-     AliaseeValueInfo = AliaseeVI; 
-     AliaseeSummary = Aliasee; 
-   } 
-   
-   bool hasAliasee() const { 
-     assert(!!AliaseeSummary == (AliaseeValueInfo && 
-                                 !AliaseeValueInfo.getSummaryList().empty()) && 
-            "Expect to have both aliasee summary and summary list or neither"); 
-     return !!AliaseeSummary; 
-   } 
-   
-   const GlobalValueSummary &getAliasee() const { 
-     assert(AliaseeSummary && "Unexpected missing aliasee summary"); 
-     return *AliaseeSummary; 
-   } 
-   
-   GlobalValueSummary &getAliasee() { 
-     return const_cast<GlobalValueSummary &>( 
-                          static_cast<const AliasSummary *>(this)->getAliasee()); 
-   } 
-   ValueInfo getAliaseeVI() const { 
-     assert(AliaseeValueInfo && "Unexpected missing aliasee"); 
-     return AliaseeValueInfo; 
-   } 
-   GlobalValue::GUID getAliaseeGUID() const { 
-     assert(AliaseeValueInfo && "Unexpected missing aliasee"); 
-     return AliaseeValueInfo.getGUID(); 
-   } 
- }; 
-   
- const inline GlobalValueSummary *GlobalValueSummary::getBaseObject() const { 
-   if (auto *AS = dyn_cast<AliasSummary>(this)) 
-     return &AS->getAliasee(); 
-   return this; 
- } 
-   
- inline GlobalValueSummary *GlobalValueSummary::getBaseObject() { 
-   if (auto *AS = dyn_cast<AliasSummary>(this)) 
-     return &AS->getAliasee(); 
-   return this; 
- } 
-   
- /// Function summary information to aid decisions and implementation of 
- /// importing. 
- class FunctionSummary : public GlobalValueSummary { 
- public: 
-   /// <CalleeValueInfo, CalleeInfo> call edge pair. 
-   using EdgeTy = std::pair<ValueInfo, CalleeInfo>; 
-   
-   /// Types for -force-summary-edges-cold debugging option. 
-   enum ForceSummaryHotnessType : unsigned { 
-     FSHT_None, 
-     FSHT_AllNonCritical, 
-     FSHT_All 
-   }; 
-   
-   /// An "identifier" for a virtual function. This contains the type identifier 
-   /// represented as a GUID and the offset from the address point to the virtual 
-   /// function pointer, where "address point" is as defined in the Itanium ABI: 
-   /// https://itanium-cxx-abi.github.io/cxx-abi/abi.html#vtable-general 
-   struct VFuncId { 
-     GlobalValue::GUID GUID; 
-     uint64_t Offset; 
-   }; 
-   
-   /// A specification for a virtual function call with all constant integer 
-   /// arguments. This is used to perform virtual constant propagation on the 
-   /// summary. 
-   struct ConstVCall { 
-     VFuncId VFunc; 
-     std::vector<uint64_t> Args; 
-   }; 
-   
-   /// All type identifier related information. Because these fields are 
-   /// relatively uncommon we only allocate space for them if necessary. 
-   struct TypeIdInfo { 
-     /// List of type identifiers used by this function in llvm.type.test 
-     /// intrinsics referenced by something other than an llvm.assume intrinsic, 
-     /// represented as GUIDs. 
-     std::vector<GlobalValue::GUID> TypeTests; 
-   
-     /// List of virtual calls made by this function using (respectively) 
-     /// llvm.assume(llvm.type.test) or llvm.type.checked.load intrinsics that do 
-     /// not have all constant integer arguments. 
-     std::vector<VFuncId> TypeTestAssumeVCalls, TypeCheckedLoadVCalls; 
-   
-     /// List of virtual calls made by this function using (respectively) 
-     /// llvm.assume(llvm.type.test) or llvm.type.checked.load intrinsics with 
-     /// all constant integer arguments. 
-     std::vector<ConstVCall> TypeTestAssumeConstVCalls, 
-         TypeCheckedLoadConstVCalls; 
-   }; 
-   
-   /// Flags specific to function summaries. 
-   struct FFlags { 
-     // Function attribute flags. Used to track if a function accesses memory, 
-     // recurses or aliases. 
-     unsigned ReadNone : 1; 
-     unsigned ReadOnly : 1; 
-     unsigned NoRecurse : 1; 
-     unsigned ReturnDoesNotAlias : 1; 
-   
-     // Indicate if the global value cannot be inlined. 
-     unsigned NoInline : 1; 
-     // Indicate if function should be always inlined. 
-     unsigned AlwaysInline : 1; 
-     // Indicate if function never raises an exception. Can be modified during 
-     // thinlink function attribute propagation 
-     unsigned NoUnwind : 1; 
-     // Indicate if function contains instructions that mayThrow 
-     unsigned MayThrow : 1; 
-   
-     // If there are calls to unknown targets (e.g. indirect) 
-     unsigned HasUnknownCall : 1; 
-   
-     // Indicate if a function must be an unreachable function. 
-     // 
-     // This bit is sufficient but not necessary; 
-     // if this bit is on, the function must be regarded as unreachable; 
-     // if this bit is off, the function might be reachable or unreachable. 
-     unsigned MustBeUnreachable : 1; 
-   
-     FFlags &operator&=(const FFlags &RHS) { 
-       this->ReadNone &= RHS.ReadNone; 
-       this->ReadOnly &= RHS.ReadOnly; 
-       this->NoRecurse &= RHS.NoRecurse; 
-       this->ReturnDoesNotAlias &= RHS.ReturnDoesNotAlias; 
-       this->NoInline &= RHS.NoInline; 
-       this->AlwaysInline &= RHS.AlwaysInline; 
-       this->NoUnwind &= RHS.NoUnwind; 
-       this->MayThrow &= RHS.MayThrow; 
-       this->HasUnknownCall &= RHS.HasUnknownCall; 
-       this->MustBeUnreachable &= RHS.MustBeUnreachable; 
-       return *this; 
-     } 
-   
-     bool anyFlagSet() { 
-       return this->ReadNone | this->ReadOnly | this->NoRecurse | 
-              this->ReturnDoesNotAlias | this->NoInline | this->AlwaysInline | 
-              this->NoUnwind | this->MayThrow | this->HasUnknownCall | 
-              this->MustBeUnreachable; 
-     } 
-   
-     operator std::string() { 
-       std::string Output; 
-       raw_string_ostream OS(Output); 
-       OS << "funcFlags: ("; 
-       OS << "readNone: " << this->ReadNone; 
-       OS << ", readOnly: " << this->ReadOnly; 
-       OS << ", noRecurse: " << this->NoRecurse; 
-       OS << ", returnDoesNotAlias: " << this->ReturnDoesNotAlias; 
-       OS << ", noInline: " << this->NoInline; 
-       OS << ", alwaysInline: " << this->AlwaysInline; 
-       OS << ", noUnwind: " << this->NoUnwind; 
-       OS << ", mayThrow: " << this->MayThrow; 
-       OS << ", hasUnknownCall: " << this->HasUnknownCall; 
-       OS << ", mustBeUnreachable: " << this->MustBeUnreachable; 
-       OS << ")"; 
-       return OS.str(); 
-     } 
-   }; 
-   
-   /// Describes the uses of a parameter by the function. 
-   struct ParamAccess { 
-     static constexpr uint32_t RangeWidth = 64; 
-   
-     /// Describes the use of a value in a call instruction, specifying the 
-     /// call's target, the value's parameter number, and the possible range of 
-     /// offsets from the beginning of the value that are passed. 
-     struct Call { 
-       uint64_t ParamNo = 0; 
-       ValueInfo Callee; 
-       ConstantRange Offsets{/*BitWidth=*/RangeWidth, /*isFullSet=*/true}; 
-   
-       Call() = default; 
-       Call(uint64_t ParamNo, ValueInfo Callee, const ConstantRange &Offsets) 
-           : ParamNo(ParamNo), Callee(Callee), Offsets(Offsets) {} 
-     }; 
-   
-     uint64_t ParamNo = 0; 
-     /// The range contains byte offsets from the parameter pointer which 
-     /// accessed by the function. In the per-module summary, it only includes 
-     /// accesses made by the function instructions. In the combined summary, it 
-     /// also includes accesses by nested function calls. 
-     ConstantRange Use{/*BitWidth=*/RangeWidth, /*isFullSet=*/true}; 
-     /// In the per-module summary, it summarizes the byte offset applied to each 
-     /// pointer parameter before passing to each corresponding callee. 
-     /// In the combined summary, it's empty and information is propagated by 
-     /// inter-procedural analysis and applied to the Use field. 
-     std::vector<Call> Calls; 
-   
-     ParamAccess() = default; 
-     ParamAccess(uint64_t ParamNo, const ConstantRange &Use) 
-         : ParamNo(ParamNo), Use(Use) {} 
-   }; 
-   
-   /// Create an empty FunctionSummary (with specified call edges). 
-   /// Used to represent external nodes and the dummy root node. 
-   static FunctionSummary 
-   makeDummyFunctionSummary(std::vector<FunctionSummary::EdgeTy> Edges) { 
-     return FunctionSummary( 
-         FunctionSummary::GVFlags( 
-             GlobalValue::LinkageTypes::AvailableExternallyLinkage, 
-             GlobalValue::DefaultVisibility, 
-             /*NotEligibleToImport=*/true, /*Live=*/true, /*IsLocal=*/false, 
-             /*CanAutoHide=*/false), 
-         /*NumInsts=*/0, FunctionSummary::FFlags{}, /*EntryCount=*/0, 
-         std::vector<ValueInfo>(), std::move(Edges), 
-         std::vector<GlobalValue::GUID>(), 
-         std::vector<FunctionSummary::VFuncId>(), 
-         std::vector<FunctionSummary::VFuncId>(), 
-         std::vector<FunctionSummary::ConstVCall>(), 
-         std::vector<FunctionSummary::ConstVCall>(), 
-         std::vector<FunctionSummary::ParamAccess>(), 
-         std::vector<CallsiteInfo>(), std::vector<AllocInfo>()); 
-   } 
-   
-   /// A dummy node to reference external functions that aren't in the index 
-   static FunctionSummary ExternalNode; 
-   
- private: 
-   /// Number of instructions (ignoring debug instructions, e.g.) computed 
-   /// during the initial compile step when the summary index is first built. 
-   unsigned InstCount; 
-   
-   /// Function summary specific flags. 
-   FFlags FunFlags; 
-   
-   /// The synthesized entry count of the function. 
-   /// This is only populated during ThinLink phase and remains unused while 
-   /// generating per-module summaries. 
-   uint64_t EntryCount = 0; 
-   
-   /// List of <CalleeValueInfo, CalleeInfo> call edge pairs from this function. 
-   std::vector<EdgeTy> CallGraphEdgeList; 
-   
-   std::unique_ptr<TypeIdInfo> TIdInfo; 
-   
-   /// Uses for every parameter to this function. 
-   using ParamAccessesTy = std::vector<ParamAccess>; 
-   std::unique_ptr<ParamAccessesTy> ParamAccesses; 
-   
-   /// Optional list of memprof callsite metadata summaries. The correspondence 
-   /// between the callsite summary and the callsites in the function is implied 
-   /// by the order in the vector (and can be validated by comparing the stack 
-   /// ids in the CallsiteInfo to those in the instruction callsite metadata). 
-   /// As a memory savings optimization, we only create these for the prevailing 
-   /// copy of a symbol when creating the combined index during LTO. 
-   using CallsitesTy = std::vector<CallsiteInfo>; 
-   std::unique_ptr<CallsitesTy> Callsites; 
-   
-   /// Optional list of allocation memprof metadata summaries. The correspondence 
-   /// between the alloc memprof summary and the allocation callsites in the 
-   /// function is implied by the order in the vector (and can be validated by 
-   /// comparing the stack ids in the AllocInfo to those in the instruction 
-   /// memprof metadata). 
-   /// As a memory savings optimization, we only create these for the prevailing 
-   /// copy of a symbol when creating the combined index during LTO. 
-   using AllocsTy = std::vector<AllocInfo>; 
-   std::unique_ptr<AllocsTy> Allocs; 
-   
- public: 
-   FunctionSummary(GVFlags Flags, unsigned NumInsts, FFlags FunFlags, 
-                   uint64_t EntryCount, std::vector<ValueInfo> Refs, 
-                   std::vector<EdgeTy> CGEdges, 
-                   std::vector<GlobalValue::GUID> TypeTests, 
-                   std::vector<VFuncId> TypeTestAssumeVCalls, 
-                   std::vector<VFuncId> TypeCheckedLoadVCalls, 
-                   std::vector<ConstVCall> TypeTestAssumeConstVCalls, 
-                   std::vector<ConstVCall> TypeCheckedLoadConstVCalls, 
-                   std::vector<ParamAccess> Params, CallsitesTy CallsiteList, 
-                   AllocsTy AllocList) 
-       : GlobalValueSummary(FunctionKind, Flags, std::move(Refs)), 
-         InstCount(NumInsts), FunFlags(FunFlags), EntryCount(EntryCount), 
-         CallGraphEdgeList(std::move(CGEdges)) { 
-     if (!TypeTests.empty() || !TypeTestAssumeVCalls.empty() || 
-         !TypeCheckedLoadVCalls.empty() || !TypeTestAssumeConstVCalls.empty() || 
-         !TypeCheckedLoadConstVCalls.empty()) 
-       TIdInfo = std::make_unique<TypeIdInfo>( 
-           TypeIdInfo{std::move(TypeTests), std::move(TypeTestAssumeVCalls), 
-                      std::move(TypeCheckedLoadVCalls), 
-                      std::move(TypeTestAssumeConstVCalls), 
-                      std::move(TypeCheckedLoadConstVCalls)}); 
-     if (!Params.empty()) 
-       ParamAccesses = std::make_unique<ParamAccessesTy>(std::move(Params)); 
-     if (!CallsiteList.empty()) 
-       Callsites = std::make_unique<CallsitesTy>(std::move(CallsiteList)); 
-     if (!AllocList.empty()) 
-       Allocs = std::make_unique<AllocsTy>(std::move(AllocList)); 
-   } 
-   // Gets the number of readonly and writeonly refs in RefEdgeList 
-   std::pair<unsigned, unsigned> specialRefCounts() const; 
-   
-   /// Check if this is a function summary. 
-   static bool classof(const GlobalValueSummary *GVS) { 
-     return GVS->getSummaryKind() == FunctionKind; 
-   } 
-   
-   /// Get function summary flags. 
-   FFlags fflags() const { return FunFlags; } 
-   
-   void setNoRecurse() { FunFlags.NoRecurse = true; } 
-   
-   void setNoUnwind() { FunFlags.NoUnwind = true; } 
-   
-   /// Get the instruction count recorded for this function. 
-   unsigned instCount() const { return InstCount; } 
-   
-   /// Get the synthetic entry count for this function. 
-   uint64_t entryCount() const { return EntryCount; } 
-   
-   /// Set the synthetic entry count for this function. 
-   void setEntryCount(uint64_t EC) { EntryCount = EC; } 
-   
-   /// Return the list of <CalleeValueInfo, CalleeInfo> pairs. 
-   ArrayRef<EdgeTy> calls() const { return CallGraphEdgeList; } 
-   
-   std::vector<EdgeTy> &mutableCalls() { return CallGraphEdgeList; } 
-   
-   void addCall(EdgeTy E) { CallGraphEdgeList.push_back(E); } 
-   
-   /// Returns the list of type identifiers used by this function in 
-   /// llvm.type.test intrinsics other than by an llvm.assume intrinsic, 
-   /// represented as GUIDs. 
-   ArrayRef<GlobalValue::GUID> type_tests() const { 
-     if (TIdInfo) 
-       return TIdInfo->TypeTests; 
-     return {}; 
-   } 
-   
-   /// Returns the list of virtual calls made by this function using 
-   /// llvm.assume(llvm.type.test) intrinsics that do not have all constant 
-   /// integer arguments. 
-   ArrayRef<VFuncId> type_test_assume_vcalls() const { 
-     if (TIdInfo) 
-       return TIdInfo->TypeTestAssumeVCalls; 
-     return {}; 
-   } 
-   
-   /// Returns the list of virtual calls made by this function using 
-   /// llvm.type.checked.load intrinsics that do not have all constant integer 
-   /// arguments. 
-   ArrayRef<VFuncId> type_checked_load_vcalls() const { 
-     if (TIdInfo) 
-       return TIdInfo->TypeCheckedLoadVCalls; 
-     return {}; 
-   } 
-   
-   /// Returns the list of virtual calls made by this function using 
-   /// llvm.assume(llvm.type.test) intrinsics with all constant integer 
-   /// arguments. 
-   ArrayRef<ConstVCall> type_test_assume_const_vcalls() const { 
-     if (TIdInfo) 
-       return TIdInfo->TypeTestAssumeConstVCalls; 
-     return {}; 
-   } 
-   
-   /// Returns the list of virtual calls made by this function using 
-   /// llvm.type.checked.load intrinsics with all constant integer arguments. 
-   ArrayRef<ConstVCall> type_checked_load_const_vcalls() const { 
-     if (TIdInfo) 
-       return TIdInfo->TypeCheckedLoadConstVCalls; 
-     return {}; 
-   } 
-   
-   /// Returns the list of known uses of pointer parameters. 
-   ArrayRef<ParamAccess> paramAccesses() const { 
-     if (ParamAccesses) 
-       return *ParamAccesses; 
-     return {}; 
-   } 
-   
-   /// Sets the list of known uses of pointer parameters. 
-   void setParamAccesses(std::vector<ParamAccess> NewParams) { 
-     if (NewParams.empty()) 
-       ParamAccesses.reset(); 
-     else if (ParamAccesses) 
-       *ParamAccesses = std::move(NewParams); 
-     else 
-       ParamAccesses = std::make_unique<ParamAccessesTy>(std::move(NewParams)); 
-   } 
-   
-   /// Add a type test to the summary. This is used by WholeProgramDevirt if we 
-   /// were unable to devirtualize a checked call. 
-   void addTypeTest(GlobalValue::GUID Guid) { 
-     if (!TIdInfo) 
-       TIdInfo = std::make_unique<TypeIdInfo>(); 
-     TIdInfo->TypeTests.push_back(Guid); 
-   } 
-   
-   const TypeIdInfo *getTypeIdInfo() const { return TIdInfo.get(); }; 
-   
-   ArrayRef<CallsiteInfo> callsites() const { 
-     if (Callsites) 
-       return *Callsites; 
-     return {}; 
-   } 
-   
-   ArrayRef<AllocInfo> allocs() const { 
-     if (Allocs) 
-       return *Allocs; 
-     return {}; 
-   } 
-   
-   friend struct GraphTraits<ValueInfo>; 
- }; 
-   
- template <> struct DenseMapInfo<FunctionSummary::VFuncId> { 
-   static FunctionSummary::VFuncId getEmptyKey() { return {0, uint64_t(-1)}; } 
-   
-   static FunctionSummary::VFuncId getTombstoneKey() { 
-     return {0, uint64_t(-2)}; 
-   } 
-   
-   static bool isEqual(FunctionSummary::VFuncId L, FunctionSummary::VFuncId R) { 
-     return L.GUID == R.GUID && L.Offset == R.Offset; 
-   } 
-   
-   static unsigned getHashValue(FunctionSummary::VFuncId I) { return I.GUID; } 
- }; 
-   
- template <> struct DenseMapInfo<FunctionSummary::ConstVCall> { 
-   static FunctionSummary::ConstVCall getEmptyKey() { 
-     return {{0, uint64_t(-1)}, {}}; 
-   } 
-   
-   static FunctionSummary::ConstVCall getTombstoneKey() { 
-     return {{0, uint64_t(-2)}, {}}; 
-   } 
-   
-   static bool isEqual(FunctionSummary::ConstVCall L, 
-                       FunctionSummary::ConstVCall R) { 
-     return DenseMapInfo<FunctionSummary::VFuncId>::isEqual(L.VFunc, R.VFunc) && 
-            L.Args == R.Args; 
-   } 
-   
-   static unsigned getHashValue(FunctionSummary::ConstVCall I) { 
-     return I.VFunc.GUID; 
-   } 
- }; 
-   
- /// The ValueInfo and offset for a function within a vtable definition 
- /// initializer array. 
- struct VirtFuncOffset { 
-   VirtFuncOffset(ValueInfo VI, uint64_t Offset) 
-       : FuncVI(VI), VTableOffset(Offset) {} 
-   
-   ValueInfo FuncVI; 
-   uint64_t VTableOffset; 
- }; 
- /// List of functions referenced by a particular vtable definition. 
- using VTableFuncList = std::vector<VirtFuncOffset>; 
-   
- /// Global variable summary information to aid decisions and 
- /// implementation of importing. 
- /// 
- /// Global variable summary has two extra flag, telling if it is 
- /// readonly or writeonly. Both readonly and writeonly variables 
- /// can be optimized in the backed: readonly variables can be 
- /// const-folded, while writeonly vars can be completely eliminated 
- /// together with corresponding stores. We let both things happen 
- /// by means of internalizing such variables after ThinLTO import. 
- class GlobalVarSummary : public GlobalValueSummary { 
- private: 
-   /// For vtable definitions this holds the list of functions and 
-   /// their corresponding offsets within the initializer array. 
-   std::unique_ptr<VTableFuncList> VTableFuncs; 
-   
- public: 
-   struct GVarFlags { 
-     GVarFlags(bool ReadOnly, bool WriteOnly, bool Constant, 
-               GlobalObject::VCallVisibility Vis) 
-         : MaybeReadOnly(ReadOnly), MaybeWriteOnly(WriteOnly), 
-           Constant(Constant), VCallVisibility(Vis) {} 
-   
-     // If true indicates that this global variable might be accessed 
-     // purely by non-volatile load instructions. This in turn means 
-     // it can be internalized in source and destination modules during 
-     // thin LTO import because it neither modified nor its address 
-     // is taken. 
-     unsigned MaybeReadOnly : 1; 
-     // If true indicates that variable is possibly only written to, so 
-     // its value isn't loaded and its address isn't taken anywhere. 
-     // False, when 'Constant' attribute is set. 
-     unsigned MaybeWriteOnly : 1; 
-     // Indicates that value is a compile-time constant. Global variable 
-     // can be 'Constant' while not being 'ReadOnly' on several occasions: 
-     // - it is volatile, (e.g mapped device address) 
-     // - its address is taken, meaning that unlike 'ReadOnly' vars we can't 
-     //   internalize it. 
-     // Constant variables are always imported thus giving compiler an 
-     // opportunity to make some extra optimizations. Readonly constants 
-     // are also internalized. 
-     unsigned Constant : 1; 
-     // Set from metadata on vtable definitions during the module summary 
-     // analysis. 
-     unsigned VCallVisibility : 2; 
-   } VarFlags; 
-   
-   GlobalVarSummary(GVFlags Flags, GVarFlags VarFlags, 
-                    std::vector<ValueInfo> Refs) 
-       : GlobalValueSummary(GlobalVarKind, Flags, std::move(Refs)), 
-         VarFlags(VarFlags) {} 
-   
-   /// Check if this is a global variable summary. 
-   static bool classof(const GlobalValueSummary *GVS) { 
-     return GVS->getSummaryKind() == GlobalVarKind; 
-   } 
-   
-   GVarFlags varflags() const { return VarFlags; } 
-   void setReadOnly(bool RO) { VarFlags.MaybeReadOnly = RO; } 
-   void setWriteOnly(bool WO) { VarFlags.MaybeWriteOnly = WO; } 
-   bool maybeReadOnly() const { return VarFlags.MaybeReadOnly; } 
-   bool maybeWriteOnly() const { return VarFlags.MaybeWriteOnly; } 
-   bool isConstant() const { return VarFlags.Constant; } 
-   void setVCallVisibility(GlobalObject::VCallVisibility Vis) { 
-     VarFlags.VCallVisibility = Vis; 
-   } 
-   GlobalObject::VCallVisibility getVCallVisibility() const { 
-     return (GlobalObject::VCallVisibility)VarFlags.VCallVisibility; 
-   } 
-   
-   void setVTableFuncs(VTableFuncList Funcs) { 
-     assert(!VTableFuncs); 
-     VTableFuncs = std::make_unique<VTableFuncList>(std::move(Funcs)); 
-   } 
-   
-   ArrayRef<VirtFuncOffset> vTableFuncs() const { 
-     if (VTableFuncs) 
-       return *VTableFuncs; 
-     return {}; 
-   } 
- }; 
-   
- struct TypeTestResolution { 
-   /// Specifies which kind of type check we should emit for this byte array. 
-   /// See http://clang.llvm.org/docs/ControlFlowIntegrityDesign.html for full 
-   /// details on each kind of check; the enumerators are described with 
-   /// reference to that document. 
-   enum Kind { 
-     Unsat,     ///< Unsatisfiable type (i.e. no global has this type metadata) 
-     ByteArray, ///< Test a byte array (first example) 
-     Inline,    ///< Inlined bit vector ("Short Inline Bit Vectors") 
-     Single,    ///< Single element (last example in "Short Inline Bit Vectors") 
-     AllOnes,   ///< All-ones bit vector ("Eliminating Bit Vector Checks for 
-                ///  All-Ones Bit Vectors") 
-     Unknown,   ///< Unknown (analysis not performed, don't lower) 
-   } TheKind = Unknown; 
-   
-   /// Range of size-1 expressed as a bit width. For example, if the size is in 
-   /// range [1,256], this number will be 8. This helps generate the most compact 
-   /// instruction sequences. 
-   unsigned SizeM1BitWidth = 0; 
-   
-   // The following fields are only used if the target does not support the use 
-   // of absolute symbols to store constants. Their meanings are the same as the 
-   // corresponding fields in LowerTypeTestsModule::TypeIdLowering in 
-   // LowerTypeTests.cpp. 
-   
-   uint64_t AlignLog2 = 0; 
-   uint64_t SizeM1 = 0; 
-   uint8_t BitMask = 0; 
-   uint64_t InlineBits = 0; 
- }; 
-   
- struct WholeProgramDevirtResolution { 
-   enum Kind { 
-     Indir,        ///< Just do a regular virtual call 
-     SingleImpl,   ///< Single implementation devirtualization 
-     BranchFunnel, ///< When retpoline mitigation is enabled, use a branch funnel 
-                   ///< that is defined in the merged module. Otherwise same as 
-                   ///< Indir. 
-   } TheKind = Indir; 
-   
-   std::string SingleImplName; 
-   
-   struct ByArg { 
-     enum Kind { 
-       Indir,            ///< Just do a regular virtual call 
-       UniformRetVal,    ///< Uniform return value optimization 
-       UniqueRetVal,     ///< Unique return value optimization 
-       VirtualConstProp, ///< Virtual constant propagation 
-     } TheKind = Indir; 
-   
-     /// Additional information for the resolution: 
-     /// - UniformRetVal: the uniform return value. 
-     /// - UniqueRetVal: the return value associated with the unique vtable (0 or 
-     ///   1). 
-     uint64_t Info = 0; 
-   
-     // The following fields are only used if the target does not support the use 
-     // of absolute symbols to store constants. 
-   
-     uint32_t Byte = 0; 
-     uint32_t Bit = 0; 
-   }; 
-   
-   /// Resolutions for calls with all constant integer arguments (excluding the 
-   /// first argument, "this"), where the key is the argument vector. 
-   std::map<std::vector<uint64_t>, ByArg> ResByArg; 
- }; 
-   
- struct TypeIdSummary { 
-   TypeTestResolution TTRes; 
-   
-   /// Mapping from byte offset to whole-program devirt resolution for that 
-   /// (typeid, byte offset) pair. 
-   std::map<uint64_t, WholeProgramDevirtResolution> WPDRes; 
- }; 
-   
- /// 160 bits SHA1 
- using ModuleHash = std::array<uint32_t, 5>; 
-   
- /// Type used for iterating through the global value summary map. 
- using const_gvsummary_iterator = GlobalValueSummaryMapTy::const_iterator; 
- using gvsummary_iterator = GlobalValueSummaryMapTy::iterator; 
-   
- /// String table to hold/own module path strings, which additionally holds the 
- /// module ID assigned to each module during the plugin step, as well as a hash 
- /// of the module. The StringMap makes a copy of and owns inserted strings. 
- using ModulePathStringTableTy = StringMap<std::pair<uint64_t, ModuleHash>>; 
-   
- /// Map of global value GUID to its summary, used to identify values defined in 
- /// a particular module, and provide efficient access to their summary. 
- using GVSummaryMapTy = DenseMap<GlobalValue::GUID, GlobalValueSummary *>; 
-   
- /// Map of a type GUID to type id string and summary (multimap used 
- /// in case of GUID conflicts). 
- using TypeIdSummaryMapTy = 
-     std::multimap<GlobalValue::GUID, std::pair<std::string, TypeIdSummary>>; 
-   
- /// The following data structures summarize type metadata information. 
- /// For type metadata overview see https://llvm.org/docs/TypeMetadata.html. 
- /// Each type metadata includes both the type identifier and the offset of 
- /// the address point of the type (the address held by objects of that type 
- /// which may not be the beginning of the virtual table). Vtable definitions 
- /// are decorated with type metadata for the types they are compatible with. 
- /// 
- /// Holds information about vtable definitions decorated with type metadata: 
- /// the vtable definition value and its address point offset in a type 
- /// identifier metadata it is decorated (compatible) with. 
- struct TypeIdOffsetVtableInfo { 
-   TypeIdOffsetVtableInfo(uint64_t Offset, ValueInfo VI) 
-       : AddressPointOffset(Offset), VTableVI(VI) {} 
-   
-   uint64_t AddressPointOffset; 
-   ValueInfo VTableVI; 
- }; 
- /// List of vtable definitions decorated by a particular type identifier, 
- /// and their corresponding offsets in that type identifier's metadata. 
- /// Note that each type identifier may be compatible with multiple vtables, due 
- /// to inheritance, which is why this is a vector. 
- using TypeIdCompatibleVtableInfo = std::vector<TypeIdOffsetVtableInfo>; 
-   
- /// Class to hold module path string table and global value map, 
- /// and encapsulate methods for operating on them. 
- class ModuleSummaryIndex { 
- private: 
-   /// Map from value name to list of summary instances for values of that 
-   /// name (may be duplicates in the COMDAT case, e.g.). 
-   GlobalValueSummaryMapTy GlobalValueMap; 
-   
-   /// Holds strings for combined index, mapping to the corresponding module ID. 
-   ModulePathStringTableTy ModulePathStringTable; 
-   
-   /// Mapping from type identifier GUIDs to type identifier and its summary 
-   /// information. Produced by thin link. 
-   TypeIdSummaryMapTy TypeIdMap; 
-   
-   /// Mapping from type identifier to information about vtables decorated 
-   /// with that type identifier's metadata. Produced by per module summary 
-   /// analysis and consumed by thin link. For more information, see description 
-   /// above where TypeIdCompatibleVtableInfo is defined. 
-   std::map<std::string, TypeIdCompatibleVtableInfo, std::less<>> 
-       TypeIdCompatibleVtableMap; 
-   
-   /// Mapping from original ID to GUID. If original ID can map to multiple 
-   /// GUIDs, it will be mapped to 0. 
-   std::map<GlobalValue::GUID, GlobalValue::GUID> OidGuidMap; 
-   
-   /// Indicates that summary-based GlobalValue GC has run, and values with 
-   /// GVFlags::Live==false are really dead. Otherwise, all values must be 
-   /// considered live. 
-   bool WithGlobalValueDeadStripping = false; 
-   
-   /// Indicates that summary-based attribute propagation has run and 
-   /// GVarFlags::MaybeReadonly / GVarFlags::MaybeWriteonly are really 
-   /// read/write only. 
-   bool WithAttributePropagation = false; 
-   
-   /// Indicates that summary-based DSOLocal propagation has run and the flag in 
-   /// every summary of a GV is synchronized. 
-   bool WithDSOLocalPropagation = false; 
-   
-   /// Indicates that we have whole program visibility. 
-   bool WithWholeProgramVisibility = false; 
-   
-   /// Indicates that summary-based synthetic entry count propagation has run 
-   bool HasSyntheticEntryCounts = false; 
-   
-   /// Indicates that distributed backend should skip compilation of the 
-   /// module. Flag is suppose to be set by distributed ThinLTO indexing 
-   /// when it detected that the module is not needed during the final 
-   /// linking. As result distributed backend should just output a minimal 
-   /// valid object file. 
-   bool SkipModuleByDistributedBackend = false; 
-   
-   /// If true then we're performing analysis of IR module, or parsing along with 
-   /// the IR from assembly. The value of 'false' means we're reading summary 
-   /// from BC or YAML source. Affects the type of value stored in NameOrGV 
-   /// union. 
-   bool HaveGVs; 
-   
-   // True if the index was created for a module compiled with -fsplit-lto-unit. 
-   bool EnableSplitLTOUnit; 
-   
-   // True if some of the modules were compiled with -fsplit-lto-unit and 
-   // some were not. Set when the combined index is created during the thin link. 
-   bool PartiallySplitLTOUnits = false; 
-   
-   /// True if some of the FunctionSummary contains a ParamAccess. 
-   bool HasParamAccess = false; 
-   
-   std::set<std::string> CfiFunctionDefs; 
-   std::set<std::string> CfiFunctionDecls; 
-   
-   // Used in cases where we want to record the name of a global, but 
-   // don't have the string owned elsewhere (e.g. the Strtab on a module). 
-   BumpPtrAllocator Alloc; 
-   StringSaver Saver; 
-   
-   // The total number of basic blocks in the module in the per-module summary or 
-   // the total number of basic blocks in the LTO unit in the combined index. 
-   uint64_t BlockCount; 
-   
-   // List of unique stack ids (hashes). We use a 4B index of the id in the 
-   // stack id lists on the alloc and callsite summaries for memory savings, 
-   // since the number of unique ids is in practice much smaller than the 
-   // number of stack id references in the summaries. 
-   std::vector<uint64_t> StackIds; 
-   
-   // Temporary map while building StackIds list. Clear when index is completely 
-   // built via releaseTemporaryMemory. 
-   std::map<uint64_t, unsigned> StackIdToIndex; 
-   
-   // YAML I/O support. 
-   friend yaml::MappingTraits<ModuleSummaryIndex>; 
-   
-   GlobalValueSummaryMapTy::value_type * 
-   getOrInsertValuePtr(GlobalValue::GUID GUID) { 
-     return &*GlobalValueMap.emplace(GUID, GlobalValueSummaryInfo(HaveGVs)) 
-                  .first; 
-   } 
-   
- public: 
-   // See HaveGVs variable comment. 
-   ModuleSummaryIndex(bool HaveGVs, bool EnableSplitLTOUnit = false) 
-       : HaveGVs(HaveGVs), EnableSplitLTOUnit(EnableSplitLTOUnit), Saver(Alloc), 
-         BlockCount(0) {} 
-   
-   // Current version for the module summary in bitcode files. 
-   // The BitcodeSummaryVersion should be bumped whenever we introduce changes 
-   // in the way some record are interpreted, like flags for instance. 
-   // Note that incrementing this may require changes in both BitcodeReader.cpp 
-   // and BitcodeWriter.cpp. 
-   static constexpr uint64_t BitcodeSummaryVersion = 9; 
-   
-   // Regular LTO module name for ASM writer 
-   static constexpr const char *getRegularLTOModuleName() { 
-     return "[Regular LTO]"; 
-   } 
-   
-   bool haveGVs() const { return HaveGVs; } 
-   
-   uint64_t getFlags() const; 
-   void setFlags(uint64_t Flags); 
-   
-   uint64_t getBlockCount() const { return BlockCount; } 
-   void addBlockCount(uint64_t C) { BlockCount += C; } 
-   void setBlockCount(uint64_t C) { BlockCount = C; } 
-   
-   gvsummary_iterator begin() { return GlobalValueMap.begin(); } 
-   const_gvsummary_iterator begin() const { return GlobalValueMap.begin(); } 
-   gvsummary_iterator end() { return GlobalValueMap.end(); } 
-   const_gvsummary_iterator end() const { return GlobalValueMap.end(); } 
-   size_t size() const { return GlobalValueMap.size(); } 
-   
-   const std::vector<uint64_t> &stackIds() const { return StackIds; } 
-   
-   unsigned addOrGetStackIdIndex(uint64_t StackId) { 
-     auto Inserted = StackIdToIndex.insert({StackId, StackIds.size()}); 
-     if (Inserted.second) 
-       StackIds.push_back(StackId); 
-     return Inserted.first->second; 
-   } 
-   
-   uint64_t getStackIdAtIndex(unsigned Index) const { 
-     assert(StackIds.size() > Index); 
-     return StackIds[Index]; 
-   } 
-   
-   // Facility to release memory from data structures only needed during index 
-   // construction (including while building combined index). Currently this only 
-   // releases the temporary map used while constructing a correspondence between 
-   // stack ids and their index in the StackIds vector. Mostly impactful when 
-   // building a large combined index. 
-   void releaseTemporaryMemory() { 
-     assert(StackIdToIndex.size() == StackIds.size()); 
-     StackIdToIndex.clear(); 
-     StackIds.shrink_to_fit(); 
-   } 
-   
-   /// Convenience function for doing a DFS on a ValueInfo. Marks the function in 
-   /// the FunctionHasParent map. 
-   static void discoverNodes(ValueInfo V, 
-                             std::map<ValueInfo, bool> &FunctionHasParent) { 
-     if (!V.getSummaryList().size()) 
-       return; // skip external functions that don't have summaries 
-   
-     // Mark discovered if we haven't yet 
-     auto S = FunctionHasParent.emplace(V, false); 
-   
-     // Stop if we've already discovered this node 
-     if (!S.second) 
-       return; 
-   
-     FunctionSummary *F = 
-         dyn_cast<FunctionSummary>(V.getSummaryList().front().get()); 
-     assert(F != nullptr && "Expected FunctionSummary node"); 
-   
-     for (const auto &C : F->calls()) { 
-       // Insert node if necessary 
-       auto S = FunctionHasParent.emplace(C.first, true); 
-   
-       // Skip nodes that we're sure have parents 
-       if (!S.second && S.first->second) 
-         continue; 
-   
-       if (S.second) 
-         discoverNodes(C.first, FunctionHasParent); 
-       else 
-         S.first->second = true; 
-     } 
-   } 
-   
-   // Calculate the callgraph root 
-   FunctionSummary calculateCallGraphRoot() { 
-     // Functions that have a parent will be marked in FunctionHasParent pair. 
-     // Once we've marked all functions, the functions in the map that are false 
-     // have no parent (so they're the roots) 
-     std::map<ValueInfo, bool> FunctionHasParent; 
-   
-     for (auto &S : *this) { 
-       // Skip external functions 
-       if (!S.second.SummaryList.size() || 
-           !isa<FunctionSummary>(S.second.SummaryList.front().get())) 
-         continue; 
-       discoverNodes(ValueInfo(HaveGVs, &S), FunctionHasParent); 
-     } 
-   
-     std::vector<FunctionSummary::EdgeTy> Edges; 
-     // create edges to all roots in the Index 
-     for (auto &P : FunctionHasParent) { 
-       if (P.second) 
-         continue; // skip over non-root nodes 
-       Edges.push_back(std::make_pair(P.first, CalleeInfo{})); 
-     } 
-     if (Edges.empty()) { 
-       // Failed to find root - return an empty node 
-       return FunctionSummary::makeDummyFunctionSummary({}); 
-     } 
-     auto CallGraphRoot = FunctionSummary::makeDummyFunctionSummary(Edges); 
-     return CallGraphRoot; 
-   } 
-   
-   bool withGlobalValueDeadStripping() const { 
-     return WithGlobalValueDeadStripping; 
-   } 
-   void setWithGlobalValueDeadStripping() { 
-     WithGlobalValueDeadStripping = true; 
-   } 
-   
-   bool withAttributePropagation() const { return WithAttributePropagation; } 
-   void setWithAttributePropagation() { 
-     WithAttributePropagation = true; 
-   } 
-   
-   bool withDSOLocalPropagation() const { return WithDSOLocalPropagation; } 
-   void setWithDSOLocalPropagation() { WithDSOLocalPropagation = true; } 
-   
-   bool withWholeProgramVisibility() const { return WithWholeProgramVisibility; } 
-   void setWithWholeProgramVisibility() { WithWholeProgramVisibility = true; } 
-   
-   bool isReadOnly(const GlobalVarSummary *GVS) const { 
-     return WithAttributePropagation && GVS->maybeReadOnly(); 
-   } 
-   bool isWriteOnly(const GlobalVarSummary *GVS) const { 
-     return WithAttributePropagation && GVS->maybeWriteOnly(); 
-   } 
-   
-   bool hasSyntheticEntryCounts() const { return HasSyntheticEntryCounts; } 
-   void setHasSyntheticEntryCounts() { HasSyntheticEntryCounts = true; } 
-   
-   bool skipModuleByDistributedBackend() const { 
-     return SkipModuleByDistributedBackend; 
-   } 
-   void setSkipModuleByDistributedBackend() { 
-     SkipModuleByDistributedBackend = true; 
-   } 
-   
-   bool enableSplitLTOUnit() const { return EnableSplitLTOUnit; } 
-   void setEnableSplitLTOUnit() { EnableSplitLTOUnit = true; } 
-   
-   bool partiallySplitLTOUnits() const { return PartiallySplitLTOUnits; } 
-   void setPartiallySplitLTOUnits() { PartiallySplitLTOUnits = true; } 
-   
-   bool hasParamAccess() const { return HasParamAccess; } 
-   
-   bool isGlobalValueLive(const GlobalValueSummary *GVS) const { 
-     return !WithGlobalValueDeadStripping || GVS->isLive(); 
-   } 
-   bool isGUIDLive(GlobalValue::GUID GUID) const; 
-   
-   /// Return a ValueInfo for the index value_type (convenient when iterating 
-   /// index). 
-   ValueInfo getValueInfo(const GlobalValueSummaryMapTy::value_type &R) const { 
-     return ValueInfo(HaveGVs, &R); 
-   } 
-   
-   /// Return a ValueInfo for GUID if it exists, otherwise return ValueInfo(). 
-   ValueInfo getValueInfo(GlobalValue::GUID GUID) const { 
-     auto I = GlobalValueMap.find(GUID); 
-     return ValueInfo(HaveGVs, I == GlobalValueMap.end() ? nullptr : &*I); 
-   } 
-   
-   /// Return a ValueInfo for \p GUID. 
-   ValueInfo getOrInsertValueInfo(GlobalValue::GUID GUID) { 
-     return ValueInfo(HaveGVs, getOrInsertValuePtr(GUID)); 
-   } 
-   
-   // Save a string in the Index. Use before passing Name to 
-   // getOrInsertValueInfo when the string isn't owned elsewhere (e.g. on the 
-   // module's Strtab). 
-   StringRef saveString(StringRef String) { return Saver.save(String); } 
-   
-   /// Return a ValueInfo for \p GUID setting value \p Name. 
-   ValueInfo getOrInsertValueInfo(GlobalValue::GUID GUID, StringRef Name) { 
-     assert(!HaveGVs); 
-     auto VP = getOrInsertValuePtr(GUID); 
-     VP->second.U.Name = Name; 
-     return ValueInfo(HaveGVs, VP); 
-   } 
-   
-   /// Return a ValueInfo for \p GV and mark it as belonging to GV. 
-   ValueInfo getOrInsertValueInfo(const GlobalValue *GV) { 
-     assert(HaveGVs); 
-     auto VP = getOrInsertValuePtr(GV->getGUID()); 
-     VP->second.U.GV = GV; 
-     return ValueInfo(HaveGVs, VP); 
-   } 
-   
-   /// Return the GUID for \p OriginalId in the OidGuidMap. 
-   GlobalValue::GUID getGUIDFromOriginalID(GlobalValue::GUID OriginalID) const { 
-     const auto I = OidGuidMap.find(OriginalID); 
-     return I == OidGuidMap.end() ? 0 : I->second; 
-   } 
-   
-   std::set<std::string> &cfiFunctionDefs() { return CfiFunctionDefs; } 
-   const std::set<std::string> &cfiFunctionDefs() const { return CfiFunctionDefs; } 
-   
-   std::set<std::string> &cfiFunctionDecls() { return CfiFunctionDecls; } 
-   const std::set<std::string> &cfiFunctionDecls() const { return CfiFunctionDecls; } 
-   
-   /// Add a global value summary for a value. 
-   void addGlobalValueSummary(const GlobalValue &GV, 
-                              std::unique_ptr<GlobalValueSummary> Summary) { 
-     addGlobalValueSummary(getOrInsertValueInfo(&GV), std::move(Summary)); 
-   } 
-   
-   /// Add a global value summary for a value of the given name. 
-   void addGlobalValueSummary(StringRef ValueName, 
-                              std::unique_ptr<GlobalValueSummary> Summary) { 
-     addGlobalValueSummary(getOrInsertValueInfo(GlobalValue::getGUID(ValueName)), 
-                           std::move(Summary)); 
-   } 
-   
-   /// Add a global value summary for the given ValueInfo. 
-   void addGlobalValueSummary(ValueInfo VI, 
-                              std::unique_ptr<GlobalValueSummary> Summary) { 
-     if (const FunctionSummary *FS = dyn_cast<FunctionSummary>(Summary.get())) 
-       HasParamAccess |= !FS->paramAccesses().empty(); 
-     addOriginalName(VI.getGUID(), Summary->getOriginalName()); 
-     // Here we have a notionally const VI, but the value it points to is owned 
-     // by the non-const *this. 
-     const_cast<GlobalValueSummaryMapTy::value_type *>(VI.getRef()) 
-         ->second.SummaryList.push_back(std::move(Summary)); 
-   } 
-   
-   /// Add an original name for the value of the given GUID. 
-   void addOriginalName(GlobalValue::GUID ValueGUID, 
-                        GlobalValue::GUID OrigGUID) { 
-     if (OrigGUID == 0 || ValueGUID == OrigGUID) 
-       return; 
-     if (OidGuidMap.count(OrigGUID) && OidGuidMap[OrigGUID] != ValueGUID) 
-       OidGuidMap[OrigGUID] = 0; 
-     else 
-       OidGuidMap[OrigGUID] = ValueGUID; 
-   } 
-   
-   /// Find the summary for ValueInfo \p VI in module \p ModuleId, or nullptr if 
-   /// not found. 
-   GlobalValueSummary *findSummaryInModule(ValueInfo VI, StringRef ModuleId) const { 
-     auto SummaryList = VI.getSummaryList(); 
-     auto Summary = 
-         llvm::find_if(SummaryList, 
-                       [&](const std::unique_ptr<GlobalValueSummary> &Summary) { 
-                         return Summary->modulePath() == ModuleId; 
-                       }); 
-     if (Summary == SummaryList.end()) 
-       return nullptr; 
-     return Summary->get(); 
-   } 
-   
-   /// Find the summary for global \p GUID in module \p ModuleId, or nullptr if 
-   /// not found. 
-   GlobalValueSummary *findSummaryInModule(GlobalValue::GUID ValueGUID, 
-                                           StringRef ModuleId) const { 
-     auto CalleeInfo = getValueInfo(ValueGUID); 
-     if (!CalleeInfo) 
-       return nullptr; // This function does not have a summary 
-     return findSummaryInModule(CalleeInfo, ModuleId); 
-   } 
-   
-   /// Returns the first GlobalValueSummary for \p GV, asserting that there 
-   /// is only one if \p PerModuleIndex. 
-   GlobalValueSummary *getGlobalValueSummary(const GlobalValue &GV, 
-                                             bool PerModuleIndex = true) const { 
-     assert(GV.hasName() && "Can't get GlobalValueSummary for GV with no name"); 
-     return getGlobalValueSummary(GV.getGUID(), PerModuleIndex); 
-   } 
-   
-   /// Returns the first GlobalValueSummary for \p ValueGUID, asserting that 
-   /// there 
-   /// is only one if \p PerModuleIndex. 
-   GlobalValueSummary *getGlobalValueSummary(GlobalValue::GUID ValueGUID, 
-                                             bool PerModuleIndex = true) const; 
-   
-   /// Table of modules, containing module hash and id. 
-   const StringMap<std::pair<uint64_t, ModuleHash>> &modulePaths() const { 
-     return ModulePathStringTable; 
-   } 
-   
-   /// Table of modules, containing hash and id. 
-   StringMap<std::pair<uint64_t, ModuleHash>> &modulePaths() { 
-     return ModulePathStringTable; 
-   } 
-   
-   /// Get the module ID recorded for the given module path. 
-   uint64_t getModuleId(const StringRef ModPath) const { 
-     return ModulePathStringTable.lookup(ModPath).first; 
-   } 
-   
-   /// Get the module SHA1 hash recorded for the given module path. 
-   const ModuleHash &getModuleHash(const StringRef ModPath) const { 
-     auto It = ModulePathStringTable.find(ModPath); 
-     assert(It != ModulePathStringTable.end() && "Module not registered"); 
-     return It->second.second; 
-   } 
-   
-   /// Convenience method for creating a promoted global name 
-   /// for the given value name of a local, and its original module's ID. 
-   static std::string getGlobalNameForLocal(StringRef Name, ModuleHash ModHash) { 
-     std::string Suffix = utostr((uint64_t(ModHash[0]) << 32) | 
-                                 ModHash[1]); // Take the first 64 bits 
-     return getGlobalNameForLocal(Name, Suffix); 
-   } 
-   
-   static std::string getGlobalNameForLocal(StringRef Name, StringRef Suffix) { 
-     SmallString<256> NewName(Name); 
-     NewName += ".llvm."; 
-     NewName += Suffix; 
-     return std::string(NewName.str()); 
-   } 
-   
-   /// Helper to obtain the unpromoted name for a global value (or the original 
-   /// name if not promoted). Split off the rightmost ".llvm.${hash}" suffix, 
-   /// because it is possible in certain clients (not clang at the moment) for 
-   /// two rounds of ThinLTO optimization and therefore promotion to occur. 
-   static StringRef getOriginalNameBeforePromote(StringRef Name) { 
-     std::pair<StringRef, StringRef> Pair = Name.rsplit(".llvm."); 
-     return Pair.first; 
-   } 
-   
-   typedef ModulePathStringTableTy::value_type ModuleInfo; 
-   
-   /// Add a new module with the given \p Hash, mapped to the given \p 
-   /// ModID, and return a reference to the module. 
-   ModuleInfo *addModule(StringRef ModPath, uint64_t ModId, 
-                         ModuleHash Hash = ModuleHash{{0}}) { 
-     return &*ModulePathStringTable.insert({ModPath, {ModId, Hash}}).first; 
-   } 
-   
-   /// Return module entry for module with the given \p ModPath. 
-   ModuleInfo *getModule(StringRef ModPath) { 
-     auto It = ModulePathStringTable.find(ModPath); 
-     assert(It != ModulePathStringTable.end() && "Module not registered"); 
-     return &*It; 
-   } 
-   
-   /// Check if the given Module has any functions available for exporting 
-   /// in the index. We consider any module present in the ModulePathStringTable 
-   /// to have exported functions. 
-   bool hasExportedFunctions(const Module &M) const { 
-     return ModulePathStringTable.count(M.getModuleIdentifier()); 
-   } 
-   
-   const TypeIdSummaryMapTy &typeIds() const { return TypeIdMap; } 
-   
-   /// Return an existing or new TypeIdSummary entry for \p TypeId. 
-   /// This accessor can mutate the map and therefore should not be used in 
-   /// the ThinLTO backends. 
-   TypeIdSummary &getOrInsertTypeIdSummary(StringRef TypeId) { 
-     auto TidIter = TypeIdMap.equal_range(GlobalValue::getGUID(TypeId)); 
-     for (auto It = TidIter.first; It != TidIter.second; ++It) 
-       if (It->second.first == TypeId) 
-         return It->second.second; 
-     auto It = TypeIdMap.insert( 
-         {GlobalValue::getGUID(TypeId), {std::string(TypeId), TypeIdSummary()}}); 
-     return It->second.second; 
-   } 
-   
-   /// This returns either a pointer to the type id summary (if present in the 
-   /// summary map) or null (if not present). This may be used when importing. 
-   const TypeIdSummary *getTypeIdSummary(StringRef TypeId) const { 
-     auto TidIter = TypeIdMap.equal_range(GlobalValue::getGUID(TypeId)); 
-     for (auto It = TidIter.first; It != TidIter.second; ++It) 
-       if (It->second.first == TypeId) 
-         return &It->second.second; 
-     return nullptr; 
-   } 
-   
-   TypeIdSummary *getTypeIdSummary(StringRef TypeId) { 
-     return const_cast<TypeIdSummary *>( 
-         static_cast<const ModuleSummaryIndex *>(this)->getTypeIdSummary( 
-             TypeId)); 
-   } 
-   
-   const auto &typeIdCompatibleVtableMap() const { 
-     return TypeIdCompatibleVtableMap; 
-   } 
-   
-   /// Return an existing or new TypeIdCompatibleVtableMap entry for \p TypeId. 
-   /// This accessor can mutate the map and therefore should not be used in 
-   /// the ThinLTO backends. 
-   TypeIdCompatibleVtableInfo & 
-   getOrInsertTypeIdCompatibleVtableSummary(StringRef TypeId) { 
-     return TypeIdCompatibleVtableMap[std::string(TypeId)]; 
-   } 
-   
-   /// For the given \p TypeId, this returns the TypeIdCompatibleVtableMap 
-   /// entry if present in the summary map. This may be used when importing. 
-   std::optional<TypeIdCompatibleVtableInfo> 
-   getTypeIdCompatibleVtableSummary(StringRef TypeId) const { 
-     auto I = TypeIdCompatibleVtableMap.find(TypeId); 
-     if (I == TypeIdCompatibleVtableMap.end()) 
-       return std::nullopt; 
-     return I->second; 
-   } 
-   
-   /// Collect for the given module the list of functions it defines 
-   /// (GUID -> Summary). 
-   void collectDefinedFunctionsForModule(StringRef ModulePath, 
-                                         GVSummaryMapTy &GVSummaryMap) const; 
-   
-   /// Collect for each module the list of Summaries it defines (GUID -> 
-   /// Summary). 
-   template <class Map> 
-   void 
-   collectDefinedGVSummariesPerModule(Map &ModuleToDefinedGVSummaries) const { 
-     for (const auto &GlobalList : *this) { 
-       auto GUID = GlobalList.first; 
-       for (const auto &Summary : GlobalList.second.SummaryList) { 
-         ModuleToDefinedGVSummaries[Summary->modulePath()][GUID] = Summary.get(); 
-       } 
-     } 
-   } 
-   
-   /// Print to an output stream. 
-   void print(raw_ostream &OS, bool IsForDebug = false) const; 
-   
-   /// Dump to stderr (for debugging). 
-   void dump() const; 
-   
-   /// Export summary to dot file for GraphViz. 
-   void 
-   exportToDot(raw_ostream &OS, 
-               const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols) const; 
-   
-   /// Print out strongly connected components for debugging. 
-   void dumpSCCs(raw_ostream &OS); 
-   
-   /// Do the access attribute and DSOLocal propagation in combined index. 
-   void propagateAttributes(const DenseSet<GlobalValue::GUID> &PreservedSymbols); 
-   
-   /// Checks if we can import global variable from another module. 
-   bool canImportGlobalVar(GlobalValueSummary *S, bool AnalyzeRefs) const; 
- }; 
-   
- /// GraphTraits definition to build SCC for the index 
- template <> struct GraphTraits<ValueInfo> { 
-   typedef ValueInfo NodeRef; 
-   using EdgeRef = FunctionSummary::EdgeTy &; 
-   
-   static NodeRef valueInfoFromEdge(FunctionSummary::EdgeTy &P) { 
-     return P.first; 
-   } 
-   using ChildIteratorType = 
-       mapped_iterator<std::vector<FunctionSummary::EdgeTy>::iterator, 
-                       decltype(&valueInfoFromEdge)>; 
-   
-   using ChildEdgeIteratorType = std::vector<FunctionSummary::EdgeTy>::iterator; 
-   
-   static NodeRef getEntryNode(ValueInfo V) { return V; } 
-   
-   static ChildIteratorType child_begin(NodeRef N) { 
-     if (!N.getSummaryList().size()) // handle external function 
-       return ChildIteratorType( 
-           FunctionSummary::ExternalNode.CallGraphEdgeList.begin(), 
-           &valueInfoFromEdge); 
-     FunctionSummary *F = 
-         cast<FunctionSummary>(N.getSummaryList().front()->getBaseObject()); 
-     return ChildIteratorType(F->CallGraphEdgeList.begin(), &valueInfoFromEdge); 
-   } 
-   
-   static ChildIteratorType child_end(NodeRef N) { 
-     if (!N.getSummaryList().size()) // handle external function 
-       return ChildIteratorType( 
-           FunctionSummary::ExternalNode.CallGraphEdgeList.end(), 
-           &valueInfoFromEdge); 
-     FunctionSummary *F = 
-         cast<FunctionSummary>(N.getSummaryList().front()->getBaseObject()); 
-     return ChildIteratorType(F->CallGraphEdgeList.end(), &valueInfoFromEdge); 
-   } 
-   
-   static ChildEdgeIteratorType child_edge_begin(NodeRef N) { 
-     if (!N.getSummaryList().size()) // handle external function 
-       return FunctionSummary::ExternalNode.CallGraphEdgeList.begin(); 
-   
-     FunctionSummary *F = 
-         cast<FunctionSummary>(N.getSummaryList().front()->getBaseObject()); 
-     return F->CallGraphEdgeList.begin(); 
-   } 
-   
-   static ChildEdgeIteratorType child_edge_end(NodeRef N) { 
-     if (!N.getSummaryList().size()) // handle external function 
-       return FunctionSummary::ExternalNode.CallGraphEdgeList.end(); 
-   
-     FunctionSummary *F = 
-         cast<FunctionSummary>(N.getSummaryList().front()->getBaseObject()); 
-     return F->CallGraphEdgeList.end(); 
-   } 
-   
-   static NodeRef edge_dest(EdgeRef E) { return E.first; } 
- }; 
-   
- template <> 
- struct GraphTraits<ModuleSummaryIndex *> : public GraphTraits<ValueInfo> { 
-   static NodeRef getEntryNode(ModuleSummaryIndex *I) { 
-     std::unique_ptr<GlobalValueSummary> Root = 
-         std::make_unique<FunctionSummary>(I->calculateCallGraphRoot()); 
-     GlobalValueSummaryInfo G(I->haveGVs()); 
-     G.SummaryList.push_back(std::move(Root)); 
-     static auto P = 
-         GlobalValueSummaryMapTy::value_type(GlobalValue::GUID(0), std::move(G)); 
-     return ValueInfo(I->haveGVs(), &P); 
-   } 
- }; 
- } // end namespace llvm 
-   
- #endif // LLVM_IR_MODULESUMMARYINDEX_H 
-