Skip to content

Commit 38e8be9

Browse files
committed
Add create_stack_slot helper to FunctionCx
This will allow centrally handling a workaround for the lack of stack alignment specifier in cranelift.
1 parent a99b1b4 commit 38e8be9

File tree

6 files changed

+52
-69
lines changed

6 files changed

+52
-69
lines changed

src/abi/mod.rs

+14-21
Original file line numberDiff line numberDiff line change
@@ -120,32 +120,25 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
120120
args: &[Value],
121121
) -> Cow<'_, [Value]> {
122122
if self.tcx.sess.target.is_like_windows {
123-
let (mut params, mut args): (Vec<_>, Vec<_>) =
124-
params
125-
.into_iter()
126-
.zip(args)
127-
.map(|(param, &arg)| {
128-
if param.value_type == types::I128 {
129-
let arg_ptr = Pointer::stack_slot(self.bcx.create_sized_stack_slot(
130-
StackSlotData { kind: StackSlotKind::ExplicitSlot, size: 16 },
131-
));
132-
arg_ptr.store(self, arg, MemFlags::trusted());
133-
(AbiParam::new(self.pointer_type), arg_ptr.get_addr(self))
134-
} else {
135-
(param, arg)
136-
}
137-
})
138-
.unzip();
123+
let (mut params, mut args): (Vec<_>, Vec<_>) = params
124+
.into_iter()
125+
.zip(args)
126+
.map(|(param, &arg)| {
127+
if param.value_type == types::I128 {
128+
let arg_ptr = self.create_stack_slot(16, 16);
129+
arg_ptr.store(self, arg, MemFlags::trusted());
130+
(AbiParam::new(self.pointer_type), arg_ptr.get_addr(self))
131+
} else {
132+
(param, arg)
133+
}
134+
})
135+
.unzip();
139136

140137
let indirect_ret_val = returns.len() == 1 && returns[0].value_type == types::I128;
141138

142139
if indirect_ret_val {
143140
params.insert(0, AbiParam::new(self.pointer_type));
144-
let ret_ptr =
145-
Pointer::stack_slot(self.bcx.create_sized_stack_slot(StackSlotData {
146-
kind: StackSlotKind::ExplicitSlot,
147-
size: 16,
148-
}));
141+
let ret_ptr = self.create_stack_slot(16, 16);
149142
args.insert(0, ret_ptr.get_addr(self));
150143
self.lib_call_unadjusted(name, params, vec![], &args);
151144
return Cow::Owned(vec![ret_ptr.load(self, types::I128, MemFlags::trusted())]);

src/abi/pass_mode.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -189,16 +189,13 @@ pub(super) fn from_casted_value<'tcx>(
189189
let abi_params = cast_target_to_abi_params(cast);
190190
let abi_param_size: u32 = abi_params.iter().map(|param| param.value_type.bytes()).sum();
191191
let layout_size = u32::try_from(layout.size.bytes()).unwrap();
192-
let stack_slot = fx.bcx.create_sized_stack_slot(StackSlotData {
193-
kind: StackSlotKind::ExplicitSlot,
194-
// FIXME Don't force the size to a multiple of 16 bytes once Cranelift gets a way to
195-
// specify stack slot alignment.
192+
let ptr = fx.create_stack_slot(
196193
// Stack slot size may be bigger for example `[u8; 3]` which is packed into an `i32`.
197194
// It may also be smaller for example when the type is a wrapper around an integer with a
198195
// larger alignment than the integer.
199-
size: (std::cmp::max(abi_param_size, layout_size) + 15) / 16 * 16,
200-
});
201-
let ptr = Pointer::stack_slot(stack_slot);
196+
std::cmp::max(abi_param_size, layout_size),
197+
u32::try_from(layout.align.pref.bytes()).unwrap(),
198+
);
202199
let mut offset = 0;
203200
let mut block_params_iter = block_params.iter().copied();
204201
for param in abi_params {

src/cast.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,7 @@ pub(crate) fn clif_int_or_float_cast(
104104
&[from],
105105
)[0];
106106
// FIXME(bytecodealliance/wasmtime#6104) use bitcast instead of store to get from i64x2 to i128
107-
let stack_slot = fx.bcx.create_sized_stack_slot(StackSlotData {
108-
kind: StackSlotKind::ExplicitSlot,
109-
size: 16,
110-
});
111-
let ret_ptr = Pointer::stack_slot(stack_slot);
107+
let ret_ptr = fx.create_stack_slot(16, 16);
112108
ret_ptr.store(fx, ret, MemFlags::trusted());
113109
ret_ptr.load(fx, types::I128, MemFlags::trusted())
114110
} else {

src/common.rs

+10
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,16 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
383383
})
384384
}
385385

