feat: JIT (WIP)

This commit is contained in:
2025-06-22 12:16:23 +08:00
parent 20b5516101
commit f679ff2ec9
4 changed files with 42 additions and 158 deletions

View File

@@ -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())
}
}

View File

@@ -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())
}
}

View File

@@ -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<JITValue> for Value {
@@ -72,18 +78,19 @@ impl From<Value> 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!()
}

View File

@@ -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));
}