Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit bb78059

Browse files
committed
Auto merge of rust-lang#14847 - HKalbasi:layout, r=HKalbasi
Reduce MIR memory usage
2 parents ce93617 + 23ce228 commit bb78059

File tree

6 files changed

+83
-55
lines changed

6 files changed

+83
-55
lines changed

crates/hir-ty/src/mir.rs

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ type PlaceElem = ProjectionElem<LocalId, Ty>;
205205
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
206206
pub struct Place {
207207
pub local: LocalId,
208-
pub projection: Vec<PlaceElem>,
208+
pub projection: Box<[PlaceElem]>,
209209
}
210210

211211
impl Place {
@@ -216,13 +216,20 @@ impl Place {
216216
fn iterate_over_parents(&self) -> impl Iterator<Item = Place> + '_ {
217217
(0..self.projection.len())
218218
.map(|x| &self.projection[0..x])
219-
.map(|x| Place { local: self.local, projection: x.to_vec() })
219+
.map(|x| Place { local: self.local, projection: x.to_vec().into() })
220+
}
221+
222+
fn project(&self, projection: PlaceElem) -> Place {
223+
Place {
224+
local: self.local,
225+
projection: self.projection.iter().cloned().chain([projection]).collect(),
226+
}
220227
}
221228
}
222229

223230
impl From<LocalId> for Place {
224231
fn from(local: LocalId) -> Self {
225-
Self { local, projection: vec![] }
232+
Self { local, projection: vec![].into() }
226233
}
227234
}
228235

@@ -437,7 +444,7 @@ pub enum TerminatorKind {
437444
/// These are owned by the callee, which is free to modify them.
438445
/// This allows the memory occupied by "by-value" arguments to be
439446
/// reused across function calls without duplicating the contents.
440-
args: Vec<Operand>,
447+
args: Box<[Operand]>,
441448
/// Where the returned value will be written
442449
destination: Place,
443450
/// Where to go after this call returns. If none, the call necessarily diverges.
@@ -894,7 +901,7 @@ pub enum Rvalue {
894901
///
895902
/// Disallowed after deaggregation for all aggregate kinds except `Array` and `Generator`. After
896903
/// generator lowering, `Generator` aggregate kinds are disallowed too.
897-
Aggregate(AggregateKind, Vec<Operand>),
904+
Aggregate(AggregateKind, Box<[Operand]>),
898905

899906
/// Transmutes a `*mut u8` into shallow-initialized `Box<T>`.
900907
///
@@ -1011,7 +1018,7 @@ impl MirBody {
10111018
for_operand(o2, &mut f);
10121019
}
10131020
Rvalue::Aggregate(_, ops) => {
1014-
for op in ops {
1021+
for op in ops.iter_mut() {
10151022
for_operand(op, &mut f);
10161023
}
10171024
}
@@ -1058,6 +1065,27 @@ impl MirBody {
10581065
}
10591066
}
10601067
}
1068+
1069+
fn shrink_to_fit(&mut self) {
1070+
let MirBody {
1071+
basic_blocks,
1072+
locals,
1073+
start_block: _,
1074+
owner: _,
1075+
binding_locals,
1076+
param_locals,
1077+
closures,
1078+
} = self;
1079+
basic_blocks.shrink_to_fit();
1080+
locals.shrink_to_fit();
1081+
binding_locals.shrink_to_fit();
1082+
param_locals.shrink_to_fit();
1083+
closures.shrink_to_fit();
1084+
for (_, b) in basic_blocks.iter_mut() {
1085+
let BasicBlock { statements, terminator: _, is_cleanup: _ } = b;
1086+
statements.shrink_to_fit();
1087+
}
1088+
}
10611089
}
10621090

10631091
#[derive(Debug, PartialEq, Eq, Clone, Copy)]

