Skip to content

Commit 39c96c7

Browse files
authored
Remove Wasmtime ABIs from Cranelift (#6649)
* Remove Wasmtime ABIs from Cranelift This commit removes the `Wasmtime*` family of ABIs from Cranelift. These were originally added to support multi-value in Wasmtime via the `TypedFunc` API, but they should now no longer be necessary. In general this is a higher-level Wasmtime concern than something all backends of Cranelift should have to deal with. Today with recent refactorings it's possible to remove the reliance on ABI details for multi-value and instead codify it directly into the Cranelift IR generated. For example wasm calls are able to have a "purely internal" ABI which Wasmtime's Rust code doesn't see at all, and the Rust code only interacts with the native ABI. The native ABI is redefined to be what the previous Wasmtime ABIs were, which is to return the first of a 2+ value return through a register (native return value) and everything else through a return pointer. * Remove some wasmtime_system_v usage in tests * Add back WasmtimeSystemV for s390x * Fix some docs and references in winch * Fix another doc link
1 parent 2f74b91 commit 39c96c7

18 files changed

Lines changed: 231 additions & 540 deletions

File tree

cranelift/codegen/src/isa/aarch64/abi.rs

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -130,17 +130,8 @@ impl ABIMachineSpec for AArch64MachineDeps {
130130
// number of register values returned in the other class. That is,
131131
// we can return values in up to 8 integer and
132132
// 8 vector registers at once.
133-
//
134-
// In Wasmtime, we can only use one register for return
135-
// value for all the register classes. That is, we can't
136-
// return values in both one integer and one vector
137-
// register; only one return value may be in a register.
138133
ArgsOrRets::Rets => {
139-
if call_conv.extends_wasmtime() {
140-
(1, 1) // x0 or v0, but not both
141-
} else {
142-
(8, 16) // x0-x7 and v0-v7
143-
}
134+
(8, 16) // x0-x7 and v0-v7
144135
}
145136
};
146137

@@ -290,10 +281,8 @@ impl ABIMachineSpec for AArch64MachineDeps {
290281
// Compute the stack slot's size.
291282
let size = (ty_bits(param.value_type) / 8) as u32;
292283

293-
let size = if is_apple_cc
294-
|| (call_conv.extends_wasmtime() && args_or_rets == ArgsOrRets::Rets)
295-
{
296-
// MacOS aarch64 and Wasmtime allow stack slots with
284+
let size = if is_apple_cc {
285+
// MacOS aarch64 allows stack slots with
297286
// sizes less than 8 bytes. They still need to be
298287
// properly aligned on their natural data alignment,
299288
// though.

cranelift/codegen/src/isa/call_conv.rs

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,9 @@ pub enum CallConv {
3030
Probestack,
3131
/// Wasmtime equivalent of SystemV, not ABI-stable.
3232
///
33-
/// Currently only differs in how multiple return values are handled,
34-
/// returning the first return value in a register and everything else
35-
/// through a return-pointer.
33+
/// FIXME: remove this when Wasmtime uses the "tail" calling convention for
34+
/// all wasm functions.
3635
WasmtimeSystemV,
37-
/// Wasmtime equivalent of WindowsFastcall, not ABI-stable.
38-
///
39-
/// Differs from fastcall in the same way as `WasmtimeSystemV`.
40-
WasmtimeFastcall,
41-
/// Wasmtime equivalent of AppleAarch64, not ABI-stable.
42-
///
43-
/// Differs from apple-aarch64 in the same way as `WasmtimeSystemV`.
44-
WasmtimeAppleAarch64,
4536
}
4637

4738
impl CallConv {
@@ -81,23 +72,15 @@ impl CallConv {
8172
/// Is the calling convention extending the Windows Fastcall ABI?
8273
pub fn extends_windows_fastcall(self) -> bool {
8374
match self {
84-
Self::WindowsFastcall | Self::WasmtimeFastcall => true,
75+
Self::WindowsFastcall => true,
8576
_ => false,
8677
}
8778
}
8879

8980
/// Is the calling convention extending the Apple aarch64 ABI?
9081
pub fn extends_apple_aarch64(self) -> bool {
9182
match self {
92-
Self::AppleAarch64 | Self::WasmtimeAppleAarch64 => true,
93-
_ => false,
94-
}
95-
}
96-
97-
/// Is the calling convention extending the Wasmtime ABI?
98-
pub fn extends_wasmtime(self) -> bool {
99-
match self {
100-
Self::WasmtimeSystemV | Self::WasmtimeFastcall | Self::WasmtimeAppleAarch64 => true,
83+
Self::AppleAarch64 => true,
10184
_ => false,
10285
}
10386
}
@@ -114,8 +97,6 @@ impl fmt::Display for CallConv {
11497
Self::AppleAarch64 => "apple_aarch64",
11598
Self::Probestack => "probestack",
11699
Self::WasmtimeSystemV => "wasmtime_system_v",
117-
Self::WasmtimeFastcall => "wasmtime_fastcall",
118-
Self::WasmtimeAppleAarch64 => "wasmtime_apple_aarch64",
119100
})
120101
}
121102
}
@@ -132,8 +113,6 @@ impl str::FromStr for CallConv {
132113
"apple_aarch64" => Ok(Self::AppleAarch64),
133114
"probestack" => Ok(Self::Probestack),
134115
"wasmtime_system_v" => Ok(Self::WasmtimeSystemV),
135-
"wasmtime_fastcall" => Ok(Self::WasmtimeFastcall),
136-
"wasmtime_apple_aarch64" => Ok(Self::WasmtimeAppleAarch64),
137116
_ => Err(()),
138117
}
139118
}

cranelift/codegen/src/isa/riscv64/abi.rs

Lines changed: 14 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -106,16 +106,12 @@ impl ABIMachineSpec for Riscv64MachineDeps {
106106
let (x_start, x_end, f_start, f_end) = match (call_conv, args_or_rets) {
107107
(isa::CallConv::Tail, _) => (9, 29, 0, 31),
108108
(_, ArgsOrRets::Args) => (10, 17, 10, 17),
109-
(_, ArgsOrRets::Rets) => {
110-
let end = if call_conv.extends_wasmtime() { 10 } else { 11 };
111-
(10, end, 10, end)
112-
}
109+
(_, ArgsOrRets::Rets) => (10, 11, 10, 11),
113110
};
114111
let mut next_x_reg = x_start;
115112
let mut next_f_reg = f_start;
116113
// Stack space.
117114
let mut next_stack: u32 = 0;
118-
let mut return_one_register_used = false;
119115

120116
for param in params {
121117
if let ir::ArgumentPurpose::StructArgument(size) = param.purpose {
@@ -135,48 +131,28 @@ impl ABIMachineSpec for Riscv64MachineDeps {
135131
let (rcs, reg_tys) = Inst::rc_for_type(param.value_type)?;
136132
let mut slots = ABIArgSlotVec::new();
137133
for (rc, reg_ty) in rcs.iter().zip(reg_tys.iter()) {
138-
let next_reg =
139-
if (next_x_reg <= x_end) && *rc == RegClass::Int && !return_one_register_used {
140-
let x = Some(x_reg(next_x_reg));
141-
if args_or_rets == ArgsOrRets::Rets && call_conv.extends_wasmtime() {
142-
return_one_register_used = true;
143-
}
144-
next_x_reg += 1;
145-
x
146-
} else if (next_f_reg <= f_end)
147-
&& *rc == RegClass::Float
148-
&& !return_one_register_used
149-
{
150-
let x = Some(f_reg(next_f_reg));
151-
if args_or_rets == ArgsOrRets::Rets && call_conv.extends_wasmtime() {
152-
return_one_register_used = true;
153-
}
154-
next_f_reg += 1;
155-
x
156-
} else {
157-
None
158-
};
134+
let next_reg = if (next_x_reg <= x_end) && *rc == RegClass::Int {
135+
let x = Some(x_reg(next_x_reg));
136+
next_x_reg += 1;
137+
x
138+
} else if (next_f_reg <= f_end) && *rc == RegClass::Float {
139+
let x = Some(f_reg(next_f_reg));
140+
next_f_reg += 1;
141+
x
142+
} else {
143+
None
144+
};
159145
if let Some(reg) = next_reg {
160146
slots.push(ABIArgSlot::Reg {
161147
reg: reg.to_real_reg().unwrap(),
162148
ty: *reg_ty,
163149
extension: param.extension,
164150
});
165151
} else {
166-
// Compute size. For the wasmtime ABI it differs from native
167-
// ABIs in how multiple values are returned, so we take a
168-
// leaf out of arm64's book by not rounding everything up to
169-
// 8 bytes. For all ABI arguments, and other ABI returns,
170-
// though, each slot takes a minimum of 8 bytes.
171-
//
172-
// Note that in all cases 16-byte stack alignment happens
152+
// Compute size and 16-byte stack alignment happens
173153
// separately after all args.
174154
let size = reg_ty.bits() / 8;
175-
let size = if args_or_rets == ArgsOrRets::Rets && call_conv.extends_wasmtime() {
176-
size
177-
} else {
178-
std::cmp::max(size, 8)
179-
};
155+
let size = std::cmp::max(size, 8);
180156
// Align.
181157
debug_assert!(size.is_power_of_two());
182158
next_stack = align_to(next_stack, size);

cranelift/codegen/src/isa/s390x/abi.rs

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -248,13 +248,12 @@ impl ABIMachineSpec for S390xMachineDeps {
248248
}
249249

250250
// In the SystemV ABI, the return area pointer is the first argument,
251-
// so we need to leave room for it if required. (In the Wasmtime ABI,
252-
// the return area pointer is the last argument and is handled below.)
253-
if add_ret_area_ptr && !call_conv.extends_wasmtime() {
251+
// so we need to leave room for it if required.
252+
if add_ret_area_ptr {
254253
next_gpr += 1;
255254
}
256255

257-
for (i, mut param) in params.into_iter().copied().enumerate() {
256+
for mut param in params.into_iter().copied() {
258257
let intreg = in_int_reg(param.value_type);
259258
let fltreg = in_flt_reg(param.value_type);
260259
let vecreg = in_vec_reg(param.value_type);
@@ -278,8 +277,6 @@ impl ABIMachineSpec for S390xMachineDeps {
278277
ArgsOrRets::Rets => get_vecreg_for_ret(next_vr),
279278
};
280279
(&mut next_vr, candidate, None)
281-
} else if call_conv.extends_wasmtime() {
282-
panic!("i128 args/return values not supported in the Wasmtime ABI");
283280
} else {
284281
// We must pass this by implicit reference.
285282
if args_or_rets == ArgsOrRets::Rets {
@@ -294,14 +291,6 @@ impl ABIMachineSpec for S390xMachineDeps {
294291
}
295292
};
296293

297-
// In the Wasmtime ABI only the first return value can be in a register.
298-
let candidate =
299-
if call_conv.extends_wasmtime() && args_or_rets == ArgsOrRets::Rets && i > 0 {
300-
None
301-
} else {
302-
candidate
303-
};
304-
305294
let slot = if let Some(reg) = candidate {
306295
*next_reg += 1;
307296
ABIArgSlot::Reg {
@@ -311,14 +300,9 @@ impl ABIMachineSpec for S390xMachineDeps {
311300
}
312301
} else {
313302
// Compute size. Every argument or return value takes a slot of
314-
// at least 8 bytes, except for return values in the Wasmtime ABI.
303+
// at least 8 bytes.
315304
let size = (ty_bits(param.value_type) / 8) as u32;
316-
let slot_size = if call_conv.extends_wasmtime() && args_or_rets == ArgsOrRets::Rets
317-
{
318-
size
319-
} else {
320-
std::cmp::max(size, 8)
321-
};
305+
let slot_size = std::cmp::max(size, 8);
322306

323307
// Align the stack slot.
324308
debug_assert!(slot_size.is_power_of_two());
@@ -372,14 +356,8 @@ impl ABIMachineSpec for S390xMachineDeps {
372356

373357
let extra_arg = if add_ret_area_ptr {
374358
debug_assert!(args_or_rets == ArgsOrRets::Args);
375-
// The return pointer is passed either as first argument
376-
// (in the SystemV ABI) or as last argument (Wasmtime ABI).
377-
let next_gpr = if call_conv.extends_wasmtime() {
378-
next_gpr
379-
} else {
380-
0
381-
};
382-
if let Some(reg) = get_intreg_for_arg(next_gpr) {
359+
// The return pointer is passed as first argument.
360+
if let Some(reg) = get_intreg_for_arg(0) {
383361
args.push(ABIArg::reg(
384362
reg.to_real_reg().unwrap(),
385363
types::I64,

cranelift/codegen/src/isa/s390x/lower/isle.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -989,7 +989,7 @@ impl generated_code::Context for IsleContext<'_, '_, MInst, S390xBackend> {
989989
/// Lane order to be used for a given calling convention.
990990
#[inline]
991991
fn lane_order_for_call_conv(call_conv: CallConv) -> LaneOrder {
992-
if call_conv.extends_wasmtime() {
992+
if call_conv == CallConv::WasmtimeSystemV {
993993
LaneOrder::LittleEndian
994994
} else {
995995
LaneOrder::BigEndian

cranelift/codegen/src/isa/x64/abi.rs

Lines changed: 10 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -215,18 +215,14 @@ impl ABIMachineSpec for X64ABIMachineSpec {
215215
ArgsOrRets::Args => {
216216
get_intreg_for_arg(&call_conv, next_gpr, next_param_idx)
217217
}
218-
ArgsOrRets::Rets => {
219-
get_intreg_for_retval(&call_conv, next_gpr, next_param_idx)
220-
}
218+
ArgsOrRets::Rets => get_intreg_for_retval(&call_conv, next_gpr),
221219
}
222220
} else {
223221
match args_or_rets {
224222
ArgsOrRets::Args => {
225223
get_fltreg_for_arg(&call_conv, next_vreg, next_param_idx)
226224
}
227-
ArgsOrRets::Rets => {
228-
get_fltreg_for_retval(&call_conv, next_vreg, next_param_idx)
229-
}
225+
ArgsOrRets::Rets => get_fltreg_for_retval(&call_conv, next_vreg),
230226
}
231227
};
232228
next_param_idx += 1;
@@ -242,20 +238,8 @@ impl ABIMachineSpec for X64ABIMachineSpec {
242238
extension: param.extension,
243239
});
244240
} else {
245-
// Compute size. For the wasmtime ABI it differs from native
246-
// ABIs in how multiple values are returned, so we take a
247-
// leaf out of arm64's book by not rounding everything up to
248-
// 8 bytes. For all ABI arguments, and other ABI returns,
249-
// though, each slot takes a minimum of 8 bytes.
250-
//
251-
// Note that in all cases 16-byte stack alignment happens
252-
// separately after all args.
253241
let size = reg_ty.bits() / 8;
254-
let size = if args_or_rets == ArgsOrRets::Rets && call_conv.extends_wasmtime() {
255-
size
256-
} else {
257-
std::cmp::max(size, 8)
258-
};
242+
let size = std::cmp::max(size, 8);
259243
// Align.
260244
debug_assert!(size.is_power_of_two());
261245
next_stack = align_to(next_stack, size);
@@ -873,18 +857,18 @@ impl ABIMachineSpec for X64ABIMachineSpec {
873857
// The `tail` calling convention doesn't have any callee-save
874858
// registers.
875859
CallConv::Tail => vec![],
876-
CallConv::Fast | CallConv::Cold | CallConv::SystemV | CallConv::WasmtimeSystemV => regs
860+
CallConv::Fast | CallConv::Cold | CallConv::SystemV => regs
877861
.iter()
878862
.cloned()
879863
.filter(|r| is_callee_save_systemv(r.to_reg(), flags.enable_pinned_reg()))
880864
.collect(),
881-
CallConv::WindowsFastcall | CallConv::WasmtimeFastcall => regs
865+
CallConv::WindowsFastcall => regs
882866
.iter()
883867
.cloned()
884868
.filter(|r| is_callee_save_fastcall(r.to_reg(), flags.enable_pinned_reg()))
885869
.collect(),
886870
CallConv::Probestack => todo!("probestack?"),
887-
CallConv::AppleAarch64 | CallConv::WasmtimeAppleAarch64 => unreachable!(),
871+
CallConv::WasmtimeSystemV | CallConv::AppleAarch64 => unreachable!(),
888872
};
889873
// Sort registers for deterministic code output. We can do an unstable sort because the
890874
// registers will be unique (there are no dups).
@@ -1001,11 +985,7 @@ fn get_fltreg_for_arg(call_conv: &CallConv, idx: usize, arg_idx: usize) -> Optio
1001985
}
1002986
}
1003987

1004-
fn get_intreg_for_retval(
1005-
call_conv: &CallConv,
1006-
intreg_idx: usize,
1007-
retval_idx: usize,
1008-
) -> Option<Reg> {
988+
fn get_intreg_for_retval(call_conv: &CallConv, intreg_idx: usize) -> Option<Reg> {
1009989
match call_conv {
1010990
CallConv::Tail => match intreg_idx {
1011991
0 => Some(regs::rax()),
@@ -1029,28 +1009,17 @@ fn get_intreg_for_retval(
10291009
1 => Some(regs::rdx()),
10301010
_ => None,
10311011
},
1032-
CallConv::WasmtimeSystemV | CallConv::WasmtimeFastcall => {
1033-
if intreg_idx == 0 && retval_idx == 0 {
1034-
Some(regs::rax())
1035-
} else {
1036-
None
1037-
}
1038-
}
10391012
CallConv::WindowsFastcall => match intreg_idx {
10401013
0 => Some(regs::rax()),
10411014
1 => Some(regs::rdx()), // The Rust ABI for i128s needs this.
10421015
_ => None,
10431016
},
10441017
CallConv::Probestack => todo!(),
1045-
CallConv::AppleAarch64 | CallConv::WasmtimeAppleAarch64 => unreachable!(),
1018+
CallConv::WasmtimeSystemV | CallConv::AppleAarch64 => unreachable!(),
10461019
}
10471020
}
10481021

1049-
fn get_fltreg_for_retval(
1050-
call_conv: &CallConv,
1051-
fltreg_idx: usize,
1052-
retval_idx: usize,
1053-
) -> Option<Reg> {
1022+
fn get_fltreg_for_retval(call_conv: &CallConv, fltreg_idx: usize) -> Option<Reg> {
10541023
match call_conv {
10551024
CallConv::Tail => match fltreg_idx {
10561025
0 => Some(regs::xmm0()),
@@ -1068,19 +1037,12 @@ fn get_fltreg_for_retval(
10681037
1 => Some(regs::xmm1()),
10691038
_ => None,
10701039
},
1071-
CallConv::WasmtimeFastcall | CallConv::WasmtimeSystemV => {
1072-
if fltreg_idx == 0 && retval_idx == 0 {
1073-
Some(regs::xmm0())
1074-
} else {
1075-
None
1076-
}
1077-
}
10781040
CallConv::WindowsFastcall => match fltreg_idx {
10791041
0 => Some(regs::xmm0()),
10801042
_ => None,
10811043
},
10821044
CallConv::Probestack => todo!(),
1083-
CallConv::AppleAarch64 | CallConv::WasmtimeAppleAarch64 => unreachable!(),
1045+
CallConv::WasmtimeSystemV | CallConv::AppleAarch64 => unreachable!(),
10841046
}
10851047
}
10861048

0 commit comments

Comments
 (0)