Skip to content

Commit a8d4ccf

Browse files
authored
Rollup merge of #69005 - ecstatic-morse:unified-dataflow-graphviz, r=wesleywiser
Small graphviz improvements for the new dataflow framework Split out from #68241. This prints the correct effect diff for each line (the before-effect and the after-effect) and makes marginal improvements to the graphviz output for the new dataflow framework including using monospaced font and better line breaking. This will only be useful when #68241 is merged and the graphviz output changes from this: ![image](https://user-images.githubusercontent.com/29463364/74107776-5e3c3300-4b28-11ea-9d33-4862228b5e87.png) to this: ![image](https://user-images.githubusercontent.com/29463364/74107751-20d7a580-4b28-11ea-99ca-24f749386601.png) r? @wesleywiser
2 parents 64d2d04 + 8d6208c commit a8d4ccf

File tree

3 files changed

+56
-35
lines changed

3 files changed

+56
-35
lines changed

src/libgraphviz/lib.rs

+10
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,8 @@ pub enum RenderOption {
597597
NoNodeLabels,
598598
NoEdgeStyles,
599599
NoNodeStyles,
600+
601+
Monospace,
600602
}
601603

602604
/// Returns vec holding all the default render options.
@@ -626,6 +628,14 @@ where
626628
W: Write,
627629
{
628630
writeln!(w, "digraph {} {{", g.graph_id().as_slice())?;
631+
632+
// Global graph properties
633+
if options.contains(&RenderOption::Monospace) {
634+
writeln!(w, r#" graph[fontname="monospace"];"#)?;
635+
writeln!(w, r#" node[fontname="monospace"];"#)?;
636+
writeln!(w, r#" edge[fontname="monospace"];"#)?;
637+
}
638+
629639
for n in g.nodes().iter() {
630640
write!(w, " ")?;
631641
let id = g.node_id(n);

src/librustc_mir/dataflow/generic/engine.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ where
331331
let mut buf = Vec::new();
332332

333333
let graphviz = graphviz::Formatter::new(body, def_id, results, &mut *formatter);
334-
dot::render(&graphviz, &mut buf)?;
334+
dot::render_opts(&graphviz, &mut buf, &[dot::RenderOption::Monospace])?;
335335
fs::write(&path, buf)?;
336336
Ok(())
337337
}

src/librustc_mir/dataflow/generic/graphviz.rs

+45-34
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,19 @@ where
171171
// | | (on successful return) | +_4 |
172172
// +-+----------------------------------+------------+
173173

174-
write!(
175-
w,
176-
r#"<table border="1" cellborder="1" cellspacing="0" cellpadding="3" sides="rb">"#,
177-
)?;
174+
// N.B., Some attributes (`align`, `balign`) are repeated on parent elements and their
175+
// children. This is because `xdot` seemed to have a hard time correctly propagating
176+
// attributes. Make sure to test the output before trying to remove the redundancy.
177+
// Notably, `align` was found to have no effect when applied only to <table>.
178+
179+
let table_fmt = concat!(
180+
" border=\"1\"",
181+
" cellborder=\"1\"",
182+
" cellspacing=\"0\"",
183+
" cellpadding=\"3\"",
184+
" sides=\"rb\"",
185+
);
186+
write!(w, r#"<table{fmt}>"#, fmt = table_fmt)?;
178187

179188
// A + B: Block header
180189
if self.state_formatter.column_names().is_empty() {
@@ -186,7 +195,7 @@ where
186195
// C: Entry state
187196
self.bg = Background::Light;
188197
self.results.seek_to_block_start(block);
189-
self.write_row_with_full_state(w, "", "(on_entry)")?;
198+
self.write_row_with_full_state(w, "", "(on entry)")?;
190199

191200
// D: Statement transfer functions
192201
for (i, statement) in body[block].statements.iter().enumerate() {
@@ -212,7 +221,7 @@ where
212221
self.write_row(w, "", "(on successful return)", |this, w, fmt| {
213222
write!(
214223
w,
215-
r#"<td colspan="{colspan}" {fmt} align="left">"#,
224+
r#"<td balign="left" colspan="{colspan}" {fmt} align="left">"#,
216225
colspan = num_state_columns,
217226
fmt = fmt,
218227
)?;
@@ -311,7 +320,9 @@ where
311320
f: impl FnOnce(&mut Self, &mut W, &str) -> io::Result<()>,
312321
) -> io::Result<()> {
313322
let bg = self.toggle_background();
314-
let fmt = format!("sides=\"tl\" {}", bg.attr());
323+
let valign = if mir.starts_with("(on ") && mir != "(on entry)" { "bottom" } else { "top" };
324+
325+
let fmt = format!("valign=\"{}\" sides=\"tl\" {}", valign, bg.attr());
315326

316327
write!(
317328
w,
@@ -345,7 +356,7 @@ where
345356
colspan = this.num_state_columns(),
346357
fmt = fmt,
347358
)?;
348-
pretty_print_state_elems(w, analysis, state.iter(), ",", LIMIT_40_ALIGN_1)?;
359+
pretty_print_state_elems(w, analysis, state.iter(), ", ", LIMIT_30_ALIGN_1)?;
349360
write!(w, "}}</td>")
350361
})
351362
}
@@ -387,7 +398,6 @@ pub struct SimpleDiff<T: Idx> {
387398
}
388399

389400
impl<T: Idx> SimpleDiff<T> {
390-
#![allow(unused)]
391401
pub fn new(bits_per_block: usize) -> Self {
392402
SimpleDiff { prev_state: BitSet::new_empty(bits_per_block), prev_loc: Location::START }
393403
}
@@ -417,8 +427,8 @@ where
417427
}
418428

419429
self.prev_loc = location;
420-
write!(w, r#"<td {fmt} align="left">"#, fmt = fmt)?;
421-
results.seek_before(location);
430+
write!(w, r#"<td {fmt} balign="left" align="left">"#, fmt = fmt)?;
431+
results.seek_after(location);
422432
let curr_state = results.get();
423433
write_diff(&mut w, results.analysis(), &self.prev_state, curr_state)?;
424434
self.prev_state.overwrite(curr_state);
@@ -434,7 +444,6 @@ pub struct TwoPhaseDiff<T: Idx> {
434444
}
435445

436446
impl<T: Idx> TwoPhaseDiff<T> {
437-
#![allow(unused)]
438447
pub fn new(bits_per_block: usize) -> Self {
439448
TwoPhaseDiff { prev_state: BitSet::new_empty(bits_per_block), prev_loc: Location::START }
440449
}
@@ -445,7 +454,7 @@ where
445454
A: Analysis<'tcx>,
446455
{
447456
fn column_names(&self) -> &[&str] {
448-
&["ENTRY", " EXIT"]
457+
&["BEFORE", " AFTER"]
449458
}
450459

451460
fn write_state_for_location(
@@ -465,7 +474,7 @@ where
465474

466475
self.prev_loc = location;
467476

468-
// Entry
477+
// Before
469478

470479
write!(w, r#"<td {fmt} align="left">"#, fmt = fmt)?;
471480
results.seek_before(location);
@@ -474,7 +483,7 @@ where
474483
self.prev_state.overwrite(curr_state);
475484
write!(w, "</td>")?;
476485

477-
// Exit
486+
// After
478487

479488
write!(w, r#"<td {fmt} align="left">"#, fmt = fmt)?;
480489
results.seek_after(location);
@@ -492,7 +501,6 @@ pub struct BlockTransferFunc<'a, 'tcx, T: Idx> {
492501
}
493502

494503
impl<T: Idx> BlockTransferFunc<'mir, 'tcx, T> {
495-
#![allow(unused)]
496504
pub fn new(
497505
body: &'mir mir::Body<'tcx>,
498506
trans_for_block: IndexVec<BasicBlock, GenKillSet<T>>,
@@ -527,12 +535,12 @@ where
527535
for set in &[&block_trans.gen, &block_trans.kill] {
528536
write!(
529537
w,
530-
r#"<td {fmt} rowspan="{rowspan}" align="center">"#,
538+
r#"<td {fmt} rowspan="{rowspan}" balign="left" align="left">"#,
531539
fmt = fmt,
532540
rowspan = rowspan
533541
)?;
534542

535-
pretty_print_state_elems(&mut w, results.analysis(), set.iter(), "\n", None)?;
543+
pretty_print_state_elems(&mut w, results.analysis(), set.iter(), BR_LEFT, None)?;
536544
write!(w, "</td>")?;
537545
}
538546

@@ -564,25 +572,28 @@ fn write_diff<A: Analysis<'tcx>>(
564572

565573
if !set.is_empty() {
566574
write!(w, r#"<font color="darkgreen">+"#)?;
567-
pretty_print_state_elems(w, analysis, set.iter(), ",", LIMIT_40_ALIGN_1)?;
575+
pretty_print_state_elems(w, analysis, set.iter(), ", ", LIMIT_30_ALIGN_1)?;
568576
write!(w, r#"</font>"#)?;
569577
}
570578

571579
if !set.is_empty() && !clear.is_empty() {
572-
write!(w, "<br/>")?;
580+
write!(w, "{}", BR_LEFT)?;
573581
}
574582

575583
if !clear.is_empty() {
576584
write!(w, r#"<font color="red">-"#)?;
577-
pretty_print_state_elems(w, analysis, clear.iter(), ",", LIMIT_40_ALIGN_1)?;
585+
pretty_print_state_elems(w, analysis, clear.iter(), ", ", LIMIT_30_ALIGN_1)?;
578586
write!(w, r#"</font>"#)?;
579587
}
580588

581589
Ok(())
582590
}
583591

592+
const BR_LEFT: &'static str = r#"<br align="left"/>"#;
593+
const BR_LEFT_SPACE: &'static str = r#"<br align="left"/> "#;
594+
584595
/// Line break policy that breaks at 40 characters and starts the next line with a single space.
585-
const LIMIT_40_ALIGN_1: Option<LineBreak> = Some(LineBreak { sequence: "<br/> ", limit: 40 });
596+
const LIMIT_30_ALIGN_1: Option<LineBreak> = Some(LineBreak { sequence: BR_LEFT_SPACE, limit: 30 });
586597

587598
struct LineBreak {
588599
sequence: &'static str,
@@ -613,25 +624,25 @@ where
613624
let mut line_break_inserted = false;
614625

615626
for idx in elems {
616-
if first {
617-
first = false;
618-
} else {
619-
write!(w, "{}", sep)?;
620-
curr_line_width += sep_width;
621-
}
622-
623627
buf.clear();
624628
analysis.pretty_print_idx(&mut buf, idx)?;
625629
let idx_str =
626630
str::from_utf8(&buf).expect("Output of `pretty_print_idx` must be valid UTF-8");
627631
let escaped = dot::escape_html(idx_str);
628632
let escaped_width = escaped.chars().count();
629633

630-
if let Some(line_break) = &line_break {
631-
if curr_line_width + sep_width + escaped_width > line_break.limit {
632-
write!(w, "{}", line_break.sequence)?;
633-
line_break_inserted = true;
634-
curr_line_width = 0;
634+
if first {
635+
first = false;
636+
} else {
637+
write!(w, "{}", sep)?;
638+
curr_line_width += sep_width;
639+
640+
if let Some(line_break) = &line_break {
641+
if curr_line_width + sep_width + escaped_width > line_break.limit {
642+
write!(w, "{}", line_break.sequence)?;
643+
line_break_inserted = true;
644+
curr_line_width = 0;
645+
}
635646
}
636647
}
637648

0 commit comments

Comments
 (0)