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

Commit d263447

Browse files
committed
Replace EmptySinglePair with SmallVec
1 parent fc595f1 commit d263447

File tree

6 files changed

+66
-100
lines changed

6 files changed

+66
-100
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ object = { version = "0.22.0", default-features = false, features = ["std", "rea
2121
ar = { git = "https://github.com/bjorn3/rust-ar.git", branch = "do_not_remove_cg_clif_ranlib" }
2222
indexmap = "1.0.2"
2323
libloading = { version = "0.6.0", optional = true }
24+
smallvec = "1.6.1"
2425

2526
# Uncomment to use local checkout of cranelift
2627
#[patch."https://github.com/bytecodealliance/wasmtime/"]

src/abi/comments.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use rustc_target::abi::call::PassMode;
88

99
use cranelift_codegen::entity::EntityRef;
1010

11-
use crate::abi::pass_mode::*;
1211
use crate::prelude::*;
1312

1413
pub(super) fn add_args_header_comment(fx: &mut FunctionCx<'_, '_, impl Module>) {
@@ -22,7 +21,7 @@ pub(super) fn add_arg_comment<'tcx>(
2221
kind: &str,
2322
local: Option<mir::Local>,
2423
local_field: Option<usize>,
25-
params: EmptySinglePair<Value>,
24+
params: &[Value],
2625
arg_abi_mode: PassMode,
2726
arg_layout: TyAndLayout<'tcx>,
2827
) {
@@ -38,9 +37,17 @@ pub(super) fn add_arg_comment<'tcx>(
3837
};
3938

4039
let params = match params {
41-
Empty => Cow::Borrowed("-"),
42-
Single(param) => Cow::Owned(format!("= {:?}", param)),
43-
Pair(param_a, param_b) => Cow::Owned(format!("= {:?}, {:?}", param_a, param_b)),
40+
[] => Cow::Borrowed("-"),
41+
[param] => Cow::Owned(format!("= {:?}", param)),
42+
[param_a, param_b] => Cow::Owned(format!("= {:?},{:?}", param_a, param_b)),
43+
params => Cow::Owned(format!(
44+
"= {}",
45+
params
46+
.iter()
47+
.map(ToString::to_string)
48+
.collect::<Vec<_>>()
49+
.join(",")
50+
)),
4451
};
4552

4653
let pass_mode = format!("{:?}", arg_abi_mode);

src/abi/mod.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use rustc_target::abi::call::{Conv, FnAbi};
1111
use rustc_target::spec::abi::Abi;
1212

1313
use cranelift_codegen::ir::AbiParam;
14+
use smallvec::smallvec;
1415

1516
use self::pass_mode::*;
1617
use crate::prelude::*;
@@ -534,15 +535,15 @@ pub(crate) fn codegen_terminator_call<'tcx>(
534535
);
535536
}
536537
let (ptr, method) = crate::vtable::get_ptr_and_method_ref(fx, args[0], idx);
537-
(Some(method), Single(ptr))
538+
(Some(method), smallvec![ptr])
538539
}
539540

540541
// Normal call
541542
Some(_) => (
542543
None,
543544
args.get(0)
544545
.map(|arg| adjust_arg_for_abi(fx, *arg, &fn_abi.args[0]))
545-
.unwrap_or(Empty),
546+
.unwrap_or(smallvec![]),
546547
),
547548

548549
// Indirect call
@@ -557,7 +558,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
557558
Some(func),
558559
args.get(0)
559560
.map(|arg| adjust_arg_for_abi(fx, *arg, &fn_abi.args[0]))
560-
.unwrap_or(Empty),
561+
.unwrap_or(smallvec![]),
561562
)
562563
}
563564
};

src/abi/pass_mode.rs

Lines changed: 42 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -5,103 +5,49 @@ use crate::value_and_place::assert_assignable;
55

