about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJonas Schievink <jonasschievink@gmail.com>2020-06-23 01:25:52 +0200
committerJonas Schievink <jonasschievink@gmail.com>2020-09-18 21:23:01 +0200
commit934634eacc2721e482672a99f91ed458580eb978 (patch)
tree0f2504cfd1ae54e339dc116b49902714d020adeb
parent88538adf9ae1886d9b5c1f45d55b2f76bd6435bd (diff)
downloadrust-934634eacc2721e482672a99f91ed458580eb978.tar.gz
rust-934634eacc2721e482672a99f91ed458580eb978.zip
More logging
-rw-r--r--compiler/rustc_mir/src/transform/dest_prop.rs80
1 files changed, 59 insertions, 21 deletions
diff --git a/compiler/rustc_mir/src/transform/dest_prop.rs b/compiler/rustc_mir/src/transform/dest_prop.rs
index 20f8f820176..d8f62e35062 100644
--- a/compiler/rustc_mir/src/transform/dest_prop.rs
+++ b/compiler/rustc_mir/src/transform/dest_prop.rs
@@ -95,12 +95,13 @@
 //! [previous attempt]: https://github.com/rust-lang/rust/pull/47954
 //! [subsequent approach]: https://github.com/rust-lang/rust/pull/71003
 
-use crate::dataflow::{self, Analysis};
+use crate::dataflow::impls::{MaybeInitializedLocals, MaybeLiveLocals};
+use crate::dataflow::Analysis;
 use crate::{
     transform::{MirPass, MirSource},
     util::{dump_mir, PassWhere},
 };
-use dataflow::impls::{MaybeInitializedLocals, MaybeLiveLocals};
+use itertools::Itertools;
 use rustc_data_structures::unify::{InPlaceUnificationTable, UnifyKey};
 use rustc_index::{
     bit_set::{BitMatrix, BitSet},
@@ -255,12 +256,14 @@ impl Replacements<'tcx> {
 
             // We still return `Err` in any case, as `src` and `dest` do not need to be unified
             // *again*.
+            trace!("push({:?}): already unified", candidate);
             return Err(());
         }
 
         let entry = &mut self.map[candidate.src];
         if entry.is_some() {
             // We're already replacing `src` with something else, so this candidate is out.
+            trace!("push({:?}): src already has replacement", candidate);
             return Err(());
         }
 
@@ -270,6 +273,7 @@ impl Replacements<'tcx> {
         self.kill.insert(candidate.src);
         self.kill.insert(candidate.dest.local);
 
+        trace!("push({:?}): accepted", candidate);
         Ok(())
     }
 
@@ -535,7 +539,7 @@ impl Conflicts<'a> {
 
                 trace!("record conflicts at {:?}", loc);
 
-                this.record_conflicts(&mut live_and_init_locals[statement_index]);
+                this.record_dataflow_conflicts(&mut live_and_init_locals[statement_index]);
             }
 
             init.seek_to_block_end(block);
@@ -544,13 +548,13 @@ impl Conflicts<'a> {
             conflicts.intersect(live.get());
             trace!("record conflicts at end of {:?}", block);
 
-            this.record_conflicts(&mut conflicts);
+            this.record_dataflow_conflicts(&mut conflicts);
         }
 
         this
     }
 
-    fn record_conflicts(&mut self, new_conflicts: &mut BitSet<Local>) {
+    fn record_dataflow_conflicts(&mut self, new_conflicts: &mut BitSet<Local>) {
         // Remove all locals that are not candidates.
         new_conflicts.intersect(self.relevant_locals);
 
@@ -559,6 +563,12 @@ impl Conflicts<'a> {
         }
     }
 
