Allow for call args in incoming stack slots.
A value passed as an argument to a function call may live in an incoming stack slot initially. Fix the call legalizer so it copies such an argument into the expected outgoing stack slot for the call.
This commit is contained in:
@@ -18,3 +18,15 @@ function %f() {
|
|||||||
ebb0:
|
ebb0:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function %pass_stack_int64(i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 vmctx) spiderwasm {
|
||||||
|
sig0 = (i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 vmctx) spiderwasm
|
||||||
|
fn0 = sig0 #00000000
|
||||||
|
|
||||||
|
ebb0(v0: i64, v1: i64, v2: i64, v3: i64, v4: i64, v5: i64, v6: i64, v7: i64, v8: i64, v9: i64, v10: i64, v11: i64, v12: i64, v13: i64, v14: i64, v15: i64, v16: i64, v17: i64, v18: i64, v19: i64, v20: i64):
|
||||||
|
call fn0(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20)
|
||||||
|
jump ebb1
|
||||||
|
|
||||||
|
ebb1:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ use abi::{legalize_abi_value, ValueConversion};
|
|||||||
use cursor::{Cursor, FuncCursor};
|
use cursor::{Cursor, FuncCursor};
|
||||||
use flowgraph::ControlFlowGraph;
|
use flowgraph::ControlFlowGraph;
|
||||||
use ir::{Function, DataFlowGraph, Inst, InstBuilder, Ebb, Type, Value, Signature, SigRef,
|
use ir::{Function, DataFlowGraph, Inst, InstBuilder, Ebb, Type, Value, Signature, SigRef,
|
||||||
ArgumentType, ArgumentPurpose, ArgumentLoc, ValueLoc, StackSlotKind};
|
ArgumentType, ArgumentPurpose, ArgumentLoc, ValueLoc};
|
||||||
use ir::instructions::CallInfo;
|
use ir::instructions::CallInfo;
|
||||||
use isa::TargetIsa;
|
use isa::TargetIsa;
|
||||||
use legalizer::split::{isplit, vsplit};
|
use legalizer::split::{isplit, vsplit};
|
||||||
@@ -651,21 +651,14 @@ fn spill_call_arguments(pos: &mut FuncCursor) -> bool {
|
|||||||
.filter_map(|(idx, (&arg, abi))| {
|
.filter_map(|(idx, (&arg, abi))| {
|
||||||
match abi.location {
|
match abi.location {
|
||||||
ArgumentLoc::Stack(offset) => {
|
ArgumentLoc::Stack(offset) => {
|
||||||
// Is `arg` already in the right kind of stack slot?
|
// Assign `arg` to a new stack slot, unless it's already in the correct
|
||||||
match locations.get(arg) {
|
// slot. The legalization needs to be idempotent, so we should see a
|
||||||
Some(&ValueLoc::Stack(ss)) => {
|
// correct outgoing slot on the second pass.
|
||||||
// We won't reassign `arg` to a different stack slot. Assert out of
|
let ss = stack_slots.get_outgoing_arg(abi.value_type, offset);
|
||||||
// the stack slot is wrong.
|
if locations[arg] != ValueLoc::Stack(ss) {
|
||||||
assert_eq!(stack_slots[ss].kind, StackSlotKind::OutgoingArg);
|
Some((idx, arg, ss))
|
||||||
assert_eq!(stack_slots[ss].offset, offset);
|
} else {
|
||||||
assert_eq!(stack_slots[ss].size, abi.value_type.bytes());
|
None
|
||||||
None
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
// Assign `arg` to a new stack slot.
|
|
||||||
let ss = stack_slots.get_outgoing_arg(abi.value_type, offset);
|
|
||||||
Some((idx, arg, ss))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
|
|||||||
Reference in New Issue
Block a user