YJIT: Merge x86_merge into x86_split (#7487)
This commit is contained in:
parent
1347d707ca
commit
487142928a
Notes:
git
2023-03-09 19:59:00 +00:00
Merged-By: k0kubun <takashikkbn@gmail.com>
@ -105,36 +105,6 @@ impl Assembler
|
|||||||
// These are the callee-saved registers in the x86-64 SysV ABI
|
// These are the callee-saved registers in the x86-64 SysV ABI
|
||||||
// RBX, RSP, RBP, and R12–R15
|
// 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
|
/// Split IR instructions for the x86 platform
|
||||||
fn x86_split(mut self) -> Assembler
|
fn x86_split(mut self) -> Assembler
|
||||||
{
|
{
|
||||||
@ -363,6 +333,18 @@ impl Assembler
|
|||||||
// just performs the call.
|
// just performs the call.
|
||||||
asm.ccall(*fptr, vec![]);
|
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() {
|
if insn.out_opnd().is_some() {
|
||||||
let out_num_bits = Opnd::match_num_bits_iter(insn.opnd_iter());
|
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 = self.lower_stack();
|
||||||
let asm = asm.x86_split();
|
let asm = asm.x86_split();
|
||||||
let asm = asm.x86_merge();
|
|
||||||
let mut asm = asm.alloc_regs(regs);
|
let mut asm = asm.alloc_regs(regs);
|
||||||
|
|
||||||
// Create label instances in the code block
|
// Create label instances in the code block
|
||||||
|
Loading…
x
Reference in New Issue
Block a user