Index: include/llvm/IR/ModuleSummaryIndex.h
===================================================================
--- include/llvm/IR/ModuleSummaryIndex.h
+++ include/llvm/IR/ModuleSummaryIndex.h
@@ -41,6 +41,7 @@
 namespace yaml {
 
 template <typename T> struct MappingTraits;
+struct ModuleSummaryIndexWithModule;
 
 } // end namespace yaml
 
@@ -544,6 +545,7 @@
 
   // YAML I/O support.
   friend yaml::MappingTraits<ModuleSummaryIndex>;
+  friend yaml::MappingTraits<yaml::ModuleSummaryIndexWithModule>;
 
   GlobalValueSummaryMapTy::value_type *
   getOrInsertValuePtr(GlobalValue::GUID GUID) {
Index: include/llvm/IR/ModuleSummaryIndexYAML.h
===================================================================
--- include/llvm/IR/ModuleSummaryIndexYAML.h
+++ include/llvm/IR/ModuleSummaryIndexYAML.h
@@ -16,6 +16,14 @@
 namespace llvm {
 namespace yaml {
 
+using NameMapTy = std::map<GlobalValue::GUID, StringRef>;
+
+template <typename T>
+struct NameMapWrapper {
+  T *Val;
+  NameMapTy *NameMap;
+};
+
 template <> struct ScalarEnumerationTraits<TypeTestResolution::Kind> {
   static void enumeration(IO &io, TypeTestResolution::Kind &value) {
     io.enumCase(value, "Unsat", TypeTestResolution::Unsat);
@@ -26,6 +34,25 @@
   }
 };
 
+template <> struct ScalarEnumerationTraits<CalleeInfo::HotnessType> {
+  static void enumeration(IO &io, CalleeInfo::HotnessType &value) {
+    io.enumCase(value, "Unknown", CalleeInfo::HotnessType::Unknown);
+    io.enumCase(value, "Cold", CalleeInfo::HotnessType::Cold);
+    io.enumCase(value, "None", CalleeInfo::HotnessType::None);
+    io.enumCase(value, "Hot", CalleeInfo::HotnessType::Hot);
+  }
+};
+
+template <> struct ScalarEnumerationTraits<GlobalValueSummary::SummaryKind> {
+  static void enumeration(IO &io, GlobalValueSummary::SummaryKind &value) {
+    io.enumCase(value, "Alias", GlobalValueSummary::SummaryKind::AliasKind);
+    io.enumCase(value, "Function",
+                GlobalValueSummary::SummaryKind::FunctionKind);
+    io.enumCase(value, "GlobalVar",
+                GlobalValueSummary::SummaryKind::GlobalVarKind);
+  }
+};
+
 template <> struct MappingTraits<TypeTestResolution> {
   static void mapping(IO &io, TypeTestResolution &res) {
     io.mapOptional("Kind", res.TheKind);
@@ -127,9 +154,20 @@
   }
 };
 
+struct CalleeInfoYaml {
+  StringRef Name;
+  GlobalValue::GUID GUID;
+  CalleeInfo::HotnessType Hotness;
+};
+
 struct FunctionSummaryYaml {
-  unsigned Linkage;
+  StringRef Name;
+  GlobalValueSummary::SummaryKind Kind;
+  GlobalValue::LinkageTypes Linkage;
   bool NotEligibleToImport, Live;
+  unsigned InstCount;
+  std::vector<CalleeInfoYaml> Calls;
+
   std::vector<uint64_t> TypeTests;
   std::vector<FunctionSummary::VFuncId> TypeTestAssumeVCalls,
       TypeCheckedLoadVCalls;
@@ -137,6 +175,20 @@
       TypeCheckedLoadConstVCalls;
 };
 
+struct GlobalVarSummaryYaml {
+  StringRef Name;
+  GlobalValueSummary::SummaryKind Kind;
+  GlobalValue::LinkageTypes Linkage;
+  bool NotEligibleToImport, Live;
+};
+
+struct AliasSummaryYaml {
+  StringRef Name;
+  GlobalValueSummary::SummaryKind Kind;
+  GlobalValue::LinkageTypes Linkage;
+  bool NotEligibleToImport, Live;
+};
+
 } // End yaml namespace
 } // End llvm namespace
 
@@ -168,11 +220,23 @@
 namespace llvm {
 namespace yaml {
 
+template <> struct MappingTraits<CalleeInfoYaml> {
+  static void mapping(IO &io, CalleeInfoYaml &summary) {
+    io.mapOptional("GUID", summary.GUID);
+    io.addComment(Comment(summary.Name, false));
+    io.mapOptional("Hotness", summary.Hotness);
+  }
+};
+
 template <> struct MappingTraits<FunctionSummaryYaml> {
   static void mapping(IO &io, FunctionSummaryYaml& summary) {
+    io.addComment(Comment(summary.Name));
+    io.mapOptional("Kind", summary.Kind);
     io.mapOptional("Linkage", summary.Linkage);
     io.mapOptional("NotEligibleToImport", summary.NotEligibleToImport);
     io.mapOptional("Live", summary.Live);
+    io.mapOptional("InstCount", summary.InstCount);
+    io.mapOptional("Calls", summary.Calls);
     io.mapOptional("TypeTests", summary.TypeTests);
     io.mapOptional("TypeTestAssumeVCalls", summary.TypeTestAssumeVCalls);
     io.mapOptional("TypeCheckedLoadVCalls", summary.TypeCheckedLoadVCalls);
@@ -183,26 +247,76 @@
   }
 };
 
+template <> struct MappingTraits<GlobalVarSummaryYaml> {
+  static void mapping(IO &io, GlobalVarSummaryYaml &summary) {
+    io.addComment(Comment(summary.Name));
+    io.mapOptional("Kind", summary.Kind);
+    io.mapOptional("Linkage", summary.Linkage);
+    io.mapOptional("NotEligibleToImport", summary.NotEligibleToImport);
+    io.mapOptional("Live", summary.Live);
+  }
+};
+
+template <> struct MappingTraits<AliasSummaryYaml> {
+  static void mapping(IO &io, AliasSummaryYaml &summary) {
+    io.addComment(Comment(summary.Name));
+    io.mapOptional("Kind", summary.Kind);
+    io.mapOptional("Linkage", summary.Linkage);
+    io.mapOptional("NotEligibleToImport", summary.NotEligibleToImport);
+    io.mapOptional("Live", summary.Live);
+  }
+};
+
 } // End yaml namespace
 } // End llvm namespace
 
 LLVM_YAML_IS_STRING_MAP(TypeIdSummary)
 LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummaryYaml)
