From 5956f0098dfc871f4e3320baac5fc39e4d5e72b2 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Thu, 9 Mar 2023 10:34:45 -0800 Subject: [PATCH] YJIT: Merge x86_merge into x86_split --- yjit/src/backend/x86_64/mod.rs | 43 ++++++++++------------------------ 1 file changed, 12 insertions(+), 31 deletions(-) diff --git a/yjit/src/backend/x86_64/mod.rs b/yjit/src/backend/x86_64/mod.rs index dd5cbe906a33b8..90a7b257b53c72 100644 --- a/yjit/src/backend/x86_64/mod.rs +++ b/yjit/src/backend/x86_64/mod.rs @@ -105,36 +105,6 @@ impl Assembler // These are the callee-saved registers in the x86-64 SysV ABI // RBX, RSP, RBP, and R12–R15 - /// Merge IR instructions for the x86 platform. As of x86_split, all `out` operands - /// are Opnd::Out, but you sometimes want to use Opnd::Reg for example to shorten the - /// generated code, which is what this pass does. - fn x86_merge(mut self) -> Assembler { - let live_ranges: Vec = take(&mut self.live_ranges); - let mut asm = Assembler::new_with_label_names(take(&mut self.label_names)); - let mut iterator = self.into_draining_iter(); - - while let Some((index, mut insn)) = iterator.next_unmapped() { - match (&insn, iterator.peek()) { - // Merge `lea` and `mov` into a single `lea` when possible - (Insn::Lea { opnd, out }, Some(Insn::Mov { dest: Opnd::Reg(reg), src })) - if matches!(out, Opnd::InsnOut { .. }) && out == src && live_ranges[index] == index + 1 => { - asm.push_insn(Insn::Lea { opnd: *opnd, out: Opnd::Reg(*reg) }); - iterator.map_insn_index(&mut asm); - iterator.next_unmapped(); // Pop merged Insn::Mov - } - _ => { - let mut opnd_iter = insn.opnd_iter_mut(); - while let Some(opnd) = opnd_iter.next() { - *opnd = iterator.map_opnd(*opnd); - } - asm.push_insn(insn); - } - } - iterator.map_insn_index(&mut asm); - } - asm - } - /// Split IR instructions for the x86 platform fn x86_split(mut self) -> Assembler { @@ -363,6 +333,18 @@ impl Assembler // just performs the call. asm.ccall(*fptr, vec![]); }, + Insn::Lea { .. } => { + // Merge `lea` and `mov` into a single `lea` when possible + match (&insn, iterator.peek()) { + (Insn::Lea { opnd, out }, Some(Insn::Mov { dest: Opnd::Reg(reg), src })) + if matches!(out, Opnd::InsnOut { .. }) && out == src && live_ranges[index] == index + 1 => { + asm.push_insn(Insn::Lea { opnd: *opnd, out: Opnd::Reg(*reg) }); + iterator.map_insn_index(&mut asm); + iterator.next_unmapped(); // Pop merged Insn::Mov + } + _ => asm.push_insn(insn), + } + }, _ => { if insn.out_opnd().is_some() { let out_num_bits = Opnd::match_num_bits_iter(insn.opnd_iter()); @@ -749,7 +731,6 @@ impl Assembler { let asm = self.lower_stack(); let asm = asm.x86_split(); - let asm = asm.x86_merge(); let mut asm = asm.alloc_regs(regs); // Create label instances in the code block