386+
pub(crate) fn create_stack_slot(&mut self, size: u32, align: u32) -> Pointer {
387+
let stack_slot = self.bcx.create_sized_stack_slot(StackSlotData {
388+
kind: StackSlotKind::ExplicitSlot,
389+
// FIXME Don't force the size to a multiple of 16 bytes once Cranelift gets a way to
390+
// specify stack slot alignment.
391+
size: (size + 15) / 16 * 16,
392+
});
393+
Pointer::stack_slot(stack_slot)
394+
}
395+
386396
pub(crate) fn set_debug_loc(&mut self, source_info: mir::SourceInfo) {
387397
if let Some(debug_context) = &mut self.cx.debug_context {
388398
let (file, line, column) =

src/inline_asm.rs

+12-10
Original file line numberDiff line numberDiff line change
@@ -878,13 +878,7 @@ fn call_inline_asm<'tcx>(
878878
inputs: Vec<(Size, Value)>,
879879
outputs: Vec<(Size, CPlace<'tcx>)>,
880880
) {
881-
let stack_slot = fx.bcx.func.create_sized_stack_slot(StackSlotData {
882-
kind: StackSlotKind::ExplicitSlot,
883-
size: u32::try_from(slot_size.bytes()).unwrap(),
884-
});
885-
if fx.clif_comments.enabled() {
886-
fx.add_comment(stack_slot, "inline asm scratch slot");
887-
}
881+
let stack_slot = fx.create_stack_slot(u32::try_from(slot_size.bytes()).unwrap(), 16);
888882

889883
let inline_asm_func = fx
890884
.module
@@ -904,15 +898,23 @@ fn call_inline_asm<'tcx>(
904898
}
905899

906900
for (offset, value) in inputs {
907-
fx.bcx.ins().stack_store(value, stack_slot, i32::try_from(offset.bytes()).unwrap());
901+
stack_slot.offset(fx, i32::try_from(offset.bytes()).unwrap().into()).store(
902+
fx,
903+
value,
904+
MemFlags::trusted(),
905+
);
908906
}
909907

910-
let stack_slot_addr = fx.bcx.ins().stack_addr(fx.pointer_type, stack_slot, 0);
908+
let stack_slot_addr = stack_slot.get_addr(fx);
911909
fx.bcx.ins().call(inline_asm_func, &[stack_slot_addr]);
912910

913911
for (offset, place) in outputs {
914912
let ty = fx.clif_type(place.layout().ty).unwrap();
915-
let value = fx.bcx.ins().stack_load(ty, stack_slot, i32::try_from(offset.bytes()).unwrap());
913+
let value = stack_slot.offset(fx, i32::try_from(offset.bytes()).unwrap().into()).load(
914+
fx,
915+
ty,
916+
MemFlags::trusted(),
917+
);
916918
place.write_cvalue(fx, CValue::by_val(value, place.layout()));
917919
}
918920
}

src/value_and_place.rs

+11-26
Original file line numberDiff line numberDiff line change
@@ -132,18 +132,11 @@ impl<'tcx> CValue<'tcx> {
132132
(ptr.get_addr(fx), vtable)
133133
}
134134
CValueInner::ByValPair(data, vtable) => {
135-
let stack_slot = fx.bcx.create_sized_stack_slot(StackSlotData {
136-
kind: StackSlotKind::ExplicitSlot,
137-
// FIXME Don't force the size to a multiple of 16 bytes once Cranelift gets a way to
138-
// specify stack slot alignment.
139-
size: (u32::try_from(fx.target_config.pointer_type().bytes()).unwrap() + 15)
140-
/ 16
141-
* 16,
142-
});
143-
let data_ptr = Pointer::stack_slot(stack_slot);
144-
let mut flags = MemFlags::new();
145-
flags.set_notrap();
146-
data_ptr.store(fx, data, flags);
135+
let data_ptr = fx.create_stack_slot(
136+
u32::try_from(fx.target_config.pointer_type().bytes()).unwrap(),
137+
u32::try_from(fx.target_config.pointer_type().bytes()).unwrap(),
138+
);
139+
data_ptr.store(fx, data, MemFlags::trusted());
147140

148141
(data_ptr.get_addr(fx), vtable)
149142
}
@@ -372,13 +365,11 @@ impl<'tcx> CPlace<'tcx> {
372365
.fatal(format!("values of type {} are too big to store on the stack", layout.ty));
373366
}
374367

375-
let stack_slot = fx.bcx.create_sized_stack_slot(StackSlotData {
376-
kind: StackSlotKind::ExplicitSlot,
377-
// FIXME Don't force the size to a multiple of 16 bytes once Cranelift gets a way to
378-
// specify stack slot alignment.
379-
size: (u32::try_from(layout.size.bytes()).unwrap() + 15) / 16 * 16,
380-
});
381-
CPlace { inner: CPlaceInner::Addr(Pointer::stack_slot(stack_slot), None), layout }
368+
let stack_slot = fx.create_stack_slot(
369+
u32::try_from(layout.size.bytes()).unwrap(),
370+
u32::try_from(layout.align.pref.bytes()).unwrap(),
371+
);
372+
CPlace { inner: CPlaceInner::Addr(stack_slot, None), layout }
382373
}
383374

384375
pub(crate) fn new_var(
@@ -543,13 +534,7 @@ impl<'tcx> CPlace<'tcx> {
543534
_ if src_ty.is_vector() && dst_ty.is_vector() => codegen_bitcast(fx, dst_ty, data),
544535
_ if src_ty.is_vector() || dst_ty.is_vector() => {
545536
// FIXME(bytecodealliance/wasmtime#6104) do something more efficient for transmutes between vectors and integers.
546-
let stack_slot = fx.bcx.create_sized_stack_slot(StackSlotData {
547-
kind: StackSlotKind::ExplicitSlot,
548-
// FIXME Don't force the size to a multiple of 16 bytes once Cranelift gets a way to
549-
// specify stack slot alignment.
550-
size: (src_ty.bytes() + 15) / 16 * 16,
551-
});
552-
let ptr = Pointer::stack_slot(stack_slot);
537+
let ptr = fx.create_stack_slot(src_ty.bytes(), src_ty.bytes());
553538
ptr.store(fx, data, MemFlags::trusted());
554539
ptr.load(fx, dst_ty, MemFlags::trusted())
555540
}

0 commit comments

Comments
 (0)