+LLVM_YAML_IS_SEQUENCE_VECTOR(CalleeInfoYaml)
+LLVM_YAML_IS_SEQUENCE_VECTOR(GlobalVarSummaryYaml)
+LLVM_YAML_IS_SEQUENCE_VECTOR(AliasSummaryYaml)
+LLVM_YAML_IS_SEQUENCE_VECTOR(std::string)
 
 namespace llvm {
 namespace yaml {
 
+template <> struct ScalarEnumerationTraits<GlobalValue::LinkageTypes> {
+  static void enumeration(IO &io, GlobalValue::LinkageTypes &value) {
+    io.enumCase(value, "ExternalLinkage",
+                GlobalValue::LinkageTypes::ExternalLinkage);
+    io.enumCase(value, "AvailableExternallyLinkage",
+                GlobalValue::LinkageTypes::AvailableExternallyLinkage);
+    io.enumCase(value, "LinkOnceAnyLinkage",
+                GlobalValue::LinkageTypes::LinkOnceAnyLinkage);
+    io.enumCase(value, "LinkOnceODRLinkage",
+                GlobalValue::LinkageTypes::LinkOnceODRLinkage);
+    io.enumCase(value, "WeakAnyLinkage",
+                GlobalValue::LinkageTypes::WeakAnyLinkage);
+    io.enumCase(value, "WeakODRLinkage",
+                GlobalValue::LinkageTypes::WeakODRLinkage);
+    io.enumCase(value, "AppendingLinkage",
+                GlobalValue::LinkageTypes::AppendingLinkage);
+    io.enumCase(value, "InternalLinkage",
+                GlobalValue::LinkageTypes::InternalLinkage);
+    io.enumCase(value, "PrivateLinkage",
+                GlobalValue::LinkageTypes::PrivateLinkage);
+    io.enumCase(value, "ExternalWeakLinkage",
+                GlobalValue::LinkageTypes::ExternalWeakLinkage);
+    io.enumCase(value, "CommonLinkage",
+                GlobalValue::LinkageTypes::CommonLinkage);
+  }
+};
+
 // FIXME: Add YAML mappings for the rest of the module summary.
-template <> struct CustomMappingTraits<GlobalValueSummaryMapTy> {
-  static void inputOne(IO &io, StringRef Key, GlobalValueSummaryMapTy &V) {
+template <> struct CustomMappingTraits<NameMapWrapper<GlobalValueSummaryMapTy>> {
+  static void inputOne(IO &io, StringRef Key, NameMapWrapper<GlobalValueSummaryMapTy> &V) {
     std::vector<FunctionSummaryYaml> FSums;
+    std::vector<GlobalVarSummaryYaml> GVSums;
+    std::vector<AliasSummaryYaml> ASums;
     io.mapRequired(Key.str().c_str(), FSums);
-    uint64_t KeyInt;
-    if (Key.getAsInteger(0, KeyInt)) {
-      io.setError("key not an integer");
-      return;
-    }
-    auto &Elem = V[KeyInt];
+    io.mapRequired(Key.str().c_str(), GVSums);
+    io.mapRequired(Key.str().c_str(), ASums);
+    auto &Elem = (*V.Val)[std::stoi(Key)];
     for (auto &FSum : FSums) {
       Elem.SummaryList.push_back(llvm::make_unique<FunctionSummary>(
           GlobalValueSummary::GVFlags(
@@ -214,29 +328,108 @@
           std::move(FSum.TypeTestAssumeConstVCalls),
           std::move(FSum.TypeCheckedLoadConstVCalls)));
     }
+
+    for (auto &GVSum : GVSums) {
+      Elem.SummaryList.push_back(llvm::make_unique<GlobalVarSummary>(
+          GlobalValueSummary::GVFlags(
+              static_cast<GlobalValue::LinkageTypes>(GVSum.Linkage),
+              GVSum.NotEligibleToImport, GVSum.Live),
+          ArrayRef<ValueInfo>{}));
+    }
+
+    for (auto &ASum : ASums) {
+      Elem.SummaryList.push_back(llvm::make_unique<AliasSummary>(
+          GlobalValueSummary::GVFlags(
+              static_cast<GlobalValue::LinkageTypes>(ASum.Linkage),
+              ASum.NotEligibleToImport, ASum.Live),
+          ArrayRef<ValueInfo>{}));
+    }
   }
-  static void output(IO &io, GlobalValueSummaryMapTy &V) {
-    for (auto &P : V) {
+
+  static void output(IO &io, NameMapWrapper<GlobalValueSummaryMapTy> &V) {
+    for (auto &P : *V.Val) {
       std::vector<FunctionSummaryYaml> FSums;
+      std::vector<GlobalVarSummaryYaml> GVSums;
+      std::vector<AliasSummaryYaml> ASums;
       for (auto &Sum : P.second.SummaryList) {
-        if (auto *FSum = dyn_cast<FunctionSummary>(Sum.get()))
+        if (auto *FSum = dyn_cast<FunctionSummary>(Sum.get())) {
+          std::vector<CalleeInfoYaml> Calls;
+          for (auto edge : FSum->calls()) {
+            Calls.push_back(CalleeInfoYaml{
+                (*V.NameMap)[edge.first.getGUID()],
+                edge.first.getGUID(), edge.second.Hotness});
+          }
           FSums.push_back(FunctionSummaryYaml{
-              FSum->flags().Linkage,
+              (*V.NameMap)[P.first],
+              FSum->getSummaryKind(),
+              static_cast<GlobalValue::LinkageTypes>(FSum->flags().Linkage),
               static_cast<bool>(FSum->flags().NotEligibleToImport),
-              static_cast<bool>(FSum->flags().Live), FSum->type_tests(),
+              static_cast<bool>(FSum->flags().Live),
+
+              FSum->instCount(), Calls, FSum->type_tests(),
               FSum->type_test_assume_vcalls(), FSum->type_checked_load_vcalls(),
               FSum->type_test_assume_const_vcalls(),
               FSum->type_checked_load_const_vcalls()});
+        }
+        if (auto *GVSum = dyn_cast<GlobalVarSummary>(Sum.get()))
+          GVSums.push_back(GlobalVarSummaryYaml{
+              (*V.NameMap)[P.first],
+              GVSum->getSummaryKind(),
+              static_cast<GlobalValue::LinkageTypes>(GVSum->flags().Linkage),
+              static_cast<bool>(GVSum->flags().NotEligibleToImport),
+              static_cast<bool>(GVSum->flags().Live)});
+        if (auto *ASum = dyn_cast<AliasSummary>(Sum.get()))
+          ASums.push_back(AliasSummaryYaml{
+              (*V.NameMap)[P.first],
+              ASum->getSummaryKind(),
+              static_cast<GlobalValue::LinkageTypes>(ASum->flags().Linkage),
+              static_cast<bool>(ASum->flags().NotEligibleToImport),
+              static_cast<bool>(ASum->flags().Live)});
       }
       if (!FSums.empty())
-        io.mapRequired(llvm::utostr(P.first).c_str(), FSums);
+        io.mapRequired(utostr(P.first).c_str(), FSums);
+      if (!GVSums.empty())
+        io.mapRequired(utostr(P.first).c_str(), GVSums);
+      if (!ASums.empty())
+        io.mapRequired(utostr(P.first).c_str(), ASums);
+    }
+  }
+};
+
+struct ModuleSummaryIndexWithModule {
+  ModuleSummaryIndex *Index;
+  Module *Mod;
+};
+
+template <> struct CustomMappingTraits<NameMapTy> {
+  static void inputOne(IO &io, StringRef Key, NameMapTy &V) {
+    // do nothing - this map is only used for output
+  }
+
+  static void output(IO &io, NameMapTy &V) {
+    for (auto &P : V) {
+      io.mapRequired(llvm::utostr(P.first).c_str(), P.second);
+    }
+  }
+};
+
+template <> struct MappingTraits<ModuleSummaryIndexWithModule> {
+  static void mapping(IO &io, ModuleSummaryIndexWithModule& M) {
+    NameMapTy NameMap;
+    if(M.Mod) {
+      for(Module::global_object_iterator i = M.Mod->global_object_begin(); i != M.Mod->global_object_end(); i++) {
+        NameMap.insert(std::make_pair(i->getGUID(), i->getName()));
+      }
     }
+    NameMapWrapper<GlobalValueSummaryMapTy> N = {&M.Index->GlobalValueMap, &NameMap};
+    io.mapRequired("ModuleSummaryIndex", N);
   }
 };
 
 template <> struct MappingTraits<ModuleSummaryIndex> {
   static void mapping(IO &io, ModuleSummaryIndex& index) {
-    io.mapOptional("GlobalValueMap", index.GlobalValueMap);
+    NameMapWrapper<GlobalValueSummaryMapTy> M = {&index.GlobalValueMap, nullptr};
+    io.mapOptional("GlobalValueMap", M);
     io.mapOptional("TypeIdMap", index.TypeIdMap);
     io.mapOptional("WithGlobalValueDeadStripping",
                    index.WithGlobalValueDeadStripping);
Index: include/llvm/Support/YAMLTraits.h
===================================================================
--- include/llvm/Support/YAMLTraits.h
+++ include/llvm/Support/YAMLTraits.h
@@ -534,6 +534,14 @@
           bool, has_MappingTraits<T, Context>::value &&
                     !has_MappingValidateTraits<T, Context>::value> {};
 
+struct Comment {
+  StringRef Str;
+  bool NewLine = true;
+
+  Comment(StringRef S) : Str(S) {};
+  Comment(StringRef S, bool N) : Str(S), NewLine(N) {};
+};
+
 // Base class for Input and Output.
 class IO {
 public:
@@ -572,6 +580,8 @@
   virtual bool bitSetMatch(const char*, bool) = 0;
   virtual void endBitSetScalar() = 0;
 
+  virtual void comment(StringRef &S, bool) = 0;
+
   virtual void scalarString(StringRef &, bool) = 0;
   virtual void blockScalarString(StringRef &) = 0;
 
@@ -643,6 +653,12 @@
     this->processKey(Key, Val, true, Ctx);
   }
 
+  void addComment(Comment C) {
+    if(outputting() && !C.Str.empty()) {
+      comment(C.Str, C.NewLine);
+    }
+  }
+
   template <typename T> void mapOptional(const char *Key, T &Val) {
     EmptyContext Ctx;
     mapOptionalWithContext(Key, Val, Ctx);
@@ -1136,6 +1152,7 @@
   bool beginBitSetScalar(bool &) override;
   bool bitSetMatch(const char *, bool ) override;
   void endBitSetScalar() override;
+  void comment(StringRef &S, bool) override;
   void scalarString(StringRef &, bool) override;
   void blockScalarString(StringRef &) override;
   void setError(const Twine &message) override;
@@ -1283,6 +1300,7 @@
   bool beginBitSetScalar(bool &) override;
   bool bitSetMatch(const char *, bool ) override;
   void endBitSetScalar() override;
+  void comment(StringRef &S, bool) override;
   void scalarString(StringRef &, bool) override;
   void blockScalarString(StringRef &) override;
   void setError(const Twine &message) override;
Index: lib/Support/YAMLTraits.cpp
===================================================================
--- lib/Support/YAMLTraits.cpp
+++ lib/Support/YAMLTraits.cpp
@@ -315,6 +315,9 @@
   }
 }
 
+// ignore comments
+void Input::comment(StringRef &S, bool) { }
+
 void Input::scalarString(StringRef &S, bool) {
   if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
     S = SN->value();
@@ -602,6 +605,23 @@
   this->outputUpToEndOfLine(" ]");
 }
 
+void Output::comment(StringRef &S, bool NewLine) {
+  if(NewLine) {
+    this->outputNewLine();
+    unsigned Indent = StateStack.size();
+    for(unsigned i = 0; i < Indent; i++)
+      output(" ");
+  } else
+    this->output(" ");
+
+  if(S.empty()) {
+    this->outputUpToEndOfLine("#");
+  } else {
+    this->output("# ");
+    this->outputUpToEndOfLine(S);
+  }
+}
+
 void Output::scalarString(StringRef &S, bool MustQuote) {
   this->newLineCheck();
   if (S.empty()) {