66
use cranelift_codegen::ir::ArgumentPurpose;
77
use rustc_target::abi::call::{ArgAbi, PassMode};
8-
pub(super) use EmptySinglePair::*;
9-
10-
#[derive(Copy, Clone, Debug)]
11-
pub(super) enum EmptySinglePair<T> {
12-
Empty,
13-
Single(T),
14-
Pair(T, T),
15-
}
16-
17-
impl<T> EmptySinglePair<T> {
18-
pub(super) fn into_iter(self) -> EmptySinglePairIter<T> {
19-
EmptySinglePairIter(self)
20-
}
21-
22-
pub(super) fn map<U>(self, mut f: impl FnMut(T) -> U) -> EmptySinglePair<U> {
23-
match self {
24-
Empty => Empty,
25-
Single(v) => Single(f(v)),
26-
Pair(a, b) => Pair(f(a), f(b)),
27-
}
28-
}
29-
}
30-
31-
pub(super) struct EmptySinglePairIter<T>(EmptySinglePair<T>);
32-
33-
impl<T> Iterator for EmptySinglePairIter<T> {
34-
type Item = T;
35-
36-
fn next(&mut self) -> Option<T> {
37-
match std::mem::replace(&mut self.0, Empty) {
38-
Empty => None,
39-
Single(v) => Some(v),
40-
Pair(a, b) => {
41-
self.0 = Single(b);
42-
Some(a)
43-
}
44-
}
45-
}
46-
}
47-
48-
impl<T: std::fmt::Debug> EmptySinglePair<T> {
49-
pub(super) fn assert_single(self) -> T {
50-
match self {
51-
Single(v) => v,
52-
_ => panic!("Called assert_single on {:?}", self),
53-
}
54-
}
55-
56-
pub(super) fn assert_pair(self) -> (T, T) {
57-
match self {
58-
Pair(a, b) => (a, b),
59-
_ => panic!("Called assert_pair on {:?}", self),
60-
}
61-
}
62-
}
8+
use smallvec::{smallvec, SmallVec};
639

