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: 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
}

View File

@@ -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,