From f679ff2ec9df601bd8ade46ab2ee48ffa50c2044 Mon Sep 17 00:00:00 2001 From: imxyy_soope_ Date: Sun, 22 Jun 2025 12:16:23 +0800 Subject: [PATCH] feat: JIT (WIP) --- src/eval/jit/compile.rs | 33 ++++----------- src/eval/jit/helpers.rs | 51 ++++++++--------------- src/eval/jit/mod.rs | 25 +++++++---- src/eval/jit/test.rs | 91 ----------------------------------------- 4 files changed, 42 insertions(+), 158 deletions(-) delete mode 100644 src/eval/jit/test.rs diff --git a/src/eval/jit/compile.rs b/src/eval/jit/compile.rs index 27d4b1b..c643ac6 100644 --- a/src/eval/jit/compile.rs +++ b/src/eval/jit/compile.rs @@ -88,10 +88,7 @@ impl JITCompile for BinOp { ctx.builder .build_store( res, - ctx.helpers.value_type.const_named_struct(&[ - ctx.helpers.const_int(Int as i64).into(), - val.into(), - ]), + ctx.helpers.new_value(Int, val.into()) ) .unwrap(); ctx.builder.position_at_end(int_float); @@ -112,10 +109,7 @@ impl JITCompile for BinOp { ctx.builder .build_store( res, - ctx.helpers.value_type.const_named_struct(&[ - ctx.helpers.const_int(Float as i64).into(), - val.into(), - ]), + ctx.helpers.new_value(Float, val.into()) ) .unwrap(); ctx.builder.position_at_end(float_int); @@ -136,10 +130,7 @@ impl JITCompile for BinOp { ctx.builder .build_store( res, - ctx.helpers.value_type.const_named_struct(&[ - ctx.helpers.const_int(Float as i64).into(), - val.into(), - ]), + ctx.helpers.new_value(Float, val.into()) ) .unwrap(); ctx.builder.position_at_end(int_int); @@ -150,10 +141,7 @@ impl JITCompile for BinOp { ctx.builder .build_store( res, - ctx.helpers.value_type.const_named_struct(&[ - ctx.helpers.const_int(Float as i64).into(), - val.into(), - ]), + ctx.helpers.new_value(Float, val.into()) ) .unwrap(); ctx.builder.position_at_end(fallback); @@ -179,10 +167,7 @@ impl JITCompile for BinOp { ctx.builder .build_store( res, - ctx.helpers.value_type.const_named_struct(&[ - ctx.helpers.const_int(Bool as i64).into(), - val.into(), - ]), + ctx.helpers.new_value(Bool, val.into()) ) .unwrap(); ctx.builder.position_at_end(fallback); @@ -233,8 +218,8 @@ impl JITCompile for If { } impl JITCompile for LoadFunc { - fn compile<'gc>(&self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> StructValue<'gc> { - todo!() + fn compile<'gc>(&self, ctx: &JITContext<'gc>, _: FunctionValue<'gc>) -> StructValue<'gc> { + ctx.helpers.new_value(ValueTag::Function, ctx.helpers.const_int(self.idx as i64).into()) } } @@ -305,8 +290,8 @@ impl JITCompile for LetVar { } impl JITCompile for Thunk { - fn compile<'gc>(&self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> StructValue<'gc> { - todo!() + fn compile<'gc>(&self, ctx: &JITContext<'gc>, _: FunctionValue<'gc>) -> StructValue<'gc> { + ctx.helpers.new_value(ValueTag::Thunk, ctx.helpers.const_int(self.idx as i64).into()) } } diff --git a/src/eval/jit/helpers.rs b/src/eval/jit/helpers.rs index 5ebdb19..3adf694 100644 --- a/src/eval/jit/helpers.rs +++ b/src/eval/jit/helpers.rs @@ -50,7 +50,7 @@ impl<'ctx> Helpers<'ctx> { let bool_type = context.bool_type(); let ptr_int_type = context.ptr_sized_int_type(execution_engine.get_target_data(), None); let ptr_type = context.ptr_type(AddressSpace::default()); - let value_type = context.struct_type(&[int_type.into(), int_type.into()], false); + let value_type = context.struct_type(&[int_type.into(), int_type.into(), int_type.into()], false); let func_type = value_type.fn_type(&[ptr_type.into()], false); let new_thunk = module.add_function( @@ -182,17 +182,20 @@ impl<'ctx> Helpers<'ctx> { } } + pub fn new_value(&self, tag: ValueTag, data: BasicValueEnum<'ctx>) -> StructValue<'ctx> { + self.value_type.const_named_struct(&[ + self.const_int(tag as i64).into(), + data, + self.int_type.const_zero().into() + ]) + } + pub fn const_int(&self, int: i64) -> IntValue<'ctx> { self.int_type.const_int(int as _, false) } pub fn new_int(&self, int: i64) -> StructValue<'ctx> { - self.value_type - .const_named_struct(&[ - self.int_type.const_int(ValueTag::Int as _, false).into(), - self.const_int(int).into(), - ]) - .into() + self.new_value(ValueTag::Int, self.const_int(int).into()) } pub fn const_float(&self, float: f64) -> FloatValue<'ctx> { @@ -200,39 +203,19 @@ impl<'ctx> Helpers<'ctx> { } pub fn new_float(&self, float: f64) -> StructValue<'ctx> { - self.value_type - .const_named_struct(&[ - self.int_type.const_int(ValueTag::Float as _, false).into(), - self.const_float(float).into(), - ]) - .into() + self.new_value(ValueTag::Float, self.const_float(float).into()) + } + + pub fn const_bool(&self, bool: bool) -> IntValue<'ctx> { + self.bool_type.const_int(bool as _, false) } pub fn new_bool(&self, bool: bool) -> StructValue<'ctx> { - self.value_type - .const_named_struct(&[ - self.int_type.const_int(ValueTag::Bool as _, false).into(), - self.bool_type.const_int(bool as _, false).into(), - ]) - .into() + self.new_value(ValueTag::Bool, self.const_bool(bool).into()) } pub fn new_null(&self) -> StructValue<'ctx> { - self.value_type - .const_named_struct(&[ - self.int_type.const_int(ValueTag::Null as _, false).into(), - self.int_type.const_zero().into(), - ]) - .into() - } - - pub fn const_string(&self, string: *const u8) -> StructValue<'ctx> { - self.value_type - .const_named_struct(&[ - self.int_type.const_int(ValueTag::String as _, false).into(), - self.ptr_int_type.const_int(string as _, false).into(), - ]) - .into() + self.new_value(ValueTag::Null, self.int_type.const_zero().into()) } } diff --git a/src/eval/jit/mod.rs b/src/eval/jit/mod.rs index 0bf1e87..5667251 100644 --- a/src/eval/jit/mod.rs +++ b/src/eval/jit/mod.rs @@ -1,5 +1,6 @@ use std::marker::PhantomData; use std::ops::Deref; +use std::rc::Rc; use inkwell::OptimizationLevel; use inkwell::builder::Builder; @@ -18,9 +19,6 @@ mod helpers; pub use compile::JITCompile; use helpers::Helpers; -#[cfg(test)] -mod test; - #[repr(u64)] #[derive(Debug, Clone, Copy)] pub enum ValueTag { @@ -50,6 +48,14 @@ pub union JITValueData { float: f64, bool: bool, ptr: *const (), + slice: Slice +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct Slice { + ptr: *const (), + len: usize } impl From for Value { @@ -72,18 +78,19 @@ impl From for JITValue { tag: ValueTag::Int, data: JITValueData { int }, }, - /* Value::Func(func) => JITValue { + Value::List(list) => JITValue { tag: ValueTag::List, data: JITValueData { slice: Slice { ptr: list.as_ptr() as *const (), len: list.len() } } }, + Value::Func(idx) => JITValue { tag: ValueTag::Function, data: JITValueData { - ptr: Rc::into_raw(func) as *const _, + int: idx as i64 }, }, - Value::Thunk(thunk) => JITValue { + Value::Thunk(idx) => JITValue { tag: ValueTag::Thunk, data: JITValueData { - ptr: Rc::into_raw(thunk.thunk) as *const _, + int: idx as i64 }, - }, */ + }, _ => todo!(), } } @@ -136,7 +143,7 @@ impl<'ctx> JITContext<'ctx> { } } - pub fn compile(&self, ir: Ir) -> JITFunc { + pub fn compile(&self, ir: Ir) -> JITFunc<'ctx> { todo!() } diff --git a/src/eval/jit/test.rs b/src/eval/jit/test.rs deleted file mode 100644 index abd2ee5..0000000 --- a/src/eval/jit/test.rs +++ /dev/null @@ -1,91 +0,0 @@ -#![allow(unused)] - -extern crate test; - -use hashbrown::{HashMap, HashSet}; - -use inkwell::context::Context; - -use ecow::EcoString; - -use super::JITContext; -use crate::ir::downgrade; -use crate::ty::common::Const; -use crate::ty::public::*; - -#[inline] -fn test_expr(expr: &str, expected: Value) { - todo!() -} - -macro_rules! map { - ($($k:expr => $v:expr),*) => { - { - #[allow(unused_mut)] - let mut m = HashMap::new(); - $( - m.insert($k, $v); - )* - m - } - }; -} - -macro_rules! thunk { - () => { - Value::Thunk - }; -} - -macro_rules! int { - ($e:expr) => { - Value::Const(Const::Int($e)) - }; -} - -macro_rules! float { - ($e:expr) => { - Value::Const(Const::Float($e as f64)) - }; -} - -macro_rules! boolean { - ($e:expr) => { - Value::Const(Const::Bool($e)) - }; -} - -macro_rules! string { - ($e:expr) => { - Value::Const(Const::String(EcoString::from($e))) - }; -} - -macro_rules! symbol { - ($e:expr) => { - Symbol::from($e.to_string()) - }; -} - -macro_rules! list { - ($($x:tt)*) => ( - Value::List(List::new(vec![$($x)*])) - ); -} - -macro_rules! attrs { - ($($x:tt)*) => ( - Value::AttrSet(AttrSet::new(map!{$($x)*})) - ) -} - -#[test] -fn test_jit_const() { - // test_expr("let f = _: 1; in (f 1) + (f 1)", int!(2)); - test_expr("let f = _: 1; in (f 1) == (f 1)", boolean!(true)); -} - -#[test] -fn test_arith() { - test_expr("let f = _: -(-1); in (f 1) + (f 1)", int!(2)); -}