about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYuki Okushi <huyuumi.dev@gmail.com>2020-02-17 13:46:54 +0900
committerGitHub <noreply@github.com>2020-02-17 13:46:54 +0900
commit50ddda694900e6e073c5d5c5d1bb4298a57d7749 (patch)
tree04c77140dd17b12ceb8d6148fb586ef3032dfd84
parentc3fed9fabd182a9479ada08d21313a9ed942436c (diff)
parent5c473a059e26614b65414cfb8cf75c283cda5a87 (diff)
downloadrust-50ddda694900e6e073c5d5c5d1bb4298a57d7749.tar.gz
rust-50ddda694900e6e073c5d5c5d1bb4298a57d7749.zip
Rollup merge of #69158 - ecstatic-morse:graphviz-diff, r=matthewjasper
Don't print block exit state in dataflow graphviz if unchanged

A small quality-of-life improvement I was using while working on #68528. It's pretty common to have a lot of zero-statement basic blocks, especially before a `SimplifyCfg` pass is run. When the dataflow state was dense, these blocks could take up a lot of vertical space since the full flow state was printed on both entry and exit. After this PR, we only print a block's exit state if it differs from that block's entry state. Take a look at the two basic blocks on the left.

Before:

![image](https://user-images.githubusercontent.com/29463364/74505395-e2d1dd00-4eab-11ea-8006-ec8f0dc9d1b6.png)

After:
![image](https://user-images.githubusercontent.com/29463364/74505277-98506080-4eab-11ea-8d95-5190bc378331.png)
-rw-r--r--src/librustc_mir/dataflow/generic/graphviz.rs55
1 files changed, 35 insertions, 20 deletions
diff --git a/src/librustc_mir/dataflow/generic/graphviz.rs b/src/librustc_mir/dataflow/generic/graphviz.rs
index b805b13592f..157526d3c51 100644
--- a/src/librustc_mir/dataflow/generic/graphviz.rs
+++ b/src/librustc_mir/dataflow/generic/graphviz.rs
@@ -195,6 +195,8 @@ where
         // C: Entry state
         self.bg = Background::Light;
         self.results.seek_to_block_start(block);
+        let block_entry_state = self.results.get().clone();
+
         self.write_row_with_full_state(w, "", "(on entry)")?;
 
         // D: Statement transfer functions
@@ -213,29 +215,42 @@ where
         self.write_row_for_location(w, "T", &terminator_str, terminator_loc)?;
 
         // F: Exit state
+
+        // Write the full dataflow state immediately after the terminator if it differs from the
+        // state at block entry.
         self.results.seek_after(terminator_loc);
-        if let mir::TerminatorKind::Call { destination: Some(_), .. } = &terminator.kind {
-            self.write_row_with_full_state(w, "", "(on unwind)")?;
-
-            let num_state_columns = self.num_state_columns();
-            self.write_row(w, "", "(on successful return)", |this, w, fmt| {
-                write!(
-                    w,
-                    r#"<td balign="left" colspan="{colspan}" {fmt} align="left">"#,
-                    colspan = num_state_columns,
-                    fmt = fmt,
-                )?;
-
-                let state_on_unwind = this.results.get().clone();
-                this.results.seek_after_assume_call_returns(terminator_loc);
-                write_diff(w, this.results.analysis(), &state_on_unwind, this.results.get())?;
-
-                write!(w, "</td>")
-            })?;
-        } else {
-            self.write_row_with_full_state(w, "", "(on exit)")?;
+        if self.results.get() != &block_entry_state {
+            let after_terminator_name = match terminator.kind {
+                mir::TerminatorKind::Call { destination: Some(_), .. } => "(on unwind)",
+                _ => "(on exit)",
+            };
+
+            self.write_row_with_full_state(w, "", after_terminator_name)?;
         }
 
+        // Write any changes caused by terminator-specific effects
+        match terminator.kind {
+            mir::TerminatorKind::Call { destination: Some(_), .. } => {
+                let num_state_columns = self.num_state_columns();
+                self.write_row(w, "", "(on successful return)", |this, w, fmt| {
+                    write!(
+                        w,
+                        r#"<td balign="left" colspan="{colspan}" {fmt} align="left">"#,
+                        colspan = num_state_columns,
+                        fmt = fmt,
+                    )?;
+
+                    let state_on_unwind = this.results.get().clone();
+                    this.results.seek_after_assume_call_returns(terminator_loc);
+                    write_diff(w, this.results.analysis(), &state_on_unwind, this.results.get())?;
+
+                    write!(w, "</td>")
+                })?;
+            }
+
+            _ => {}
+        };
+
         write!(w, "</table>")
     }