Skip to content

Commit

Permalink
[ThinLTO] Use defined node and edge order when dumping DOT file
Browse files Browse the repository at this point in the history
Differential revision: https://reviews.llvm.org/D58631

llvm-svn: 354850
  • Loading branch information
eleviant committed Feb 26, 2019
1 parent c6d54ae commit 24b3d25
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 73 deletions.
12 changes: 10 additions & 2 deletions llvm/include/llvm/IR/ModuleSummaryIndex.h
Expand Up @@ -1169,8 +1169,16 @@ class ModuleSummaryIndex {

/// Collect for each module the list of Summaries it defines (GUID ->
/// Summary).
void collectDefinedGVSummariesPerModule(
StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries) const;
template <class Map>
void
collectDefinedGVSummariesPerModule(Map &ModuleToDefinedGVSummaries) const {
for (auto &GlobalList : *this) {
auto GUID = GlobalList.first;
for (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;
Expand Down
20 changes: 5 additions & 15 deletions llvm/lib/IR/ModuleSummaryIndex.cpp
Expand Up @@ -65,17 +65,6 @@ void ModuleSummaryIndex::collectDefinedFunctionsForModule(
}
}

// Collect for each module the list of function it defines (GUID -> Summary).
void ModuleSummaryIndex::collectDefinedGVSummariesPerModule(
StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries) const {
for (auto &GlobalList : *this) {
auto GUID = GlobalList.first;
for (auto &Summary : GlobalList.second.SummaryList) {
ModuleToDefinedGVSummaries[Summary->modulePath()][GUID] = Summary.get();
}
}
}

GlobalValueSummary *
ModuleSummaryIndex::getGlobalValueSummary(uint64_t ValueGUID,
bool PerModuleIndex) const {
Expand Down Expand Up @@ -341,7 +330,8 @@ static bool hasReadOnlyFlag(const GlobalValueSummary *S) {
void ModuleSummaryIndex::exportToDot(raw_ostream &OS) const {
std::vector<Edge> CrossModuleEdges;
DenseMap<GlobalValue::GUID, std::vector<uint64_t>> NodeMap;
StringMap<GVSummaryMapTy> ModuleToDefinedGVS;
using GVSOrderedMapTy = std::map<GlobalValue::GUID, GlobalValueSummary *>;
std::map<StringRef, GVSOrderedMapTy> ModuleToDefinedGVS;
collectDefinedGVSummariesPerModule(ModuleToDefinedGVS);

// Get node identifier in form MXXX_<GUID>. The MXXX prefix is required,
Expand Down Expand Up @@ -378,12 +368,12 @@ void ModuleSummaryIndex::exportToDot(raw_ostream &OS) const {

OS << "digraph Summary {\n";
for (auto &ModIt : ModuleToDefinedGVS) {
auto ModId = getModuleId(ModIt.first());
OS << " // Module: " << ModIt.first() << "\n";
auto ModId = getModuleId(ModIt.first);
OS << " // Module: " << ModIt.first << "\n";
OS << " subgraph cluster_" << std::to_string(ModId) << " {\n";
OS << " style = filled;\n";
OS << " color = lightgrey;\n";
OS << " label = \"" << sys::path::filename(ModIt.first()) << "\";\n";
OS << " label = \"" << sys::path::filename(ModIt.first) << "\";\n";
OS << " node [style=filled,fillcolor=lightblue];\n";

auto &GVSMap = ModIt.second;
Expand Down
107 changes: 51 additions & 56 deletions llvm/test/ThinLTO/X86/dot-dumper.ll
Expand Up @@ -10,64 +10,59 @@
; RUN: -r=%t2.bc,A,p \
; RUN: -r=%t2.bc,B,p

; Never assume specific order of clusters, nodes or edges
; RUN: cat %t1.dot | FileCheck --check-prefix=STRUCTURE1 %s
; RUN: cat %t1.dot | FileCheck --check-prefix=CLUSTER0 --check-prefix=PERMODULE0 %s
; RUN: cat %t2.dot | FileCheck --check-prefix=STRUCTURE2 %s
; RUN: cat %t2.dot | FileCheck --check-prefix=CLUSTER1 --check-prefix=PERMODULE1 %s
; RUN: cat %t3.index.dot | FileCheck --check-prefix=STRUCTURE %s
; RUN: cat %t3.index.dot | FileCheck --check-prefix=CLUSTER0 --check-prefix=COMBINED0 %s
; RUN: cat %t3.index.dot | FileCheck --check-prefix=CLUSTER1 --check-prefix=COMBINED1 %s
; RUN: cat %t1.dot | FileCheck --check-prefix=PERMODULE %s
; RUN: cat %t3.index.dot | FileCheck --check-prefix=COMBINED %s

; %t1 index
; STRUCTURE1: digraph Summary {
; STRUCTURE1: subgraph cluster_0
; STRUCTURE1: // Cross-module edges:
; STRUCTURE1: 0 [label="@0"]; // defined externally
; STRUCTURE1: M0_{{[0-9]+}} -> 0 [style=dotted]; // alias
; STRUCTURE1-DAG: [[A:[0-9]+]] [label="A"]; // defined externally
; STRUCTURE1-DAG: [[FOO:[0-9]+]] [label="foo"]; // defined externally
; STRUCTURE1-DAG: M0_{{[0-9]+}} -> [[FOO]] // call
; STRUCTURE1-DAG: M0_{{[0-9]+}} -> [[A]] [{{.*}}]; // const-ref
; STRUCTURE1-NEXT: }
; PERMODULE: digraph Summary {
; PERMODULE-NEXT: // Module:
; PERMODULE-NEXT: subgraph cluster_0 {
; PERMODULE-NEXT: style = filled;
; PERMODULE-NEXT: color = lightgrey;
; PERMODULE-NEXT: label = "";
; PERMODULE-NEXT: node [style=filled,fillcolor=lightblue];
; PERMODULE-NEXT: M0_[[MAIN_ALIAS:[0-9]+]] [style="dotted,filled",shape="box",label="main_alias",fillcolor="red"]; // alias, dead
; PERMODULE-NEXT: M0_[[MAIN:[0-9]+]] [shape="record",label="main|extern (inst: 4, ffl: 00000)}",fillcolor="red"]; // function, dead
; PERMODULE-NEXT: // Edges:
; PERMODULE-NEXT: }
; PERMODULE-NEXT: // Cross-module edges:
; PERMODULE-NEXT: 0 [label="@0"]; // defined externally
; PERMODULE-NEXT: M0_[[MAIN_ALIAS]] -> 0 [style=dotted]; // alias
; PERMODULE-NEXT: [[A:[0-9]+]] [label="A"]; // defined externally
; PERMODULE-NEXT: M0_[[MAIN]] -> [[A]] [style=dashed,color=forestgreen]; // const-ref
; PERMODULE-NEXT: [[FOO:[0-9]+]] [label="foo"]; // defined externally
; PERMODULE-NEXT: M0_[[MAIN]] -> [[FOO]] // call (hotness : Unknown)
; PERMODULE-NEXT: }

; %t2 index
; STRUCTURE2: digraph Summary {
; STRUCTURE2: subgraph cluster_0
; STRUCTURE2: // Cross-module edges:
; STRUCTURE2-NEXT: }

; Combined index
; STRUCTURE: digraph Summary {
; STRUCTURE-DAG: subgraph cluster_0
; STRUCTURE-DAG: subgraph cluster_1
; STRUCTURE: // Cross-module edges:
; STRUCTURE-DAG: M0_{{[0-9]+}} -> M1_{{[0-9]+}} // call
; STRUCTURE-DAG: M0_{{[0-9]+}} -> M1_{{[0-9]+}} [{{.*}}]; // const-ref
; STRUCTURE-NEXT: }

; PERMODULE0: // Module:
; COMBINED0: // Module: {{.*}}1.bc
; CLUSTER0-NEXT: subgraph cluster_[[ID0:[0-1]]] {
; CLUSTER0-DAG: M[[ID0]]_[[MAIN_ALIAS:[0-9]+]] [{{.*}}main_alias{{.*}}]; // alias, dead
; CLUSTER0-DAG: M[[ID0]]_[[MAIN:[0-9]+]] [{{.*}}main|extern{{.*}}]; // function
; CLUSTER0-NEXT: // Edges:
; COMBINED0-NEXT: M[[ID0]]_[[MAIN_ALIAS]] -> M[[ID0]]_[[MAIN]] [{{.*}}]; // alias
; CLUSTER0-NEXT: }

; PERMODULE1: // Module:
; COMBINED1: // Module: {{.*}}2.bc
; CLUSTER1-NEXT: subgraph cluster_[[ID1:[0-1]]] {
; CLUSTER1-DAG: M[[ID1]]_[[A:[0-9]+]] [{{.*}}A|extern{{.*}}]; // variable
; COMBINED1-SAME: , immutable
; CLUSTER1-DAG: M[[ID1]]_[[FOO:[0-9]+]] [{{.*}}foo|extern{{.*}} ffl: 00001{{.*}}]; // function
; CLUSTER1-DAG: M[[ID1]]_[[B:[0-9]+]] [{{.*}}B|extern{{.*}}]; // variable
; COMBINED1-SAME: , immutable
; CLUSTER1-DAG: M[[ID1]]_[[BAR:[0-9]+]] [{{.*}}bar|extern{{.*}}]; // function, dead
; CLUSTER1-NEXT: // Edges:
; CLUSTER1-DAG: M[[ID1]]_[[FOO]] -> M[[ID1]]_[[B]] [{{.*}}]; // const-ref
; CLUSTER1-DAG: M[[ID1]]_[[FOO]] -> M[[ID1]]_[[A]] [{{.*}}]; // const-ref
; CLUSTER1-DAG: }
; COMBINED: digraph Summary {
; COMBINED-NEXT: // Module: {{.*}}dot-dumper{{.*}}1.bc
; COMBINED-NEXT: subgraph cluster_0 {
; COMBINED-NEXT: style = filled;
; COMBINED-NEXT: color = lightgrey;
; COMBINED-NEXT: label = "dot-dumper{{.*}}1.bc";
; COMBINED-NEXT: node [style=filled,fillcolor=lightblue];
; COMBINED-NEXT: M0_[[MAIN_ALIAS:[0-9]+]] [style="dotted,filled",shape="box",label="main_alias",fillcolor="red"]; // alias, dead
; COMBINED-NEXT: M0_[[MAIN:[0-9]+]] [shape="record",label="main|extern (inst: 4, ffl: 00000)}"]; // function
; COMBINED-NEXT: // Edges:
; COMBINED-NEXT: M0_[[MAIN_ALIAS]] -> M0_[[MAIN]] [style=dotted]; // alias
; COMBINED-NEXT: }
; COMBINED-NEXT: // Module: {{.*}}dot-dumper{{.*}}2.bc
; COMBINED-NEXT: subgraph cluster_1 {
; COMBINED-NEXT: style = filled;
; COMBINED-NEXT: color = lightgrey;
; COMBINED-NEXT: label = "dot-dumper{{.*}}2.bc";
; COMBINED-NEXT: node [style=filled,fillcolor=lightblue];
; COMBINED-NEXT: M1_[[FOO:[0-9]+]] [shape="record",label="foo|extern (inst: 4, ffl: 00001)}"]; // function
; COMBINED-NEXT: M1_[[A:[0-9]+]] [shape="Mrecord",label="A|extern}"]; // variable, immutable
; COMBINED-NEXT: M1_[[B:[0-9]+]] [shape="Mrecord",label="B|extern}"]; // variable, immutable
; COMBINED-NEXT: M1_{{[0-9]+}} [shape="record",label="bar|extern (inst: 1, ffl: 00000)}",fillcolor="red"]; // function, dead
; COMBINED-NEXT: // Edges:
; COMBINED-NEXT: M1_[[FOO]] -> M1_[[B]] [style=dashed,color=forestgreen]; // const-ref
; COMBINED-NEXT: M1_[[FOO]] -> M1_[[A]] [style=dashed,color=forestgreen]; // const-ref
; COMBINED-NEXT: }
; COMBINED-NEXT: // Cross-module edges:
; COMBINED-NEXT: M0_[[MAIN]] -> M1_[[A]] [style=dashed,color=forestgreen]; // const-ref
; COMBINED-NEXT: M0_[[MAIN]] -> M1_[[FOO]] // call (hotness : Unknown)
; COMBINED-NEXT: }

target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
Expand Down

0 comments on commit 24b3d25

Please sign in to comment.