6410
pub(super) trait ArgAbiExt<'tcx> {
65-
fn get_abi_param(&self, tcx: TyCtxt<'tcx>) -> EmptySinglePair<AbiParam>;
11+
fn get_abi_param(&self, tcx: TyCtxt<'tcx>) -> SmallVec<[AbiParam; 2]>;
6612
fn get_abi_return(&self, tcx: TyCtxt<'tcx>) -> (Option<AbiParam>, Vec<AbiParam>);
6713
}
6814

6915
impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
70-
fn get_abi_param(&self, tcx: TyCtxt<'tcx>) -> EmptySinglePair<AbiParam> {
16+
fn get_abi_param(&self, tcx: TyCtxt<'tcx>) -> SmallVec<[AbiParam; 2]> {
7117
match self.mode {
72-
PassMode::Ignore => EmptySinglePair::Empty,
18+
PassMode::Ignore => smallvec![],
7319
PassMode::Direct(_) => match &self.layout.abi {
7420
Abi::Scalar(scalar) => {
75-
EmptySinglePair::Single(AbiParam::new(scalar_to_clif_type(tcx, scalar.clone())))
21+
smallvec![AbiParam::new(scalar_to_clif_type(tcx, scalar.clone()))]
7622
}
7723
Abi::Vector { .. } => {
7824
let vector_ty = crate::intrinsics::clif_vector_type(tcx, self.layout).unwrap();
79-
EmptySinglePair::Single(AbiParam::new(vector_ty))
25+
smallvec![AbiParam::new(vector_ty)]
8026
}
8127
_ => unreachable!("{:?}", self.layout.abi),
8228
},
8329
PassMode::Pair(_, _) => match &self.layout.abi {
8430
Abi::ScalarPair(a, b) => {
8531
let a = scalar_to_clif_type(tcx, a.clone());
8632
let b = scalar_to_clif_type(tcx, b.clone());
87-
EmptySinglePair::Pair(AbiParam::new(a), AbiParam::new(b))
33+
smallvec![AbiParam::new(a), AbiParam::new(b)]
8834
}
8935
_ => unreachable!("{:?}", self.layout.abi),
9036
},
91-
PassMode::Cast(_) => EmptySinglePair::Single(AbiParam::new(pointer_ty(tcx))),
37+
PassMode::Cast(_) => smallvec![AbiParam::new(pointer_ty(tcx))],
9238
PassMode::Indirect {
9339
attrs: _,
9440
extra_attrs: None,
9541
on_stack,
9642
} => {
9743
if on_stack {
9844
let size = u32::try_from(self.layout.size.bytes()).unwrap();
99-
EmptySinglePair::Single(AbiParam::special(
45+
smallvec![AbiParam::special(
10046
pointer_ty(tcx),
10147
ArgumentPurpose::StructArgument(size),
102-
))
48+
)]
10349
} else {
104-
EmptySinglePair::Single(AbiParam::new(pointer_ty(tcx)))
50+
smallvec![AbiParam::new(pointer_ty(tcx))]
10551
}
10652
}
10753
PassMode::Indirect {
@@ -110,10 +56,10 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
11056
on_stack,
11157
} => {
11258
assert!(!on_stack);
113-
EmptySinglePair::Pair(
59+
smallvec![
11460
AbiParam::new(pointer_ty(tcx)),
11561
AbiParam::new(pointer_ty(tcx)),
116-
)
62+
]
11763
}
11864
}
11965
}
@@ -176,18 +122,18 @@ pub(super) fn adjust_arg_for_abi<'tcx>(
176122
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
177123
arg: CValue<'tcx>,
178124
arg_abi: &ArgAbi<'tcx, Ty<'tcx>>,
179-
) -> EmptySinglePair<Value> {
125+
) -> SmallVec<[Value; 2]> {
180126
assert_assignable(fx, arg.layout().ty, arg_abi.layout.ty);
181127
match arg_abi.mode {
182-
PassMode::Ignore => Empty,
183-
PassMode::Direct(_) => Single(arg.load_scalar(fx)),
128+
PassMode::Ignore => smallvec![],
129+
PassMode::Direct(_) => smallvec![arg.load_scalar(fx)],
184130
PassMode::Pair(_, _) => {
185131
let (a, b) = arg.load_scalar_pair(fx);
186-
Pair(a, b)
132+
smallvec![a, b]
187133
}
188134
PassMode::Cast(_) | PassMode::Indirect { .. } => match arg.force_stack(fx) {
189-
(ptr, None) => Single(ptr.get_addr(fx)),
190-
(ptr, Some(meta)) => Pair(ptr.get_addr(fx), meta),
135+
(ptr, None) => smallvec![ptr.get_addr(fx)],
136+
(ptr, Some(meta)) => smallvec![ptr.get_addr(fx), meta],
191137
},
192138
}
193139
}
@@ -202,47 +148,57 @@ pub(super) fn cvalue_for_param<'tcx>(
202148
arg_abi: &ArgAbi<'tcx, Ty<'tcx>>,
203149
) -> Option<CValue<'tcx>> {
204150
let clif_types = arg_abi.get_abi_param(fx.tcx);
205-
let block_params =
206-
clif_types.map(|abi_param| fx.bcx.append_block_param(start_block, abi_param.value_type));
151+
let block_params = clif_types
152+
.into_iter()
153+
.map(|abi_param| fx.bcx.append_block_param(start_block, abi_param.value_type))
154+
.collect::<SmallVec<[_; 2]>>();
207155

208156
#[cfg(debug_assertions)]
209157
crate::abi::comments::add_arg_comment(
210158
fx,
211159
"arg",
212160
local,
213161
local_field,
214-
block_params,
162+
&block_params,
215163
arg_abi.mode,
216164
arg_abi.layout,
217165
);
218166

219167
match arg_abi.mode {
220168
PassMode::Ignore => None,
221169
PassMode::Direct(_) => {
222-
Some(CValue::by_val(block_params.assert_single(), arg_abi.layout))
170+
assert_eq!(block_params.len(), 1, "{:?}", block_params);
171+
Some(CValue::by_val(block_params[0], arg_abi.layout))
223172
}
224173
PassMode::Pair(_, _) => {
225-
let (a, b) = block_params.assert_pair();
226-
Some(CValue::by_val_pair(a, b, arg_abi.layout))
174+
assert_eq!(block_params.len(), 2, "{:?}", block_params);
175+
Some(CValue::by_val_pair(
176+
block_params[0],
177+
block_params[1],
178+
arg_abi.layout,
179+
))
227180
}
228181
PassMode::Cast(_)
229182
| PassMode::Indirect {
230183
attrs: _,
231184
extra_attrs: None,
232185
on_stack: _,
233-
} => Some(CValue::by_ref(
234-
Pointer::new(block_params.assert_single()),
235-
arg_abi.layout,
236-
)),
186+
} => {
187+
assert_eq!(block_params.len(), 1, "{:?}", block_params);
188+
Some(CValue::by_ref(
189+
Pointer::new(block_params[0]),
190+
arg_abi.layout,
191+
))
192+
}
237193
PassMode::Indirect {
238194
attrs: _,
239195
extra_attrs: Some(_),
240196
on_stack: _,
241197
} => {
242-
let (ptr, meta) = block_params.assert_pair();
198+
assert_eq!(block_params.len(), 2, "{:?}", block_params);
243199
Some(CValue::by_ref_unsized(
244-
Pointer::new(ptr),
245-
meta,
200+
Pointer::new(block_params[0]),
201+
block_params[1],
246202
arg_abi.layout,
247203
))
248204
}

src/abi/returning.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
//! Return value handling
22
3-
use crate::abi::pass_mode::*;
43
use crate::prelude::*;
54

65
use rustc_middle::ty::layout::FnAbiExt;
76
use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode};
7+
use smallvec::{SmallVec, smallvec};
88

