1
+ use gsgdt:: GraphvizSettings ;
1
2
use rustc_graphviz as dot;
2
3
use rustc_hir:: def_id:: DefId ;
3
- use rustc_index:: vec:: Idx ;
4
4
use rustc_middle:: mir:: * ;
5
5
use rustc_middle:: ty:: TyCtxt ;
6
6
use std:: fmt:: Debug ;
7
7
use std:: io:: { self , Write } ;
8
8
9
+ use super :: generic_graph:: mir_fn_to_generic_graph;
9
10
use super :: pretty:: dump_mir_def_ids;
10
11
11
12
/// Write a graphviz DOT graph of a list of MIRs.
32
33
Ok ( ( ) )
33
34
}
34
35
35
- // Must match `[0-9A-Za-z_]*`. This does not appear in the rendered graph, so
36
- // it does not have to be user friendly.
37
- pub fn graphviz_safe_def_name ( def_id : DefId ) -> String {
38
- format ! ( "{}_{}" , def_id. krate. index( ) , def_id. index. index( ) , )
39
- }
40
-
41
36
/// Write a graphviz DOT graph of the MIR.
42
37
pub fn write_mir_fn_graphviz < ' tcx , W > (
43
38
tcx : TyCtxt < ' tcx > ,
@@ -48,12 +43,6 @@ pub fn write_mir_fn_graphviz<'tcx, W>(
48
43
where
49
44
W : Write ,
50
45
{
51
- let def_id = body. source . def_id ( ) ;
52
- let kind = if subgraph { "subgraph" } else { "digraph" } ;
53
- let cluster = if subgraph { "cluster_" } else { "" } ; // Prints a border around MIR
54
- let def_name = graphviz_safe_def_name ( def_id) ;
55
- writeln ! ( w, "{} {}Mir_{} {{" , kind, cluster, def_name) ?;
56
-
57
46
// Global graph properties
58
47
let font = format ! ( r#"fontname="{}""# , tcx. sess. opts. debugging_opts. graphviz_font) ;
59
48
let mut graph_attrs = vec ! [ & font[ ..] ] ;
@@ -67,131 +56,31 @@ where
67
56
content_attrs. push ( r#"fontcolor="white""# ) ;
68
57
}
69
58
70
- writeln ! ( w, r#" graph [{}];"# , graph_attrs. join( " " ) ) ?;
71
- let content_attrs_str = content_attrs. join ( " " ) ;
72
- writeln ! ( w, r#" node [{}];"# , content_attrs_str) ?;
73
- writeln ! ( w, r#" edge [{}];"# , content_attrs_str) ?;
74
-
75
59
// Graph label
76
- write_graph_label ( tcx, body, w) ?;
77
-
78
- // Nodes
79
- for ( block, _) in body. basic_blocks ( ) . iter_enumerated ( ) {
80
- write_node ( block, body, dark_mode, w) ?;
81
- }
82
-
83
- // Edges
84
- for ( source, _) in body. basic_blocks ( ) . iter_enumerated ( ) {
85
- write_edges ( source, body, w) ?;
86
- }
87
- writeln ! ( w, "}}" )
88
- }
89
-
90
- /// Write a graphviz HTML-styled label for the given basic block, with
91
- /// all necessary escaping already performed. (This is suitable for
92
- /// emitting directly, as is done in this module, or for use with the
93
- /// LabelText::HtmlStr from librustc_graphviz.)
94
- ///
95
- /// `init` and `fini` are callbacks for emitting additional rows of
96
- /// data (using HTML enclosed with `<tr>` in the emitted text).
97
- pub fn write_node_label < W : Write , INIT , FINI > (
98
- block : BasicBlock ,
99
- body : & Body < ' _ > ,
100
- dark_mode : bool ,
101
- w : & mut W ,
102
- num_cols : u32 ,
103
- init : INIT ,
104
- fini : FINI ,
105
- ) -> io:: Result < ( ) >
106
- where
107
- INIT : Fn ( & mut W ) -> io:: Result < ( ) > ,
108
- FINI : Fn ( & mut W ) -> io:: Result < ( ) > ,
109
- {
110
- let data = & body[ block] ;
111
-
112
- write ! ( w, r#"<table border="0" cellborder="1" cellspacing="0">"# ) ?;
113
-
114
- // Basic block number at the top.
115
- let ( blk, bgcolor) = if data. is_cleanup {
116
- let color = if dark_mode { "royalblue" } else { "lightblue" } ;
117
- ( format ! ( "{} (cleanup)" , block. index( ) ) , color)
118
- } else {
119
- let color = if dark_mode { "dimgray" } else { "gray" } ;
120
- ( format ! ( "{}" , block. index( ) ) , color)
60
+ let mut label = String :: from ( "" ) ;
61
+ // FIXME: remove this unwrap
62
+ write_graph_label ( tcx, body, & mut label) . unwrap ( ) ;
63
+ let g = mir_fn_to_generic_graph ( tcx, body) ;
64
+ let settings = GraphvizSettings {
65
+ graph_attrs : Some ( graph_attrs. join ( " " ) ) ,
66
+ node_attrs : Some ( content_attrs. join ( " " ) ) ,
67
+ edge_attrs : Some ( content_attrs. join ( " " ) ) ,
68
+ graph_label : Some ( label) ,
121
69
} ;
122
- write ! (
123
- w,
124
- r#"<tr><td bgcolor="{bgcolor}" {attrs} colspan="{colspan}">{blk}</td></tr>"# ,
125
- attrs = r#"align="center""# ,
126
- colspan = num_cols,
127
- blk = blk,
128
- bgcolor = bgcolor
129
- ) ?;
130
-
131
- init ( w) ?;
132
-
133
- // List of statements in the middle.
134
- if !data. statements . is_empty ( ) {
135
- write ! ( w, r#"<tr><td align="left" balign="left">"# ) ?;
136
- for statement in & data. statements {
137
- write ! ( w, "{}<br/>" , escape( statement) ) ?;
138
- }
139
- write ! ( w, "</td></tr>" ) ?;
140
- }
141
-
142
- // Terminator head at the bottom, not including the list of successor blocks. Those will be
143
- // displayed as labels on the edges between blocks.
144
- let mut terminator_head = String :: new ( ) ;
145
- data. terminator ( ) . kind . fmt_head ( & mut terminator_head) . unwrap ( ) ;
146
- write ! ( w, r#"<tr><td align="left">{}</td></tr>"# , dot:: escape_html( & terminator_head) ) ?;
147
-
148
- fini ( w) ?;
149
-
150
- // Close the table
151
- write ! ( w, "</table>" )
152
- }
153
-
154
- /// Write a graphviz DOT node for the given basic block.
155
- fn write_node < W : Write > (
156
- block : BasicBlock ,
157
- body : & Body < ' _ > ,
158
- dark_mode : bool ,
159
- w : & mut W ,
160
- ) -> io:: Result < ( ) > {
161
- let def_id = body. source . def_id ( ) ;
162
- // Start a new node with the label to follow, in one of DOT's pseudo-HTML tables.
163
- write ! ( w, r#" {} [shape="none", label=<"# , node( def_id, block) ) ?;
164
- write_node_label ( block, body, dark_mode, w, 1 , |_| Ok ( ( ) ) , |_| Ok ( ( ) ) ) ?;
165
- // Close the node label and the node itself.
166
- writeln ! ( w, ">];" )
167
- }
168
-
169
- /// Write graphviz DOT edges with labels between the given basic block and all of its successors.
170
- fn write_edges < W : Write > ( source : BasicBlock , body : & Body < ' _ > , w : & mut W ) -> io:: Result < ( ) > {
171
- let def_id = body. source . def_id ( ) ;
172
- let terminator = body[ source] . terminator ( ) ;
173
- let labels = terminator. kind . fmt_successor_labels ( ) ;
174
-
175
- for ( & target, label) in terminator. successors ( ) . zip ( labels) {
176
- let src = node ( def_id, source) ;
177
- let trg = node ( def_id, target) ;
178
- writeln ! ( w, r#" {} -> {} [label="{}"];"# , src, trg, label) ?;
179
- }
180
-
181
- Ok ( ( ) )
70
+ g. to_dot ( w, & settings, subgraph)
182
71
}
183
72
184
73
/// Write the graphviz DOT label for the overall graph. This is essentially a block of text that
185
74
/// will appear below the graph, showing the type of the `fn` this MIR represents and the types of
186
75
/// all the variables and temporaries.
187
- fn write_graph_label < ' tcx , W : Write > (
76
+ fn write_graph_label < ' tcx , W : std :: fmt :: Write > (
188
77
tcx : TyCtxt < ' tcx > ,
189
78
body : & Body < ' _ > ,
190
79
w : & mut W ,
191
- ) -> io :: Result < ( ) > {
80
+ ) -> std :: fmt :: Result {
192
81
let def_id = body. source . def_id ( ) ;
193
82
194
- write ! ( w, " label=< fn {}(" , dot:: escape_html( & tcx. def_path_str( def_id) ) ) ?;
83
+ write ! ( w, "fn {}(" , dot:: escape_html( & tcx. def_path_str( def_id) ) ) ?;
195
84
196
85
// fn argument types.
197
86
for ( i, arg) in body. args_iter ( ) . enumerate ( ) {
@@ -224,11 +113,7 @@ fn write_graph_label<'tcx, W: Write>(
224
113
) ?;
225
114
}
226
115
227
- writeln ! ( w, ">;" )
228
- }
229
-
230
- fn node ( def_id : DefId , block : BasicBlock ) -> String {
231
- format ! ( "bb{}__{}" , block. index( ) , graphviz_safe_def_name( def_id) )
116
+ Ok ( ( ) )
232
117
}
233
118
234
119
fn escape < T : Debug > ( t : & T ) -> String {
0 commit comments