make inliner remove the fn_entry flag on Retag statements

This commit is contained in:
Ralf Jung 2018-10-24 13:47:48 +02:00
parent 96ba4af258
commit 8a61d492a9
3 changed files with 74 additions and 7 deletions

View File

@ -152,6 +152,13 @@ macro_rules! make_mir_visitor {
self.super_ascribe_user_ty(place, variance, user_ty, location);
}
fn visit_retag(&mut self,
fn_entry: & $($mutability)* bool,
place: & $($mutability)* Place<'tcx>,
location: Location) {
self.super_retag(fn_entry, place, location);
}
fn visit_place(&mut self,
place: & $($mutability)* Place<'tcx>,
context: PlaceContext<'tcx>,
@ -371,13 +378,6 @@ macro_rules! make_mir_visitor {
);
}
StatementKind::EndRegion(_) => {}
StatementKind::Retag { fn_entry: _, ref $($mutability)* place } => {
self.visit_place(
place,
PlaceContext::MutatingUse(MutatingUseContext::Retag),
location,
);
}
StatementKind::SetDiscriminant{ ref $($mutability)* place, .. } => {
self.visit_place(
place,
@ -413,6 +413,9 @@ macro_rules! make_mir_visitor {
self.visit_operand(input, location);
}
}
StatementKind::Retag { ref $($mutability)* fn_entry, ref $($mutability)* place } => {
self.visit_retag(fn_entry, place, location);
}
StatementKind::AscribeUserType(
ref $($mutability)* place,
ref $($mutability)* variance,
@ -715,6 +718,17 @@ macro_rules! make_mir_visitor {
self.visit_user_type_projection(user_ty);
}
fn super_retag(&mut self,
_fn_entry: & $($mutability)* bool,
place: & $($mutability)* Place<'tcx>,
location: Location) {
self.visit_place(
place,
PlaceContext::MutatingUse(MutatingUseContext::Retag),
location,
);
}
fn super_place(&mut self,
place: & $($mutability)* Place<'tcx>,
context: PlaceContext<'tcx>,

View File

@ -691,6 +691,14 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
self.in_cleanup_block = false;
}
fn visit_retag(&mut self, fn_entry: &mut bool, place: &mut Place<'tcx>, loc: Location) {
self.super_retag(fn_entry, place, loc);
// We have to patch all inlined retags to be aware that they are no longer
// happening on function entry.
*fn_entry = false;
}
fn visit_terminator_kind(&mut self, block: BasicBlock,
kind: &mut TerminatorKind<'tcx>, loc: Location) {
self.super_terminator_kind(block, kind, loc);

View File

@ -0,0 +1,45 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-flags: -Z span_free_formats -Z mir-emit-retag
// Tests that MIR inliner fixes up `Retag`'s `fn_entry` flag
fn main() {
println!("{}", bar());
}
#[inline(always)]
fn foo(x: &i32, y: &i32) -> bool {
*x == *y
}
fn bar() -> bool {
let f = foo;
f(&1, &-1)
}
// END RUST SOURCE
// START rustc.bar.Inline.after.mir
// ...
// bb0: {
// ...
// Retag(_3);
// Retag(_6);
// StorageLive(_9);
// _9 = (*_3);
// StorageLive(_10);
// _10 = (*_6);
// _0 = Eq(move _9, move _10);
// ...
// return;
// }
// ...
// END rustc.bar.Inline.after.mir