crates/hir-ty/src/mir/borrowck.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ fn moved_out_of_ref(db: &dyn HirDatabase, body: &MirBody) -> Vec<MovedOutOfRef>
9393
Operand::Copy(p) | Operand::Move(p) => {
9494
let mut ty: Ty = body.locals[p.local].ty.clone();
9595
let mut is_dereference_of_ref = false;
96-
for proj in &p.projection {
96+
for proj in &*p.projection {
9797
if *proj == ProjectionElem::Deref && ty.as_reference().is_some() {
9898
is_dereference_of_ref = true;
9999
}
@@ -143,7 +143,7 @@ fn moved_out_of_ref(db: &dyn HirDatabase, body: &MirBody) -> Vec<MovedOutOfRef>
143143
for_operand(o2, statement.span);
144144
}
145145
Rvalue::Aggregate(_, ops) => {
146-
for op in ops {
146+
for op in ops.iter() {
147147
for_operand(op, statement.span);
148148
}
149149
}

crates/hir-ty/src/mir/eval.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,7 @@ impl Evaluator<'_> {
562562
let mut ty: Ty =
563563
self.ty_filler(&locals.body.locals[p.local].ty, locals.subst, locals.body.owner)?;
564564
let mut metadata: Option<IntervalOrOwned> = None; // locals are always sized
565-
for proj in &p.projection {
565+
for proj in &*p.projection {
566566
let prev_ty = ty.clone();
567567
ty = proj.projected_ty(
568568
ty,

crates/hir-ty/src/mir/lower.rs

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
387387
current,
388388
place,
389389
ty,
390-
vec![],
390+
Box::new([]),
391391
expr_id.into(),
392392
)?;
393393
}
@@ -561,7 +561,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
561561
};
562562
self.push_assignment(current, ref_mut_iterator_place.clone(), Rvalue::Ref(BorrowKind::Mut { allow_two_phase_borrow: false }, iterator_place), expr_id.into());
563563
self.lower_loop(current, place, label, expr_id.into(), |this, begin| {
564-
let Some(current) = this.lower_call(iter_next_fn_op, vec![Operand::Copy(ref_mut_iterator_place)], option_item_place.clone(), begin, false, expr_id.into())?
564+
let Some(current) = this.lower_call(iter_next_fn_op, Box::new([Operand::Copy(ref_mut_iterator_place)]), option_item_place.clone(), begin, false, expr_id.into())?
565565
else {
566566
return Ok(());
567567
};
@@ -758,8 +758,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
758758
match x {
759759
Some(x) => x,
760760
None => {
761-
let mut p = sp.clone();
762-
p.projection.push(ProjectionElem::Field(FieldId {
761+
let p = sp.project(ProjectionElem::Field(FieldId {
763762
parent: variant_id,
764763
local_id: LocalFieldId::from_raw(RawIdx::from(i as u32)),
765764
}));
@@ -782,10 +781,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
782781
};
783782
let local_id =
784783
variant_data.field(name).ok_or(MirLowerError::UnresolvedField)?;
785-
let mut place = place;
786-
place
787-
.projection
788-
.push(PlaceElem::Field(FieldId { parent: union_id.into(), local_id }));
784+
let place = place.project(PlaceElem::Field(FieldId { parent: union_id.into(), local_id }));
789785
self.lower_expr_to_place(*expr, place, current)
790786
}
791787
}
@@ -826,8 +822,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
826822
let Some((operand, current)) = self.lower_expr_to_some_operand(*expr, current)? else {
827823
return Ok(None);
828824
};
829-
let mut p = place;
830-
p.projection.push(ProjectionElem::Deref);
825+
let p = place.project(ProjectionElem::Deref);
831826
self.push_assignment(current, p, operand.into(), expr_id.into());
832827
Ok(Some(current))
833828
},
@@ -1031,7 +1026,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
10311026
self.push_assignment(
10321027
current,
10331028
place,
1034-
Rvalue::Aggregate(AggregateKind::Closure(ty), operands),
1029+
Rvalue::Aggregate(AggregateKind::Closure(ty), operands.into()),
10351030
expr_id.into(),
10361031
);
10371032
Ok(Some(current))
@@ -1128,11 +1123,11 @@ impl<'ctx> MirLowerCtx<'ctx> {
11281123
let index = name
11291124
.as_tuple_index()
11301125
.ok_or(MirLowerError::TypeError("named field on tuple"))?;
1131-
place.projection.push(ProjectionElem::TupleOrClosureField(index))
1126+
*place = place.project(ProjectionElem::TupleOrClosureField(index))
11321127
} else {
11331128
let field =
11341129
self.infer.field_resolution(expr_id).ok_or(MirLowerError::UnresolvedField)?;
1135-
place.projection.push(ProjectionElem::Field(field));
1130+
*place = place.project(ProjectionElem::Field(field));
11361131
}
11371132
} else {
11381133
not_supported!("")
@@ -1242,7 +1237,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
12421237
prev_block: BasicBlockId,
12431238
place: Place,
12441239
ty: Ty,
1245-
fields: Vec<Operand>,
1240+
fields: Box<[Operand]>,
12461241
span: MirSpan,
12471242
) -> Result<BasicBlockId> {
12481243
let subst = match ty.kind(Interner) {
@@ -1280,13 +1275,13 @@ impl<'ctx> MirLowerCtx<'ctx> {
12801275
else {
12811276
return Ok(None);
12821277
};
1283-
self.lower_call(func, args, place, current, is_uninhabited, span)
1278+
self.lower_call(func, args.into(), place, current, is_uninhabited, span)
12841279
}
12851280

12861281
fn lower_call(
12871282
&mut self,
12881283
func: Operand,
1289-
args: Vec<Operand>,
1284+
args: Box<[Operand]>,
12901285
place: Place,
12911286
current: BasicBlockId,
12921287
is_uninhabited: bool,
@@ -1744,12 +1739,13 @@ pub fn mir_body_for_closure_query(
17441739
match r {
17451740
Some(x) => {
17461741
p.local = closure_local;
1747-
let prev_projs =
1748-
mem::replace(&mut p.projection, vec![PlaceElem::TupleOrClosureField(x.1)]);
1742+
let mut next_projs = vec![PlaceElem::TupleOrClosureField(x.1)];
1743+
let prev_projs = mem::take(&mut p.projection);
17491744
if x.0.kind != CaptureKind::ByValue {
1750-
p.projection.push(ProjectionElem::Deref);
1745+
next_projs.push(ProjectionElem::Deref);
17511746
}
1752-
p.projection.extend(prev_projs.into_iter().skip(x.0.place.projections.len()));
1747+
next_projs.extend(prev_projs.iter().cloned().skip(x.0.place.projections.len()));
1748+
p.projection = next_projs.into();
17531749
}
17541750
None => err = Some(p.clone()),
17551751
}
@@ -1764,6 +1760,7 @@ pub fn mir_body_for_closure_query(
17641760
if let Some(err) = err {
17651761
return Err(MirLowerError::UnresolvedUpvar(err));
17661762
}
1763+
ctx.result.shrink_to_fit();
17671764
Ok(Arc::new(ctx.result))
17681765
}
17691766

@@ -1780,7 +1777,8 @@ pub fn mir_body_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Result<Arc<Mi
17801777
});
17811778
let body = db.body(def);
17821779
let infer = db.infer(def);
1783-
let result = lower_to_mir(db, def, &body, &infer, body.body_expr)?;
1780+
let mut result = lower_to_mir(db, def, &body, &infer, body.body_expr)?;
1781+
result.shrink_to_fit();
17841782
Ok(Arc::new(result))
17851783
}
17861784

crates/hir-ty/src/mir/lower/as_place.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ impl MirLowerCtx<'_> {
6565
)? else {
6666
return Ok(None);
6767
};
68-
x.0.projection.push(ProjectionElem::Deref);
68+
x.0 = x.0.project(ProjectionElem::Deref);
6969
Ok(Some(x))
7070
}
7171
Adjust::Deref(Some(od)) => {
@@ -139,15 +139,14 @@ impl MirLowerCtx<'_> {
139139
let ty = self.expr_ty_without_adjust(expr_id);
140140
let ref_ty =
141141
TyKind::Ref(Mutability::Not, static_lifetime(), ty).intern(Interner);
142-
let mut temp: Place = self.temp(ref_ty, current, expr_id.into())?.into();
142+
let temp: Place = self.temp(ref_ty, current, expr_id.into())?.into();
143143
self.push_assignment(
144144
current,
145145
temp.clone(),
146146
Operand::Static(s).into(),
147147
expr_id.into(),
148148
);
149-
temp.projection.push(ProjectionElem::Deref);
150-
Ok(Some((temp, current)))
149+
Ok(Some((temp.project(ProjectionElem::Deref), current)))
151150
}
152151
_ => try_rvalue(self),
153152
}
@@ -196,7 +195,7 @@ impl MirLowerCtx<'_> {
196195
let Some((mut r, current)) = self.lower_expr_as_place(current, *expr, true)? else {
197196
return Ok(None);
198197
};
199-
r.projection.push(ProjectionElem::Deref);
198+
r = r.project(ProjectionElem::Deref);
200199
Ok(Some((r, current)))
201200
}
202201
_ => try_rvalue(self),
@@ -253,7 +252,7 @@ impl MirLowerCtx<'_> {
253252
let Some(current) = self.lower_expr_to_place(*index, l_index.into(), current)? else {
254253
return Ok(None);
255254
};
256-
p_base.projection.push(ProjectionElem::Index(l_index));
255+
p_base = p_base.project(ProjectionElem::Index(l_index));
257256
Ok(Some((p_base, current)))
258257
}
259258
_ => try_rvalue(self),
@@ -283,10 +282,10 @@ impl MirLowerCtx<'_> {
283282
)
284283
.intern(Interner),
285284
);
286-
let Some(current) = self.lower_call(index_fn_op, vec![Operand::Copy(place), index_operand], result.clone(), current, false, span)? else {
285+
let Some(current) = self.lower_call(index_fn_op, Box::new([Operand::Copy(place), index_operand]), result.clone(), current, false, span)? else {
287286
return Ok(None);
288287
};
289-
result.projection.push(ProjectionElem::Deref);
288+
result = result.project(ProjectionElem::Deref);
290289
Ok(Some((result, current)))
291290
}
292291

