[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
|
||||
.iter()
|
||||
.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 {
|
||||
Expr::Var(var_index) => var_pool.get(*var_index).name.as_ref(),
|
||||
Expr::Literal(_) => {
|
||||
@@ -122,16 +126,9 @@ fn unwrap_inst(
|
||||
} else if op.is_value() {
|
||||
let n = inst.value_opnums.iter().position(|&i| i == op_num).unwrap();
|
||||
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 {
|
||||
// This is a value list argument.
|
||||
assert!(iform.has_value_list);
|
||||
// This is a value list argument or a varargs.
|
||||
assert!(iform.has_value_list || op.is_varargs());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -167,10 +164,14 @@ fn unwrap_inst(
|
||||
let name = &var_pool
|
||||
.get(apply.args[i].maybe_var().expect("vararg without name"))
|
||||
.name;
|
||||
|
||||
// Above name is set to an `Vec` representing the varargs. However it is expected to be
|
||||
// `&[Value]` below, so we borrow it.
|
||||
fmtln!(fmt, "let {} = &{};", name, name);
|
||||
let n = inst
|
||||
.imm_opnums
|
||||
.iter()
|
||||
.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