Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

YJIT: Merge x86_merge into x86_split #7487

Merged
merged 1 commit into from Mar 9, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
43 changes: 12 additions & 31 deletions yjit/src/backend/x86_64/mod.rs
Expand Up @@ -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
{
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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
Expand Down