@@ -330,10 +329,10 @@ impl MirLowerCtx<'_> {
330329
.intern(Interner),
331330
);
332331
let mut result: Place = self.temp(target_ty_ref, current, span)?.into();
333-
let Some(current) = self.lower_call(deref_fn_op, vec![Operand::Copy(ref_place)], result.clone(), current, false, span)? else {
332+
let Some(current) = self.lower_call(deref_fn_op, Box::new([Operand::Copy(ref_place)]), result.clone(), current, false, span)? else {
334333
return Ok(None);
335334
};
336-
result.projection.push(ProjectionElem::Deref);
335+
result = result.project(ProjectionElem::Deref);
337336
Ok(Some((result, current)))
338337
}
339338
}

crates/hir-ty/src/mir/lower/pattern_matching.rs

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,10 @@ impl MirLowerCtx<'_> {
110110
Pat::Slice { prefix, slice, suffix } => {
111111
pattern_matching_dereference(&mut cond_ty, &mut binding_mode, &mut cond_place);
112112
for (i, &pat) in prefix.iter().enumerate() {
113-
let mut next_place = cond_place.clone();
114-
next_place
115-
.projection
116-
.push(ProjectionElem::ConstantIndex { offset: i as u64, from_end: false });
113+
let next_place = cond_place.project(ProjectionElem::ConstantIndex {
114+
offset: i as u64,
115+
from_end: false,
116+
});
117117
let cond_ty = self.infer[pat].clone();
118118
(current, current_else) = self.pattern_match(
119119
current,
@@ -126,8 +126,7 @@ impl MirLowerCtx<'_> {
126126
}
127127
if let Some(slice) = slice {
128128
if let Pat::Bind { id, subpat: _ } = self.body[*slice] {
129-
let mut next_place = cond_place.clone();
130-
next_place.projection.push(ProjectionElem::Subslice {
129+
let next_place = cond_place.project(ProjectionElem::Subslice {
131130
from: prefix.len() as u64,
132131
to: suffix.len() as u64,
133132
});
@@ -142,10 +141,10 @@ impl MirLowerCtx<'_> {
142141
}
143142
}
144143
for (i, &pat) in suffix.iter().enumerate() {
145-
let mut next_place = cond_place.clone();
146-
next_place
147-
.projection
148-
.push(ProjectionElem::ConstantIndex { offset: i as u64, from_end: true });
144+
let next_place = cond_place.project(ProjectionElem::ConstantIndex {
145+
offset: i as u64,
146+
from_end: true,
147+
});
149148
let cond_ty = self.infer[pat].clone();
150149
(current, current_else) = self.pattern_match(
151150
current,
@@ -269,11 +268,10 @@ impl MirLowerCtx<'_> {
269268
Pat::Ref { pat, mutability: _ } => {
270269
if let Some((ty, _, _)) = cond_ty.as_reference() {
271270
cond_ty = ty.clone();
272-
cond_place.projection.push(ProjectionElem::Deref);
273271
self.pattern_match(
274272
current,
275273
current_else,
276-
cond_place,
274+
cond_place.project(ProjectionElem::Deref),
277275
cond_ty,
278276
*pat,
279277
binding_mode,
@@ -479,8 +477,7 @@ impl MirLowerCtx<'_> {
479477
binding_mode: BindingAnnotation,
480478
) -> Result<(BasicBlockId, Option<BasicBlockId>)> {
481479
for (proj, arg, ty) in args {
482-
let mut cond_place = cond_place.clone();
483-
cond_place.projection.push(proj);
480+
let cond_place = cond_place.project(proj);
484481
(current, current_else) =
485482
self.pattern_match(current, current_else, cond_place, ty, arg, binding_mode)?;
486483
}
@@ -513,5 +510,11 @@ fn pattern_matching_dereference(
513510
cond_place: &mut Place,
514511
) {
515512
let cnt = pattern_matching_dereference_count(cond_ty, binding_mode);
516-
cond_place.projection.extend((0..cnt).map(|_| ProjectionElem::Deref));
513+
cond_place.projection = cond_place
514+
.projection
515+
.iter()
516+
.cloned()
517+
.chain((0..cnt).map(|_| ProjectionElem::Deref))
518+
.collect::<Vec<_>>()
519+
.into();
517520
}

0 commit comments

Comments
 (0)