Skip to content

Commit

Permalink
Auto merge of rust-lang#63420 - spastorino:place2_5, r=oli-obk
Browse files Browse the repository at this point in the history
[Place 2.0] Convert Place's projection to a boxed slice

This is still work in progress, it's not compiling right now I need to review a bit more to see what's going on but wanted to open the PR to start discussing it.

r? @oli-obk
  • Loading branch information
bors committed Sep 13, 2019
2 parents 3287a65 + 28db2c9 commit a6946a8
Show file tree
Hide file tree
Showing 61 changed files with 1,590 additions and 1,776 deletions.
308 changes: 91 additions & 217 deletions src/librustc/mir/mod.rs

Large diffs are not rendered by default.

15 changes: 5 additions & 10 deletions src/librustc/mir/tcx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,21 +121,16 @@ BraceStructTypeFoldableImpl! {
impl<'tcx> Place<'tcx> {
pub fn ty_from<D>(
base: &PlaceBase<'tcx>,
projection: &Option<Box<Projection<'tcx>>>,
projection: &[PlaceElem<'tcx>],
local_decls: &D,
tcx: TyCtxt<'tcx>
) -> PlaceTy<'tcx>
where D: HasLocalDecls<'tcx>
{
Place::iterate_over(base, projection, |place_base, place_projections| {
let mut place_ty = place_base.ty(local_decls);

for proj in place_projections {
place_ty = place_ty.projection_ty(tcx, &proj.elem);
}

place_ty
})
projection.iter().fold(
base.ty(local_decls),
|place_ty, elem| place_ty.projection_ty(tcx, elem)
)
}

pub fn ty<D>(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> PlaceTy<'tcx>
Expand Down
72 changes: 39 additions & 33 deletions src/librustc/mir/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,18 +152,18 @@ macro_rules! make_mir_visitor {
}

fn visit_place_base(&mut self,
place_base: & $($mutability)? PlaceBase<'tcx>,
base: & $($mutability)? PlaceBase<'tcx>,
context: PlaceContext,
location: Location) {
self.super_place_base(place_base, context, location);
self.super_place_base(base, context, location);
}

fn visit_projection(&mut self,
place_base: & $($mutability)? PlaceBase<'tcx>,
place: & $($mutability)? Projection<'tcx>,
base: & $($mutability)? PlaceBase<'tcx>,
projection: & $($mutability)? [PlaceElem<'tcx>],
context: PlaceContext,
location: Location) {
self.super_projection(place_base, place, context, location);
self.super_projection(base, projection, context, location);
}

fn visit_constant(&mut self,
Expand Down Expand Up @@ -344,7 +344,9 @@ macro_rules! make_mir_visitor {

self.visit_source_info(source_info);
match kind {
StatementKind::Assign(place, rvalue) => {
StatementKind::Assign(
box(ref $($mutability)? place, ref $($mutability)? rvalue)
) => {
self.visit_assign(place, rvalue, location);
}
StatementKind::FakeRead(_, place) => {
Expand Down Expand Up @@ -391,7 +393,10 @@ macro_rules! make_mir_visitor {
StatementKind::Retag(kind, place) => {
self.visit_retag(kind, place, location);
}
StatementKind::AscribeUserType(place, variance, user_ty) => {
StatementKind::AscribeUserType(
box(ref $($mutability)? place, ref $($mutability)? user_ty),
variance
) => {
self.visit_ascribe_user_ty(place, variance, user_ty, location);
}
StatementKind::Nop => {}
Expand Down Expand Up @@ -685,7 +690,7 @@ macro_rules! make_mir_visitor {
location: Location) {
let mut context = context;

if place.projection.is_some() {
if !place.projection.is_empty() {
context = if context.is_mutating_use() {
PlaceContext::MutatingUse(MutatingUseContext::Projection)
} else {
Expand All @@ -695,9 +700,10 @@ macro_rules! make_mir_visitor {

self.visit_place_base(& $($mutability)? place.base, context, location);

if let Some(box proj) = & $($mutability)? place.projection {
self.visit_projection(& $($mutability)? place.base, proj, context, location);
}
self.visit_projection(& $($mutability)? place.base,
& $($mutability)? place.projection,
context,
location);
}

fn super_place_base(&mut self,
Expand All @@ -715,31 +721,31 @@ macro_rules! make_mir_visitor {
}

fn super_projection(&mut self,
place_base: & $($mutability)? PlaceBase<'tcx>,
proj: & $($mutability)? Projection<'tcx>,
base: & $($mutability)? PlaceBase<'tcx>,
projection: & $($mutability)? [PlaceElem<'tcx>],
context: PlaceContext,
location: Location) {
if let Some(box proj_base) = & $($mutability)? proj.base {
self.visit_projection(place_base, proj_base, context, location);
}
if let [proj_base @ .., elem] = projection {
self.visit_projection(base, proj_base, context, location);

match & $($mutability)? proj.elem {
ProjectionElem::Field(_field, ty) => {
self.visit_ty(ty, TyContext::Location(location));
}
ProjectionElem::Index(local) => {
self.visit_local(
local,
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
location
);
}
ProjectionElem::Deref |
ProjectionElem::Subslice { from: _, to: _ } |
ProjectionElem::ConstantIndex { offset: _,
min_length: _,
from_end: _ } |
ProjectionElem::Downcast(_, _) => {
match elem {
ProjectionElem::Field(_field, ty) => {
self.visit_ty(ty, TyContext::Location(location));
}
ProjectionElem::Index(local) => {
self.visit_local(
local,
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
location
);
}
ProjectionElem::Deref |
ProjectionElem::Subslice { from: _, to: _ } |
ProjectionElem::ConstantIndex { offset: _,
min_length: _,
from_end: _ } |
ProjectionElem::Downcast(_, _) => {
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc_codegen_ssa/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#![feature(box_syntax)]
#![feature(core_intrinsics)]
#![feature(libc)]
#![feature(slice_patterns)]
#![feature(stmt_expr_attributes)]
#![feature(try_blocks)]
#![feature(in_band_lifetimes)]
Expand Down
23 changes: 10 additions & 13 deletions src/librustc_codegen_ssa/mir/analyze.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
) {
let cx = self.fx.cx;

if let Some(proj) = place_ref.projection {
if let [proj_base @ .., elem] = place_ref.projection {
// Allow uses of projections that are ZSTs or from scalar fields.
let is_consume = match context {
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) |
Expand All @@ -114,12 +114,12 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
};
if is_consume {
let base_ty =
mir::Place::ty_from(place_ref.base, &proj.base, self.fx.mir, cx.tcx());
mir::Place::ty_from(place_ref.base, proj_base, self.fx.mir, cx.tcx());
let base_ty = self.fx.monomorphize(&base_ty);

// ZSTs don't require any actual memory access.
let elem_ty = base_ty
.projection_ty(cx.tcx(), &proj.elem)
.projection_ty(cx.tcx(), elem)
.ty;
let elem_ty = self.fx.monomorphize(&elem_ty);
let span = if let mir::PlaceBase::Local(index) = place_ref.base {
Expand All @@ -131,7 +131,7 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
return;
}

if let mir::ProjectionElem::Field(..) = proj.elem {
if let mir::ProjectionElem::Field(..) = elem {
let layout = cx.spanned_layout_of(base_ty.ty, span);
if cx.is_backend_immediate(layout) || cx.is_backend_scalar_pair(layout) {
// Recurse with the same context, instead of `Projection`,
Expand All @@ -140,7 +140,7 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
self.process_place(
&mir::PlaceRef {
base: place_ref.base,
projection: &proj.base,
projection: proj_base,
},
context,
location,
Expand All @@ -151,11 +151,11 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
}

// A deref projection only reads the pointer, never needs the place.
if let mir::ProjectionElem::Deref = proj.elem {
if let mir::ProjectionElem::Deref = elem {
self.process_place(
&mir::PlaceRef {
base: place_ref.base,
projection: &proj.base,
projection: proj_base,
},
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
location
Expand All @@ -168,7 +168,7 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
// visit_place API
let mut context = context;

if place_ref.projection.is_some() {
if !place_ref.projection.is_empty() {
context = if context.is_mutating_use() {
PlaceContext::MutatingUse(MutatingUseContext::Projection)
} else {
Expand All @@ -177,10 +177,7 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
}

self.visit_place_base(place_ref.base, context, location);

if let Some(box proj) = place_ref.projection {
self.visit_projection(place_ref.base, proj, context, location);
}
self.visit_projection(place_ref.base, place_ref.projection, context, location);
}

}
Expand All @@ -196,7 +193,7 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>

if let mir::Place {
base: mir::PlaceBase::Local(index),
projection: None,
projection: box [],
} = *place {
self.assign(index, location);
let decl_span = self.fx.mir.local_decls[index].source_info.span;
Expand Down
10 changes: 5 additions & 5 deletions src/librustc_codegen_ssa/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {

PassMode::Direct(_) | PassMode::Pair(..) => {
let op =
self.codegen_consume(&mut bx, &mir::Place::RETURN_PLACE.as_ref());
self.codegen_consume(&mut bx, &mir::Place::return_place().as_ref());
if let Ref(llval, _, align) = op.val {
bx.load(llval, align)
} else {
Expand Down Expand Up @@ -612,7 +612,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
ty,
def_id: _,
}),
projection: None,
projection: box [],
}
) |
mir::Operand::Move(
Expand All @@ -622,7 +622,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
ty,
def_id: _,
}),
projection: None,
projection: box [],
}
) => {
let param_env = ty::ParamEnv::reveal_all();
Expand Down Expand Up @@ -1105,7 +1105,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
let dest = if let mir::Place {
base: mir::PlaceBase::Local(index),
projection: None,
projection: box [],
} = *dest {
match self.locals[index] {
LocalRef::Place(dest) => dest,
Expand Down Expand Up @@ -1166,7 +1166,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
) {
if let mir::Place {
base: mir::PlaceBase::Local(index),
projection: None,
projection: box [],
} = *dst {
match self.locals[index] {
LocalRef::Place(place) => self.codegen_transmute_into(bx, src, place),
Expand Down
68 changes: 33 additions & 35 deletions src/librustc_codegen_ssa/mir/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,47 +384,45 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
) -> Option<OperandRef<'tcx, Bx::Value>> {
debug!("maybe_codegen_consume_direct(place_ref={:?})", place_ref);

place_ref.iterate(|place_base, place_projection| {
if let mir::PlaceBase::Local(index) = place_base {
match self.locals[*index] {
LocalRef::Operand(Some(mut o)) => {
// Moves out of scalar and scalar pair fields are trivial.
for proj in place_projection {
match proj.elem {
mir::ProjectionElem::Field(ref f, _) => {
o = o.extract_field(bx, f.index());
}
mir::ProjectionElem::Index(_) |
mir::ProjectionElem::ConstantIndex { .. } => {
// ZSTs don't require any actual memory access.
// FIXME(eddyb) deduplicate this with the identical
// checks in `codegen_consume` and `extract_field`.
let elem = o.layout.field(bx.cx(), 0);
if elem.is_zst() {
o = OperandRef::new_zst(bx, elem);
} else {
return None;
}
if let mir::PlaceBase::Local(index) = place_ref.base {
match self.locals[*index] {
LocalRef::Operand(Some(mut o)) => {
// Moves out of scalar and scalar pair fields are trivial.
for elem in place_ref.projection.iter() {
match elem {
mir::ProjectionElem::Field(ref f, _) => {
o = o.extract_field(bx, f.index());
}
mir::ProjectionElem::Index(_) |
mir::ProjectionElem::ConstantIndex { .. } => {
// ZSTs don't require any actual memory access.
// FIXME(eddyb) deduplicate this with the identical
// checks in `codegen_consume` and `extract_field`.
let elem = o.layout.field(bx.cx(), 0);
if elem.is_zst() {
o = OperandRef::new_zst(bx, elem);
} else {
return None;
}
_ => return None,
}
_ => return None,
}

Some(o)
}
LocalRef::Operand(None) => {
bug!("use of {:?} before def", place_ref);
}
LocalRef::Place(..) | LocalRef::UnsizedPlace(..) => {
// watch out for locals that do not have an
// alloca; they are handled somewhat differently
None
}

Some(o)
}
LocalRef::Operand(None) => {
bug!("use of {:?} before def", place_ref);
}
LocalRef::Place(..) | LocalRef::UnsizedPlace(..) => {
// watch out for locals that do not have an
// alloca; they are handled somewhat differently
None
}
} else {
None
}
})
} else {
None
}
}

pub fn codegen_consume(
Expand Down
Loading

0 comments on commit a6946a8

Please sign in to comment.