Skip to content

Commit e9c4114

Browse files
committed
Convert Place's projection to a boxed slice
1 parent 824383d commit e9c4114

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1399
-1570
lines changed

src/librustc/mir/mod.rs

Lines changed: 82 additions & 208 deletions
Large diffs are not rendered by default.

src/librustc/mir/tcx.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -121,21 +121,19 @@ BraceStructTypeFoldableImpl! {
121121
impl<'tcx> Place<'tcx> {
122122
pub fn ty_from<D>(
123123
base: &PlaceBase<'tcx>,
124-
projection: &Option<Box<Projection<'tcx>>>,
124+
projection: &[PlaceElem<'tcx>],
125125
local_decls: &D,
126126
tcx: TyCtxt<'tcx>
127127
) -> PlaceTy<'tcx>
128128
where D: HasLocalDecls<'tcx>
129129
{
130-
Place::iterate_over(base, projection, |place_base, place_projections| {
131-
let mut place_ty = place_base.ty(local_decls);
130+
let mut place_ty = base.ty(local_decls);
132131

133-
for proj in place_projections {
134-
place_ty = place_ty.projection_ty(tcx, &proj.elem);
135-
}
132+
for elem in projection.iter() {
133+
place_ty = place_ty.projection_ty(tcx, elem);
134+
}
136135

137-
place_ty
138-
})
136+
place_ty
139137
}
140138

141139
pub fn ty<D>(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> PlaceTy<'tcx>

src/librustc/mir/visit.rs

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -152,18 +152,18 @@ macro_rules! make_mir_visitor {
152152
}
153153

154154
fn visit_place_base(&mut self,
155-
place_base: & $($mutability)? PlaceBase<'tcx>,
155+
base: & $($mutability)? PlaceBase<'tcx>,
156156
context: PlaceContext,
157157
location: Location) {
158-
self.super_place_base(place_base, context, location);
158+
self.super_place_base(base, context, location);
159159
}
160160

161161
fn visit_projection(&mut self,
162-
place_base: & $($mutability)? PlaceBase<'tcx>,
163-
place: & $($mutability)? Projection<'tcx>,
162+
base: & $($mutability)? PlaceBase<'tcx>,
163+
projection: & $($mutability)? [PlaceElem<'tcx>],
164164
context: PlaceContext,
165165
location: Location) {
166-
self.super_projection(place_base, place, context, location);
166+
self.super_projection(base, projection, context, location);
167167
}
168168

169169
fn visit_constant(&mut self,
@@ -685,7 +685,7 @@ macro_rules! make_mir_visitor {
685685
location: Location) {
686686
let mut context = context;
687687

688-
if place.projection.is_some() {
688+
if !place.projection.is_empty() {
689689
context = if context.is_mutating_use() {
690690
PlaceContext::MutatingUse(MutatingUseContext::Projection)
691691
} else {
@@ -695,9 +695,10 @@ macro_rules! make_mir_visitor {
695695

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

698-
if let Some(box proj) = & $($mutability)? place.projection {
699-
self.visit_projection(& $($mutability)? place.base, proj, context, location);
700-
}
698+
self.visit_projection(& $($mutability)? place.base,
699+
& $($mutability)? place.projection,
700+
context,
701+
location);
701702
}
702703

703704
fn super_place_base(&mut self,
@@ -715,31 +716,34 @@ macro_rules! make_mir_visitor {
715716
}
716717

717718
fn super_projection(&mut self,
718-
place_base: & $($mutability)? PlaceBase<'tcx>,
719-
proj: & $($mutability)? Projection<'tcx>,
719+
base: & $($mutability)? PlaceBase<'tcx>,
720+
projection: & $($mutability)? [PlaceElem<'tcx>],
720721
context: PlaceContext,
721722
location: Location) {
722-
if let Some(box proj_base) = & $($mutability)? proj.base {
723-
self.visit_projection(place_base, proj_base, context, location);
724-
}
725-
726-
match & $($mutability)? proj.elem {
727-
ProjectionElem::Field(_field, ty) => {
728-
self.visit_ty(ty, TyContext::Location(location));
729-
}
730-
ProjectionElem::Index(local) => {
731-
self.visit_local(
732-
local,
733-
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
734-
location
735-
);
736-
}
737-
ProjectionElem::Deref |
738-
ProjectionElem::Subslice { from: _, to: _ } |
739-
ProjectionElem::ConstantIndex { offset: _,
740-
min_length: _,
741-
from_end: _ } |
742-
ProjectionElem::Downcast(_, _) => {
723+
if !projection.is_empty() {
724+
let proj_len = projection.len();
725+
let proj_base = & $($mutability)? projection[..proj_len - 1];
726+
self.visit_projection(base, proj_base, context, location);
727+
728+
let elem = & $($mutability)? projection[proj_len - 1];
729+
match elem {
730+
ProjectionElem::Field(_field, ty) => {
731+
self.visit_ty(ty, TyContext::Location(location));
732+
}
733+
ProjectionElem::Index(local) => {
734+
self.visit_local(
735+
local,
736+
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
737+
location
738+
);
739+
}
740+
ProjectionElem::Deref |
741+
ProjectionElem::Subslice { from: _, to: _ } |
742+
ProjectionElem::ConstantIndex { offset: _,
743+
min_length: _,
744+
from_end: _ } |
745+
ProjectionElem::Downcast(_, _) => {
746+
}
743747
}
744748
}
745749
}

src/librustc_codegen_ssa/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#![feature(box_syntax)]
55
#![feature(core_intrinsics)]
66
#![feature(libc)]
7+
#![feature(slice_patterns)]
78
#![feature(stmt_expr_attributes)]
89
#![feature(try_blocks)]
910
#![feature(in_band_lifetimes)]

src/librustc_codegen_ssa/mir/analyze.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,10 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
105105
) {
106106
let cx = self.fx.cx;
107107

108-
if let Some(proj) = place_ref.projection {
108+
if let [.., elem] = place_ref.projection {
109+
// FIXME(spastorino) include this in the pattern when stabilized
110+
let proj_base = &place_ref.projection[..place_ref.projection.len() - 1];
111+
109112
// Allow uses of projections that are ZSTs or from scalar fields.
110113
let is_consume = match context {
111114
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) |
@@ -114,12 +117,12 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
114117
};
115118
if is_consume {
116119
let base_ty =
117-
mir::Place::ty_from(place_ref.base, &proj.base, self.fx.mir, cx.tcx());
120+
mir::Place::ty_from(place_ref.base, proj_base, self.fx.mir, cx.tcx());
118121
let base_ty = self.fx.monomorphize(&base_ty);
119122

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

134-
if let mir::ProjectionElem::Field(..) = proj.elem {
137+
if let mir::ProjectionElem::Field(..) = elem {
135138
let layout = cx.spanned_layout_of(base_ty.ty, span);
136139
if cx.is_backend_immediate(layout) || cx.is_backend_scalar_pair(layout) {
137140
// Recurse with the same context, instead of `Projection`,
@@ -140,7 +143,7 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
140143
self.process_place(
141144
&mir::PlaceRef {
142145
base: place_ref.base,
143-
projection: &proj.base,
146+
projection: proj_base,
144147
},
145148
context,
146149
location,
@@ -151,11 +154,11 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
151154
}
152155

153156
// A deref projection only reads the pointer, never needs the place.
154-
if let mir::ProjectionElem::Deref = proj.elem {
157+
if let mir::ProjectionElem::Deref = elem {
155158
self.process_place(
156159
&mir::PlaceRef {
157160
base: place_ref.base,
158-
projection: &proj.base,
161+
projection: proj_base,
159162
},
160163
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
161164
location
@@ -168,7 +171,7 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
168171
// visit_place API
169172
let mut context = context;
170173

171-
if place_ref.projection.is_some() {
174+
if !place_ref.projection.is_empty() {
172175
context = if context.is_mutating_use() {
173176
PlaceContext::MutatingUse(MutatingUseContext::Projection)
174177
} else {
@@ -177,10 +180,7 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
177180
}
178181

179182
self.visit_place_base(place_ref.base, context, location);
180-
181-
if let Some(box proj) = place_ref.projection {
182-
self.visit_projection(place_ref.base, proj, context, location);
183-
}
183+
self.visit_projection(place_ref.base, place_ref.projection, context, location);
184184
}
185185

186186
}
@@ -196,7 +196,7 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
196196

197197
if let mir::Place {
198198
base: mir::PlaceBase::Local(index),
199-
projection: None,
199+
projection: box [],
200200
} = *place {
201201
self.assign(index, location);
202202
let decl_span = self.fx.mir.local_decls[index].source_info.span;

src/librustc_codegen_ssa/mir/block.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
253253

254254
PassMode::Direct(_) | PassMode::Pair(..) => {
255255
let op =
256-
self.codegen_consume(&mut bx, &mir::Place::RETURN_PLACE.as_ref());
256+
self.codegen_consume(&mut bx, &mir::Place::return_place().as_ref());
257257
if let Ref(llval, _, align) = op.val {
258258
bx.load(llval, align)
259259
} else {
@@ -612,7 +612,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
612612
ty,
613613
def_id: _,
614614
}),
615-
projection: None,
615+
projection: box [],
616616
}
617617
) |
618618
mir::Operand::Move(
@@ -622,7 +622,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
622622
ty,
623623
def_id: _,
624624
}),
625-
projection: None,
625+
projection: box [],
626626
}
627627
) => {
628628
let param_env = ty::ParamEnv::reveal_all();
@@ -1105,7 +1105,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
11051105
}
11061106
let dest = if let mir::Place {
11071107
base: mir::PlaceBase::Local(index),
1108-
projection: None,
1108+
projection: box [],
11091109
} = *dest {
11101110
match self.locals[index] {
11111111
LocalRef::Place(dest) => dest,
@@ -1166,7 +1166,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
11661166
) {
11671167
if let mir::Place {
11681168
base: mir::PlaceBase::Local(index),
1169-
projection: None,
1169+
projection: box [],
11701170
} = *dst {
11711171
match self.locals[index] {
11721172
LocalRef::Place(place) => self.codegen_transmute_into(bx, src, place),

src/librustc_codegen_ssa/mir/operand.rs

Lines changed: 33 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -384,47 +384,45 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
384384
) -> Option<OperandRef<'tcx, Bx::Value>> {
385385
debug!("maybe_codegen_consume_direct(place_ref={:?})", place_ref);
386386

387-
place_ref.iterate(|place_base, place_projection| {
388-
if let mir::PlaceBase::Local(index) = place_base {
389-
match self.locals[*index] {
390-
LocalRef::Operand(Some(mut o)) => {
391-
// Moves out of scalar and scalar pair fields are trivial.
392-
for proj in place_projection {
393-
match proj.elem {
394-
mir::ProjectionElem::Field(ref f, _) => {
395-
o = o.extract_field(bx, f.index());
396-
}
397-
mir::ProjectionElem::Index(_) |
398-
mir::ProjectionElem::ConstantIndex { .. } => {
399-
// ZSTs don't require any actual memory access.
400-
// FIXME(eddyb) deduplicate this with the identical
401-
// checks in `codegen_consume` and `extract_field`.
402-
let elem = o.layout.field(bx.cx(), 0);
403-
if elem.is_zst() {
404-
o = OperandRef::new_zst(bx, elem);
405-
} else {
406-
return None;
407-
}
387+
if let mir::PlaceBase::Local(index) = place_ref.base {
388+
match self.locals[*index] {
389+
LocalRef::Operand(Some(mut o)) => {
390+
// Moves out of scalar and scalar pair fields are trivial.
391+
for elem in place_ref.projection.iter() {
392+
match elem {
393+
mir::ProjectionElem::Field(ref f, _) => {
394+
o = o.extract_field(bx, f.index());
395+
}
396+
mir::ProjectionElem::Index(_) |
397+
mir::ProjectionElem::ConstantIndex { .. } => {
398+
// ZSTs don't require any actual memory access.
399+
// FIXME(eddyb) deduplicate this with the identical
400+
// checks in `codegen_consume` and `extract_field`.
401+
let elem = o.layout.field(bx.cx(), 0);
402+
if elem.is_zst() {
403+
o = OperandRef::new_zst(bx, elem);
404+
} else {
405+
return None;
408406
}
409-
_ => return None,
410407
}
408+
_ => return None,
411409
}
412-
413-
Some(o)
414-
}
415-
LocalRef::Operand(None) => {
416-
bug!("use of {:?} before def", place_ref);
417-
}
418-
LocalRef::Place(..) | LocalRef::UnsizedPlace(..) => {
419-
// watch out for locals that do not have an
420-
// alloca; they are handled somewhat differently
421-
None
422410
}
411+
412+
Some(o)
413+
}
414+
LocalRef::Operand(None) => {
415+
bug!("use of {:?} before def", place_ref);
416+
}
417+
LocalRef::Place(..) | LocalRef::UnsizedPlace(..) => {
418+
// watch out for locals that do not have an
419+
// alloca; they are handled somewhat differently
420+
None
423421
}
424-
} else {
425-
None
426422
}
427-
})
423+
} else {
424+
None
425+
}
428426
}
429427

430428
pub fn codegen_consume(

0 commit comments

Comments
 (0)