Avoid introducing a move for struct return (#6245)

* Move sret_reg handling to Lower:new, from gen_arg_setup

* Update exp files

* Review feedback

* Review feedback
This commit is contained in:
Trevor Elliott
2023-04-20 11:13:40 -07:00
committed by GitHub
parent 620ec03ca4
commit b667f5fa5b
3 changed files with 47 additions and 48 deletions

View File

@@ -377,12 +377,27 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
}
}
// Make a sret register, if one is needed.
// Find the sret register, if it's used.
let mut sret_reg = None;
for ret in &vcode.abi().signature().returns.clone() {
for ret in vcode.abi().signature().returns.iter() {
if ret.purpose == ArgumentPurpose::StructReturn {
assert!(sret_reg.is_none());
sret_reg = Some(vregs.alloc(ret.value_type)?);
let entry_bb = f.stencil.layout.entry_block().unwrap();
for (&param, sig_param) in f
.dfg
.block_params(entry_bb)
.iter()
.zip(vcode.abi().signature().params.iter())
{
if sig_param.purpose == ArgumentPurpose::StructReturn {
let regs = value_regs[param];
assert!(regs.len() == 1);
assert!(sret_reg.is_none());
sret_reg = Some(regs);
}
}
assert!(sret_reg.is_some());
}
}
@@ -576,24 +591,6 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
{
self.emit(insn);
}
if self.abi().signature().params[i].purpose == ArgumentPurpose::StructReturn {
assert!(regs.len() == 1);
let ty = self.abi().signature().params[i].value_type;
// The ABI implementation must have ensured that a StructReturn
// arg is present in the return values.
assert!(self
.abi()
.signature()
.returns
.iter()
.position(|ret| ret.purpose == ArgumentPurpose::StructReturn)
.is_some());
self.emit(I::gen_move(
Writable::from_reg(self.sret_reg.unwrap().regs()[0]),
regs.regs()[0].to_reg(),
ty,
));
}
}
if let Some(insn) = self
.vcode