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

Refactor Singlepass #2706

Merged
merged 46 commits into from
Dec 9, 2021
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
235b309
feat(compiler) Created abstraction for Reg and Location
ptitSeb Nov 3, 2021
9710ab8
fixed lint
ptitSeb Nov 3, 2021
17ccce9
Move Size enum to common_decl
ptitSeb Nov 10, 2021
45261a7
Abstraction for CombinedRegister
ptitSeb Nov 12, 2021
633896e
improve(compiler) Abstracted Machine on SinglePass (still need more a…
ptitSeb Nov 12, 2021
6c9be49
improvement(compiler) start to make codegen independant from arch (WIP)
ptitSeb Nov 17, 2021
443d16a
improvement(compiler) More work on codegen abstraction (atomic cmpxchg)
ptitSeb Nov 18, 2021
ace5d51
improvement(compiler) More work on codegen abstraction (atomic xchg)
ptitSeb Nov 18, 2021
6a33200
improvement(compiler) abstraction of emit_memory_op
ptitSeb Nov 23, 2021
36f947c
improvement(compiler) abstraction of lock + logic in codegen
ptitSeb Nov 24, 2021
3736eea
improvement(compiler) abstraction of lock add/sub in codegen
ptitSeb Nov 24, 2021
5b64a39
improvement(compiler) abstraction of atomic store (and a bunch of rel…
ptitSeb Nov 25, 2021
0c0d437
improvement(compiler) abstraction of relaxed move with zero or sign e…
ptitSeb Nov 26, 2021
5ae9c0f
improvement(compiler) abstraction of canonicalization and Operator::End
ptitSeb Nov 26, 2021
052351b
improvement(compiler) abstraction of Operator Return, Br, BrIf and Br…
ptitSeb Nov 26, 2021
9d751a7
improvement(compiler) abstraction of Operator CallIndirect
ptitSeb Nov 26, 2021
2b99188
improvement(compiler) abstraction of Operator Call
ptitSeb Nov 29, 2021
e84ba7a
improvement(compiler) abstraction of Operator F64Convert*
ptitSeb Nov 29, 2021
8b9535b
improvement(compiler) abstraction of Operator F32Convert*
ptitSeb Nov 29, 2021
232a9c0
improvement(compiler) abstraction of Operator I32Convert* and I64Conv…
ptitSeb Nov 29, 2021
a60dda9
improvement(compiler) abstraction of more F32/F64 coversion and opera…
ptitSeb Nov 30, 2021
cf3eea1
improvement(compiler) abstraction of more F32/F64 comparaisons
ptitSeb Nov 30, 2021
c247bf3
improvement(compiler) abstraction of F32 min/max operators
ptitSeb Dec 1, 2021
e430851
improvement(compiler) abstraction of F64/F32 add/sub/mul/div operators
ptitSeb Dec 1, 2021
f1244ac
improvement(compiler) abstraction of remaining i32 Operators
ptitSeb Dec 1, 2021
dccc6bf
improvement(compiler) abstraction of remaining i64 Operators
ptitSeb Dec 1, 2021
d49bc4d
improvement(compiler) abstraction of native calls
ptitSeb Dec 2, 2021
5660c09
improvement(compiler) abstraction of logic and math atomic operators
ptitSeb Dec 3, 2021
3c2e0ea
improvement(compiler) fix merge issues
ptitSeb Dec 3, 2021
b100880
improvement(compiler) fix test for machine_x86
ptitSeb Dec 3, 2021
d39e765
improvement(compiler) refactored atomic access again
ptitSeb Dec 3, 2021
6817a2d
improvement(compiler) refactored atomic exchange again
ptitSeb Dec 3, 2021
19691f6
improvement(compiler) refactored atomic cmpxchg again
ptitSeb Dec 3, 2021
5164cb9
improvement(compiler) refactored non-atomic load and store Operator
ptitSeb Dec 3, 2021
049a1f7
improvement(compiler) Fixed some of the later refactoring of memory_op
ptitSeb Dec 3, 2021
5ed8fbf
Fixed linting
ptitSeb Dec 3, 2021
517f81b
improvement(compiler) More x86_64 speicific code removed from CodeGen
ptitSeb Dec 6, 2021
7771fab
improvement(compiler) Remove CombinedRegister from Machine
ptitSeb Dec 6, 2021
b315ed5
Fixed linting
ptitSeb Dec 6, 2021
ab931de
improvement(compiler) Remove last GPR:: direct access in codegen
ptitSeb Dec 7, 2021
7dea877
improvement(compiler) Remove CombineRegister from CodeGen
ptitSeb Dec 7, 2021
3e52f77
improvement(compiler) CodeGen now completly abstracted, using Machine…
ptitSeb Dec 8, 2021
6fd9d13
improvement(compiler) renammed codeGen_x64 to CodeGen, now that it's …
ptitSeb Dec 8, 2021
e03fe0d
improvement(compiler) disabled test_release_locations_keep_state_nopa…
ptitSeb Dec 8, 2021
d29c1c4
improvement(compiler) Rename Emitter trait to EmitterX64 to avoid nam…
ptitSeb Dec 9, 2021
1bb284a
improvement(compiler) Removed commented test
ptitSeb Dec 9, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7,941 changes: 2,161 additions & 5,780 deletions lib/compiler-singlepass/src/codegen_x64.rs

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions lib/compiler-singlepass/src/common_decl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,14 @@ pub struct FunctionStateMap {
pub trappable_offsets: BTreeMap<usize, OffsetInfo>, /* suspend_offset -> info */
}

#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub enum Size {
S8,
S16,
S32,
S64,
}

/// A kind of suspend offset.
#[derive(Clone, Copy, Debug)]
pub enum SuspendOffset {
Expand Down
18 changes: 12 additions & 6 deletions lib/compiler-singlepass/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
// Allow unused imports while developing.
#![allow(unused_imports, dead_code)]

use crate::codegen_x64::{
gen_import_call_trampoline, gen_std_dynamic_import_trampoline, gen_std_trampoline,
CodegenError, FuncGen,
};
use crate::codegen_x64::FuncGen;
use crate::config::Singlepass;
use crate::machine::{
gen_import_call_trampoline, gen_std_dynamic_import_trampoline, gen_std_trampoline, CodegenError,
};
use loupe::MemoryUsage;
#[cfg(feature = "rayon")]
use rayon::prelude::{IntoParallelIterator, ParallelIterator};
Expand Down Expand Up @@ -95,6 +95,7 @@ impl Compiler for SinglepassCompiler {
&vmoffsets,
i,
&module.signatures[module.functions[i]],
target,
calling_convention,
)
})
Expand Down Expand Up @@ -153,7 +154,7 @@ impl Compiler for SinglepassCompiler {
.values()
.collect::<Vec<_>>()
.into_par_iter_if_rayon()
.map(|func_type| gen_std_trampoline(&func_type, calling_convention))
.map(|func_type| gen_std_trampoline(&func_type, target, calling_convention))
.collect::<Vec<_>>()
.into_iter()
.collect::<PrimaryMap<_, _>>();
Expand All @@ -163,7 +164,12 @@ impl Compiler for SinglepassCompiler {
.collect::<Vec<_>>()
.into_par_iter_if_rayon()
.map(|func_type| {
gen_std_dynamic_import_trampoline(&vmoffsets, &func_type, calling_convention)
gen_std_dynamic_import_trampoline(
&vmoffsets,
&func_type,
target,
calling_convention,
)
})
.collect::<Vec<_>>()
.into_iter()
Expand Down
110 changes: 62 additions & 48 deletions lib/compiler-singlepass/src/emitter_x64.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
use crate::common_decl::Size;
use crate::location::Location as AbstractLocation;
pub use crate::location::Multiplier;
pub use crate::machine::{Label, Offset};
pub use crate::x64_decl::{GPR, XMM};
use dynasm::dynasm;
use dynasmrt::{
Expand All @@ -20,17 +24,7 @@ macro_rules! dynasm {
};
}

#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum Location {
Imm8(u8),
Imm32(u32),
Imm64(u64),
// Imm128(u128),
GPR(GPR),
XMM(XMM),
Memory(GPR, i32),
MemoryAddTriple(GPR, GPR, i32),
}
pub type Location = AbstractLocation<GPR, XMM>;

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Condition {
Expand All @@ -49,14 +43,6 @@ pub enum Condition {
Carry,
}

#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub enum Size {
S8,
S16,
S32,
S64,
}

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[allow(dead_code)]
pub enum XMMOrMemory {
Expand All @@ -72,19 +58,16 @@ pub enum GPROrMemory {
}

pub trait Emitter {
type Label;
type Offset;

fn get_label(&mut self) -> Self::Label;
fn get_offset(&self) -> Self::Offset;
fn get_label(&mut self) -> Label;
fn get_offset(&self) -> Offset;
fn get_jmp_instr_size(&self) -> u8;

fn finalize_function(&mut self) {}

fn emit_u64(&mut self, x: u64);
fn emit_bytes(&mut self, bytes: &[u8]);

fn emit_label(&mut self, label: Self::Label);
fn emit_label(&mut self, label: Label);

fn emit_nop(&mut self);

Expand All @@ -94,11 +77,11 @@ pub trait Emitter {

fn emit_mov(&mut self, sz: Size, src: Location, dst: Location);
fn emit_lea(&mut self, sz: Size, src: Location, dst: Location);
fn emit_lea_label(&mut self, label: Self::Label, dst: Location);
fn emit_lea_label(&mut self, label: Label, dst: Location);
fn emit_cdq(&mut self);
fn emit_cqo(&mut self);
fn emit_xor(&mut self, sz: Size, src: Location, dst: Location);
fn emit_jmp(&mut self, condition: Condition, label: Self::Label);
fn emit_jmp(&mut self, condition: Condition, label: Label);
fn emit_jmp_location(&mut self, loc: Location);
fn emit_set(&mut self, condition: Condition, dst: GPR);
fn emit_push(&mut self, sz: Size, src: Location);
Expand All @@ -117,6 +100,7 @@ pub trait Emitter {
fn emit_rol(&mut self, sz: Size, src: Location, dst: Location);
fn emit_ror(&mut self, sz: Size, src: Location, dst: Location);
fn emit_and(&mut self, sz: Size, src: Location, dst: Location);
fn emit_test(&mut self, sz: Size, src: Location, dst: Location);
fn emit_or(&mut self, sz: Size, src: Location, dst: Location);
fn emit_bsr(&mut self, sz: Size, src: Location, dst: Location);
fn emit_bsf(&mut self, sz: Size, src: Location, dst: Location);
Expand Down Expand Up @@ -211,7 +195,7 @@ pub trait Emitter {

fn emit_ud2(&mut self);
fn emit_ret(&mut self);
fn emit_call_label(&mut self, label: Self::Label);
fn emit_call_label(&mut self, label: Label);
fn emit_call_location(&mut self, loc: Location);

fn emit_call_register(&mut self, reg: GPR);
Expand Down Expand Up @@ -635,9 +619,6 @@ macro_rules! avx_round_fn {
}

impl Emitter for Assembler {
type Label = DynamicLabel;
type Offset = AssemblyOffset;

fn get_label(&mut self) -> DynamicLabel {
self.new_dynamic_label()
}
Expand Down Expand Up @@ -672,7 +653,7 @@ impl Emitter for Assembler {
}
}

fn emit_label(&mut self, label: Self::Label) {
fn emit_label(&mut self, label: Label) {
dynasm!(self ; => label);
}

Expand Down Expand Up @@ -764,32 +745,32 @@ impl Emitter for Assembler {
(Size::S32, Location::Imm64(src), Location::Memory(dst, disp)) => {
dynasm!(self ; mov DWORD [Rq(dst as u8) + disp], src as i32);
}
(Size::S32, Location::GPR(src), Location::XMM(dst)) => {
(Size::S32, Location::GPR(src), Location::SIMD(dst)) => {
dynasm!(self ; movd Rx(dst as u8), Rd(src as u8));
}
(Size::S32, Location::XMM(src), Location::GPR(dst)) => {
(Size::S32, Location::SIMD(src), Location::GPR(dst)) => {
dynasm!(self ; movd Rd(dst as u8), Rx(src as u8));
}
(Size::S32, Location::Memory(src, disp), Location::XMM(dst)) => {
(Size::S32, Location::Memory(src, disp), Location::SIMD(dst)) => {
dynasm!(self ; movd Rx(dst as u8), [Rq(src as u8) + disp]);
}
(Size::S32, Location::XMM(src), Location::Memory(dst, disp)) => {
(Size::S32, Location::SIMD(src), Location::Memory(dst, disp)) => {
dynasm!(self ; movd [Rq(dst as u8) + disp], Rx(src as u8));
}

(Size::S64, Location::GPR(src), Location::XMM(dst)) => {
(Size::S64, Location::GPR(src), Location::SIMD(dst)) => {
dynasm!(self ; movq Rx(dst as u8), Rq(src as u8));
}
(Size::S64, Location::XMM(src), Location::GPR(dst)) => {
(Size::S64, Location::SIMD(src), Location::GPR(dst)) => {
dynasm!(self ; movq Rq(dst as u8), Rx(src as u8));
}
(Size::S64, Location::Memory(src, disp), Location::XMM(dst)) => {
(Size::S64, Location::Memory(src, disp), Location::SIMD(dst)) => {
dynasm!(self ; movq Rx(dst as u8), [Rq(src as u8) + disp]);
}
(Size::S64, Location::XMM(src), Location::Memory(dst, disp)) => {
(Size::S64, Location::SIMD(src), Location::Memory(dst, disp)) => {
dynasm!(self ; movq [Rq(dst as u8) + disp], Rx(src as u8));
}
(_, Location::XMM(src), Location::XMM(dst)) => {
(_, Location::SIMD(src), Location::SIMD(dst)) => {
dynasm!(self ; movq Rx(dst as u8), Rx(src as u8));
}

Expand All @@ -806,16 +787,44 @@ impl Emitter for Assembler {
(Size::S64, Location::Memory(src, disp), Location::GPR(dst)) => {
dynasm!(self ; lea Rq(dst as u8), [Rq(src as u8) + disp]);
}
(Size::S32, Location::MemoryAddTriple(src1, src2, disp), Location::GPR(dst)) => {
dynasm!(self ; lea Rd(dst as u8), [Rq(src1 as u8) + Rq(src2 as u8) + disp]);
(Size::S32, Location::Memory2(src1, src2, mult, disp), Location::GPR(dst)) => {
match mult {
Multiplier::Zero => dynasm!(self ; lea Rd(dst as u8), [Rq(src1 as u8) + disp]),
Multiplier::One => {
dynasm!(self ; lea Rd(dst as u8), [Rq(src1 as u8) + Rq(src2 as u8) + disp])
}
Multiplier::Two => {
dynasm!(self ; lea Rd(dst as u8), [Rq(src1 as u8) + Rq(src2 as u8) * 2 + disp])
}
Multiplier::Four => {
dynasm!(self ; lea Rd(dst as u8), [Rq(src1 as u8) + Rq(src2 as u8) * 4 + disp])
}
Multiplier::Height => {
dynasm!(self ; lea Rd(dst as u8), [Rq(src1 as u8) + Rq(src2 as u8) * 8 + disp])
}
};
}
(Size::S64, Location::MemoryAddTriple(src1, src2, disp), Location::GPR(dst)) => {
dynasm!(self ; lea Rq(dst as u8), [Rq(src1 as u8) + Rq(src2 as u8) + disp]);
(Size::S64, Location::Memory2(src1, src2, mult, disp), Location::GPR(dst)) => {
match mult {
Multiplier::Zero => dynasm!(self ; lea Rq(dst as u8), [Rq(src1 as u8) + disp]),
Multiplier::One => {
dynasm!(self ; lea Rq(dst as u8), [Rq(src1 as u8) + Rq(src2 as u8) + disp])
}
Multiplier::Two => {
dynasm!(self ; lea Rq(dst as u8), [Rq(src1 as u8) + Rq(src2 as u8) * 2 + disp])
}
Multiplier::Four => {
dynasm!(self ; lea Rq(dst as u8), [Rq(src1 as u8) + Rq(src2 as u8) * 4 + disp])
}
Multiplier::Height => {
dynasm!(self ; lea Rq(dst as u8), [Rq(src1 as u8) + Rq(src2 as u8) * 8 + disp])
}
};
}
_ => panic!("singlepass can't emit LEA {:?} {:?} {:?}", sz, src, dst),
}
}
fn emit_lea_label(&mut self, label: Self::Label, dst: Location) {
fn emit_lea_label(&mut self, label: Label, dst: Location) {
match dst {
Location::GPR(x) => {
dynasm!(self ; lea Rq(x as u8), [=>label]);
Expand All @@ -834,7 +843,7 @@ impl Emitter for Assembler {
panic!("singlepass can't emit XOR {:?} {:?} {:?}", sz, src, dst)
});
}
fn emit_jmp(&mut self, condition: Condition, label: Self::Label) {
fn emit_jmp(&mut self, condition: Condition, label: Label) {
match condition {
Condition::None => jmp_op!(jmp, self, label),
Condition::Above => jmp_op!(ja, self, label),
Expand Down Expand Up @@ -1007,6 +1016,11 @@ impl Emitter for Assembler {
panic!("singlepass can't emit AND {:?} {:?} {:?}", sz, src, dst)
});
}
fn emit_test(&mut self, sz: Size, src: Location, dst: Location) {
binop_all_nofp!(test, self, sz, src, dst, {
panic!("singlepass can't emit TEST {:?} {:?} {:?}", sz, src, dst)
});
}
fn emit_or(&mut self, sz: Size, src: Location, dst: Location) {
binop_all_nofp!(or, self, sz, src, dst, {
panic!("singlepass can't emit OR {:?} {:?} {:?}", sz, src, dst)
Expand Down Expand Up @@ -1393,7 +1407,7 @@ impl Emitter for Assembler {
dynasm!(self ; ret);
}

fn emit_call_label(&mut self, label: Self::Label) {
fn emit_call_label(&mut self, label: Label) {
dynasm!(self ; call =>label);
}
fn emit_call_location(&mut self, loc: Location) {
Expand Down
2 changes: 2 additions & 0 deletions lib/compiler-singlepass/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ mod common_decl;
mod compiler;
mod config;
mod emitter_x64;
mod location;
mod machine;
mod machine_x64;
mod x64_decl;

pub use crate::compiler::SinglepassCompiler;
Expand Down
79 changes: 79 additions & 0 deletions lib/compiler-singlepass/src/location.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use crate::common_decl::RegisterIndex;
use crate::machine::*;
use std::fmt::Debug;
use std::hash::Hash;

#[allow(dead_code)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum Multiplier {
Zero = 0,
One = 1,
Two = 2,
Four = 4,
Height = 8,
}

#[allow(dead_code)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum Location<R, S> {
GPR(R),
SIMD(S),
Memory(R, i32),
Memory2(R, R, Multiplier, i32), // R + R*Multiplier + i32
Imm8(u8),
Imm32(u32),
Imm64(u64),
None,
}

impl<R, S> MaybeImmediate for Location<R, S> {
fn imm_value(&self) -> Option<Value> {
match *self {
Location::Imm8(imm) => Some(Value::I8(imm as i8)),
Location::Imm32(imm) => Some(Value::I32(imm as i32)),
Location::Imm64(imm) => Some(Value::I64(imm as i64)),
_ => None,
}
}
}

pub trait Reg: Copy + Clone + Eq + PartialEq + Debug + Hash + Ord {
fn is_callee_save(self) -> bool;
fn is_reserved(self) -> bool;
fn into_index(self) -> usize;
fn from_index(i: usize) -> Result<Self, ()>;
}

pub trait Descriptor<R: Reg, S: Reg> {
const FP: R;
const VMCTX: R;
const GPR_COUNT: usize;
const SIMD_COUNT: usize;
const WORD_SIZE: usize;
const STACK_GROWS_DOWN: bool;
const FP_STACK_ARG_OFFSET: i32;
const ARG_REG_COUNT: usize;
fn callee_save_gprs() -> Vec<R>;
fn caller_save_gprs() -> Vec<R>;
fn callee_save_simd() -> Vec<S>;
fn caller_save_simd() -> Vec<S>;
fn callee_param_location(n: usize) -> Location<R, S>;
fn caller_arg_location(n: usize) -> Location<R, S>;
fn return_location() -> Location<R, S>;
}

pub trait CombinedRegister: Copy + Clone + Eq + PartialEq + Debug {
/// Returns the index of the register.
fn to_index(&self) -> RegisterIndex;
/// Converts a DWARF regnum to CombinedRegister.
fn _from_dwarf_regnum(x: u16) -> Option<Self>;
/// Convert from a GPR register
fn from_gpr(x: u16) -> Self;
/// Convert from an SIMD register
fn from_simd(x: u16) -> Self;
/// Returns the instruction prefix for move to stack
/// for example `movq %this_reg, ?(%rsp)` on x86_64
/// To build an instruction, append the memory location as a 32-bit
/// offset to the stack pointer to this prefix.
fn _prefix_mov_to_stack(&self) -> Option<&'static [u8]>;
}
Loading