Skip to content

Commit b28efb1

Browse files
committed
Save 2 pointers in TerminatorKind (96 → 80 bytes)
These things don't need to be `Vec`s; boxed slices are enough. The frequent one here is call arguments, but MIR building knows the number of arguments from the THIR, so the collect is always getting the allocation right in the first place, and thus this shouldn't ever add the shrink-in-place overhead.
1 parent 25c9f2c commit b28efb1

File tree

16 files changed

+72
-72
lines changed

16 files changed

+72
-72
lines changed

compiler/rustc_middle/src/mir/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1817,11 +1817,11 @@ mod size_asserts {
18171817
use super::*;
18181818
use rustc_data_structures::static_assert_size;
18191819
// tidy-alphabetical-start
1820-
static_assert_size!(BasicBlockData<'_>, 144);
1820+
static_assert_size!(BasicBlockData<'_>, 128);
18211821
static_assert_size!(LocalDecl<'_>, 40);
18221822
static_assert_size!(SourceScopeData<'_>, 64);
18231823
static_assert_size!(Statement<'_>, 32);
1824-
static_assert_size!(Terminator<'_>, 112);
1824+
static_assert_size!(Terminator<'_>, 96);
18251825
static_assert_size!(VarDebugInfo<'_>, 88);
18261826
// tidy-alphabetical-end
18271827
}

compiler/rustc_middle/src/mir/syntax.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,7 @@ pub enum TerminatorKind<'tcx> {
730730
/// reused across function calls without duplicating the contents.
731731
/// The span for each arg is also included
732732
/// (e.g. `a` and `b` in `x.foo(a, b)`).
733-
args: Vec<Spanned<Operand<'tcx>>>,
733+
args: Box<[Spanned<Operand<'tcx>>]>,
734734
/// Where the returned value will be written
735735
destination: Place<'tcx>,
736736
/// Where to go after this call returns. If none, the call necessarily diverges.
@@ -837,7 +837,7 @@ pub enum TerminatorKind<'tcx> {
837837
template: &'tcx [InlineAsmTemplatePiece],
838838

839839
/// The operands for the inline assembly, as `Operand`s or `Place`s.
840-
operands: Vec<InlineAsmOperand<'tcx>>,
840+
operands: Box<[InlineAsmOperand<'tcx>]>,
841841

842842
/// Miscellaneous options for the inline assembly.
843843
options: InlineAsmOptions,
@@ -849,7 +849,7 @@ pub enum TerminatorKind<'tcx> {
849849
/// Valid targets for the inline assembly.
850850
/// The first element is the fallthrough destination, unless
851851
/// InlineAsmOptions::NORETURN is set.
852-
targets: Vec<BasicBlock>,
852+
targets: Box<[BasicBlock]>,
853853

854854
/// Action to be taken if the inline assembly unwinds. This is present
855855
/// if and only if InlineAsmOptions::MAY_UNWIND is set.
@@ -1561,6 +1561,6 @@ mod size_asserts {
15611561
static_assert_size!(PlaceElem<'_>, 24);
15621562
static_assert_size!(Rvalue<'_>, 40);
15631563
static_assert_size!(StatementKind<'_>, 16);
1564-
static_assert_size!(TerminatorKind<'_>, 96);
1564+
static_assert_size!(TerminatorKind<'_>, 80);
15651565
// tidy-alphabetical-end
15661566
}

compiler/rustc_mir_build/src/build/custom/parse/instruction.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
170170
.map(|arg|
171171
Ok(Spanned { node: self.parse_operand(*arg)?, span: self.thir.exprs[*arg].span } )
172172
)
173-
.collect::<PResult<Vec<_>>>()?;
173+
.collect::<PResult<Box<[_]>>>()?;
174174
Ok(TerminatorKind::Call {
175175
func: fun,
176176
args,

compiler/rustc_mir_build/src/build/expr/as_rvalue.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
152152
source_info,
153153
TerminatorKind::Call {
154154
func: exchange_malloc,
155-
args: vec![
155+
args: [
156156
Spanned { node: Operand::Move(size), span: DUMMY_SP },
157157
Spanned { node: Operand::Move(align), span: DUMMY_SP },
158-
],
158+
]
159+
.into(),
159160
destination: storage,
160161
target: Some(success),
161162
unwind: UnwindAction::Continue,

compiler/rustc_mir_build/src/build/expr/into.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
238238
}
239239
ExprKind::Call { ty: _, fun, ref args, from_hir_call, fn_span } => {
240240
let fun = unpack!(block = this.as_local_operand(block, fun));
241-
let args: Vec<_> = args
241+
let args: Box<[_]> = args
242242
.into_iter()
243243
.copied()
244244
.map(|arg| Spanned {
@@ -485,7 +485,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
485485
operands,
486486
options,
487487
line_spans,
488-
targets,
488+
targets: targets.into_boxed_slice(),
489489
unwind: if options.contains(InlineAsmOptions::MAY_UNWIND) {
490490
UnwindAction::Continue
491491
} else {

compiler/rustc_mir_build/src/build/matches/test.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
324324
user_ty: None,
325325
const_: method,
326326
})),
327-
args: vec![Spanned { node: Operand::Move(ref_src), span }],
327+
args: [Spanned { node: Operand::Move(ref_src), span }].into(),
328328
destination: temp,
329329
target: Some(target_block),
330330
unwind: UnwindAction::Continue,
@@ -486,10 +486,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
486486

487487
const_: method,
488488
})),
489-
args: vec![
489+
args: [
490490
Spanned { node: Operand::Copy(val), span: DUMMY_SP },
491491
Spanned { node: expect, span: DUMMY_SP },
492-
],
492+
]
493+
.into(),
493494
destination: eq_result,
494495
target: Some(eq_block),
495496
unwind: UnwindAction::Continue,

compiler/rustc_mir_dataflow/src/elaborate_drops.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -650,10 +650,8 @@ where
650650
[ty.into()],
651651
self.source_info.span,
652652
),
653-
args: vec![Spanned {
654-
node: Operand::Move(Place::from(ref_place)),
655-
span: DUMMY_SP,
656-
}],
653+
args: [Spanned { node: Operand::Move(Place::from(ref_place)), span: DUMMY_SP }]
654+
.into(),
657655
destination: unit_temp,
658656
target: Some(succ),
659657
unwind: unwind.into_action(),

compiler/rustc_mir_dataflow/src/framework/tests.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ fn mock_body<'tcx>() -> mir::Body<'tcx> {
3434
2,
3535
mir::TerminatorKind::Call {
3636
func: mir::Operand::Copy(dummy_place.clone()),
37-
args: vec![],
37+
args: [].into(),
3838
destination: dummy_place.clone(),
3939
target: Some(mir::START_BLOCK),
4040
unwind: mir::UnwindAction::Continue,
@@ -48,7 +48,7 @@ fn mock_body<'tcx>() -> mir::Body<'tcx> {
4848
4,
4949
mir::TerminatorKind::Call {
5050
func: mir::Operand::Copy(dummy_place.clone()),
51-
args: vec![],
51+
args: [].into(),
5252
destination: dummy_place.clone(),
5353
target: Some(mir::START_BLOCK),
5454
unwind: mir::UnwindAction::Continue,

compiler/rustc_mir_transform/src/coroutine.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -677,8 +677,8 @@ fn transform_async_context<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
677677

678678
fn eliminate_get_context_call<'tcx>(bb_data: &mut BasicBlockData<'tcx>) -> Local {
679679
let terminator = bb_data.terminator.take().unwrap();
680-
if let TerminatorKind::Call { mut args, destination, target, .. } = terminator.kind {
681-
let arg = args.pop().unwrap();
680+
if let TerminatorKind::Call { args, destination, target, .. } = terminator.kind {
681+
let [arg] = *Box::try_from(args).unwrap();
682682
let local = arg.node.place().unwrap().local;
683683

684684
let arg = Rvalue::Use(arg.node);

compiler/rustc_mir_transform/src/coverage/tests.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ impl<'tcx> MockBlocks<'tcx> {
134134
some_from_block,
135135
TerminatorKind::Call {
136136
func: Operand::Copy(self.dummy_place.clone()),
137-
args: vec![],
137+
args: [].into(),
138138
destination: self.dummy_place.clone(),
139139
target: Some(TEMP_BLOCK),
140140
unwind: UnwindAction::Continue,

compiler/rustc_mir_transform/src/inline.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -624,8 +624,7 @@ impl<'tcx> Inliner<'tcx> {
624624
};
625625

626626
// Copy the arguments if needed.
627-
let args: Vec<_> =
628-
self.make_call_args(args, &callsite, caller_body, &callee_body, return_block);
627+
let args = self.make_call_args(args, &callsite, caller_body, &callee_body, return_block);
629628

630629
let mut integrator = Integrator {
631630
args: &args,
@@ -736,12 +735,12 @@ impl<'tcx> Inliner<'tcx> {
736735

737736
fn make_call_args(
738737
&self,
739-
args: Vec<Spanned<Operand<'tcx>>>,
738+
args: Box<[Spanned<Operand<'tcx>>]>,
740739
callsite: &CallSite<'tcx>,
741740
caller_body: &mut Body<'tcx>,
742741
callee_body: &Body<'tcx>,
743742
return_block: Option<BasicBlock>,
744-
) -> Vec<Local> {
743+
) -> Box<[Local]> {
745744
let tcx = self.tcx;
746745

747746
// There is a bit of a mismatch between the *caller* of a closure and the *callee*.
@@ -768,7 +767,8 @@ impl<'tcx> Inliner<'tcx> {
768767
//
769768
// and the vector is `[closure_ref, tmp0, tmp1, tmp2]`.
770769
if callsite.fn_sig.abi() == Abi::RustCall && callee_body.spread_arg.is_none() {
771-
let mut args = args.into_iter();
770+
// FIXME(edition_2024): switch back to a normal method call.
771+
let mut args = <_>::into_iter(args);
772772
let self_ = self.create_temp_if_necessary(
773773
args.next().unwrap().node,
774774
callsite,
@@ -802,7 +802,8 @@ impl<'tcx> Inliner<'tcx> {
802802

803803
closure_ref_arg.chain(tuple_tmp_args).collect()
804804
} else {
805-
args.into_iter()
805+
// FIXME(edition_2024): switch back to a normal method call.
806+
<_>::into_iter(args)
806807
.map(|a| self.create_temp_if_necessary(a.node, callsite, caller_body, return_block))
807808
.collect()
808809
}

compiler/rustc_mir_transform/src/instsimplify.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Performs various peephole optimizations.
22
33
use crate::simplify::simplify_duplicate_switch_targets;
4+
use crate::take_array;
45
use rustc_ast::attr;
56
use rustc_middle::bug;
67
use rustc_middle::mir::*;
@@ -285,7 +286,8 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
285286
return;
286287
}
287288

288-
let Some(arg_place) = args.pop().unwrap().node.place() else { return };
289+
let Ok([arg]) = take_array(args) else { return };
290+
let Some(arg_place) = arg.node.place() else { return };
289291

290292
statements.push(Statement {
291293
source_info: terminator.source_info,

compiler/rustc_mir_transform/src/lib.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,9 @@ fn remap_mir_for_const_eval_select<'tcx>(
160160
} if let ty::FnDef(def_id, _) = *const_.ty().kind()
161161
&& tcx.is_intrinsic(def_id, sym::const_eval_select) =>
162162
{
163-
let [tupled_args, called_in_const, called_at_rt]: [_; 3] =
164-
std::mem::take(args).try_into().unwrap();
163+
let Ok([tupled_args, called_in_const, called_at_rt]) = take_array(args) else {
164+
unreachable!()
165+
};
165166
let ty = tupled_args.node.ty(&body.local_decls, tcx);
166167
let fields = ty.tuple_fields();
167168
let num_args = fields.len();
@@ -211,6 +212,11 @@ fn remap_mir_for_const_eval_select<'tcx>(
211212
body
212213
}
213214

215+
fn take_array<T, const N: usize>(b: &mut Box<[T]>) -> Result<[T; N], Box<[T]>> {
216+
let b: Box<[T; N]> = std::mem::take(b).try_into()?;
217+
Ok(*b)
218+
}
219+
214220
fn is_mir_available(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
215221
tcx.mir_keys(()).contains(&def_id)
216222
}

compiler/rustc_mir_transform/src/lower_intrinsics.rs

+23-38
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Lowers intrinsic calls
22
3+
use crate::take_array;
34
use rustc_middle::mir::*;
45
use rustc_middle::ty::{self, TyCtxt};
56
use rustc_middle::{bug, span_bug};
@@ -50,42 +51,34 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
5051
}
5152
sym::copy_nonoverlapping => {
5253
let target = target.unwrap();
53-
let mut args = args.drain(..);
54+
let Ok([src, dst, count]) = take_array(args) else {
55+
bug!("Wrong arguments for copy_non_overlapping intrinsic");
56+
};
5457
block.statements.push(Statement {
5558
source_info: terminator.source_info,
5659
kind: StatementKind::Intrinsic(Box::new(
5760
NonDivergingIntrinsic::CopyNonOverlapping(
5861
rustc_middle::mir::CopyNonOverlapping {
59-
src: args.next().unwrap().node,
60-
dst: args.next().unwrap().node,
61-
count: args.next().unwrap().node,
62+
src: src.node,
63+
dst: dst.node,
64+
count: count.node,
6265
},
6366
),
6467
)),
6568
});
66-
assert_eq!(
67-
args.next(),
68-
None,
69-
"Extra argument for copy_non_overlapping intrinsic"
70-
);
71-
drop(args);
7269
terminator.kind = TerminatorKind::Goto { target };
7370
}
7471
sym::assume => {
7572
let target = target.unwrap();
76-
let mut args = args.drain(..);
73+
let Ok([arg]) = take_array(args) else {
74+
bug!("Wrong arguments for assume intrinsic");
75+
};
7776
block.statements.push(Statement {
7877
source_info: terminator.source_info,
7978
kind: StatementKind::Intrinsic(Box::new(
80-
NonDivergingIntrinsic::Assume(args.next().unwrap().node),
79+
NonDivergingIntrinsic::Assume(arg.node),
8180
)),
8281
});
83-
assert_eq!(
84-
args.next(),
85-
None,
86-
"Extra argument for copy_non_overlapping intrinsic"
87-
);
88-
drop(args);
8982
terminator.kind = TerminatorKind::Goto { target };
9083
}
9184
sym::wrapping_add
@@ -100,13 +93,9 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
10093
| sym::unchecked_shl
10194
| sym::unchecked_shr => {
10295
let target = target.unwrap();
103-
let lhs;
104-
let rhs;
105-
{
106-
let mut args = args.drain(..);
107-
lhs = args.next().unwrap();
108-
rhs = args.next().unwrap();
109-
}
96+
let Ok([lhs, rhs]) = take_array(args) else {
97+
bug!("Wrong arguments for {} intrinsic", intrinsic.name);
98+
};
11099
let bin_op = match intrinsic.name {
111100
sym::wrapping_add => BinOp::Add,
112101
sym::wrapping_sub => BinOp::Sub,
@@ -132,13 +121,9 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
132121
}
133122
sym::add_with_overflow | sym::sub_with_overflow | sym::mul_with_overflow => {
134123
if let Some(target) = *target {
135-
let lhs;
136-
let rhs;
137-
{
138-
let mut args = args.drain(..);
139-
lhs = args.next().unwrap();
140-
rhs = args.next().unwrap();
141-
}
124+
let Ok([lhs, rhs]) = take_array(args) else {
125+
bug!("Wrong arguments for {} intrinsic", intrinsic.name);
126+
};
142127
let bin_op = match intrinsic.name {
143128
sym::add_with_overflow => BinOp::AddWithOverflow,
144129
sym::sub_with_overflow => BinOp::SubWithOverflow,
@@ -174,7 +159,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
174159
}
175160
}
176161
sym::read_via_copy => {
177-
let [arg] = args.as_slice() else {
162+
let Ok([arg]) = take_array(args) else {
178163
span_bug!(terminator.source_info.span, "Wrong number of arguments");
179164
};
180165
let derefed_place = if let Some(place) = arg.node.place()
@@ -207,7 +192,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
207192
}
208193
sym::write_via_move => {
209194
let target = target.unwrap();
210-
let Ok([ptr, val]) = <[_; 2]>::try_from(std::mem::take(args)) else {
195+
let Ok([ptr, val]) = take_array(args) else {
211196
span_bug!(
212197
terminator.source_info.span,
213198
"Wrong number of arguments for write_via_move intrinsic",
@@ -247,7 +232,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
247232
}
248233
sym::offset => {
249234
let target = target.unwrap();
250-
let Ok([ptr, delta]) = <[_; 2]>::try_from(std::mem::take(args)) else {
235+
let Ok([ptr, delta]) = take_array(args) else {
251236
span_bug!(
252237
terminator.source_info.span,
253238
"Wrong number of arguments for offset intrinsic",
@@ -264,7 +249,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
264249
}
265250
sym::transmute | sym::transmute_unchecked => {
266251
let dst_ty = destination.ty(local_decls, tcx).ty;
267-
let Ok([arg]) = <[_; 1]>::try_from(std::mem::take(args)) else {
252+
let Ok([arg]) = take_array(args) else {
268253
span_bug!(
269254
terminator.source_info.span,
270255
"Wrong number of arguments for transmute intrinsic",
@@ -289,7 +274,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
289274
}
290275
}
291276
sym::aggregate_raw_ptr => {
292-
let Ok([data, meta]) = <[_; 2]>::try_from(std::mem::take(args)) else {
277+
let Ok([data, meta]) = take_array(args) else {
293278
span_bug!(
294279
terminator.source_info.span,
295280
"Wrong number of arguments for aggregate_raw_ptr intrinsic",
@@ -317,7 +302,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
317302
terminator.kind = TerminatorKind::Goto { target };
318303
}
319304
sym::ptr_metadata => {
320-
let Ok([ptr]) = <[_; 1]>::try_from(std::mem::take(args)) else {
305+
let Ok([ptr]) = take_array(args) else {
321306
span_bug!(
322307
terminator.source_info.span,
323308
"Wrong number of arguments for ptr_metadata intrinsic",

0 commit comments

Comments
 (0)