<div dir="ltr">This has been reverted by r302140<br><br><div class="gmail_quote"><div dir="ltr">On Thu, May 4, 2017 at 1:45 PM Eric Liu <<a href="mailto:ioeric@google.com">ioeric@google.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi Peter, <div><br></div><div>This revision causes crash in clang bootstrap in our internal integration. I'll revert this for now and send you the repro instructions separately. Sorry about that.</div></div><div dir="ltr"><div><br></div><div>- Eric</div></div><div dir="ltr"><br><div class="gmail_quote"><div dir="ltr">On Thu, May 4, 2017 at 5:49 AM Peter Collingbourne via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: pcc<br>
Date: Wed May  3 22:36:16 2017<br>
New Revision: 302108<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=302108&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=302108&view=rev</a><br>
Log:<br>
IR: Use pointers instead of GUIDs to represent edges in the module summary. NFCI.<br>
<br>
When profiling a no-op incremental link of Chromium I found that the functions<br>
computeImportForFunction and computeDeadSymbols were consuming roughly 10% of<br>
the profile. The goal of this change is to improve the performance of those<br>
functions by changing the map lookups that they were previously doing into<br>
pointer dereferences.<br>
<br>
This is achieved by changing the ValueInfo data structure to be a pointer to<br>
an element of the global value map owned by ModuleSummaryIndex, and changing<br>
reference lists in the GlobalValueSummary to hold ValueInfos instead of GUIDs.<br>
This means that a ValueInfo will take a client directly to the summary list<br>
for a given GUID.<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D32471" rel="noreferrer" target="_blank">https://reviews.llvm.org/D32471</a><br>
<br>
Modified:<br>
    llvm/trunk/include/llvm/IR/ModuleSummaryIndex.h<br>
    llvm/trunk/include/llvm/IR/ModuleSummaryIndexYAML.h<br>
    llvm/trunk/lib/Analysis/ModuleSummaryAnalysis.cpp<br>
    llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp<br>
    llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp<br>
    llvm/trunk/lib/IR/ModuleSummaryIndex.cpp<br>
    llvm/trunk/lib/LTO/LTO.cpp<br>
    llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp<br>
    llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp<br>
    llvm/trunk/lib/Transforms/IPO/LowerTypeTests.cpp<br>
    llvm/trunk/lib/Transforms/IPO/WholeProgramDevirt.cpp<br>
    llvm/trunk/tools/llvm-link/llvm-link.cpp<br>
    llvm/trunk/tools/llvm-lto/llvm-lto.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/IR/ModuleSummaryIndex.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/ModuleSummaryIndex.h?rev=302108&r1=302107&r2=302108&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/ModuleSummaryIndex.h?rev=302108&r1=302107&r2=302108&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/IR/ModuleSummaryIndex.h (original)<br>
+++ llvm/trunk/include/llvm/IR/ModuleSummaryIndex.h Wed May  3 22:36:16 2017<br>
@@ -45,58 +45,54 @@ struct CalleeInfo {<br>
   }<br>
 };<br>
