Skip to content

Commit

Permalink
Auto merge of #69916 - oli-obk:mir_bless, r=eddyb
Browse files Browse the repository at this point in the history
Enable blessing of mir opt tests

cc @rust-lang/wg-mir-opt
cc @RalfJung

Long overdue, but now you can finally just add a

```rust
// EMIT_MIR rustc.function_name.MirPassName.before.mir
```

(or `after.mir` since most of the time you want to know the MIR after a pass). A `--bless` invocation will automatically create the files for you.

I suggest we do this for all mir opt tests that have all of the MIR in their source anyway

If you use `rustc.function.MirPass.diff` you only get the diff that the MIR pass causes on the MIR.

Fixes #67865
  • Loading branch information
bors committed Mar 27, 2020
2 parents 697d6b3 + c9a5a03 commit 0a2df62
Show file tree
Hide file tree
Showing 24 changed files with 1,201 additions and 274 deletions.
4 changes: 2 additions & 2 deletions src/librustc_data_structures/sorted_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,13 @@ impl<K: Ord, V> SortedMap<K, V> {

/// Iterate over the keys, sorted
#[inline]
pub fn keys(&self) -> impl Iterator<Item = &K> + ExactSizeIterator {
pub fn keys(&self) -> impl Iterator<Item = &K> + ExactSizeIterator + DoubleEndedIterator {
self.data.iter().map(|&(ref k, _)| k)
}

/// Iterate over values, sorted by key
#[inline]
pub fn values(&self) -> impl Iterator<Item = &V> + ExactSizeIterator {
pub fn values(&self) -> impl Iterator<Item = &V> + ExactSizeIterator + DoubleEndedIterator {
self.data.iter().map(|&(_, ref v)| v)
}

Expand Down
96 changes: 25 additions & 71 deletions src/librustc_mir/interpret/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -649,58 +649,15 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
&self,
allocs_seen: &mut FxHashSet<AllocId>,
allocs_to_print: &mut VecDeque<AllocId>,
mut msg: String,
alloc: &Allocation<Tag, Extra>,
extra: String,
) {
use std::fmt::Write;

let prefix_len = msg.len();
let mut relocations = vec![];

for i in 0..alloc.size.bytes() {
let i = Size::from_bytes(i);
if let Some(&(_, target_id)) = alloc.relocations().get(&i) {
if allocs_seen.insert(target_id) {
allocs_to_print.push_back(target_id);
}
relocations.push((i, target_id));
}
if alloc.undef_mask().is_range_defined(i, i + Size::from_bytes(1)).is_ok() {
// this `as usize` is fine, since `i` came from a `usize`
let i = i.bytes_usize();

// Checked definedness (and thus range) and relocations. This access also doesn't
// influence interpreter execution but is only for debugging.
let bytes = alloc.inspect_with_undef_and_ptr_outside_interpreter(i..i + 1);
write!(msg, "{:02x} ", bytes[0]).unwrap();
} else {
msg.push_str("__ ");
for &(_, (_, target_id)) in alloc.relocations().iter() {
if allocs_seen.insert(target_id) {
allocs_to_print.push_back(target_id);
}
}

eprintln!(
"{}({} bytes, alignment {}){}",
msg,
alloc.size.bytes(),
alloc.align.bytes(),
extra
);

if !relocations.is_empty() {
msg.clear();
write!(msg, "{:1$}", "", prefix_len).unwrap(); // Print spaces.
let mut pos = Size::ZERO;
let relocation_width = (self.pointer_size().bytes() - 1) * 3;
for (i, target_id) in relocations {
write!(msg, "{:1$}", "", ((i - pos) * 3).bytes_usize()).unwrap();
let target = format!("({})", target_id);
// this `as usize` is fine, since we can't print more chars than `usize::MAX`
write!(msg, "└{0:─^1$}┘ ", target, relocation_width as usize).unwrap();
pos = i + self.pointer_size();
}
eprintln!("{}", msg);
}
crate::util::pretty::write_allocation(self.tcx.tcx, alloc, &mut std::io::stderr(), "")
.unwrap();
}

/// Print a list of allocations and all allocations they point to, recursively.
Expand All @@ -713,45 +670,42 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
let mut allocs_seen = FxHashSet::default();

while let Some(id) = allocs_to_print.pop_front() {
let msg = format!("Alloc {:<5} ", format!("{}:", id));
eprint!("Alloc {:<5}: ", id);
fn msg<Tag, Extra>(alloc: &Allocation<Tag, Extra>, extra: &str) {
eprintln!(
"({} bytes, alignment {}){}",
alloc.size.bytes(),
alloc.align.bytes(),
extra
)
};

// normal alloc?
match self.alloc_map.get_or(id, || Err(())) {
Ok((kind, alloc)) => {
let extra = match kind {
MemoryKind::Stack => " (stack)".to_owned(),
MemoryKind::Vtable => " (vtable)".to_owned(),
MemoryKind::CallerLocation => " (caller_location)".to_owned(),
MemoryKind::Machine(m) => format!(" ({:?})", m),
match kind {
MemoryKind::Stack => msg(alloc, " (stack)"),
MemoryKind::Vtable => msg(alloc, " (vtable)"),
MemoryKind::CallerLocation => msg(alloc, " (caller_location)"),
MemoryKind::Machine(m) => msg(alloc, &format!(" ({:?})", m)),
};
self.dump_alloc_helper(
&mut allocs_seen,
&mut allocs_to_print,
msg,
alloc,
extra,
);
self.dump_alloc_helper(&mut allocs_seen, &mut allocs_to_print, alloc);
}
Err(()) => {
// global alloc?
match self.tcx.alloc_map.lock().get(id) {
Some(GlobalAlloc::Memory(alloc)) => {
self.dump_alloc_helper(
&mut allocs_seen,
&mut allocs_to_print,
msg,
alloc,
" (immutable)".to_owned(),
);
msg(alloc, " (immutable)");
self.dump_alloc_helper(&mut allocs_seen, &mut allocs_to_print, alloc);
}
Some(GlobalAlloc::Function(func)) => {
eprintln!("{} {}", msg, func);
eprintln!("{}", func);
}
Some(GlobalAlloc::Static(did)) => {
eprintln!("{} {:?}", msg, did);
eprintln!("{:?}", did);
}
None => {
eprintln!("{} (deallocated)", msg);
eprintln!("(deallocated)");
}
}
}
Expand Down
Loading

0 comments on commit 0a2df62

Please sign in to comment.