1
Fork 0

More logging

This commit is contained in:
Jonas Schievink 2020-06-23 01:25:52 +02:00
parent 88538adf9a
commit 934634eacc

View file

@ -95,12 +95,13 @@
//! [previous attempt]: https://github.com/rust-lang/rust/pull/47954 //! [previous attempt]: https://github.com/rust-lang/rust/pull/47954
//! [subsequent approach]: https://github.com/rust-lang/rust/pull/71003 //! [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::{ use crate::{
transform::{MirPass, MirSource}, transform::{MirPass, MirSource},
util::{dump_mir, PassWhere}, util::{dump_mir, PassWhere},
}; };
use dataflow::impls::{MaybeInitializedLocals, MaybeLiveLocals}; use itertools::Itertools;
use rustc_data_structures::unify::{InPlaceUnificationTable, UnifyKey}; use rustc_data_structures::unify::{InPlaceUnificationTable, UnifyKey};
use rustc_index::{ use rustc_index::{
bit_set::{BitMatrix, BitSet}, 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 // We still return `Err` in any case, as `src` and `dest` do not need to be unified
// *again*. // *again*.
trace!("push({:?}): already unified", candidate);
return Err(()); return Err(());
} }
let entry = &mut self.map[candidate.src]; let entry = &mut self.map[candidate.src];
if entry.is_some() { if entry.is_some() {
// We're already replacing `src` with something else, so this candidate is out. // We're already replacing `src` with something else, so this candidate is out.
trace!("push({:?}): src already has replacement", candidate);
return Err(()); return Err(());
} }
@ -270,6 +273,7 @@ impl Replacements<'tcx> {
self.kill.insert(candidate.src); self.kill.insert(candidate.src);
self.kill.insert(candidate.dest.local); self.kill.insert(candidate.dest.local);
trace!("push({:?}): accepted", candidate);
Ok(()) Ok(())
} }
@ -535,7 +539,7 @@ impl Conflicts<'a> {
trace!("record conflicts at {:?}", loc); 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); init.seek_to_block_end(block);
@ -544,13 +548,13 @@ impl Conflicts<'a> {
conflicts.intersect(live.get()); conflicts.intersect(live.get());
trace!("record conflicts at end of {:?}", block); trace!("record conflicts at end of {:?}", block);
this.record_conflicts(&mut conflicts); this.record_dataflow_conflicts(&mut conflicts);
} }
this 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. // Remove all locals that are not candidates.
new_conflicts.intersect(self.relevant_locals); 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 /// Records locals that must not overlap during the evaluation of `stmt`. These locals conflict
/// and must not be merged. /// and must not be merged.
fn record_statement_conflicts(&mut self, stmt: &Statement<'_>) { fn record_statement_conflicts(&mut self, stmt: &Statement<'_>) {
@ -575,8 +585,11 @@ impl Conflicts<'a> {
if !in_place.is_indirect() { if !in_place.is_indirect() {
for out_place in &*asm.outputs { for out_place in &*asm.outputs {
if !out_place.is_indirect() && !in_place.is_indirect() { if !out_place.is_indirect() && !in_place.is_indirect() {
self.matrix.insert(in_place.local, out_place.local); self.record_local_conflict(
self.matrix.insert(out_place.local, in_place.local); in_place.local,
out_place.local,
"aliasing llvm_asm! operands",
);
} }
} }
} }
@ -599,16 +612,22 @@ impl Conflicts<'a> {
TerminatorKind::DropAndReplace { location, value, target: _, unwind: _ } => { TerminatorKind::DropAndReplace { location, value, target: _, unwind: _ } => {
if let Some(place) = value.place() { if let Some(place) = value.place() {
if !place.is_indirect() && !location.is_indirect() { if !place.is_indirect() && !location.is_indirect() {
self.matrix.insert(place.local, location.local); self.record_local_conflict(
self.matrix.insert(location.local, place.local); place.local,
location.local,
"DropAndReplace operand overlap",
);
} }
} }
} }
TerminatorKind::Yield { value, resume: _, resume_arg, drop: _ } => { TerminatorKind::Yield { value, resume: _, resume_arg, drop: _ } => {
if let Some(place) = value.place() { if let Some(place) = value.place() {
if !place.is_indirect() && !resume_arg.is_indirect() { if !place.is_indirect() && !resume_arg.is_indirect() {
self.matrix.insert(place.local, resume_arg.local); self.record_local_conflict(
self.matrix.insert(resume_arg.local, place.local); place.local,
resume_arg.local,
"Yield operand overlap",
);
} }
} }
} }
@ -623,8 +642,11 @@ impl Conflicts<'a> {
for arg in args.iter().chain(Some(func)) { for arg in args.iter().chain(Some(func)) {
if let Some(place) = arg.place() { if let Some(place) = arg.place() {
if !place.is_indirect() && !dest_place.is_indirect() { if !place.is_indirect() && !dest_place.is_indirect() {
self.matrix.insert(dest_place.local, place.local); self.record_local_conflict(
self.matrix.insert(place.local, dest_place.local); dest_place.local,
place.local,
"call dest/arg overlap",
);
} }
} }
} }
@ -653,8 +675,11 @@ impl Conflicts<'a> {
InlineAsmOperand::In { reg: _, value } => { InlineAsmOperand::In { reg: _, value } => {
if let Some(p) = value.place() { if let Some(p) = value.place() {
if !p.is_indirect() && !dest_place.is_indirect() { if !p.is_indirect() && !dest_place.is_indirect() {
self.matrix.insert(p.local, dest_place.local); self.record_local_conflict(
self.matrix.insert(dest_place.local, p.local); p.local,
dest_place.local,
"asm! operand overlap",
);
} }
} }
} }
@ -664,8 +689,11 @@ impl Conflicts<'a> {
place: Some(place), place: Some(place),
} => { } => {
if !place.is_indirect() && !dest_place.is_indirect() { if !place.is_indirect() && !dest_place.is_indirect() {
self.matrix.insert(place.local, dest_place.local); self.record_local_conflict(
self.matrix.insert(dest_place.local, place.local); place.local,
dest_place.local,
"asm! operand overlap",
);
} }
} }
InlineAsmOperand::InOut { InlineAsmOperand::InOut {
@ -676,15 +704,21 @@ impl Conflicts<'a> {
} => { } => {
if let Some(place) = in_value.place() { if let Some(place) = in_value.place() {
if !place.is_indirect() && !dest_place.is_indirect() { if !place.is_indirect() && !dest_place.is_indirect() {
self.matrix.insert(place.local, dest_place.local); self.record_local_conflict(
self.matrix.insert(dest_place.local, place.local); place.local,
dest_place.local,
"asm! operand overlap",
);
} }
} }
if let Some(place) = out_place { if let Some(place) = out_place {
if !place.is_indirect() && !dest_place.is_indirect() { if !place.is_indirect() && !dest_place.is_indirect() {
self.matrix.insert(place.local, dest_place.local); self.record_local_conflict(
self.matrix.insert(dest_place.local, place.local); 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 // FIXME: This might be somewhat slow. Conflict graphs are undirected, maybe we can use
// something with union-find to speed this up? // 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. // Make all locals that conflict with `a` also conflict with `b`, and vice versa.
self.unify_cache.clear(); self.unify_cache.clear();
for conflicts_with_a in self.matrix.iter(a) { for conflicts_with_a in self.matrix.iter(a) {