summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2023-03-09 11:58:40 -0800
committerGitHub <noreply@github.com>2023-03-09 11:58:40 -0800
commit487142928aec557fce21bb191afa0169f4479fbd (patch)
tree8c5d7d69bfca541d78a865a39790f77e3cea4b05
parent1347d707cad8307b91df7e03e5347231ffafe40f (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.rs43
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