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:
Jakob Stoklund Olesen
2017-10-02 15:56:38 -07:00
parent 374ed3a07b
commit ef048b8899
2 changed files with 21 additions and 16 deletions

View File

@@ -18,3 +18,15 @@ function %f() {
ebb0:
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
}

View File

@@ -21,7 +21,7 @@ use abi::{legalize_abi_value, ValueConversion};
use cursor::{Cursor, FuncCursor};
use flowgraph::ControlFlowGraph;
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 isa::TargetIsa;
use legalizer::split::{isplit, vsplit};
@@ -651,21 +651,14 @@ fn spill_call_arguments(pos: &mut FuncCursor) -> bool {
.filter_map(|(idx, (&arg, abi))| {
match abi.location {
ArgumentLoc::Stack(offset) => {
// Is `arg` already in the right kind of stack slot?
match locations.get(arg) {
Some(&ValueLoc::Stack(ss)) => {
// We won't reassign `arg` to a different stack slot. Assert out of
// the stack slot is wrong.
assert_eq!(stack_slots[ss].kind, StackSlotKind::OutgoingArg);
assert_eq!(stack_slots[ss].offset, offset);
assert_eq!(stack_slots[ss].size, abi.value_type.bytes());
None
}
_ => {
// Assign `arg` to a new stack slot.
let ss = stack_slots.get_outgoing_arg(abi.value_type, offset);
Some((idx, arg, ss))
}
// Assign `arg` to a new stack slot, unless it's already in the correct
// slot. The legalization needs to be idempotent, so we should see a
// correct outgoing slot on the second pass.
let ss = stack_slots.get_outgoing_arg(abi.value_type, offset);
if locations[arg] != ValueLoc::Stack(ss) {
Some((idx, arg, ss))
} else {
None
}
}
_ => None,