Skip to content

Commit 9a47f74

Browse files
Use SmallVec in SwitchTargets
This allows building common SwitchTargets (eg. for `if`s) without allocation.
1 parent 432535d commit 9a47f74

File tree

5 files changed

+14
-15
lines changed

5 files changed

+14
-15
lines changed

compiler/rustc_codegen_ssa/src/mir/block.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
196196
mut bx: Bx,
197197
discr: &mir::Operand<'tcx>,
198198
switch_ty: Ty<'tcx>,
199-
targets: &SwitchTargets<'tcx>,
199+
targets: &SwitchTargets,
200200
) {
201201
let discr = self.codegen_operand(&mut bx, &discr);
202202
// `switch_ty` is redundant, sanity-check that.

compiler/rustc_middle/src/mir/terminator/mod.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::mir::interpret::Scalar;
22
use crate::ty::{self, Ty, TyCtxt};
33
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
4+
use smallvec::{smallvec, SmallVec};
45

56
use super::{
67
AssertMessage, BasicBlock, InlineAsmOperand, Operand, Place, SourceInfo, Successors,
@@ -17,10 +18,10 @@ use std::slice;
1718
pub use super::query::*;
1819

1920
#[derive(Debug, Clone, TyEncodable, TyDecodable, HashStable, PartialEq)]
20-
pub struct SwitchTargets<'tcx> {
21+
pub struct SwitchTargets {
2122
/// Possible values. The locations to branch to in each case
2223
/// are found in the corresponding indices from the `targets` vector.
23-
values: Cow<'tcx, [u128]>,
24+
values: SmallVec<[u128; 1]>,
2425

2526
/// Possible branch sites. The last element of this vector is used
2627
/// for the otherwise branch, so targets.len() == values.len() + 1
@@ -34,24 +35,24 @@ pub struct SwitchTargets<'tcx> {
3435
//
3536
// However we’ve decided to keep this as-is until we figure a case
3637
// where some other approach seems to be strictly better than other.
37-
targets: Vec<BasicBlock>,
38+
targets: SmallVec<[BasicBlock; 2]>,
3839
}
3940

40-
impl<'tcx> SwitchTargets<'tcx> {
41+
impl SwitchTargets {
4142
/// Creates switch targets from an iterator of values and target blocks.
4243
///
4344
/// The iterator may be empty, in which case the `SwitchInt` instruction is equivalent to
4445
/// `goto otherwise;`.
4546
pub fn new(targets: impl Iterator<Item = (u128, BasicBlock)>, otherwise: BasicBlock) -> Self {
46-
let (values, mut targets): (Vec<_>, Vec<_>) = targets.unzip();
47+
let (values, mut targets): (SmallVec<_>, SmallVec<_>) = targets.unzip();
4748
targets.push(otherwise);
4849
Self { values: values.into(), targets }
4950
}
5051

5152
/// Builds a switch targets definition that jumps to `then` if the tested value equals `value`,
5253
/// and to `else_` if not.
53-
pub fn static_if(value: &'static [u128; 1], then: BasicBlock, else_: BasicBlock) -> Self {
54-
Self { values: Cow::Borrowed(value), targets: vec![then, else_] }
54+
pub fn static_if(value: u128, then: BasicBlock, else_: BasicBlock) -> Self {
55+
Self { values: smallvec![value], targets: smallvec![then, else_] }
5556
}
5657

5758
/// Returns the fallback target that is jumped to when none of the values match the operand.
@@ -113,7 +114,7 @@ pub enum TerminatorKind<'tcx> {
113114
/// FIXME: remove this redundant information. Currently, it is relied on by pretty-printing.
114115
switch_ty: Ty<'tcx>,
115116

116-
targets: SwitchTargets<'tcx>,
117+
targets: SwitchTargets,
117118
},
118119

119120
/// Indicates that the landing pad is finished and unwinding should
@@ -295,7 +296,7 @@ impl<'tcx> TerminatorKind<'tcx> {
295296
TerminatorKind::SwitchInt {
296297
discr: cond,
297298
switch_ty: tcx.types.bool,
298-
targets: SwitchTargets::static_if(&[0], f, t),
299+
targets: SwitchTargets::static_if(0, f, t),
299300
}
300301
}
301302

compiler/rustc_mir/src/dataflow/framework/direction.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,7 @@ impl Direction for Forward {
514514

515515
struct SwitchIntEdgeEffectApplier<'a, D, F> {
516516
exit_state: &'a mut D,
517-
targets: &'a SwitchTargets<'a>,
517+
targets: &'a SwitchTargets,
518518
propagate: F,
519519

520520
effects_applied: bool,

compiler/rustc_mir/src/transform/simplify_comparison_integral.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,5 +227,5 @@ struct OptimizationInfo<'tcx> {
227227
/// Either Eq or Ne
228228
op: BinOp,
229229
/// Current targets used in the switch
230-
targets: SwitchTargets<'tcx>,
230+
targets: SwitchTargets,
231231
}

compiler/rustc_mir/src/util/elaborate_drops.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -760,8 +760,6 @@ where
760760
let elem_size = Place::from(self.new_temp(tcx.types.usize));
761761
let len = Place::from(self.new_temp(tcx.types.usize));
762762

763-
static USIZE_SWITCH_ZERO: &[u128; 1] = &[0];
764-
765763
let base_block = BasicBlockData {
766764
statements: vec![
767765
self.assign(elem_size, Rvalue::NullaryOp(NullOp::SizeOf, ety)),
@@ -774,7 +772,7 @@ where
774772
discr: move_(elem_size),
775773
switch_ty: tcx.types.usize,
776774
targets: SwitchTargets::static_if(
777-
USIZE_SWITCH_ZERO,
775+
0,
778776
self.drop_loop_pair(ety, false, len),
779777
self.drop_loop_pair(ety, true, len),
780778
),

0 commit comments

Comments
 (0)