feat: SCC analysis (WIP)

This commit is contained in:
2025-06-15 17:23:32 +08:00
parent 7b6db44207
commit b2d2490327
13 changed files with 842 additions and 352 deletions

View File

@@ -1,4 +1,4 @@
use inkwell::values::{BasicValueEnum, FunctionValue};
use inkwell::values::{StructValue, FunctionValue};
use crate::ir::*;
use crate::ty::common as c;
@@ -7,35 +7,35 @@ use crate::ty::internal::Value;
use super::JITContext;
pub trait JITCompile {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> BasicValueEnum<'gc>;
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> StructValue<'gc>;
}
impl JITCompile for Attrs {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> BasicValueEnum<'gc> {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> StructValue<'gc> {
todo!()
}
}
impl JITCompile for List {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> BasicValueEnum<'gc> {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> StructValue<'gc> {
todo!()
}
}
impl JITCompile for HasAttr {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> BasicValueEnum<'gc> {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> StructValue<'gc> {
todo!()
}
}
impl JITCompile for BinOp {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> BasicValueEnum<'gc> {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> StructValue<'gc> {
todo!()
}
}
impl JITCompile for UnOp {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> BasicValueEnum<'gc> {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> StructValue<'gc> {
todo!();
let rhs = self.rhs.compile(ctx, func);
let tag = ctx.get_tag(rhs);
@@ -45,60 +45,60 @@ impl JITCompile for UnOp {
ctx.builder.build_switch(tag, fallback, &[]).unwrap();
ctx.builder.position_at_end(fallback);
ctx.builder.position_at_end(ret);
ctx.builder.build_load(ctx.helpers.value_type, res, "load_res").unwrap()
ctx.builder.build_load(ctx.helpers.value_type, res, "load_res").unwrap().try_into().unwrap()
}
}
impl JITCompile for Select {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> BasicValueEnum<'gc> {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> StructValue<'gc> {
todo!()
}
}
impl JITCompile for If {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> BasicValueEnum<'gc> {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> StructValue<'gc> {
todo!()
}
}
impl JITCompile for LoadFunc {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> BasicValueEnum<'gc> {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> StructValue<'gc> {
todo!()
}
}
impl JITCompile for Call {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> BasicValueEnum<'gc> {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> StructValue<'gc> {
todo!()
}
}
impl JITCompile for Let {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> BasicValueEnum<'gc> {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> StructValue<'gc> {
todo!()
}
}
impl JITCompile for With {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> BasicValueEnum<'gc> {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> StructValue<'gc> {
todo!()
}
}
impl JITCompile for Assert {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> BasicValueEnum<'gc> {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> StructValue<'gc> {
todo!()
}
}
impl JITCompile for ConcatStrings {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> BasicValueEnum<'gc> {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> StructValue<'gc> {
todo!()
}
}
impl JITCompile for Const {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> BasicValueEnum<'gc> {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> StructValue<'gc> {
use c::Const::*;
match self.val {
Bool(x) => ctx.helpers.new_bool(x),
@@ -110,37 +110,37 @@ impl JITCompile for Const {
}
impl JITCompile for String {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> BasicValueEnum<'gc> {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> StructValue<'gc> {
todo!()
}
}
impl JITCompile for Var {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> BasicValueEnum<'gc> {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> StructValue<'gc> {
todo!()
}
}
impl JITCompile for Arg {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> BasicValueEnum<'gc> {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> StructValue<'gc> {
todo!()
}
}
impl JITCompile for LetVar {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> BasicValueEnum<'gc> {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> StructValue<'gc> {
todo!()
}
}
impl JITCompile for Thunk {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> BasicValueEnum<'gc> {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> StructValue<'gc> {
todo!()
}
}
impl JITCompile for Path {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> BasicValueEnum<'gc> {
fn compile<'gc>(self, ctx: &JITContext<'gc>, func: FunctionValue<'gc>) -> StructValue<'gc> {
todo!()
}
}

View File

@@ -5,7 +5,7 @@ use inkwell::context::Context;
use inkwell::execution_engine::ExecutionEngine;
use inkwell::module::Module;
use inkwell::types::{FloatType, FunctionType, IntType, PointerType, StructType};
use inkwell::values::{BasicValueEnum, FloatValue, FunctionValue, IntValue};
use inkwell::values::{BasicValueEnum, FloatValue, FunctionValue, IntValue, StructValue};
use crate::env::VmEnv;
use crate::eval::Engine;
@@ -180,7 +180,7 @@ impl<'ctx> Helpers<'ctx> {
self.int_type.const_int(int as _, false)
}
pub fn new_int(&self, int: i64) -> BasicValueEnum<'ctx> {
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(),
@@ -193,7 +193,7 @@ impl<'ctx> Helpers<'ctx> {
self.float_type.const_float(float)
}
pub fn new_float(&self, float: f64) -> BasicValueEnum<'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(),
@@ -202,7 +202,7 @@ impl<'ctx> Helpers<'ctx> {
.into()
}
pub fn new_bool(&self, bool: bool) -> BasicValueEnum<'ctx> {
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(),
@@ -211,7 +211,7 @@ impl<'ctx> Helpers<'ctx> {
.into()
}
pub fn new_null(&self) -> BasicValueEnum<'ctx> {
pub fn new_null(&self) -> StructValue<'ctx> {
self.value_type
.const_named_struct(&[
self.int_type.const_int(ValueTag::Null as _, false).into(),
@@ -220,7 +220,7 @@ impl<'ctx> Helpers<'ctx> {
.into()
}
pub fn const_string(&self, string: *const u8) -> BasicValueEnum<'ctx> {
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(),

View File

@@ -139,10 +139,10 @@ impl<'ctx> JITContext<'ctx> {
}
pub fn compile(&self, ir: Ir) -> JITFunc {
todo!()
}
pub fn get_tag(&self, val: BasicValueEnum<'ctx>) -> IntValue<'ctx> {
pub fn get_tag(&self, val: StructValue<'ctx>) -> IntValue<'ctx> {
let alloca = self
.builder
.build_alloca(self.helpers.value_type, "get_tag_alloca").unwrap();