[meta] Simplify handling of variable arguments in legalization;
If a legalization contains varargs, it defers creating the binding for the varargs, making the generated code easier to understand.
This commit is contained in:
@@ -44,6 +44,10 @@ fn unwrap_inst(
|
|||||||
.args
|
.args
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
|
.filter(|(arg_num, _)| {
|
||||||
|
// Variable args are specially handled after extracting args.
|
||||||
|
!inst.operands_in[*arg_num].is_varargs()
|
||||||
|
})
|
||||||
.map(|(arg_num, arg)| match &arg {
|
.map(|(arg_num, arg)| match &arg {
|
||||||
Expr::Var(var_index) => var_pool.get(*var_index).name.as_ref(),
|
Expr::Var(var_index) => var_pool.get(*var_index).name.as_ref(),
|
||||||
Expr::Literal(_) => {
|
Expr::Literal(_) => {
|
||||||
@@ -122,16 +126,9 @@ fn unwrap_inst(
|
|||||||
} else if op.is_value() {
|
} else if op.is_value() {
|
||||||
let n = inst.value_opnums.iter().position(|&i| i == op_num).unwrap();
|
let n = inst.value_opnums.iter().position(|&i| i == op_num).unwrap();
|
||||||
fmtln!(fmt, "pos.func.dfg.resolve_aliases(args[{}]),", n);
|
fmtln!(fmt, "pos.func.dfg.resolve_aliases(args[{}]),", n);
|
||||||
} else if op.is_varargs() {
|
|
||||||
let n = inst.imm_opnums.iter().chain(inst.value_opnums.iter()).max().map(|n| n + 1).unwrap_or(0);
|
|
||||||
// We need to create a `Vec` here, as using a slice would result in a borrowck
|
|
||||||
// error later on.
|
|
||||||
fmtln!(fmt, "\
|
|
||||||
args.iter().skip({}).map(|&arg| pos.func.dfg.resolve_aliases(arg)).collect::<Vec<_>>(),\
|
|
||||||
", n);
|
|
||||||
} else {
|
} else {
|
||||||
// This is a value list argument.
|
// This is a value list argument or a varargs.
|
||||||
assert!(iform.has_value_list);
|
assert!(iform.has_value_list || op.is_varargs());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -167,10 +164,14 @@ fn unwrap_inst(
|
|||||||
let name = &var_pool
|
let name = &var_pool
|
||||||
.get(apply.args[i].maybe_var().expect("vararg without name"))
|
.get(apply.args[i].maybe_var().expect("vararg without name"))
|
||||||
.name;
|
.name;
|
||||||
|
let n = inst
|
||||||
// Above name is set to an `Vec` representing the varargs. However it is expected to be
|
.imm_opnums
|
||||||
// `&[Value]` below, so we borrow it.
|
.iter()
|
||||||
fmtln!(fmt, "let {} = &{};", name, name);
|
.chain(inst.value_opnums.iter())
|
||||||
|
.max()
|
||||||
|
.copied()
|
||||||
|
.unwrap_or(0);
|
||||||
|
fmtln!(fmt, "let {} = &Vec::from(&args[{}..]);", name, n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user