diff options
author | Maxime Chevalier-Boisvert <[email protected]> | 2022-05-19 15:01:20 -0400 |
---|---|---|
committer | Takashi Kokubun <[email protected]> | 2022-08-29 08:46:53 -0700 |
commit | 1b2ee62149d5fa8d8cbe2097f9fd7a3af31989c2 (patch) | |
tree | 26350c8aa8408b3ddbd4be9e19e7942433da2b00 /yjit/src/backend/x86_64/mod.rs | |
parent | 564f9503603ae261561193f69f1fbdef6a140aa1 (diff) |
Implement target-specific insn splitting with Kevin. Add tests.
Diffstat (limited to 'yjit/src/backend/x86_64/mod.rs')
-rw-r--r-- | yjit/src/backend/x86_64/mod.rs | 46 |
1 files changed, 45 insertions, 1 deletions
diff --git a/yjit/src/backend/x86_64/mod.rs b/yjit/src/backend/x86_64/mod.rs index ed68e13eb6..65259a72f6 100644 --- a/yjit/src/backend/x86_64/mod.rs +++ b/yjit/src/backend/x86_64/mod.rs @@ -45,7 +45,7 @@ impl From<Opnd> for X86Opnd { impl Assembler { // Get the list of registers from which we can allocate on this platform - pub fn get_scrach_regs() -> Vec<Reg> + pub fn get_scratch_regs() -> Vec<Reg> { vec![ RAX_REG, @@ -54,6 +54,40 @@ impl Assembler } // Emit platform-specific machine code + fn target_split(mut self) -> Assembler + { + let live_ranges: Vec<usize> = std::mem::take(&mut self.live_ranges); + + self.transform_insns(|asm, index, op, opnds, target| { + match op { + Op::Add | Op::Sub | Op::And => { + match opnds.as_slice() { + // Instruction output whose live range spans beyond this instruction + [Opnd::InsnOut(out_idx), _] => { + if live_ranges[*out_idx] > index { + let opnd0 = asm.load(opnds[0]); + asm.push_insn(op, vec![opnd0, opnds[1]], None); + return; + } + }, + + [Opnd::Mem(_), _] => { + let opnd0 = asm.load(opnds[0]); + asm.push_insn(op, vec![opnd0, opnds[1]], None); + return; + }, + + _ => {} + } + }, + _ => {} + }; + + asm.push_insn(op, opnds, target); + }) + } + + // Emit platform-specific machine code pub fn target_emit(&self, cb: &mut CodeBlock) { // For each instruction @@ -87,4 +121,14 @@ impl Assembler }; } } + + // Optimize and compile the stored instructions + pub fn compile_with_regs(self, cb: &mut CodeBlock, regs: Vec<Reg>) + { + dbg!(self + .target_split() + .split_loads() + .alloc_regs(regs)) + .target_emit(cb); + } } |