<br>
-/// Struct to hold value either by GUID or GlobalValue*. Values in combined<br>
-/// indexes as well as indirect calls are GUIDs, all others are GlobalValues.<br>
-struct ValueInfo {<br>
-  /// The value representation used in this instance.<br>
-  enum ValueInfoKind {<br>
-    VI_GUID,<br>
-    VI_Value,<br>
-  };<br>
+class GlobalValueSummary;<br>
<br>
-  /// Union of the two possible value types.<br>
-  union ValueUnion {<br>
-    GlobalValue::GUID Id;<br>
-    const GlobalValue *GV;<br>
-    ValueUnion(GlobalValue::GUID Id) : Id(Id) {}<br>
-    ValueUnion(const GlobalValue *GV) : GV(GV) {}<br>
-  };<br>
+typedef std::vector<std::unique_ptr<GlobalValueSummary>> GlobalValueSummaryList;<br>
<br>
-  /// The value being represented.<br>
-  ValueUnion TheValue;<br>
-  /// The value representation.<br>
-  ValueInfoKind Kind;<br>
-  /// Constructor for a GUID value<br>
-  ValueInfo(GlobalValue::GUID Id = 0) : TheValue(Id), Kind(VI_GUID) {}<br>
-  /// Constructor for a GlobalValue* value<br>
-  ValueInfo(const GlobalValue *V) : TheValue(V), Kind(VI_Value) {}<br>
-  /// Accessor for GUID value<br>
-  GlobalValue::GUID getGUID() const {<br>
-    assert(Kind == VI_GUID && "Not a GUID type");<br>
-    return TheValue.Id;<br>
-  }<br>
-  /// Accessor for GlobalValue* value<br>
-  const GlobalValue *getValue() const {<br>
-    assert(Kind == VI_Value && "Not a Value type");<br>
-    return TheValue.GV;<br>
+struct GlobalValueSummaryInfo {<br>
+  /// The GlobalValue corresponding to this summary. This is only used in<br>
+  /// per-module summaries.<br>
+  const GlobalValue *GV = nullptr;<br>
+<br>
+  /// List of global value summary structures for a particular value held<br>
+  /// in the GlobalValueMap. Requires a vector in the case of multiple<br>
+  /// COMDAT values of the same name.<br>
+  GlobalValueSummaryList SummaryList;<br>
+};<br>
+<br>
+/// Map from global value GUID to corresponding summary structures. Use a<br>
+/// std::map rather than a DenseMap so that pointers to the map's value_type<br>
+/// (which are used by ValueInfo) are not invalidated by insertion. Also it will<br>
+/// likely incur less overhead, as the value type is not very small and the size<br>
+/// of the map is unknown, resulting in inefficiencies due to repeated<br>
+/// insertions and resizing.<br>
+typedef std::map<GlobalValue::GUID, GlobalValueSummaryInfo><br>
+    GlobalValueSummaryMapTy;<br>
+<br>
+/// Struct that holds a reference to a particular GUID in a global value<br>
+/// summary.<br>
+struct ValueInfo {<br>
+  const GlobalValueSummaryMapTy::value_type *Ref = nullptr;<br>
+  ValueInfo() = default;<br>
+  ValueInfo(const GlobalValueSummaryMapTy::value_type *Ref) : Ref(Ref) {}<br>
+  operator bool() const { return Ref; }<br>
+<br>
+  GlobalValue::GUID getGUID() const { return Ref->first; }<br>
+  const GlobalValue *getValue() const { return Ref->second.GV; }<br>
+  ArrayRef<std::unique_ptr<GlobalValueSummary>> getSummaryList() const {<br>
+    return Ref->second.SummaryList;<br>
   }<br>
-  bool isGUID() const { return Kind == VI_GUID; }<br>
 };<br>
<br>
 template <> struct DenseMapInfo<ValueInfo> {<br>
-  static inline ValueInfo getEmptyKey() { return ValueInfo((GlobalValue *)-1); }<br>
-  static inline ValueInfo getTombstoneKey() {<br>
-    return ValueInfo((GlobalValue *)-2);<br>
-  }<br>
-  static bool isEqual(ValueInfo L, ValueInfo R) {<br>
-    if (L.isGUID() != R.isGUID())<br>
-      return false;<br>
-    return L.isGUID() ? (L.getGUID() == R.getGUID())<br>
-                      : (L.getValue() == R.getValue());<br>
+  static inline ValueInfo getEmptyKey() {<br>
+    return ValueInfo((GlobalValueSummaryMapTy::value_type *)-1);<br>
   }<br>
-  static unsigned getHashValue(ValueInfo I) {<br>
-    return I.isGUID() ? I.getGUID() : (uintptr_t)I.getValue();<br>
+  static inline ValueInfo getTombstoneKey() {<br>
+    return ValueInfo((GlobalValueSummaryMapTy::value_type *)-2);<br>
   }<br>
+  static bool isEqual(ValueInfo L, ValueInfo R) { return L.Ref == R.Ref; }<br>
+  static unsigned getHashValue(ValueInfo I) { return (uintptr_t)I.Ref; }<br>
 };<br>
<br>
 /// \brief Function and variable summary information to aid decisions and<br>
@@ -483,19 +479,6 @@ struct TypeIdSummary {<br>
 /// 160 bits SHA1<br>
 typedef std::array<uint32_t, 5> ModuleHash;<br>
<br>
-/// List of global value summary structures for a particular value held<br>
-/// in the GlobalValueMap. Requires a vector in the case of multiple<br>
-/// COMDAT values of the same name.<br>
-typedef std::vector<std::unique_ptr<GlobalValueSummary>> GlobalValueSummaryList;<br>
-<br>
-/// Map from global value GUID to corresponding summary structures.<br>
-/// Use a std::map rather than a DenseMap since it will likely incur<br>
-/// less overhead, as the value type is not very small and the size<br>
-/// of the map is unknown, resulting in inefficiencies due to repeated<br>
-/// insertions and resizing.<br>
-typedef std::map<GlobalValue::GUID, GlobalValueSummaryList><br>
-    GlobalValueSummaryMapTy;<br>
-<br>
 /// Type used for iterating through the global value summary map.<br>
 typedef GlobalValueSummaryMapTy::const_iterator const_gvsummary_iterator;<br>
 typedef GlobalValueSummaryMapTy::iterator gvsummary_iterator;<br>
@@ -532,6 +515,11 @@ private:<br>
   // YAML I/O support.<br>
   friend yaml::MappingTraits<ModuleSummaryIndex>;<br>
<br>
+  GlobalValueSummaryMapTy::value_type *<br>
+  getOrInsertValuePtr(GlobalValue::GUID GUID) {<br>
+    return &*GlobalValueMap.emplace(GUID, GlobalValueSummaryInfo{}).first;<br>
+  }<br>
+<br>
 public:<br>
   gvsummary_iterator begin() { return GlobalValueMap.begin(); }<br>
   const_gvsummary_iterator begin() const { return GlobalValueMap.begin(); }<br>
@@ -539,21 +527,22 @@ public:<br>
   const_gvsummary_iterator end() const { return GlobalValueMap.end(); }<br>
   size_t size() const { return GlobalValueMap.size(); }<br>
<br>
-  /// Get the list of global value summary objects for a given value name.<br>
-  const GlobalValueSummaryList &getGlobalValueSummaryList(StringRef ValueName) {<br>
-    return GlobalValueMap[GlobalValue::getGUID(ValueName)];<br>
-  }<br>
-<br>
-  /// Get the list of global value summary objects for a given value name.<br>
-  const const_gvsummary_iterator<br>
-  findGlobalValueSummaryList(StringRef ValueName) const {<br>
-    return GlobalValueMap.find(GlobalValue::getGUID(ValueName));<br>
-  }<br>
-<br>
-  /// Get the list of global value summary objects for a given value GUID.<br>
-  const const_gvsummary_iterator<br>
-  findGlobalValueSummaryList(GlobalValue::GUID ValueGUID) const {<br>
-    return GlobalValueMap.find(ValueGUID);<br>
+  /// Return a ValueInfo for GUID if it exists, otherwise return ValueInfo().<br>
+  ValueInfo getValueInfo(GlobalValue::GUID GUID) const {<br>
+    auto I = GlobalValueMap.find(GUID);<br>
+    return ValueInfo(I == GlobalValueMap.end() ? nullptr : &*I);<br>
+  }<br>
+<br>
+  /// Return a ValueInfo for \p GUID.<br>
+  ValueInfo getOrInsertValueInfo(GlobalValue::GUID GUID) {<br>
+    return ValueInfo(getOrInsertValuePtr(GUID));<br>
+  }<br>
+<br>
+  /// Return a ValueInfo for \p GV and mark it as belonging to GV.<br>
+  ValueInfo getOrInsertValueInfo(const GlobalValue *GV) {<br>
+    auto VP = getOrInsertValuePtr(GV->getGUID());<br>
+    VP->second.GV = GV;<br>
+    return ValueInfo(VP);<br>
   }<br>
<br>
   /// Return the GUID for \p OriginalId in the OidGuidMap.<br>
@@ -565,17 +554,18 @@ public:<br>
   /// Add a global value summary for a value of the given name.<br>
   void addGlobalValueSummary(StringRef ValueName,<br>
                              std::unique_ptr<GlobalValueSummary> Summary) {<br>
-    addOriginalName(GlobalValue::getGUID(ValueName),<br>
-                    Summary->getOriginalName());<br>
-    GlobalValueMap[GlobalValue::getGUID(ValueName)].push_back(<br>
-        std::move(Summary));<br>
+    addGlobalValueSummary(getOrInsertValueInfo(GlobalValue::getGUID(ValueName)),<br>
+                          std::move(Summary));<br>
   }<br>
<br>
-  /// Add a global value summary for a value of the given GUID.<br>
-  void addGlobalValueSummary(GlobalValue::GUID ValueGUID,<br>
+  /// Add a global value summary for the given ValueInfo.<br>
+  void addGlobalValueSummary(ValueInfo VI,<br>
                              std::unique_ptr<GlobalValueSummary> Summary) {<br>
-    addOriginalName(ValueGUID, Summary->getOriginalName());<br>
-    GlobalValueMap[ValueGUID].push_back(std::move(Summary));<br>
+    addOriginalName(VI.getGUID(), Summary->getOriginalName());<br>
+    // Here we have a notionally const VI, but the value it points to is owned<br>
+    // by the non-const *this.<br>
+    const_cast<GlobalValueSummaryMapTy::value_type *>(VI.Ref)<br>
+        ->second.SummaryList.push_back(std::move(Summary));<br>
   }<br>
<br>
   /// Add an original name for the value of the given GUID.<br>
@@ -593,16 +583,16 @@ public:<br>
   /// not found.<br>
   GlobalValueSummary *findSummaryInModule(GlobalValue::GUID ValueGUID,<br>
                                           StringRef ModuleId) const {<br>
-    auto CalleeInfoList = findGlobalValueSummaryList(ValueGUID);<br>
-    if (CalleeInfoList == end()) {<br>
+    auto CalleeInfo = getValueInfo(ValueGUID);<br>
+    if (!CalleeInfo) {<br>
       return nullptr; // This function does not have a summary<br>
     }<br>
     auto Summary =<br>
-        llvm::find_if(CalleeInfoList->second,<br>
+        llvm::find_if(CalleeInfo.getSummaryList(),<br>
                       [&](const std::unique_ptr<GlobalValueSummary> &Summary) {<br>
                         return Summary->modulePath() == ModuleId;<br>
                       });<br>
-    if (Summary == CalleeInfoList->second.end())<br>
+    if (Summary == CalleeInfo.getSummaryList().end())<br>
       return nullptr;<br>
     return Summary->get();<br>
   }<br>
<br>
Modified: llvm/trunk/include/llvm/IR/ModuleSummaryIndexYAML.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/ModuleSummaryIndexYAML.h?rev=302108&r1=302107&r2=302108&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/ModuleSummaryIndexYAML.h?rev=302108&r1=302107&r2=302108&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/IR/ModuleSummaryIndexYAML.h (original)<br>
+++ llvm/trunk/include/llvm/IR/ModuleSummaryIndexYAML.h Wed May  3 22:36:16 2017<br>
@@ -201,7 +201,7 @@ template <> struct CustomMappingTraits<G<br>
     for (auto &FSum : FSums) {<br>
       GlobalValueSummary::GVFlags GVFlags(GlobalValue::ExternalLinkage, false,<br>
                                           false);<br>
-      Elem.push_back(llvm::make_unique<FunctionSummary>(<br>
+      Elem.SummaryList.push_back(llvm::make_unique<FunctionSummary>(<br>
           GVFlags, 0, ArrayRef<ValueInfo>{},<br>
           ArrayRef<FunctionSummary::EdgeTy>{}, std::move(FSum.TypeTests),<br>
           std::move(FSum.TypeTestAssumeVCalls),<br>
@@ -213,7 +213,7 @@ template <> struct CustomMappingTraits<G<br>
   static void output(IO &io, GlobalValueSummaryMapTy &V) {<br>
     for (auto &P : V) {<br>
       std::vector<FunctionSummaryYaml> FSums;<br>
-      for (auto &Sum : P.second) {<br>
+      for (auto &Sum : P.second.SummaryList) {<br>
         if (auto *FSum = dyn_cast<FunctionSummary>(Sum.get()))<br>
           FSums.push_back(FunctionSummaryYaml{<br>
               FSum->type_tests(), FSum->type_test_assume_vcalls(),<br>
<br>
Modified: llvm/trunk/lib/Analysis/ModuleSummaryAnalysis.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ModuleSummaryAnalysis.cpp?rev=302108&r1=302107&r2=302108&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ModuleSummaryAnalysis.cpp?rev=302108&r1=302107&r2=302108&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Analysis/ModuleSummaryAnalysis.cpp (original)<br>
+++ llvm/trunk/lib/Analysis/ModuleSummaryAnalysis.cpp Wed May  3 22:36:16 2017<br>
@@ -37,7 +37,8 @@ using namespace llvm;<br>
 // Walk through the operands of a given User via worklist iteration and populate<br>
 // the set of GlobalValue references encountered. Invoked either on an<br>
 // Instruction or a GlobalVariable (which walks its initializer).<br>
-static void findRefEdges(const User *CurUser, SetVector<ValueInfo> &RefEdges,<br>
+static void findRefEdges(ModuleSummaryIndex &Index, const User *CurUser,<br>
+                         SetVector<ValueInfo> &RefEdges,<br>
                          SmallPtrSet<const User *, 8> &Visited) {<br>
   SmallVector<const User *, 32> Worklist;<br>
   Worklist.push_back(CurUser);<br>
@@ -61,7 +62,7 @@ static void findRefEdges(const User *Cur<br>
         // the reference set unless it is a callee. Callees are handled<br>
         // specially by WriteFunction and are added to a separate list.<br>
         if (!(CS && CS.isCallee(&OI)))<br>
-          RefEdges.insert(GV);<br>
+          RefEdges.insert(Index.getOrInsertValueInfo(GV));<br>
         continue;<br>
       }<br>
       Worklist.push_back(Operand);<br>
@@ -198,7 +199,7 @@ computeFunctionSummary(ModuleSummaryInde<br>
       if (isa<DbgInfoIntrinsic>(I))<br>
         continue;<br>
       ++NumInsts;<br>
-      findRefEdges(&I, RefEdges, Visited);<br>
+      findRefEdges(Index, &I, RefEdges, Visited);<br>
       auto CS = ImmutableCallSite(&I);<br>
       if (!CS)<br>
         continue;<br>
@@ -239,7 +240,9 @@ computeFunctionSummary(ModuleSummaryInde<br>
         // to record the call edge to the alias in that case. Eventually<br>
         // an alias summary will be created to associate the alias and<br>
         // aliasee.<br>
-        CallGraphEdges[cast<GlobalValue>(CalledValue)].updateHotness(Hotness);<br>
+        CallGraphEdges[Index.getOrInsertValueInfo(<br>
+                           cast<GlobalValue>(CalledValue))]<br>
+            .updateHotness(Hotness);<br>
       } else {<br>
         // Skip inline assembly calls.<br>
         if (CI && CI->isInlineAsm())<br>
@@ -254,15 +257,16 @@ computeFunctionSummary(ModuleSummaryInde<br>
             ICallAnalysis.getPromotionCandidatesForInstruction(<br>
                 &I, NumVals, TotalCount, NumCandidates);<br>
         for (auto &Candidate : CandidateProfileData)<br>
-          CallGraphEdges[Candidate.Value].updateHotness(<br>
-              getHotness(Candidate.Count, PSI));<br>
+          CallGraphEdges[Index.getOrInsertValueInfo(Candidate.Value)]<br>
+              .updateHotness(getHotness(Candidate.Count, PSI));<br>
       }<br>
     }<br>
<br>
   // Explicit add hot edges to enforce importing for designated GUIDs for<br>
   // sample PGO, to enable the same inlines as the profiled optimized binary.<br>
   for (auto &I : F.getImportGUIDs())<br>
-    CallGraphEdges[I].updateHotness(CalleeInfo::HotnessType::Hot);<br>
+    CallGraphEdges[Index.getOrInsertValueInfo(I)].updateHotness(<br>
+        CalleeInfo::HotnessType::Hot);<br>
<br>
   bool NonRenamableLocal = isNonRenamableLocal(F);<br>
   bool NotEligibleForImport =<br>
@@ -288,7 +292,7 @@ computeVariableSummary(ModuleSummaryInde<br>
                        DenseSet<GlobalValue::GUID> &CantBePromoted) {<br>
   SetVector<ValueInfo> RefEdges;<br>
   SmallPtrSet<const User *, 8> Visited;<br>
-  findRefEdges(&V, RefEdges, Visited);<br>
+  findRefEdges(Index, &V, RefEdges, Visited);<br>
   bool NonRenamableLocal = isNonRenamableLocal(V);<br>
   GlobalValueSummary::GVFlags Flags(V.getLinkage(), NonRenamableLocal,<br>
                                     /* LiveRoot = */ false);<br>
@@ -317,12 +321,9 @@ computeAliasSummary(ModuleSummaryIndex &<br>
<br>
 // Set LiveRoot flag on entries matching the given value name.<br>
 static void setLiveRoot(ModuleSummaryIndex &Index, StringRef Name) {<br>
-  auto SummaryList =<br>
-      Index.findGlobalValueSummaryList(GlobalValue::getGUID(Name));<br>
-  if (SummaryList == Index.end())<br>
-    return;<br>
-  for (auto &Summary : SummaryList->second)<br>
-    Summary->setLiveRoot();<br>
+  if (ValueInfo VI = Index.getValueInfo(GlobalValue::getGUID(Name)))<br>
+    for (auto &Summary : VI.getSummaryList())<br>
+      Summary->setLiveRoot();<br>
 }<br>
<br>
 ModuleSummaryIndex llvm::buildModuleSummaryIndex(<br>
@@ -446,12 +447,16 @@ ModuleSummaryIndex llvm::buildModuleSumm<br>
   }<br>
<br>
   for (auto &GlobalList : Index) {<br>
-    assert(GlobalList.second.size() == 1 &&<br>
+    // Ignore entries for references that are undefined in the current module.<br>
+    if (GlobalList.second.SummaryList.empty())<br>
+      continue;<br>
+<br>
+    assert(GlobalList.second.SummaryList.size() == 1 &&<br>
            "Expected module's index to have one summary per GUID");<br>
-    auto &Summary = GlobalList.second[0];<br>
+    auto &Summary = GlobalList.second.SummaryList[0];<br>
     bool AllRefsCanBeExternallyReferenced =<br>
         llvm::all_of(Summary->refs(), [&](const ValueInfo &VI) {<br>
-          return !CantBePromoted.count(VI.getValue()->getGUID());<br>
+          return !CantBePromoted.count(VI.getGUID());<br>
         });<br>
     if (!AllRefsCanBeExternallyReferenced) {<br>
       Summary->setNotEligibleToImport();<br>
@@ -461,9 +466,7 @@ ModuleSummaryIndex llvm::buildModuleSumm<br>
     if (auto *FuncSummary = dyn_cast<FunctionSummary>(Summary.get())) {<br>
       bool AllCallsCanBeExternallyReferenced = llvm::all_of(<br>
           FuncSummary->calls(), [&](const FunctionSummary::EdgeTy &Edge) {<br>
-            auto GUID = Edge.first.isGUID() ? Edge.first.getGUID()<br>
-                                            : Edge.first.getValue()->getGUID();<br>
-            return !CantBePromoted.count(GUID);<br>
+            return !CantBePromoted.count(Edge.first.getGUID());<br>
           });<br>
       if (!AllCallsCanBeExternallyReferenced)<br>
         Summary->setNotEligibleToImport();<br>
<br>
Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=302108&r1=302107&r2=302108&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=302108&r1=302107&r2=302108&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)<br>
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Wed May  3 22:36:16 2017<br>
@@ -694,15 +694,16 @@ class ModuleSummaryIndexBitcodeReader :<br>
   /// Used to enable on-demand parsing of the VST.<br>
   uint64_t VSTOffset = 0;<br>
<br>
-  // Map to save ValueId to GUID association that was recorded in the<br>
+  // Map to save ValueId to ValueInfo association that was recorded in the<br>
   // ValueSymbolTable. It is used after the VST is parsed to convert<br>
   // call graph edges read from the function summary from referencing<br>
-  // callees by their ValueId to using the GUID instead, which is how<br>
+  // callees by their ValueId to using the ValueInfo instead, which is how<br>
   // they are recorded in the summary index being built.<br>
-  // We save a second GUID which is the same as the first one, but ignoring the<br>
-  // linkage, i.e. for value other than local linkage they are identical.<br>
-  DenseMap<unsigned, std::pair<GlobalValue::GUID, GlobalValue::GUID>><br>
-      ValueIdToCallGraphGUIDMap;<br>
+  // We save a GUID which refers to the same global as the ValueInfo, but<br>
+  // ignoring the linkage, i.e. for values other than local linkage they are<br>
+  // identical.<br>
+  DenseMap<unsigned, std::pair<ValueInfo, GlobalValue::GUID>><br>
+      ValueIdToValueInfoMap;<br>
<br>
   /// Map populated during module path string table parsing, from the<br>
   /// module ID to a string reference owned by the index's module<br>
@@ -742,8 +743,8 @@ private:<br>
   Error parseEntireSummary();<br>
   Error parseModuleStringTable();<br>
<br>
-  std::pair<GlobalValue::GUID, GlobalValue::GUID><br>
-  getGUIDFromValueId(unsigned ValueId);<br>
+  std::pair<ValueInfo, GlobalValue::GUID><br>
+  getValueInfoFromValueId(unsigned ValueId);<br>
<br>
   ModulePathStringTableTy::iterator addThisModulePath();<br>
 };<br>
@@ -4697,11 +4698,11 @@ ModuleSummaryIndexBitcodeReader::addThis<br>
   return TheIndex.addModulePath(ModulePath, ModuleId);<br>
 }<br>
<br>
-std::pair<GlobalValue::GUID, GlobalValue::GUID><br>
-ModuleSummaryIndexBitcodeReader::getGUIDFromValueId(unsigned ValueId) {<br>
-  auto VGI = ValueIdToCallGraphGUIDMap.find(ValueId);<br>
-  assert(VGI != ValueIdToCallGraphGUIDMap.end());<br>
-  return VGI->second;<br>
+std::pair<ValueInfo, GlobalValue::GUID><br>
+ModuleSummaryIndexBitcodeReader::getValueInfoFromValueId(unsigned ValueId) {<br>
+  auto VGI = ValueIdToValueInfoMap[ValueId];<br>
+  assert(VGI.first);<br>
+  return VGI;<br>
 }<br>
<br>
 void ModuleSummaryIndexBitcodeReader::setValueGUID(<br>
@@ -4716,8 +4717,8 @@ void ModuleSummaryIndexBitcodeReader::se<br>
   if (PrintSummaryGUIDs)<br>
     dbgs() << "GUID " << ValueGUID << "(" << OriginalNameID << ") is "<br>
            << ValueName << "\n";<br>
-  ValueIdToCallGraphGUIDMap[ValueID] =<br>
-      std::make_pair(ValueGUID, OriginalNameID);<br>
+  ValueIdToValueInfoMap[ValueID] =<br>
+      std::make_pair(TheIndex.getOrInsertValueInfo(ValueGUID), OriginalNameID);<br>
 }<br>
<br>
 // Specialized value symbol table parser used when reading module index<br>
@@ -4795,7 +4796,8 @@ Error ModuleSummaryIndexBitcodeReader::p<br>
       GlobalValue::GUID RefGUID = Record[1];<br>
       // The "original name", which is the second value of the pair will be<br>
       // overriden later by a FS_COMBINED_ORIGINAL_NAME in the combined index.<br>
-      ValueIdToCallGraphGUIDMap[ValueID] = std::make_pair(RefGUID, RefGUID);<br>
+      ValueIdToValueInfoMap[ValueID] =<br>
+          std::make_pair(TheIndex.getOrInsertValueInfo(RefGUID), RefGUID);<br>
       break;<br>
     }<br>
     }<br>
@@ -4940,7 +4942,7 @@ ModuleSummaryIndexBitcodeReader::makeRef<br>
   std::vector<ValueInfo> Ret;<br>
   Ret.reserve(Record.size());<br>
   for (uint64_t RefValueId : Record)<br>
-    Ret.push_back(getGUIDFromValueId(RefValueId).first);<br>
+    Ret.push_back(getValueInfoFromValueId(RefValueId).first);<br>
   return Ret;<br>
 }<br>
<br>
@@ -4950,14 +4952,14 @@ std::vector<FunctionSummary::EdgeTy> Mod<br>
   Ret.reserve(Record.size());<br>
   for (unsigned I = 0, E = Record.size(); I != E; ++I) {<br>
     CalleeInfo::HotnessType Hotness = CalleeInfo::HotnessType::Unknown;<br>
-    GlobalValue::GUID CalleeGUID = getGUIDFromValueId(Record[I]).first;<br>
+    ValueInfo Callee = getValueInfoFromValueId(Record[I]).first;<br>
     if (IsOldProfileFormat) {<br>
       I += 1; // Skip old callsitecount field<br>
       if (HasProfile)<br>
         I += 1; // Skip old profilecount field<br>
     } else if (HasProfile)<br>
       Hotness = static_cast<CalleeInfo::HotnessType>(Record[++I]);<br>
-    Ret.push_back(FunctionSummary::EdgeTy{CalleeGUID, CalleeInfo{Hotness}});<br>
+    Ret.push_back(FunctionSummary::EdgeTy{Callee, CalleeInfo{Hotness}});<br>
   }<br>
   return Ret;<br>
 }<br>
@@ -5027,7 +5029,8 @@ Error ModuleSummaryIndexBitcodeReader::p<br>
     case bitc::FS_VALUE_GUID: { // [valueid, refguid]<br>
       uint64_t ValueID = Record[0];<br>
       GlobalValue::GUID RefGUID = Record[1];<br>
-      ValueIdToCallGraphGUIDMap[ValueID] = std::make_pair(RefGUID, RefGUID);<br>
+      ValueIdToValueInfoMap[ValueID] =<br>
+          std::make_pair(TheIndex.getOrInsertValueInfo(RefGUID), RefGUID);<br>
       break;<br>
     }<br>
     // FS_PERMODULE: [valueid, flags, instcount, numrefs, numrefs x valueid,<br>
@@ -5068,10 +5071,10 @@ Error ModuleSummaryIndexBitcodeReader::p<br>
       PendingTypeCheckedLoadVCalls.clear();<br>
       PendingTypeTestAssumeConstVCalls.clear();<br>
       PendingTypeCheckedLoadConstVCalls.clear();<br>
-      auto GUID = getGUIDFromValueId(ValueID);<br>
+      auto VIAndOriginalGUID = getValueInfoFromValueId(ValueID);<br>
       FS->setModulePath(addThisModulePath()->first());<br>
-      FS->setOriginalName(GUID.second);<br>
-      TheIndex.addGlobalValueSummary(GUID.first, std::move(FS));<br>
+      FS->setOriginalName(VIAndOriginalGUID.second);<br>
+      TheIndex.addGlobalValueSummary(VIAndOriginalGUID.first, std::move(FS));<br>
       break;<br>
     }<br>
     // FS_ALIAS: [valueid, flags, valueid]<br>
@@ -5091,14 +5094,15 @@ Error ModuleSummaryIndexBitcodeReader::p<br>
       // ownership.<br>
       AS->setModulePath(addThisModulePath()->first());<br>
<br>
-      GlobalValue::GUID AliaseeGUID = getGUIDFromValueId(AliaseeID).first;<br>
+      GlobalValue::GUID AliaseeGUID =<br>
+          getValueInfoFromValueId(AliaseeID).first.getGUID();<br>
       auto AliaseeInModule =<br>
           TheIndex.findSummaryInModule(AliaseeGUID, ModulePath);<br>
       if (!AliaseeInModule)<br>
         return error("Alias expects aliasee summary to be parsed");<br>
       AS->setAliasee(AliaseeInModule);<br>
<br>
-      auto GUID = getGUIDFromValueId(ValueID);<br>
+      auto GUID = getValueInfoFromValueId(ValueID);<br>
       AS->setOriginalName(GUID.second);<br>
       TheIndex.addGlobalValueSummary(GUID.first, std::move(AS));<br>
       break;<br>
@@ -5112,7 +5116,7 @@ Error ModuleSummaryIndexBitcodeReader::p<br>
           makeRefList(ArrayRef<uint64_t>(Record).slice(2));<br>
       auto FS = llvm::make_unique<GlobalVarSummary>(Flags, std::move(Refs));<br>
       FS->setModulePath(addThisModulePath()->first());<br>
-      auto GUID = getGUIDFromValueId(ValueID);<br>
+      auto GUID = getValueInfoFromValueId(ValueID);<br>
       FS->setOriginalName(GUID.second);<br>
       TheIndex.addGlobalValueSummary(GUID.first, std::move(FS));<br>
       break;<br>
@@ -5139,7 +5143,7 @@ Error ModuleSummaryIndexBitcodeReader::p<br>
       std::vector<FunctionSummary::EdgeTy> Edges = makeCallList(<br>
           ArrayRef<uint64_t>(Record).slice(CallGraphEdgeStartIndex),<br>
           IsOldProfileFormat, HasProfile);<br>
-      GlobalValue::GUID GUID = getGUIDFromValueId(ValueID).first;<br>
+      ValueInfo VI = getValueInfoFromValueId(ValueID).first;<br>
       auto FS = llvm::make_unique<FunctionSummary>(<br>
           Flags, InstCount, std::move(Refs), std::move(Edges),<br>
           std::move(PendingTypeTests), std::move(PendingTypeTestAssumeVCalls),<br>
@@ -5152,9 +5156,9 @@ Error ModuleSummaryIndexBitcodeReader::p<br>
       PendingTypeTestAssumeConstVCalls.clear();<br>
       PendingTypeCheckedLoadConstVCalls.clear();<br>
       LastSeenSummary = FS.get();<br>
-      LastSeenGUID = GUID;<br>
+      LastSeenGUID = VI.getGUID();<br>
       FS->setModulePath(ModuleIdMap[ModuleId]);<br>
-      TheIndex.addGlobalValueSummary(GUID, std::move(FS));<br>
+      TheIndex.addGlobalValueSummary(VI, std::move(FS));<br>
       break;<br>
     }<br>
     // FS_COMBINED_ALIAS: [valueid, modid, flags, valueid]<br>
@@ -5170,16 +5174,17 @@ Error ModuleSummaryIndexBitcodeReader::p<br>
       LastSeenSummary = AS.get();<br>
       AS->setModulePath(ModuleIdMap[ModuleId]);<br>
<br>
-      auto AliaseeGUID = getGUIDFromValueId(AliaseeValueId).first;<br>
+      auto AliaseeGUID =<br>
+          getValueInfoFromValueId(AliaseeValueId).first.getGUID();<br>
       auto AliaseeInModule =<br>
           TheIndex.findSummaryInModule(AliaseeGUID, AS->modulePath());<br>
       if (!AliaseeInModule)<br>
         return error("Alias expects aliasee summary to be parsed");<br>
       AS->setAliasee(AliaseeInModule);<br>
<br>
-      GlobalValue::GUID GUID = getGUIDFromValueId(ValueID).first;<br>
-      LastSeenGUID = GUID;<br>
-      TheIndex.addGlobalValueSummary(GUID, std::move(AS));<br>
+      ValueInfo VI = getValueInfoFromValueId(ValueID).first;<br>
+      LastSeenGUID = VI.getGUID();<br>
+      TheIndex.addGlobalValueSummary(VI, std::move(AS));<br>
       break;<br>
     }<br>
     // FS_COMBINED_GLOBALVAR_INIT_REFS: [valueid, modid, flags, n x valueid]<br>
@@ -5193,9 +5198,9 @@ Error ModuleSummaryIndexBitcodeReader::p<br>
       auto FS = llvm::make_unique<GlobalVarSummary>(Flags, std::move(Refs));<br>
       LastSeenSummary = FS.get();<br>
       FS->setModulePath(ModuleIdMap[ModuleId]);<br>
-      GlobalValue::GUID GUID = getGUIDFromValueId(ValueID).first;<br>
-      LastSeenGUID = GUID;<br>
-      TheIndex.addGlobalValueSummary(GUID, std::move(FS));<br>
+      ValueInfo VI = getValueInfoFromValueId(ValueID).first;<br>
+      LastSeenGUID = VI.getGUID();<br>
+      TheIndex.addGlobalValueSummary(VI, std::move(FS));<br>
       break;<br>
     }<br>
     // FS_COMBINED_ORIGINAL_NAME: [original_name]<br>
<br>
Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=302108&r1=302107&r2=302108&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=302108&r1=302107&r2=302108&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original)<br>
+++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Wed May  3 22:36:16 2017<br>
@@ -156,14 +156,14 @@ public:<br>
       return;<br>
     for (const auto &GUIDSummaryLists : *Index)<br>
       // Examine all summaries for this GUID.<br>
-      for (auto &Summary : GUIDSummaryLists.second)<br>
+      for (auto &Summary : GUIDSummaryLists.second.SummaryList)<br>
         if (auto FS = dyn_cast<FunctionSummary>(Summary.get()))<br>
           // For each call in the function summary, see if the call<br>
           // is to a GUID (which means it is for an indirect call,<br>
           // otherwise we would have a Value for it). If so, synthesize<br>
           // a value id.<br>
           for (auto &CallEdge : FS->calls())<br>
-            if (CallEdge.first.isGUID())<br>
+            if (!CallEdge.first.getValue())<br>
               assignValueId(CallEdge.first.getGUID());<br>
   }<br>
<br>
@@ -304,7 +304,7 @@ private:<br>
   }<br>
   // Helper to get the valueId for the type of value recorded in VI.<br>
   unsigned getValueId(ValueInfo VI) {<br>
-    if (VI.isGUID())<br>
+    if (!VI.getValue())<br>
       return getValueId(VI.getGUID());<br>
     return VE.getValueID(VI.getValue());<br>
   }<br>
@@ -358,7 +358,7 @@ public:<br>
           Callback(Summary);<br>
     } else {<br>
       for (auto &Summaries : Index)<br>
-        for (auto &Summary : Summaries.second)<br>
+        for (auto &Summary : Summaries.second.SummaryList)<br>
           Callback({Summaries.first, Summary.get()});<br>
     }<br>
   }<br>
@@ -3270,15 +3270,14 @@ void ModuleBitcodeWriter::writePerModule<br>
 void ModuleBitcodeWriter::writeModuleLevelReferences(<br>
     const GlobalVariable &V, SmallVector<uint64_t, 64> &NameVals,<br>
     unsigned FSModRefsAbbrev) {<br>
-  auto Summaries =<br>
-      Index->findGlobalValueSummaryList(GlobalValue::getGUID(V.getName()));<br>
-  if (Summaries == Index->end()) {<br>
+  auto VI = Index->getValueInfo(GlobalValue::getGUID(V.getName()));<br>
+  if (!VI || VI.getSummaryList().empty()) {<br>
     // Only declarations should not have a summary (a declaration might however<br>
     // have a summary if the def was in module level asm).<br>
     assert(V.isDeclaration());<br>
     return;<br>
   }<br>
-  auto *Summary = Summaries->second.front().get();<br>
+  auto *Summary = VI.getSummaryList()[0].get();<br>
   NameVals.push_back(VE.getValueID(&V));<br>
   GlobalVarSummary *VS = cast<GlobalVarSummary>(Summary);<br>
   NameVals.push_back(getEncodedGVSummaryFlags(VS->flags()));<br>
@@ -3367,15 +3366,14 @@ void ModuleBitcodeWriter::writePerModule<br>
     if (!F.hasName())<br>
       report_fatal_error("Unexpected anonymous function when writing summary");<br>
<br>
-    auto Summaries =<br>
-        Index->findGlobalValueSummaryList(GlobalValue::getGUID(F.getName()));<br>
-    if (Summaries == Index->end()) {<br>
+    ValueInfo VI = Index->getValueInfo(GlobalValue::getGUID(F.getName()));<br>
+    if (!VI || VI.getSummaryList().empty()) {<br>
       // Only declarations should not have a summary (a declaration might<br>
       // however have a summary if the def was in module level asm).<br>
       assert(F.isDeclaration());<br>
       continue;<br>
     }<br>
-    auto *Summary = Summaries->second.front().get();<br>
+    auto *Summary = VI.getSummaryList()[0].get();<br>
     writePerModuleFunctionSummaryRecord(NameVals, Summary, VE.getValueID(&F),<br>
                                         FSCallsAbbrev, FSCallsProfileAbbrev, F);<br>
   }<br>
<br>
Modified: llvm/trunk/lib/IR/ModuleSummaryIndex.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/ModuleSummaryIndex.cpp?rev=302108&r1=302107&r2=302108&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/ModuleSummaryIndex.cpp?rev=302108&r1=302107&r2=302108&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/IR/ModuleSummaryIndex.cpp (original)<br>
+++ llvm/trunk/lib/IR/ModuleSummaryIndex.cpp Wed May  3 22:36:16 2017<br>
@@ -22,7 +22,7 @@ void ModuleSummaryIndex::collectDefinedF<br>
     StringRef ModulePath, GVSummaryMapTy &GVSummaryMap) const {<br>
   for (auto &GlobalList : *this) {<br>
     auto GUID = GlobalList.first;<br>
-    for (auto &GlobSummary : GlobalList.second) {<br>
+    for (auto &GlobSummary : GlobalList.second.SummaryList) {<br>
       auto *Summary = dyn_cast_or_null<FunctionSummary>(GlobSummary.get());<br>
       if (!Summary)<br>
         // Ignore global variable, focus on functions<br>
@@ -40,7 +40,7 @@ void ModuleSummaryIndex::collectDefinedG<br>
     StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries) const {<br>
   for (auto &GlobalList : *this) {<br>
     auto GUID = GlobalList.first;<br>
-    for (auto &Summary : GlobalList.second) {<br>
+    for (auto &Summary : GlobalList.second.SummaryList) {<br>
       ModuleToDefinedGVSummaries[Summary->modulePath()][GUID] = Summary.get();<br>
     }<br>
   }<br>
@@ -49,10 +49,10 @@ void ModuleSummaryIndex::collectDefinedG<br>
 GlobalValueSummary *<br>
 ModuleSummaryIndex::getGlobalValueSummary(uint64_t ValueGUID,<br>
                                           bool PerModuleIndex) const {<br>
-  auto SummaryList = findGlobalValueSummaryList(ValueGUID);<br>
-  assert(SummaryList != end() && "GlobalValue not found in index");<br>
-  assert((!PerModuleIndex || SummaryList->second.size() == 1) &&<br>
+  auto VI = getValueInfo(ValueGUID);<br>
+  assert(VI && "GlobalValue not found in index");<br>
+  assert((!PerModuleIndex || VI.getSummaryList().size() == 1) &&<br>
          "Expected a single entry per global value in per-module index");<br>
-  auto &Summary = SummaryList->second[0];<br>
+  auto &Summary = VI.getSummaryList()[0];<br>
   return Summary.get();<br>
 }<br>
<br>
Modified: llvm/trunk/lib/LTO/LTO.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/LTO.cpp?rev=302108&r1=302107&r2=302108&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/LTO.cpp?rev=302108&r1=302107&r2=302108&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/LTO/LTO.cpp (original)<br>
+++ llvm/trunk/lib/LTO/LTO.cpp Wed May  3 22:36:16 2017<br>
@@ -274,13 +274,14 @@ void llvm::thinLTOResolveWeakForLinkerIn<br>
   // when needed.<br>
   DenseSet<GlobalValueSummary *> GlobalInvolvedWithAlias;<br>
   for (auto &I : Index)<br>
-    for (auto &S : I.second)<br>
+    for (auto &S : I.second.SummaryList)<br>
       if (auto AS = dyn_cast<AliasSummary>(S.get()))<br>
         GlobalInvolvedWithAlias.insert(&AS->getAliasee());<br>
<br>
   for (auto &I : Index)<br>
-    thinLTOResolveWeakForLinkerGUID(I.second, I.first, GlobalInvolvedWithAlias,<br>
-                                    isPrevailing, recordNewLinkage);<br>
+    thinLTOResolveWeakForLinkerGUID(I.second.SummaryList, I.first,<br>
+                                    GlobalInvolvedWithAlias, isPrevailing,<br>
+                                    recordNewLinkage);<br>
 }<br>
<br>
 static void thinLTOInternalizeAndPromoteGUID(<br>
@@ -301,7 +302,7 @@ void llvm::thinLTOInternalizeAndPromoteI<br>
     ModuleSummaryIndex &Index,<br>
     function_ref<bool(StringRef, GlobalValue::GUID)> isExported) {<br>
   for (auto &I : Index)<br>
-    thinLTOInternalizeAndPromoteGUID(I.second, I.first, isExported);<br>
+    thinLTOInternalizeAndPromoteGUID(I.second.SummaryList, I.first, isExported);<br>
 }<br>
<br>
 // Requires a destructor for std::vector<InputModule>.<br>
<br>
Modified: llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp?rev=302108&r1=302107&r2=302108&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp?rev=302108&r1=302107&r2=302108&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp (original)<br>
+++ llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp Wed May  3 22:36:16 2017<br>
@@ -119,8 +119,9 @@ static void computePrevailingCopies(<br>
   };<br>
<br>
   for (auto &I : Index) {<br>
-    if (HasMultipleCopies(I.second))<br>
-      PrevailingCopy[I.first] = getFirstDefinitionForLinker(I.second);<br>
+    if (HasMultipleCopies(I.second.SummaryList))<br>
+      PrevailingCopy[I.first] =<br>
+          getFirstDefinitionForLinker(I.second.SummaryList);<br>
   }<br>
 }<br>
<br>
<br>
Modified: llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp?rev=302108&r1=302107&r2=302108&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp?rev=302108&r1=302107&r2=302108&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp Wed May  3 22:36:16 2017<br>
@@ -117,7 +117,7 @@ namespace {<br>
 /// - [insert you fancy metric here]<br>
 static const GlobalValueSummary *<br>
 selectCallee(const ModuleSummaryIndex &Index,<br>
-             const GlobalValueSummaryList &CalleeSummaryList,<br>
+             ArrayRef<std::unique_ptr<GlobalValueSummary>> CalleeSummaryList,<br>
              unsigned Threshold, StringRef CallerModulePath) {<br>
   auto It = llvm::find_if(<br>
       CalleeSummaryList,<br>
@@ -168,19 +168,6 @@ selectCallee(const ModuleSummaryIndex &I<br>
   return cast<GlobalValueSummary>(It->get());<br>
 }<br>
<br>
-/// Return the summary for the function \p GUID that fits the \p Threshold, or<br>
-/// null if there's no match.<br>
-static const GlobalValueSummary *selectCallee(GlobalValue::GUID GUID,<br>
-                                              unsigned Threshold,<br>
-                                              const ModuleSummaryIndex &Index,<br>
-                                              StringRef CallerModulePath) {<br>
-  auto CalleeSummaryList = Index.findGlobalValueSummaryList(GUID);<br>
-  if (CalleeSummaryList == Index.end())<br>
-    return nullptr; // This function does not have a summary<br>
-  return selectCallee(Index, CalleeSummaryList->second, Threshold,<br>
-                      CallerModulePath);<br>
-}<br>
-<br>
 using EdgeInfo = std::tuple<const FunctionSummary *, unsigned /* Threshold */,<br>
                             GlobalValue::GUID>;<br>
<br>
@@ -194,19 +181,23 @@ static void computeImportForFunction(<br>
     FunctionImporter::ImportMapTy &ImportList,<br>
     StringMap<FunctionImporter::ExportSetTy> *ExportLists = nullptr) {<br>
   for (auto &Edge : Summary.calls()) {<br>
-    auto GUID = Edge.first.getGUID();<br>
-    DEBUG(dbgs() << " edge -> " << GUID << " Threshold:" << Threshold << "\n");<br>
+    ValueInfo VI = Edge.first;<br>
+    DEBUG(dbgs() << " edge -> " << VI.getGUID() << " Threshold:" << Threshold<br>
+                 << "\n");<br>
<br>
-    if (Index.findGlobalValueSummaryList(GUID) == Index.end()) {<br>
+    if (VI.getSummaryList().empty()) {<br>
       // For SamplePGO, the indirect call targets for local functions will<br>
       // have its original name annotated in profile. We try to find the<br>
       // corresponding PGOFuncName as the GUID.<br>
-      GUID = Index.getGUIDFromOriginalID(GUID);<br>
+      auto GUID = Index.getGUIDFromOriginalID(VI.getGUID());<br>
       if (GUID == 0)<br>
         continue;<br>
+      VI = Index.getValueInfo(GUID);<br>
+      if (!VI)<br>
+        continue;<br>
     }<br>
<br>
-    if (DefinedGVSummaries.count(GUID)) {<br>
+    if (DefinedGVSummaries.count(VI.getGUID())) {<br>
       DEBUG(dbgs() << "ignored! Target already in destination module.\n");<br>
       continue;<br>
     }<br>
@@ -222,8 +213,8 @@ static void computeImportForFunction(<br>
     const auto NewThreshold =<br>
         Threshold * GetBonusMultiplier(Edge.second.Hotness);<br>
<br>
-    auto *CalleeSummary =<br>
-        selectCallee(GUID, NewThreshold, Index, Summary.modulePath());<br>
+    auto *CalleeSummary = selectCallee(Index, VI.getSummaryList(), NewThreshold,<br>
+                                       Summary.modulePath());<br>
     if (!CalleeSummary) {<br>
       DEBUG(dbgs() << "ignored! No qualifying callee with summary found.\n");<br>
       continue;<br>
@@ -255,7 +246,7 @@ static void computeImportForFunction(<br>
     const auto AdjThreshold = GetAdjustedThreshold(Threshold, IsHotCallsite);<br>
<br>
     auto ExportModulePath = ResolvedCalleeSummary->modulePath();<br>
-    auto &ProcessedThreshold = ImportList[ExportModulePath][GUID];<br>
+    auto &ProcessedThreshold = ImportList[ExportModulePath][VI.getGUID()];<br>
     /// Since the traversal of the call graph is DFS, we can revisit a function<br>
     /// a second time with a higher threshold. In this case, it is added back to<br>
     /// the worklist with the new threshold.<br>
@@ -271,7 +262,7 @@ static void computeImportForFunction(<br>
     // Make exports in the source module.<br>
     if (ExportLists) {<br>
       auto &ExportList = (*ExportLists)[ExportModulePath];<br>
-      ExportList.insert(GUID);<br>
+      ExportList.insert(VI.getGUID());<br>
       if (!PreviouslyImported) {<br>
         // This is the first time this function was exported from its source<br>
         // module, so mark all functions and globals it references as exported<br>
@@ -291,7 +282,7 @@ static void computeImportForFunction(<br>
     }<br>
<br>
     // Insert the newly imported function to the worklist.<br>
-    Worklist.emplace_back(ResolvedCalleeSummary, AdjThreshold, GUID);<br>
+    Worklist.emplace_back(ResolvedCalleeSummary, AdjThreshold, VI.getGUID());<br>
   }<br>
 }<br>
<br>
@@ -431,57 +422,56 @@ DenseSet<GlobalValue::GUID> llvm::comput<br>
   if (GUIDPreservedSymbols.empty())<br>
     // Don't do anything when nothing is live, this is friendly with tests.<br>
     return DenseSet<GlobalValue::GUID>();<br>
-  DenseSet<GlobalValue::GUID> LiveSymbols = GUIDPreservedSymbols;<br>
-  SmallVector<GlobalValue::GUID, 128> Worklist;<br>
-  Worklist.reserve(LiveSymbols.size() * 2);<br>
-  for (auto GUID : LiveSymbols) {<br>
-    DEBUG(dbgs() << "Live root: " << GUID << "\n");<br>
-    Worklist.push_back(GUID);<br>
+  DenseSet<ValueInfo> LiveSymbols;<br>
+  SmallVector<ValueInfo, 128> Worklist;<br>
+  Worklist.reserve(GUIDPreservedSymbols.size() * 2);<br>
+  for (auto GUID : GUIDPreservedSymbols) {<br>
+    ValueInfo VI = Index.getValueInfo(GUID);<br>
+    if (!VI)<br>
+      continue;<br>
+    DEBUG(dbgs() << "Live root: " << VI.getGUID() << "\n");<br>
+    LiveSymbols.insert(VI);<br>
+    Worklist.push_back(VI);<br>
   }<br>
   // Add values flagged in the index as live roots to the worklist.<br>
   for (const auto &Entry : Index) {<br>
     bool IsLiveRoot = llvm::any_of(<br>
-        Entry.second,<br>
+        Entry.second.SummaryList,<br>
         [&](const std::unique_ptr<llvm::GlobalValueSummary> &Summary) {<br>
           return Summary->liveRoot();<br>
         });<br>
     if (!IsLiveRoot)<br>
       continue;<br>
     DEBUG(dbgs() << "Live root (summary): " << Entry.first << "\n");<br>
-    Worklist.push_back(Entry.first);<br>
+    Worklist.push_back(ValueInfo(&Entry));<br>
   }<br>
<br>
   while (!Worklist.empty()) {<br>
-    auto GUID = Worklist.pop_back_val();<br>
-    auto It = Index.findGlobalValueSummaryList(GUID);<br>
-    if (It == Index.end()) {<br>
-      DEBUG(dbgs() << "Not in index: " << GUID << "\n");<br>
-      continue;<br>
-    }<br>
+    auto VI = Worklist.pop_back_val();<br>
<br>
     // FIXME: we should only make the prevailing copy live here<br>
-    for (auto &Summary : It->second) {<br>
+    for (auto &Summary : VI.getSummaryList()) {<br>
       for (auto Ref : Summary->refs()) {<br>
-        auto RefGUID = Ref.getGUID();<br>
-        if (LiveSymbols.insert(RefGUID).second) {<br>
-          DEBUG(dbgs() << "Marking live (ref): " << RefGUID << "\n");<br>
-          Worklist.push_back(RefGUID);<br>
+        if (LiveSymbols.insert(Ref).second) {<br>
+          DEBUG(dbgs() << "Marking live (ref): " << Ref.getGUID() << "\n");<br>
+          Worklist.push_back(Ref);<br>
         }<br>
       }<br>
       if (auto *FS = dyn_cast<FunctionSummary>(Summary.get())) {<br>
         for (auto Call : FS->calls()) {<br>
-          auto CallGUID = Call.first.getGUID();<br>
-          if (LiveSymbols.insert(CallGUID).second) {<br>
-            DEBUG(dbgs() << "Marking live (call): " << CallGUID << "\n");<br>
-            Worklist.push_back(CallGUID);<br>
+          if (LiveSymbols.insert(Call.first).second) {<br>
+            DEBUG(dbgs() << "Marking live (call): " << Call.first.getGUID()<br>
+                         << "\n");<br>
+            Worklist.push_back(Call.first);<br>
           }<br>
         }<br>
       }<br>
       if (auto *AS = dyn_cast<AliasSummary>(Summary.get())) {<br>
         auto AliaseeGUID = AS->getAliasee().getOriginalName();<br>
-        if (LiveSymbols.insert(AliaseeGUID).second) {<br>
+        ValueInfo AliaseeVI = Index.getValueInfo(AliaseeGUID);<br>
+        if (AliaseeVI && LiveSymbols.insert(AliaseeVI).second) {<br>
           DEBUG(dbgs() << "Marking live (alias): " << AliaseeGUID << "\n");<br>
-          Worklist.push_back(AliaseeGUID);<br>
+          Worklist.push_back(AliaseeVI);<br>
         }<br>
       }<br>
     }<br>
@@ -490,10 +480,9 @@ DenseSet<GlobalValue::GUID> llvm::comput<br>
   DeadSymbols.reserve(<br>
       std::min(Index.size(), Index.size() - LiveSymbols.size()));<br>
   for (auto &Entry : Index) {<br>
-    auto GUID = Entry.first;<br>
-    if (!LiveSymbols.count(GUID)) {<br>
-      DEBUG(dbgs() << "Marking dead: " << GUID << "\n");<br>
-      DeadSymbols.insert(GUID);<br>
+    if (!LiveSymbols.count(ValueInfo(&Entry))) {<br>
+      DEBUG(dbgs() << "Marking dead: " << Entry.first << "\n");<br>
+      DeadSymbols.insert(Entry.first);<br>
     }<br>
   }<br>
   DEBUG(dbgs() << LiveSymbols.size() << " symbols Live, and "<br>
@@ -825,7 +814,7 @@ static bool doImportingForModule(Module<br>
   // is only enabled when testing importing via the 'opt' tool, which does<br>
   // not do the ThinLink that would normally determine what values to promote.<br>
   for (auto &I : *Index) {<br>
-    for (auto &S : I.second) {<br>
+    for (auto &S : I.second.SummaryList) {<br>
       if (GlobalValue::isLocalLinkage(S->linkage()))<br>
         S->setLinkage(GlobalValue::ExternalLinkage);<br>
     }<br>
<br>
Modified: llvm/trunk/lib/Transforms/IPO/LowerTypeTests.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/LowerTypeTests.cpp?rev=302108&r1=302107&r2=302108&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/LowerTypeTests.cpp?rev=302108&r1=302107&r2=302108&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Transforms/IPO/LowerTypeTests.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/IPO/LowerTypeTests.cpp Wed May  3 22:36:16 2017<br>
@@ -1440,7 +1440,7 @@ bool LowerTypeTestsModule::lower() {<br>
     }<br>
<br>
     for (auto &P : *ExportSummary) {<br>
-      for (auto &S : P.second) {<br>
+      for (auto &S : P.second.SummaryList) {<br>
         auto *FS = dyn_cast<FunctionSummary>(S.get());<br>
         if (!FS)<br>
           continue;<br>
<br>
Modified: llvm/trunk/lib/Transforms/IPO/WholeProgramDevirt.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/WholeProgramDevirt.cpp?rev=302108&r1=302107&r2=302108&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/WholeProgramDevirt.cpp?rev=302108&r1=302107&r2=302108&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Transforms/IPO/WholeProgramDevirt.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/IPO/WholeProgramDevirt.cpp Wed May  3 22:36:16 2017<br>
@@ -1322,7 +1322,7 @@ bool DevirtModule::run() {<br>
     }<br>
<br>
     for (auto &P : *ExportSummary) {<br>
-      for (auto &S : P.second) {<br>
+      for (auto &S : P.second.SummaryList) {<br>
         auto *FS = dyn_cast<FunctionSummary>(S.get());<br>
         if (!FS)<br>
           continue;<br>
<br>
Modified: llvm/trunk/tools/llvm-link/llvm-link.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-link/llvm-link.cpp?rev=302108&r1=302107&r2=302108&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-link/llvm-link.cpp?rev=302108&r1=302107&r2=302108&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/llvm-link/llvm-link.cpp (original)<br>
+++ llvm/trunk/tools/llvm-link/llvm-link.cpp Wed May  3 22:36:16 2017<br>
@@ -300,7 +300,7 @@ static bool linkFiles(const char *argv0,<br>
       // does not do the ThinLink that would normally determine what values to<br>
       // promote.<br>
       for (auto &I : *Index) {<br>
-        for (auto &S : I.second) {<br>
+        for (auto &S : I.second.SummaryList) {<br>
           if (GlobalValue::isLocalLinkage(S->linkage()))<br>
             S->setLinkage(GlobalValue::ExternalLinkage);<br>
         }<br>
<br>
Modified: llvm/trunk/tools/llvm-lto/llvm-lto.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-lto/llvm-lto.cpp?rev=302108&r1=302107&r2=302108&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-lto/llvm-lto.cpp?rev=302108&r1=302107&r2=302108&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/llvm-lto/llvm-lto.cpp (original)<br>
+++ llvm/trunk/tools/llvm-lto/llvm-lto.cpp Wed May  3 22:36:16 2017<br>
@@ -284,7 +284,7 @@ void printIndexStats() {<br>
<br>
     unsigned Calls = 0, Refs = 0, Functions = 0, Alias = 0, Globals = 0;<br>
     for (auto &Summaries : *Index) {<br>
-      for (auto &Summary : Summaries.second) {<br>
+      for (auto &Summary : Summaries.second.SummaryList) {<br>
         Refs += Summary->refs().size();<br>
         if (auto *FuncSummary = dyn_cast<FunctionSummary>(Summary.get())) {<br>
           Functions++;<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div></div></blockquote></div></div>