зеркало из https://github.com/github/ruby.git
YJIT: Merge x86_merge into x86_split (#7487)
This commit is contained in:
Родитель
1347d707ca
Коммит
487142928a
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче