Skip to content

Commit f0c98c2

Browse files
committed
Allocate vec capacity upfront in coroutine layout computation
1 parent c6efb90 commit f0c98c2

File tree

1 file changed

+23
-21
lines changed

1 file changed

+23
-21
lines changed

compiler/rustc_mir_transform/src/coroutine.rs

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,15 @@
5252
5353
mod by_move_body;
5454
mod drop;
55-
use std::{iter, ops};
55+
use std::ops;
5656

5757
pub(super) use by_move_body::coroutine_by_move_body_def_id;
5858
use drop::{
5959
cleanup_async_drops, create_coroutine_drop_shim, create_coroutine_drop_shim_async,
6060
create_coroutine_drop_shim_proxy_async, elaborate_coroutine_drops, expand_async_drops,
6161
has_expandable_async_drops, insert_clean_drop,
6262
};
63+
use itertools::izip;
6364
use rustc_abi::{FieldIdx, VariantIdx};
6465
use rustc_data_structures::fx::FxHashSet;
6566
use rustc_errors::pluralize;
@@ -982,8 +983,8 @@ fn compute_layout<'tcx>(
982983
} = liveness;
983984

984985
// Gather live local types and their indices.
985-
let mut locals = IndexVec::<CoroutineSavedLocal, _>::new();
986-
let mut tys = IndexVec::<CoroutineSavedLocal, _>::new();
986+
let mut locals = IndexVec::<CoroutineSavedLocal, _>::with_capacity(saved_locals.domain_size());
987+
let mut tys = IndexVec::<CoroutineSavedLocal, _>::with_capacity(saved_locals.domain_size());
987988
for (saved_local, local) in saved_locals.iter_enumerated() {
988989
debug!("coroutine saved local {:?} => {:?}", saved_local, local);
989990

@@ -1017,38 +1018,39 @@ fn compute_layout<'tcx>(
10171018
// In debuginfo, these will correspond to the beginning (UNRESUMED) or end
10181019
// (RETURNED, POISONED) of the function.
10191020
let body_span = body.source_scopes[OUTERMOST_SOURCE_SCOPE].span;
1020-
let mut variant_source_info: IndexVec<VariantIdx, SourceInfo> = [
1021+
let mut variant_source_info: IndexVec<VariantIdx, SourceInfo> = IndexVec::with_capacity(
1022+
CoroutineArgs::RESERVED_VARIANTS + live_locals_at_suspension_points.len(),
1023+
);
1024+
variant_source_info.extend([
10211025
SourceInfo::outermost(body_span.shrink_to_lo()),
10221026
SourceInfo::outermost(body_span.shrink_to_hi()),
10231027
SourceInfo::outermost(body_span.shrink_to_hi()),
1024-
]
1025-
.iter()
1026-
.copied()
1027-
.collect();
1028+
]);
10281029

10291030
// Build the coroutine variant field list.
10301031
// Create a map from local indices to coroutine struct indices.
1031-
let mut variant_fields: IndexVec<VariantIdx, IndexVec<FieldIdx, CoroutineSavedLocal>> =
1032-
iter::repeat(IndexVec::new()).take(CoroutineArgs::RESERVED_VARIANTS).collect();
1032+
let mut variant_fields: IndexVec<VariantIdx, _> = IndexVec::from_elem_n(
1033+
IndexVec::new(),
1034+
CoroutineArgs::RESERVED_VARIANTS + live_locals_at_suspension_points.len(),
1035+
);
10331036
let mut remap = IndexVec::from_elem_n(None, saved_locals.domain_size());
1034-
for (suspension_point_idx, live_locals) in live_locals_at_suspension_points.iter().enumerate() {
1035-
let variant_index =
1036-
VariantIdx::from(CoroutineArgs::RESERVED_VARIANTS + suspension_point_idx);
1037-
let mut fields = IndexVec::new();
1038-
for (idx, saved_local) in live_locals.iter().enumerate() {
1039-
fields.push(saved_local);
1037+
for (live_locals, &source_info_at_suspension_point, (variant_index, fields)) in izip!(
1038+
&live_locals_at_suspension_points,
1039+
&source_info_at_suspension_points,
1040+
variant_fields.iter_enumerated_mut().skip(CoroutineArgs::RESERVED_VARIANTS)
1041+
) {
1042+
*fields = live_locals.iter().collect();
1043+
for (idx, &saved_local) in fields.iter_enumerated() {
10401044
// Note that if a field is included in multiple variants, we will
10411045
// just use the first one here. That's fine; fields do not move
10421046
// around inside coroutines, so it doesn't matter which variant
10431047
// index we access them by.
1044-
let idx = FieldIdx::from_usize(idx);
10451048
remap[locals[saved_local]] = Some((tys[saved_local].ty, variant_index, idx));
10461049
}
1047-
variant_fields.push(fields);
1048-
variant_source_info.push(source_info_at_suspension_points[suspension_point_idx]);
1050+
variant_source_info.push(source_info_at_suspension_point);
10491051
}
1050-
debug!("coroutine variant_fields = {:?}", variant_fields);
1051-
debug!("coroutine storage_conflicts = {:#?}", storage_conflicts);
1052+
debug!(?variant_fields);
1053+
debug!(?storage_conflicts);
10521054

10531055
let mut field_names = IndexVec::from_elem(None, &tys);
10541056
for var in &body.var_debug_info {

0 commit comments

Comments
 (0)