+    fn record_local_conflict(&mut self, a: Local, b: Local, why: &str) {
+        trace!("conflict {:?} <-> {:?} due to {}", a, b, why);
+        self.matrix.insert(a, b);
+        self.matrix.insert(b, a);
+    }
+
     /// Records locals that must not overlap during the evaluation of `stmt`. These locals conflict
     /// and must not be merged.
     fn record_statement_conflicts(&mut self, stmt: &Statement<'_>) {
@@ -575,8 +585,11 @@ impl Conflicts<'a> {
                         if !in_place.is_indirect() {
                             for out_place in &*asm.outputs {
                                 if !out_place.is_indirect() && !in_place.is_indirect() {
-                                    self.matrix.insert(in_place.local, out_place.local);
-                                    self.matrix.insert(out_place.local, in_place.local);
+                                    self.record_local_conflict(
+                                        in_place.local,
+                                        out_place.local,
+                                        "aliasing llvm_asm! operands",
+                                    );
                                 }
                             }
                         }
@@ -599,16 +612,22 @@ impl Conflicts<'a> {
             TerminatorKind::DropAndReplace { location, value, target: _, unwind: _ } => {
                 if let Some(place) = value.place() {
                     if !place.is_indirect() && !location.is_indirect() {
-                        self.matrix.insert(place.local, location.local);
-                        self.matrix.insert(location.local, place.local);
+                        self.record_local_conflict(
+                            place.local,
+                            location.local,
+                            "DropAndReplace operand overlap",
+                        );
                     }
                 }
             }
             TerminatorKind::Yield { value, resume: _, resume_arg, drop: _ } => {
                 if let Some(place) = value.place() {
                     if !place.is_indirect() && !resume_arg.is_indirect() {
-                        self.matrix.insert(place.local, resume_arg.local);
-                        self.matrix.insert(resume_arg.local, place.local);
+                        self.record_local_conflict(
+                            place.local,
+                            resume_arg.local,
+                            "Yield operand overlap",
+                        );
                     }
                 }
             }
@@ -623,8 +642,11 @@ impl Conflicts<'a> {
                 for arg in args.iter().chain(Some(func)) {
                     if let Some(place) = arg.place() {
                         if !place.is_indirect() && !dest_place.is_indirect() {
-                            self.matrix.insert(dest_place.local, place.local);
-                            self.matrix.insert(place.local, dest_place.local);
+                            self.record_local_conflict(
+                                dest_place.local,
+                                place.local,
+                                "call dest/arg overlap",
+                            );
                         }
                     }
                 }
@@ -653,8 +675,11 @@ impl Conflicts<'a> {
                                     InlineAsmOperand::In { reg: _, value } => {
                                         if let Some(p) = value.place() {
                                             if !p.is_indirect() && !dest_place.is_indirect() {
-                                                self.matrix.insert(p.local, dest_place.local);
-                                                self.matrix.insert(dest_place.local, p.local);
+                                                self.record_local_conflict(
+                                                    p.local,
+                                                    dest_place.local,
+                                                    "asm! operand overlap",
+                                                );
                                             }
                                         }
                                     }
@@ -664,8 +689,11 @@ impl Conflicts<'a> {
                                         place: Some(place),
                                     } => {
                                         if !place.is_indirect() && !dest_place.is_indirect() {
-                                            self.matrix.insert(place.local, dest_place.local);
-                                            self.matrix.insert(dest_place.local, place.local);
+                                            self.record_local_conflict(
+                                                place.local,
+                                                dest_place.local,
+                                                "asm! operand overlap",
+                                            );
                                         }
                                     }
                                     InlineAsmOperand::InOut {
@@ -676,15 +704,21 @@ impl Conflicts<'a> {
                                     } => {
                                         if let Some(place) = in_value.place() {
                                             if !place.is_indirect() && !dest_place.is_indirect() {
-                                                self.matrix.insert(place.local, dest_place.local);
-                                                self.matrix.insert(dest_place.local, place.local);
+                                                self.record_local_conflict(
+                                                    place.local,
+                                                    dest_place.local,
+                                                    "asm! operand overlap",
+                                                );
                                             }
                                         }
 
                                         if let Some(place) = out_place {
                                             if !place.is_indirect() && !dest_place.is_indirect() {
-                                                self.matrix.insert(place.local, dest_place.local);
-                                                self.matrix.insert(dest_place.local, place.local);
+                                                self.record_local_conflict(
+                                                    place.local,
+                                                    dest_place.local,
+                                                    "asm! operand overlap",
+                                                );
                                             }
                                         }
                                     }
@@ -750,6 +784,10 @@ impl Conflicts<'a> {
         // FIXME: This might be somewhat slow. Conflict graphs are undirected, maybe we can use
         // something with union-find to speed this up?
 
+        trace!("unify({:?}, {:?})", a, b);
+        trace!("{:?} conflicts: {:?}", a, self.matrix.iter(a).format(", "));
+        trace!("{:?} conflicts: {:?}", b, self.matrix.iter(b).format(", "));
+
         // Make all locals that conflict with `a` also conflict with `b`, and vice versa.
         self.unify_cache.clear();
         for conflicts_with_a in self.matrix.iter(a) {