ABI: implement register arguments with constraints. (#4858)
* ABI: implement register arguments with constraints. Currently, Cranelift's ABI code emits a sequence of moves from physical registers into vregs at the top of the function body, one for every register-carried argument. For a number of reasons, we want to move to operand constraints instead, and remove the use of explicitly-named "pinned vregs"; this allows for better regalloc in theory, as it removes the need to "reverse-engineer" the sequence of moves. This PR alters the ABI code so that it generates a single "args" pseudo-instruction as the first instruction in the function body. This pseudo-inst defs all register arguments, and constrains them to the appropriate registers at the def-point. Subsequently the regalloc can move them wherever it needs to. Some care was taken not to have this pseudo-inst show up in post-regalloc disassemblies, but the change did cause a general regalloc "shift" in many tests, so the precise-output updates are a bit noisy. Sorry about that! A subsequent PR will handle the other half of the ABI code, namely, the callsite case, with a similar preg-to-constraint conversion. * Update based on review feedback. * Review feedback.
This commit is contained in:
@@ -586,8 +586,9 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
|
||||
let regs = writable_value_regs(self.value_regs[*param]);
|
||||
for insn in self
|
||||
.vcode
|
||||
.abi()
|
||||
.gen_copy_arg_to_regs(self.sigs(), i, regs)
|
||||
.vcode
|
||||
.abi
|
||||
.gen_copy_arg_to_regs(&self.vcode.vcode.sigs, i, regs)
|
||||
.into_iter()
|
||||
{
|
||||
self.emit(insn);
|
||||
@@ -611,7 +612,22 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(insn) = self.vcode.abi().gen_retval_area_setup(self.sigs()) {
|
||||
if let Some(insn) = self
|
||||
.vcode
|
||||
.vcode
|
||||
.abi
|
||||
.gen_retval_area_setup(&self.vcode.vcode.sigs)
|
||||
{
|
||||
self.emit(insn);
|
||||
}
|
||||
|
||||
// The `args` instruction below must come first. Finish
|
||||
// the current "IR inst" (with a default source location,
|
||||
// as for other special instructions inserted during
|
||||
// lowering) and continue the scan backward.
|
||||
self.finish_ir_inst(Default::default());
|
||||
|
||||
if let Some(insn) = self.vcode.vcode.abi.take_args() {
|
||||
self.emit(insn);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user