Index: lib/IR/ModuleSummaryIndex.cpp =================================================================== --- lib/IR/ModuleSummaryIndex.cpp +++ lib/IR/ModuleSummaryIndex.cpp @@ -198,9 +198,12 @@ ", ffl: " + fflagsToString(FS->fflags()); } +static std::string getNodeVisualName(GlobalValue::GUID Id) { + return std::string("@") + std::to_string(Id); +} + static std::string getNodeVisualName(const ValueInfo &VI) { - return VI.name().empty() ? std::string("@") + std::to_string(VI.getGUID()) - : VI.name().str(); + return VI.name().empty() ? getNodeVisualName(VI.getGUID()) : VI.name().str(); } static std::string getNodeLabel(const ValueInfo &VI, GlobalValueSummary *GVS) { @@ -221,13 +224,19 @@ // specific module associated with it. Typically this is function // or variable defined in native object or library. static void defineExternalNode(raw_ostream &OS, const char *Pfx, - const ValueInfo &VI) { - auto StrId = std::to_string(VI.getGUID()); - OS << " " << StrId << " [label=\"" << getNodeVisualName(VI) - << "\"]; // defined externally\n"; + const ValueInfo &VI, GlobalValue::GUID Id) { + auto StrId = std::to_string(Id); + OS << " " << StrId << " [label=\""; + + if (VI) { + OS << getNodeVisualName(VI); + } else { + OS << getNodeVisualName(Id); + } + OS << "\"]; // defined externally\n"; } -void ModuleSummaryIndex::exportToDot(raw_ostream& OS) const { +void ModuleSummaryIndex::exportToDot(raw_ostream &OS) const { std::vector CrossModuleEdges; DenseMap> NodeMap; StringMap ModuleToDefinedGVS; @@ -330,7 +339,7 @@ for (auto &E : CrossModuleEdges) { auto &ModList = NodeMap[E.Dst]; if (ModList.empty()) { - defineExternalNode(OS, " ", getValueInfo(E.Dst)); + defineExternalNode(OS, " ", getValueInfo(E.Dst), E.Dst); // Add fake module to the list to draw an edge to an external node // in the loop below. ModList.push_back(-1);