Merge {make_incoming,get_outgoing}_{,struct_}arg

This commit is contained in:
bjorn3
2020-07-15 19:20:50 +02:00
committed by Benjamin Bouvier
parent 0d4fa6d32a
commit 4971d9ee80
3 changed files with 23 additions and 29 deletions

View File

@@ -286,12 +286,7 @@ impl StackSlots {
}
/// Create a stack slot representing an incoming function argument.
pub fn make_incoming_arg(&mut self, ty: Type, offset: StackOffset) -> StackSlot {
self.make_incoming_struct_arg(ty.bytes(), offset)
}
/// Create a stack slot representing an incoming struct function argument.
pub fn make_incoming_struct_arg(&mut self, size: u32, offset: StackOffset) -> StackSlot {
pub fn make_incoming_arg(&mut self, size: u32, offset: StackOffset) -> StackSlot {
let mut data = StackSlotData::new(StackSlotKind::IncomingArg, size);
debug_assert!(offset <= StackOffset::max_value() - data.size as StackOffset);
data.offset = Some(offset);
@@ -305,12 +300,7 @@ impl StackSlots {
///
/// The requested offset is relative to this function's stack pointer immediately before making
/// the call.
pub fn get_outgoing_arg(&mut self, ty: Type, offset: StackOffset) -> StackSlot {
self.get_outgoing_struct_arg(ty.bytes(), offset)
}
/// FIXME
pub fn get_outgoing_struct_arg(&mut self, size: u32, offset: StackOffset) -> StackSlot {
pub fn get_outgoing_arg(&mut self, size: u32, offset: StackOffset) -> StackSlot {
// Look for an existing outgoing stack slot with the same offset and size.
let inspos = match self.outgoing.binary_search_by_key(&(offset, size), |&ss| {
(self[ss].offset.unwrap(), self[ss].size)
@@ -395,9 +385,9 @@ mod tests {
fn outgoing() {
let mut sss = StackSlots::new();
let ss0 = sss.get_outgoing_arg(types::I32, 8);
let ss1 = sss.get_outgoing_arg(types::I32, 4);
let ss2 = sss.get_outgoing_arg(types::I64, 8);
let ss0 = sss.get_outgoing_arg(4, 8);
let ss1 = sss.get_outgoing_arg(4, 4);
let ss2 = sss.get_outgoing_arg(8, 8);
assert_eq!(sss[ss0].offset, Some(8));
assert_eq!(sss[ss0].size, 4);
@@ -408,9 +398,9 @@ mod tests {
assert_eq!(sss[ss2].offset, Some(8));
assert_eq!(sss[ss2].size, 8);
assert_eq!(sss.get_outgoing_arg(types::I32, 8), ss0);
assert_eq!(sss.get_outgoing_arg(types::I32, 4), ss1);
assert_eq!(sss.get_outgoing_arg(types::I64, 8), ss2);
assert_eq!(sss.get_outgoing_arg(4, 8), ss0);
assert_eq!(sss.get_outgoing_arg(4, 4), ss1);
assert_eq!(sss.get_outgoing_arg(8, 8), ss2);
}
#[test]

View File

@@ -121,7 +121,7 @@ fn legalize_entry_params(func: &mut Function, entry: Block) {
} else {
unreachable!("StructArgument must already have a Stack ArgumentLoc assigned");
};
let ss = pos.func.stack_slots.make_incoming_struct_arg(size, offset);
let ss = pos.func.stack_slots.make_incoming_arg(size, offset);
let struct_arg = pos.ins().stack_addr(arg_type, ss, 0);
pos.func.dfg.change_to_alias(arg, struct_arg);
let dummy = pos
@@ -1024,7 +1024,9 @@ fn spill_entry_params(func: &mut Function, entry: Block) {
{
if let ArgumentPurpose::StructArgument(_) = abi.purpose {
} else if let ArgumentLoc::Stack(offset) = abi.location {
let ss = func.stack_slots.make_incoming_arg(abi.value_type, offset);
let ss = func
.stack_slots
.make_incoming_arg(abi.value_type.bytes(), offset);
func.locations[arg] = ValueLoc::Stack(ss);
}
}
@@ -1066,11 +1068,13 @@ fn spill_call_arguments(pos: &mut FuncCursor, isa: &dyn TargetIsa) -> bool {
// slot. The legalization needs to be idempotent, so we should see a
// correct outgoing slot on the second pass.
let (ss, size) = match abi.purpose {
ArgumentPurpose::StructArgument(size) => (
stack_slots.get_outgoing_struct_arg(size, offset),
Some(size),
ArgumentPurpose::StructArgument(size) => {
(stack_slots.get_outgoing_arg(size, offset), Some(size))
}
_ => (
stack_slots.get_outgoing_arg(abi.value_type.bytes(), offset),
None,
),
_ => (stack_slots.get_outgoing_arg(abi.value_type, offset), None),
};
if locations[arg] != ValueLoc::Stack(ss) {
Some((idx, arg, ss, size))

View File

@@ -152,8 +152,8 @@ mod tests {
assert_eq!(layout_stack(sss, is_leaf, 16), Ok(0));
// Same for incoming arguments with non-negative offsets.
let in0 = sss.make_incoming_arg(types::I64, 0);
let in1 = sss.make_incoming_arg(types::I64, 8);
let in0 = sss.make_incoming_arg(8, 0);
let in1 = sss.make_incoming_arg(8, 8);
assert_eq!(layout_stack(sss, is_leaf, 1), Ok(0));
assert_eq!(layout_stack(sss, is_leaf, 16), Ok(0));
@@ -178,7 +178,7 @@ mod tests {
// An incoming argument with negative offset counts towards the total frame size, but it
// should still pack nicely with the spill slots.
let in2 = sss.make_incoming_arg(types::I32, -4);
let in2 = sss.make_incoming_arg(4, -4);
assert_eq!(layout_stack(sss, is_leaf, 1), Ok(16));
assert_eq!(sss[in0].offset, Some(0));
@@ -195,7 +195,7 @@ mod tests {
assert_eq!(sss[ss1].offset, Some(-8));
// Finally, make sure there is room for the outgoing args.
let out0 = sss.get_outgoing_arg(types::I32, 0);
let out0 = sss.get_outgoing_arg(4, 0);
assert_eq!(layout_stack(sss, is_leaf, 1), Ok(20));
assert_eq!(sss[in0].offset, Some(0));
@@ -214,7 +214,7 @@ mod tests {
assert_eq!(sss[out0].offset, Some(0));
// Also test that an unsupported offset is rejected.
sss.get_outgoing_arg(types::I8, StackOffset::max_value() - 1);
sss.get_outgoing_arg(1, StackOffset::max_value() - 1);
assert_eq!(
layout_stack(sss, is_leaf, 1),
Err(CodegenError::ImplLimitExceeded)