99
/// Can the given type be returned into an ssa var or does it need to be returned on the stack.
1010
pub(crate) fn can_return_to_ssa_var<'tcx>(
@@ -62,10 +62,10 @@ pub(super) fn codegen_return_param<'tcx>(
6262
ssa_analyzed: &rustc_index::vec::IndexVec<Local, crate::analyze::SsaKind>,
6363
start_block: Block,
6464
) -> CPlace<'tcx> {
65-
let (ret_place, ret_param) = match fx.fn_abi.as_ref().unwrap().ret.mode {
65+
let (ret_place, ret_param): (_, SmallVec<[_; 2]>) = match fx.fn_abi.as_ref().unwrap().ret.mode {
6666
PassMode::Ignore => (
6767
CPlace::no_place(fx.fn_abi.as_ref().unwrap().ret.layout),
68-
Empty,
68+
smallvec![],
6969
),
7070
PassMode::Direct(_) | PassMode::Pair(_, _) => {
7171
let is_ssa = ssa_analyzed[RETURN_PLACE] == crate::analyze::SsaKind::Ssa;
@@ -76,7 +76,7 @@ pub(super) fn codegen_return_param<'tcx>(
7676
fx.fn_abi.as_ref().unwrap().ret.layout,
7777
is_ssa,
7878
),
79-
Empty,
79+
smallvec![],
8080
)
8181
}
8282
PassMode::Cast(_)
@@ -91,7 +91,7 @@ pub(super) fn codegen_return_param<'tcx>(
9191
Pointer::new(ret_param),
9292
fx.fn_abi.as_ref().unwrap().ret.layout,
9393
),
94-
Single(ret_param),
94+
smallvec![ret_param],
9595
)
9696
}
9797
PassMode::Indirect {
@@ -110,7 +110,7 @@ pub(super) fn codegen_return_param<'tcx>(
110110
"ret",
111111
Some(RETURN_PLACE),
112112
None,
113-
ret_param,
113+
&ret_param,
114114
fx.fn_abi.as_ref().unwrap().ret.mode,
115115
fx.fn_abi.as_ref().unwrap().ret.layout,
116116
);

0 commit comments

Comments
 (0)