feat: SCC analysis (thunk capture WIP)

This commit is contained in:
2025-06-17 11:53:54 +08:00
parent b2d2490327
commit 7f6848c9e5
19 changed files with 501 additions and 458 deletions

View File

@@ -1,4 +1,4 @@
use inkwell::values::{StructValue, FunctionValue};
use inkwell::values::{FunctionValue, StructValue};
use crate::ir::*;
use crate::ty::common as c;
@@ -41,11 +41,18 @@ impl JITCompile for UnOp {
let tag = ctx.get_tag(rhs);
let fallback = ctx.context.append_basic_block(func, "fallback");
let ret = ctx.context.append_basic_block(func, "fallback");
let res = ctx.builder.build_alloca(ctx.helpers.value_type, "res_alloca").unwrap();
let res = ctx
.builder
.build_alloca(ctx.helpers.value_type, "res_alloca")
.unwrap();
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().try_into().unwrap()
ctx.builder
.build_load(ctx.helpers.value_type, res, "load_res")
.unwrap()
.try_into()
.unwrap()
}
}

View File

@@ -184,7 +184,7 @@ impl<'ctx> Helpers<'ctx> {
self.value_type
.const_named_struct(&[
self.int_type.const_int(ValueTag::Int as _, false).into(),
self.const_int(int).into()
self.const_int(int).into(),
])
.into()
}
@@ -197,7 +197,7 @@ impl<'ctx> Helpers<'ctx> {
self.value_type
.const_named_struct(&[
self.int_type.const_int(ValueTag::Float as _, false).into(),
self.const_float(float).into()
self.const_float(float).into(),
])
.into()
}

View File

@@ -6,7 +6,9 @@ use inkwell::builder::Builder;
use inkwell::context::Context;
use inkwell::execution_engine::ExecutionEngine;
use inkwell::module::Module;
use inkwell::values::{AnyValue, AsValueRef, BasicMetadataValueEnum, BasicValueEnum, IntValue, StructValue};
use inkwell::values::{
AnyValue, AsValueRef, BasicMetadataValueEnum, BasicValueEnum, IntValue, StructValue,
};
use crate::env::VmEnv;
use crate::ir::{Ir, UnOpKind};
@@ -144,21 +146,25 @@ impl<'ctx> JITContext<'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();
.builder
.build_alloca(self.helpers.value_type, "get_tag_alloca")
.unwrap();
self.builder.build_store(alloca, val).unwrap();
self.builder
.build_load(
self.context.bool_type(),
self.builder
.build_struct_gep(self.helpers.value_type, alloca, 1, "get_tag_gep").unwrap(),
.build_struct_gep(self.helpers.value_type, alloca, 1, "get_tag_gep")
.unwrap(),
"get_tag",
).unwrap()
)
.unwrap()
.into_int_value()
}
pub fn call(&self, args: &[BasicMetadataValueEnum<'ctx>]) -> StructValue<'ctx> {
self.builder.build_call(self.helpers.call, args, "call")
self.builder
.build_call(self.helpers.call, args, "call")
.unwrap()
.as_any_value_enum()
.into_struct_value()