Migrate from Place enum to Place struct

This commit is contained in:
Santiago Pastorino 2019-04-30 18:58:24 +02:00
parent 5c26b52368
commit d0accade3e
46 changed files with 1457 additions and 786 deletions

View file

@ -103,7 +103,10 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
location: Location) {
debug!("visit_assign(place={:?}, rvalue={:?})", place, rvalue);
if let mir::Place::Base(mir::PlaceBase::Local(index)) = *place {
if let mir::Place {
base: mir::PlaceBase::Local(index),
projection: None,
} = *place {
self.assign(index, location);
if !self.fx.rvalue_creates_operand(rvalue) {
self.not_ssa(index);
@ -157,7 +160,7 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
debug!("visit_place(place={:?}, context={:?})", place, context);
let cx = self.fx.cx;
if let mir::Place::Projection(ref proj) = *place {
if let Some(proj) = &place.projection {
// Allow uses of projections that are ZSTs or from scalar fields.
let is_consume = match context {
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) |
@ -165,7 +168,7 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
_ => false
};
if is_consume {
let base_ty = proj.base.ty(self.fx.mir, cx.tcx());
let base_ty = mir::Place::ty_from(&place.base, &proj.base, self.fx.mir, cx.tcx());
let base_ty = self.fx.monomorphize(&base_ty);
// ZSTs don't require any actual memory access.
@ -183,7 +186,15 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
// Recurse with the same context, instead of `Projection`,
// potentially stopping at non-operand projections,
// which would trigger `not_ssa` on locals.
self.visit_place(&proj.base, context, location);
self.visit_place(
// FIXME do not clone
&mir::Place {
base: place.base.clone(),
projection: proj.base.clone(),
},
context,
location,
);
return;
}
}
@ -192,7 +203,11 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
// A deref projection only reads the pointer, never needs the place.
if let mir::ProjectionElem::Deref = proj.elem {
return self.visit_place(
&proj.base,
// FIXME do not clone
&mir::Place {
base: place.base.clone(),
projection: proj.base.clone(),
},
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
location
);

View file

@ -607,18 +607,22 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// but specified directly in the code. This means it gets promoted
// and we can then extract the value by evaluating the promoted.
mir::Operand::Copy(
Place::Base(
PlaceBase::Static(
box Static { kind: StaticKind::Promoted(promoted), ty }
)
)
Place {
base: PlaceBase::Static(box Static {
kind: StaticKind::Promoted(promoted),
ty,
}),
projection: None,
}
) |
mir::Operand::Move(
Place::Base(
PlaceBase::Static(
box Static { kind: StaticKind::Promoted(promoted), ty }
)
)
Place {
base: PlaceBase::Static(box Static {
kind: StaticKind::Promoted(promoted),
ty,
}),
projection: None,
}
) => {
let param_env = ty::ParamEnv::reveal_all();
let cid = mir::interpret::GlobalId {
@ -1098,7 +1102,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
if fn_ret.is_ignore() {
return ReturnDest::Nothing;
}
let dest = if let mir::Place::Base(mir::PlaceBase::Local(index)) = *dest {
let dest = if let mir::Place {
base: mir::PlaceBase::Local(index),
projection: None,
} = *dest {
match self.locals[index] {
LocalRef::Place(dest) => dest,
LocalRef::UnsizedPlace(_) => bug!("return type must be sized"),
@ -1153,7 +1160,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
src: &mir::Operand<'tcx>,
dst: &mir::Place<'tcx>
) {
if let mir::Place::Base(mir::PlaceBase::Local(index)) = *dst {
if let mir::Place {
base: mir::PlaceBase::Local(index),
projection: None,
} = *dst {
match self.locals[index] {
LocalRef::Place(place) => self.codegen_transmute_into(bx, src, place),
LocalRef::UnsizedPlace(_) => bug!("transmute must not involve unsized locals"),

View file

@ -435,9 +435,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let cx = self.cx;
let tcx = self.cx.tcx();
let result = match *place {
mir::Place::Base(mir::PlaceBase::Local(index)) => {
match self.locals[index] {
let result = match place {
mir::Place {
base: mir::PlaceBase::Local(index),
projection: None,
} => {
match self.locals[*index] {
LocalRef::Place(place) => {
return place;
}
@ -449,15 +452,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}
}
mir::Place::Base(
mir::PlaceBase::Static(
box mir::Static { ty, kind: mir::StaticKind::Promoted(promoted) }
)
) => {
mir::Place {
base: mir::PlaceBase::Static(box mir::Static {
ty,
kind: mir::StaticKind::Promoted(promoted),
}),
projection: None,
} => {
let param_env = ty::ParamEnv::reveal_all();
let cid = mir::interpret::GlobalId {
instance: self.instance,
promoted: Some(promoted),
promoted: Some(*promoted),
};
let layout = cx.layout_of(self.monomorphize(&ty));
match bx.tcx().const_eval(param_env.and(cid)) {
@ -480,26 +485,41 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}
}
mir::Place::Base(
mir::PlaceBase::Static(
box mir::Static { ty, kind: mir::StaticKind::Static(def_id) }
)
) => {
mir::Place {
base: mir::PlaceBase::Static(box mir::Static {
ty,
kind: mir::StaticKind::Static(def_id),
}),
projection: None,
} => {
// NB: The layout of a static may be unsized as is the case when working
// with a static that is an extern_type.
let layout = cx.layout_of(self.monomorphize(&ty));
let static_ = bx.get_static(def_id);
let static_ = bx.get_static(*def_id);
PlaceRef::new_thin_place(bx, static_, layout, layout.align.abi)
},
mir::Place::Projection(box mir::Projection {
ref base,
elem: mir::ProjectionElem::Deref
}) => {
mir::Place {
base,
projection: Some(box mir::Projection {
base: proj_base,
elem: mir::ProjectionElem::Deref,
}),
} => {
// Load the pointer from its location.
self.codegen_consume(bx, base).deref(bx.cx())
self.codegen_consume(bx, &mir::Place {
base: base.clone(),
projection: proj_base.clone(),
}).deref(bx.cx())
}
mir::Place::Projection(ref projection) => {
let cg_base = self.codegen_place(bx, &projection.base);
mir::Place {
base,
projection: Some(projection),
} => {
// FIXME turn this recursion into iteration
let cg_base = self.codegen_place(bx, &mir::Place {
base: base.clone(),
projection: projection.base.clone(),
});
match projection.elem {
mir::ProjectionElem::Deref => bug!(),

View file

@ -515,7 +515,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
) -> Bx::Value {
// ZST are passed as operands and require special handling
// because codegen_place() panics if Local is operand.
if let mir::Place::Base(mir::PlaceBase::Local(index)) = *place {
if let mir::Place {
base: mir::PlaceBase::Local(index),
projection: None,
} = *place {
if let LocalRef::Operand(Some(op)) = self.locals[index] {
if let ty::Array(_, n) = op.layout.ty.sty {
let n = n.unwrap_usize(bx.cx().tcx());

View file

@ -17,7 +17,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
self.set_debug_loc(&mut bx, statement.source_info);
match statement.kind {
mir::StatementKind::Assign(ref place, ref rvalue) => {
if let mir::Place::Base(mir::PlaceBase::Local(index)) = *place {
if let mir::Place {
base: mir::PlaceBase::Local(index),
projection: None,
} = *place {
match self.locals[index] {
LocalRef::Place(cg_dest) => {
self.codegen_rvalue(bx, cg_dest, rvalue)