diff options
| author | Takashi Kokubun <takashikkbn@gmail.com> | 2023-03-09 11:58:40 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-03-09 11:58:40 -0800 |
| commit | 487142928aec557fce21bb191afa0169f4479fbd (patch) | |
| tree | 8c5d7d69bfca541d78a865a39790f77e3cea4b05 | |
| parent | 1347d707cad8307b91df7e03e5347231ffafe40f (diff) | |
YJIT: Merge x86_merge into x86_split (#7487)
Notes
Notes:
Merged-By: k0kubun <takashikkbn@gmail.com>
| -rw-r--r-- | yjit/src/backend/x86_64/mod.rs | 43 |
1 files changed, 12 insertions, 31 deletions
diff --git a/yjit/src/backend/x86_64/mod.rs b/yjit/src/backend/x86_64/mod.rs index dd5cbe906a..90a7b257b5 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<usize> = 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 |
