From 0fbfb36262e6998c03eb336b8707ffcb73677b46 Mon Sep 17 00:00:00 2001 From: zzy <2450266535@qq.com> Date: Tue, 21 Apr 2026 14:05:21 +0800 Subject: [PATCH] =?UTF-8?q?feat(cbuild):=20=E6=9B=B4=E6=96=B0=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E9=85=8D=E7=BD=AE=E4=BB=A5=E6=94=AF=E6=8C=81HIR?= =?UTF-8?q?=E4=B8=AD=E9=97=B4=E8=A1=A8=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 统一包名格式化,添加空格对齐 - 将依赖项从ir和lir重命名为hir,移除lir注释 - 为ast2ir模块添加正确的包名称"scc_ast2ir" - 更新依赖引用路径指向新的HIR库结构 - 移除注释掉的ir2mcode和sccf2target依赖项 refactor(ast2ir): 迁移到HIR中间表示替换IR表示 - 更新头文件包含,使用hir_builder.h替代ir_builder.h - 修改上下文结构体,将scc_ir_builder_t替换为scc_hir_builder_t - 更新函数签名,将参数类型从scc_ir_*转换为scc_hir_* - 调整返回值类型,将scc_ir_value_ref_t和scc_ir_type_ref_t 分别替换为scc_hir_value_ref_t和scc_hir_type_ref_t - 重新排列头文件包含顺序以满足依赖关系 --- cbuild.toml | 6 +- libs/ast2ir/cbuild.toml | 8 +- libs/ast2ir/include/scc_ast2ir.h | 18 +- libs/ast2ir/src/scc_ast2ir.c | 622 ++++++++-------- libs/ir/cbuild.toml | 13 - libs/ir/cfg/cbuild.toml | 12 + libs/ir/cfg/include/scc_cfg.h | 108 +++ libs/ir/cfg/src/scc_cfg.c | 81 ++ libs/ir/hir/cbuild.toml | 14 + libs/ir/hir/include/hir_builder.h | 281 +++++++ libs/ir/hir/include/hir_def.h | 255 +++++++ libs/ir/hir/include/hir_dump.h | 21 + libs/ir/hir/include/hir_module.h | 50 ++ libs/ir/hir/include/hir_prog.h | 17 + libs/ir/hir/include/scc_hir.h | 14 + libs/ir/hir/src/hir_builder.c | 691 ++++++++++++++++++ libs/ir/{src/ir_dump.c => hir/src/hir_dump.c} | 451 ++++++------ libs/ir/hir/src/hir_module.c | 128 ++++ libs/ir/{src/ir_prog.c => hir/src/hir_prog.c} | 10 +- libs/ir/hir/src/scc_hir.c | 117 +++ libs/ir/{ => hir}/tests/test_ir_unit.c | 0 libs/ir/include/ir_builder.h | 289 -------- libs/ir/include/ir_ctx.h | 27 - libs/ir/include/ir_def.h | 287 -------- libs/ir/include/ir_dump.h | 22 - libs/ir/include/ir_module.h | 49 -- libs/ir/include/ir_prog.h | 17 - libs/ir/include/scc_ir.h | 15 - libs/ir/src/ir_builder.c | 493 ------------- libs/ir/src/ir_ctx.c | 194 ----- libs/ir/src/ir_module.c | 136 ---- libs/ir/src/scc_ir.c | 117 --- libs/lir/cbuild.toml | 13 - libs/lir/include/scc_ir2lir.h | 12 - libs/lir/include/scc_lir.h | 263 ------- libs/lir/include/scc_lir_builder.h | 26 - libs/lir/include/scc_lir_dump.h | 22 - libs/lir/include/scc_lir_module.h | 98 --- libs/lir/src/scc_ir2lir.c | 599 --------------- libs/lir/src/scc_lir_builder.c | 68 -- libs/lir/src/scc_lir_dump.c | 452 ------------ libs/lir/src/scc_lir_module.c | 172 ----- runtime/ap/cbuild.toml | 9 + runtime/ap/include/ap.h | 92 +++ runtime/ap/src/ap.c | 48 ++ runtime/ap/src/lib.c | 5 + runtime/scc_utils/include/scc_ap.h | 16 + src/config.h | 24 +- src/main.c | 62 +- 49 files changed, 2555 insertions(+), 3989 deletions(-) delete mode 100644 libs/ir/cbuild.toml create mode 100644 libs/ir/cfg/cbuild.toml create mode 100644 libs/ir/cfg/include/scc_cfg.h create mode 100644 libs/ir/cfg/src/scc_cfg.c create mode 100644 libs/ir/hir/cbuild.toml create mode 100644 libs/ir/hir/include/hir_builder.h create mode 100644 libs/ir/hir/include/hir_def.h create mode 100644 libs/ir/hir/include/hir_dump.h create mode 100644 libs/ir/hir/include/hir_module.h create mode 100644 libs/ir/hir/include/hir_prog.h create mode 100644 libs/ir/hir/include/scc_hir.h create mode 100644 libs/ir/hir/src/hir_builder.c rename libs/ir/{src/ir_dump.c => hir/src/hir_dump.c} (58%) create mode 100644 libs/ir/hir/src/hir_module.c rename libs/ir/{src/ir_prog.c => hir/src/hir_prog.c} (52%) create mode 100644 libs/ir/hir/src/scc_hir.c rename libs/ir/{ => hir}/tests/test_ir_unit.c (100%) delete mode 100644 libs/ir/include/ir_builder.h delete mode 100644 libs/ir/include/ir_ctx.h delete mode 100644 libs/ir/include/ir_def.h delete mode 100644 libs/ir/include/ir_dump.h delete mode 100644 libs/ir/include/ir_module.h delete mode 100644 libs/ir/include/ir_prog.h delete mode 100644 libs/ir/include/scc_ir.h delete mode 100644 libs/ir/src/ir_builder.c delete mode 100644 libs/ir/src/ir_ctx.c delete mode 100644 libs/ir/src/ir_module.c delete mode 100644 libs/ir/src/scc_ir.c delete mode 100644 libs/lir/cbuild.toml delete mode 100644 libs/lir/include/scc_ir2lir.h delete mode 100644 libs/lir/include/scc_lir.h delete mode 100644 libs/lir/include/scc_lir_builder.h delete mode 100644 libs/lir/include/scc_lir_dump.h delete mode 100644 libs/lir/include/scc_lir_module.h delete mode 100644 libs/lir/src/scc_ir2lir.c delete mode 100644 libs/lir/src/scc_lir_builder.c delete mode 100644 libs/lir/src/scc_lir_dump.c delete mode 100644 libs/lir/src/scc_lir_module.c create mode 100644 runtime/ap/cbuild.toml create mode 100644 runtime/ap/include/ap.h create mode 100644 runtime/ap/src/ap.c create mode 100644 runtime/ap/src/lib.c create mode 100644 runtime/scc_utils/include/scc_ap.h diff --git a/cbuild.toml b/cbuild.toml index 9ef074a..8a8e5dc 100644 --- a/cbuild.toml +++ b/cbuild.toml @@ -1,5 +1,5 @@ [package] -name = "scc" +name = "scc" version = "0.1.0" dependencies = [ @@ -9,8 +9,8 @@ dependencies = [ { name = "parser", path = "./libs/parser" }, { name = "ast", path = "./libs/ast" }, { name = "ast2ir", path = "./libs/ast2ir" }, - { name = "ir", path = "./libs/ir" }, - { name = "lir", path = "./libs/lir" }, + { name = "hir", path = "./libs/ir/hir" }, + # { name = "lir", path = "./libs/ir/lir" }, # { name = "ir2mcode", path = "./libs/ir2mcode" }, # { name = "sccf2target", path = "./libs/target/sccf2target" }, diff --git a/libs/ast2ir/cbuild.toml b/libs/ast2ir/cbuild.toml index 833cc97..78b8d71 100644 --- a/libs/ast2ir/cbuild.toml +++ b/libs/ast2ir/cbuild.toml @@ -1,12 +1,12 @@ [package] -name = "" -version = "0.1.0" -authors = [] +name = "scc_ast2ir" +version = "0.1.0" +authors = [] description = "" dependencies = [ { name = "scc_ast", path = "../ast" }, - { name = "scc_ir", path = "../ir" }, + { name = "scc_hir", path = "../ir/hir" }, { name = "scc_abi", path = "../abi" }, ] # features = {} diff --git a/libs/ast2ir/include/scc_ast2ir.h b/libs/ast2ir/include/scc_ast2ir.h index 7ca099d..051c9c8 100644 --- a/libs/ast2ir/include/scc_ast2ir.h +++ b/libs/ast2ir/include/scc_ast2ir.h @@ -1,13 +1,12 @@ #ifndef __SCC_AST2IR_H__ #define __SCC_AST2IR_H__ -#include "scc_type_abi.h" -#include +#include #include -#include +#include typedef struct { - scc_ir_builder_t builder; + scc_hir_builder_t builder; scc_hashtable_t ast2ir_cache; ///< ast node to ir ref cache scc_hashtable_t symtab; ///< symbol to ir_ref // scc_strpool_t strpool; ///< string pool @@ -16,17 +15,18 @@ typedef struct { } scc_ast2ir_ctx_t; void scc_ast2ir_ctx_init(scc_ast2ir_ctx_t *ctx, const scc_abi_type_calc_t *abi, - scc_ir_cprog_t *cprog); + scc_hir_cprog_t *cprog); void scc_ast2ir_ctx_drop(scc_ast2ir_ctx_t *ctx); void scc_ast2ir_translation_unit(scc_ast2ir_ctx_t *ctx, const scc_ast_translation_unit_t *tu); void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, const scc_ast_decl_t *decl, cbool is_global); -scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, - const scc_ast_expr_t *expr, cbool is_lvalue); +scc_hir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, + const scc_ast_expr_t *expr, + cbool is_lvalue); void scc_ast2ir_stmt(scc_ast2ir_ctx_t *ctx, const scc_ast_stmt_t *stmt); -scc_ir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx, - const scc_ast_type_t *ast_type); +scc_hir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx, + const scc_ast_type_t *ast_type); #endif /* __SCC_AST2IR_H__ */ diff --git a/libs/ast2ir/src/scc_ast2ir.c b/libs/ast2ir/src/scc_ast2ir.c index af75a61..75ce536 100644 --- a/libs/ast2ir/src/scc_ast2ir.c +++ b/libs/ast2ir/src/scc_ast2ir.c @@ -1,51 +1,40 @@ -#include "ast_def.h" -#include "ir_builder.h" -#include "ir_def.h" -#include "log.h" +#include +#include +#include #include -static scc_ir_type_ref_t parse_base_type(scc_ast2ir_ctx_t *ctx, - const scc_ast_type_t *ast_type) { +static scc_hir_type_ref_t parse_base_type(scc_ast2ir_ctx_t *ctx, + const scc_ast_type_t *ast_type) { scc_abi_type_layout_t layout; // 映射内置类型 ctx->abi->compute_type_layout(ctx->abi, (void *)ast_type, &layout); switch (layout.size) { case 0: - return scc_ir_builder_type_void(&ctx->builder); + return scc_hir_builder_type_void(&ctx->builder); case 1: - return scc_ir_builder_type_i8(&ctx->builder); + return scc_hir_builder_type_i8(&ctx->builder); case 2: - return scc_ir_builder_type_i16(&ctx->builder); + return scc_hir_builder_type_i16(&ctx->builder); case 4: - return scc_ir_builder_type_i32(&ctx->builder); + return scc_hir_builder_type_i32(&ctx->builder); case 8: - return scc_ir_builder_type_i64(&ctx->builder); + return scc_hir_builder_type_i64(&ctx->builder); break; default: break; } - return SCC_IR_REF_nullptr; + return SCC_HIR_REF_nullptr; } static inline void parse_struct_union_layout(scc_ast_type_t *type) {} -static inline void parse_lexme2const_int(const char *lexme, - scc_ir_const_int_t *value) { - // FIXME - usize int_lit = 0; - for (usize i = 0; i < scc_strlen(lexme); i++) { - int_lit = int_lit * 10 + (lexme[i] - '0'); - } - value->int64 = int_lit; -} - // 辅助函数:计算数组实际长度(如果原长度为0) static void resolve_array_length(scc_ast2ir_ctx_t *ctx, - const scc_ir_type_t *orig_array_type, - scc_ir_type_t *resolved_array_type, + const scc_hir_type_t *orig_array_type, + scc_hir_type_t *resolved_array_type, const scc_ast_expr_t *init_expr) { *resolved_array_type = *orig_array_type; // 拷贝 - Assert(orig_array_type->tag == SCC_IR_TYPE_ARRAY); + Assert(orig_array_type->tag == SCC_HIR_TYPE_ARRAY); if (orig_array_type->data.array.len != 0) return; // 长度已知,无需推断 @@ -74,23 +63,24 @@ static void resolve_array_length(scc_ast2ir_ctx_t *ctx, // 辅助函数:生成数组初始化代码 static void emit_array_initialization(scc_ast2ir_ctx_t *ctx, - scc_ir_value_ref_t array_ptr, - const scc_ir_type_t *array_type, + scc_hir_value_ref_t array_ptr, + const scc_hir_type_t *array_type, const scc_ast_expr_t *init_expr) { - Assert(array_type->tag == SCC_IR_TYPE_ARRAY); - scc_ir_type_ref_t elem_type_ref = array_type->data.array.base; - const scc_ir_type_t *elem_type = - scc_ir_module_get_type(ctx->builder.ctx.module, elem_type_ref); + Assert(array_type->tag == SCC_HIR_TYPE_ARRAY); + scc_hir_type_ref_t elem_type_ref = array_type->data.array.base; + const scc_hir_type_t *elem_type = + scc_hir_module_get_type(&ctx->builder.cprog->module, elem_type_ref); usize array_len = array_type->data.array.len; // 字符串字面量初始化:直接 memcpy if (init_expr->base.type == SCC_AST_EXPR_STRING_LITERAL) { - scc_ir_value_ref_t str_val = scc_ast2ir_expr(ctx, init_expr, false); - scc_ir_const_int_t len_const = {.int64 = array_len}; - scc_ir_value_ref_t len_ref = scc_ir_builder_const_int( - &ctx->builder, scc_ir_builder_type_u64(&ctx->builder), len_const); - scc_ir_builder_builtin_memcpy(&ctx->builder, array_ptr, str_val, - len_ref); + scc_hir_value_ref_t str_val = scc_ast2ir_expr(ctx, init_expr, false); + scc_ap_t len_ap; + scc_ap_set_int(&len_ap, array_len); + scc_hir_value_ref_t len_ref = scc_hir_builder_integer( + &ctx->builder, scc_hir_builder_type_u64(&ctx->builder), &len_ap); + scc_hir_builder_builtin_memcpy(&ctx->builder, array_ptr, str_val, + len_ref); return; } @@ -109,21 +99,22 @@ static void emit_array_initialization(scc_ast2ir_ctx_t *ctx, break; // 防止溢出 // 生成元素地址:array_ptr + idx * elem_size - scc_ir_value_ref_t idx_val = scc_ir_builder_const_int( - &ctx->builder, scc_ir_builder_type_u64(&ctx->builder), - (scc_ir_const_int_t){.int64 = idx}); - scc_ir_value_ref_t elem_ptr = - scc_ir_builder_get_elem_ptr(&ctx->builder, array_ptr, idx_val); + scc_ap_t offset_ap; + scc_ap_set_int(&offset_ap, idx); + scc_hir_value_ref_t idx_val = scc_hir_builder_integer( + &ctx->builder, scc_hir_builder_type_u64(&ctx->builder), &offset_ap); + scc_hir_value_ref_t elem_ptr = + scc_hir_builder_get_elem_ptr(&ctx->builder, array_ptr, idx_val); // 递归处理:如果元素本身是数组且初始化表达式是复合初始化,需要嵌套处理 - if (elem_type->tag == SCC_IR_TYPE_ARRAY && + if (elem_type->tag == SCC_HIR_TYPE_ARRAY && elem_expr->base.type == SCC_AST_EXPR_COMPOUND) { // 递归调用自身,但注意 elem_ptr 已经是子数组的首地址 emit_array_initialization(ctx, elem_ptr, elem_type, elem_expr); } else { // 标量元素:计算右值并 store - scc_ir_value_ref_t val = scc_ast2ir_expr(ctx, elem_expr, false); - scc_ir_builder_store(&ctx->builder, elem_ptr, val); + scc_hir_value_ref_t val = scc_ast2ir_expr(ctx, elem_expr, false); + scc_hir_builder_store(&ctx->builder, elem_ptr, val); } idx++; } @@ -131,29 +122,29 @@ static void emit_array_initialization(scc_ast2ir_ctx_t *ctx, // 这里简单忽略,实际可生成 memset 循环,但为简化暂不处理 } -scc_ir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx, - const scc_ast_type_t *ast_type) { +scc_hir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx, + const scc_ast_type_t *ast_type) { if (ctx == nullptr || ast_type == nullptr) { LOG_ERROR("args is nullptr"); return 0; } - scc_ir_type_t ir_type; + scc_hir_type_t ir_type; switch (ast_type->base.type) { case SCC_AST_TYPE_BUILTIN: { return parse_base_type(ctx, ast_type); } case SCC_AST_TYPE_POINTER: { - scc_ir_type_init(&ir_type, SCC_IR_TYPE_PTR); - scc_ir_type_ref_t pointee_type = + scc_hir_type_init(&ir_type, SCC_HIR_TYPE_PTR); + scc_hir_type_ref_t pointee_type = scc_ast2ir_type(ctx, ast_type->pointer.pointee); ir_type.data.pointer.base = pointee_type; break; } case SCC_AST_TYPE_ARRAY: { - scc_ir_type_init(&ir_type, SCC_IR_TYPE_ARRAY); + scc_hir_type_init(&ir_type, SCC_HIR_TYPE_ARRAY); - scc_ir_type_ref_t element_type = + scc_hir_type_ref_t element_type = scc_ast2ir_type(ctx, ast_type->array.element); ir_type.data.array.base = element_type; @@ -163,30 +154,31 @@ scc_ir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx, if (ast_type->array.size->base.type != SCC_AST_EXPR_INT_LITERAL) { Panic("TODO: array size expression"); } - scc_ir_const_int_t value; - parse_lexme2const_int(ast_type->array.size->literal.lexme, &value); - ir_type.data.array.len = value.int32; + scc_ap_t value; + scc_ap_from_cstr(&value, ast_type->array.size->literal.lexme, 10); + // FIXME hack + ir_type.data.array.len = value.data.digit; } break; } case SCC_AST_TYPE_FUNCTION: { - scc_ir_type_init(&ir_type, SCC_IR_TYPE_FUNC); + scc_hir_type_init(&ir_type, SCC_HIR_TYPE_FUNC); // 处理返回类型 - scc_ir_type_ref_t ret_type = + scc_hir_type_ref_t ret_type = scc_ast2ir_type(ctx, ast_type->function.return_type); // 将返回类型添加到程序的类型容器中 ir_type.data.function.ret_type = ret_type; // 转换参数类型 - scc_ir_type_ref_vec_t params; + scc_hir_type_ref_vec_t params; scc_vec_init(params); scc_vec_foreach(ast_type->function.params, i) { scc_ast_decl_t *decl_param = scc_vec_at(ast_type->function.params, i); Assert(decl_param->base.type == SCC_AST_DECL_PARAM); - scc_ir_type_ref_t tmp_type = + scc_hir_type_ref_t tmp_type = scc_ast2ir_type(ctx, decl_param->param.type); scc_vec_push(params, tmp_type); } @@ -195,15 +187,15 @@ scc_ir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx, } case SCC_AST_TYPE_STRUCT: case SCC_AST_TYPE_UNION: { - scc_ir_type_init(&ir_type, ast_type->base.type == SCC_AST_TYPE_STRUCT - ? SCC_IR_TYPE_STRUCT - : SCC_IR_TYPE_UNION); + scc_hir_type_init(&ir_type, ast_type->base.type == SCC_AST_TYPE_STRUCT + ? SCC_HIR_TYPE_STRUCT + : SCC_HIR_TYPE_UNION); Assert(ast_type->record.decl != nullptr); scc_vec_foreach(ast_type->record.decl->record.fields, i) { scc_ast_decl_t *decl_field = scc_vec_at(ast_type->record.decl->record.fields, i); Assert(decl_field->base.type == SCC_AST_DECL_VAR); - scc_ir_type_ref_t field_type = + scc_hir_type_ref_t field_type = scc_ast2ir_type(ctx, decl_field->var.type); scc_vec_push(ir_type.data.aggregate.fields, field_type); } @@ -221,93 +213,99 @@ scc_ir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx, LOG_FATAL("Unsupported AST type: %d", ast_type->base.type); return 0; } - return scc_ir_builder_type(&ctx->builder, &ir_type); + return scc_hir_builder_type(&ctx->builder, &ir_type); } -scc_ir_value_ref_t scc_ast2ir_logical_expr(scc_ast2ir_ctx_t *ctx, - const scc_ast_expr_t *expr, - scc_ir_value_ref_t lhs, - scc_ir_value_ref_t rhs) { - // scc_ir_bblock_ref_t start_block = - // scc_ir_builder_current_bblock(&ctx->builder); +scc_hir_value_ref_t scc_ast2ir_logical_expr(scc_ast2ir_ctx_t *ctx, + const scc_ast_expr_t *expr, + scc_hir_value_ref_t lhs, + scc_hir_value_ref_t rhs) { + // scc_hir_bblock_ref_t start_block = + // scc_hir_builder_current_bblock(&ctx->builder); - scc_ir_value_ref_t right_block = - scc_ir_builder_bblock(&ctx->builder, "logic_right"); - scc_ir_value_ref_t end_block = - scc_ir_builder_bblock(&ctx->builder, "logic_end"); + scc_hir_value_ref_t right_block = + scc_hir_builder_bblock(&ctx->builder, "logic_right"); + scc_hir_value_ref_t end_block = + scc_hir_builder_bblock(&ctx->builder, "logic_end"); // 为结果创建临时存储空间 - scc_ir_type_ref_t int32_type = scc_ir_builder_type_i32(&ctx->builder); - scc_ir_value_ref_t result_var = - scc_ir_builder_alloca(&ctx->builder, int32_type, "logic_result"); + scc_hir_type_ref_t int32_type = scc_hir_builder_type_i32(&ctx->builder); + scc_hir_value_ref_t result_var = + scc_hir_builder_alloca(&ctx->builder, int32_type, "logic_result"); // 计算左操作数 - scc_ir_value_ref_t left_val = scc_ast2ir_expr(ctx, expr->binary.lhs, false); - scc_ir_value_ref_t zero_val = scc_ir_builder_const_int( - &ctx->builder, int32_type, (scc_ir_const_int_t){.int32 = 0}); - scc_ir_value_ref_t one_val = scc_ir_builder_const_int( - &ctx->builder, int32_type, (scc_ir_const_int_t){.int32 = 1}); + scc_hir_value_ref_t left_val = + scc_ast2ir_expr(ctx, expr->binary.lhs, false); + + scc_ap_t zero_ap; + scc_ap_set_int(&zero_ap, 0); + scc_ap_t one_ap; + scc_ap_set_int(&one_ap, 1); + scc_hir_value_ref_t zero_val = + scc_hir_builder_integer(&ctx->builder, int32_type, &zero_ap); + scc_hir_value_ref_t one_val = + scc_hir_builder_integer(&ctx->builder, int32_type, &one_ap); if (expr->binary.op == SCC_AST_OP_LOGICAL_AND) { // a && b - scc_ir_value_ref_t false_block = - scc_ir_builder_bblock(&ctx->builder, "and_false"); + scc_hir_value_ref_t false_block = + scc_hir_builder_bblock(&ctx->builder, "and_false"); // 如果左操作数为0,结果为0(短路) - scc_ir_value_ref_t is_left_zero = scc_ir_builder_binop( - &ctx->builder, SCC_IR_OP_EQ, left_val, zero_val); - scc_ir_builder_branch(&ctx->builder, is_left_zero, false_block, - right_block); + scc_hir_value_ref_t is_left_zero = scc_hir_builder_binop( + &ctx->builder, SCC_HIR_OP_EQ, left_val, zero_val); + scc_hir_builder_branch(&ctx->builder, is_left_zero, false_block, + right_block); // false_block: 左边为0,结果为0 - scc_ir_builder_set_current_bblock(&ctx->builder, false_block); - scc_ir_builder_store(&ctx->builder, result_var, zero_val); - scc_ir_builder_jump(&ctx->builder, end_block); + scc_hir_builder_set_current_bblock(&ctx->builder, false_block); + scc_hir_builder_store(&ctx->builder, result_var, zero_val); + scc_hir_builder_jump(&ctx->builder, end_block); // right_block: 左边非0,计算右边 - scc_ir_builder_set_current_bblock(&ctx->builder, right_block); - scc_ir_value_ref_t right_val = + scc_hir_builder_set_current_bblock(&ctx->builder, right_block); + scc_hir_value_ref_t right_val = scc_ast2ir_expr(ctx, expr->binary.rhs, false); - scc_ir_value_ref_t is_right_zero = scc_ir_builder_binop( - &ctx->builder, SCC_IR_OP_EQ, right_val, zero_val); - scc_ir_value_ref_t result = - scc_ir_builder_binop(&ctx->builder, SCC_IR_OP_XOR, is_right_zero, - one_val); // !right == 0 ? 1 : 0 - scc_ir_builder_store(&ctx->builder, result_var, result); - scc_ir_builder_jump(&ctx->builder, end_block); + scc_hir_value_ref_t is_right_zero = scc_hir_builder_binop( + &ctx->builder, SCC_HIR_OP_EQ, right_val, zero_val); + scc_hir_value_ref_t result = + scc_hir_builder_binop(&ctx->builder, SCC_HIR_OP_XOR, is_right_zero, + one_val); // !right == 0 ? 1 : 0 + scc_hir_builder_store(&ctx->builder, result_var, result); + scc_hir_builder_jump(&ctx->builder, end_block); } else { // SCC_AST_OP_LOGICAL_OR // a || b - scc_ir_value_ref_t true_block = - scc_ir_builder_bblock(&ctx->builder, "or_true"); + scc_hir_value_ref_t true_block = + scc_hir_builder_bblock(&ctx->builder, "or_true"); // 如果左操作数非0,结果为1(短路) - scc_ir_value_ref_t is_left_nonzero = scc_ir_builder_binop( - &ctx->builder, SCC_IR_OP_NEQ, left_val, zero_val); - scc_ir_builder_branch(&ctx->builder, is_left_nonzero, true_block, - right_block); + scc_hir_value_ref_t is_left_nonzero = scc_hir_builder_binop( + &ctx->builder, SCC_HIR_OP_NEQ, left_val, zero_val); + scc_hir_builder_branch(&ctx->builder, is_left_nonzero, true_block, + right_block); // true_block: 左边非0,结果为1 - scc_ir_builder_set_current_bblock(&ctx->builder, true_block); - scc_ir_builder_store(&ctx->builder, result_var, one_val); - scc_ir_builder_jump(&ctx->builder, end_block); + scc_hir_builder_set_current_bblock(&ctx->builder, true_block); + scc_hir_builder_store(&ctx->builder, result_var, one_val); + scc_hir_builder_jump(&ctx->builder, end_block); // right_block: 左边为0,计算右边 - scc_ir_builder_set_current_bblock(&ctx->builder, right_block); - scc_ir_value_ref_t right_val = + scc_hir_builder_set_current_bblock(&ctx->builder, right_block); + scc_hir_value_ref_t right_val = scc_ast2ir_expr(ctx, expr->binary.rhs, false); - scc_ir_value_ref_t is_right_zero = scc_ir_builder_binop( - &ctx->builder, SCC_IR_OP_EQ, right_val, zero_val); - scc_ir_value_ref_t result = - scc_ir_builder_binop(&ctx->builder, SCC_IR_OP_XOR, is_right_zero, - one_val); // !right == 0 ? 1 : 0 - scc_ir_builder_store(&ctx->builder, result_var, result); - scc_ir_builder_jump(&ctx->builder, end_block); + scc_hir_value_ref_t is_right_zero = scc_hir_builder_binop( + &ctx->builder, SCC_HIR_OP_EQ, right_val, zero_val); + scc_hir_value_ref_t result = + scc_hir_builder_binop(&ctx->builder, SCC_HIR_OP_XOR, is_right_zero, + one_val); // !right == 0 ? 1 : 0 + scc_hir_builder_store(&ctx->builder, result_var, result); + scc_hir_builder_jump(&ctx->builder, end_block); } // 设置结束块为当前块,并返回结果 - scc_ir_builder_set_current_bblock(&ctx->builder, end_block); - return scc_ir_builder_load(&ctx->builder, result_var); + scc_hir_builder_set_current_bblock(&ctx->builder, end_block); + return scc_hir_builder_load(&ctx->builder, result_var); } /** @@ -315,11 +313,11 @@ scc_ir_value_ref_t scc_ast2ir_logical_expr(scc_ast2ir_ctx_t *ctx, * * @param ctx * @param expr - * @return scc_ir_value_ref_t + * @return scc_hir_value_ref_t */ -scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, - const scc_ast_expr_t *expr, - cbool is_lvalue) { +scc_hir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, + const scc_ast_expr_t *expr, + cbool is_lvalue) { if (ctx == nullptr || expr == nullptr) { LOG_ERROR("args is nullptr"); return 0; @@ -329,7 +327,7 @@ scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, switch (expr->base.type) { case SCC_AST_EXPR_BINARY: { scc_ast_expr_t tmp_expr; - scc_ir_value_ref_t lhs, rhs; + scc_hir_value_ref_t lhs, rhs; switch (expr->binary.op) { case SCC_AST_OP_ASSIGN: // = rhs = scc_ast2ir_expr(ctx, expr->binary.rhs, false); @@ -400,35 +398,35 @@ scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, } if (is_assign) { lhs = scc_ast2ir_expr(ctx, expr->binary.lhs, true); - return scc_ir_builder_store(&ctx->builder, lhs, rhs); + return scc_hir_builder_store(&ctx->builder, lhs, rhs); } rhs = scc_ast2ir_expr(ctx, expr->binary.rhs, false); lhs = scc_ast2ir_expr(ctx, expr->binary.lhs, false); // 映射操作符 - scc_ir_op_type_t op; + scc_hir_op_type_t op; switch (expr->binary.op) { /* clang-format off */ - case SCC_AST_OP_ADD: op = SCC_IR_OP_ADD; break; - case SCC_AST_OP_SUB: op = SCC_IR_OP_SUB; break; - case SCC_AST_OP_MUL: op = SCC_IR_OP_MUL; break; - case SCC_AST_OP_DIV: op = SCC_IR_OP_DIV; break; - case SCC_AST_OP_MOD: op = SCC_IR_OP_MOD; break; - case SCC_AST_OP_BITWISE_AND: op = SCC_IR_OP_AND; break; - case SCC_AST_OP_BITWISE_OR: op = SCC_IR_OP_OR; break; - case SCC_AST_OP_BITWISE_XOR: op = SCC_IR_OP_XOR; break; - case SCC_AST_OP_LEFT_SHIFT: op = SCC_IR_OP_SHL; break; + case SCC_AST_OP_ADD: op = SCC_HIR_OP_ADD; break; + case SCC_AST_OP_SUB: op = SCC_HIR_OP_SUB; break; + case SCC_AST_OP_MUL: op = SCC_HIR_OP_MUL; break; + case SCC_AST_OP_DIV: op = SCC_HIR_OP_DIV; break; + case SCC_AST_OP_MOD: op = SCC_HIR_OP_MOD; break; + case SCC_AST_OP_BITWISE_AND: op = SCC_HIR_OP_AND; break; + case SCC_AST_OP_BITWISE_OR: op = SCC_HIR_OP_OR; break; + case SCC_AST_OP_BITWISE_XOR: op = SCC_HIR_OP_XOR; break; + case SCC_AST_OP_LEFT_SHIFT: op = SCC_HIR_OP_SHL; break; case SCC_AST_OP_RIGHT_SHIFT: { - op = SCC_IR_OP_SHR; - // FIXME op = SCC_IR_OP_SAR; + op = SCC_HIR_OP_SHR; + // FIXME op = SCC_HIR_OP_SAR; break; } - case SCC_AST_OP_EQUAL: op = SCC_IR_OP_EQ; break; - case SCC_AST_OP_NOT_EQUAL: op = SCC_IR_OP_NEQ; break; - case SCC_AST_OP_LESS: op = SCC_IR_OP_LT; break; - case SCC_AST_OP_LESS_EQUAL: op = SCC_IR_OP_LE; break; - case SCC_AST_OP_GREATER: op = SCC_IR_OP_GT; break; - case SCC_AST_OP_GREATER_EQUAL: op = SCC_IR_OP_GE; break; + case SCC_AST_OP_EQUAL: op = SCC_HIR_OP_EQ; break; + case SCC_AST_OP_NOT_EQUAL: op = SCC_HIR_OP_NEQ; break; + case SCC_AST_OP_LESS: op = SCC_HIR_OP_LT; break; + case SCC_AST_OP_LESS_EQUAL: op = SCC_HIR_OP_LE; break; + case SCC_AST_OP_GREATER: op = SCC_HIR_OP_GT; break; + case SCC_AST_OP_GREATER_EQUAL: op = SCC_HIR_OP_GE; break; case SCC_AST_OP_COMMA: { // 逗号运算符:计算左表达式,丢弃结果,返回右表达式 return rhs; @@ -443,24 +441,24 @@ scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, return 0; } // 创建操作节点 - return scc_ir_builder_binop(&ctx->builder, op, lhs, rhs); + return scc_hir_builder_binop(&ctx->builder, op, lhs, rhs); } case SCC_AST_EXPR_UNARY: { if (expr->unary.op == SCC_AST_OP_ADDRESS_OF) { return scc_ast2ir_expr(ctx, expr->unary.operand, true); } else if (expr->unary.op == SCC_AST_OP_INDIRECTION) { // 从地址取值 - scc_ir_value_ref_t ptr = + scc_hir_value_ref_t ptr = scc_ast2ir_expr(ctx, expr->unary.operand, false); if (is_lvalue) { // 作为左值使用(如 *ptr = ...),直接返回指针值(地址) return ptr; } else { // 作为右值使用(如 x = *ptr),加载指针指向的值 - return scc_ir_builder_load(&ctx->builder, ptr); + return scc_hir_builder_load(&ctx->builder, ptr); } } - scc_ir_value_ref_t operand = + scc_hir_value_ref_t operand = scc_ast2ir_expr(ctx, expr->unary.operand, is_lvalue); // /* 一元操作符 */ // SCC_AST_OP_UNARY_PLUS, // + (一元) @@ -480,13 +478,14 @@ scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, case SCC_AST_OP_UNARY_MINUS: { // 负号 // 实现为0 - operand - scc_ir_const_int_t value; - scc_ir_type_ref_t type_ref = scc_ir_builder_type_i32(&ctx->builder); - value.int32 = 0; - scc_ir_value_ref_t zero_ref = - scc_ir_builder_const_int(&ctx->builder, type_ref, value); - return scc_ir_builder_binop(&ctx->builder, SCC_IR_OP_SUB, zero_ref, - operand); + scc_hir_type_ref_t type_ref = + scc_hir_builder_type_i32(&ctx->builder); + scc_ap_t value; + scc_ap_set_int(&value, 0); + scc_hir_value_ref_t zero_ref = + scc_hir_builder_integer(&ctx->builder, type_ref, &value); + return scc_hir_builder_binop(&ctx->builder, SCC_HIR_OP_SUB, + zero_ref, operand); } case SCC_AST_OP_ADDRESS_OF: case SCC_AST_OP_INDIRECTION: @@ -494,18 +493,19 @@ scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, break; case SCC_AST_OP_BITWISE_NOT: // 按位取反 - return scc_ir_builder_binop(&ctx->builder, SCC_IR_OP_NOT, operand, - 0); + return scc_hir_builder_binop(&ctx->builder, SCC_HIR_OP_NOT, operand, + 0); case SCC_AST_OP_LOGICAL_NOT: { // 逻辑非 // 实现为与0比较 - scc_ir_const_int_t value; - scc_ir_type_ref_t type_ref = scc_ir_builder_type_i32(&ctx->builder); - value.int32 = 0; - scc_ir_value_ref_t zero_ref = - scc_ir_builder_const_int(&ctx->builder, type_ref, value); - return scc_ir_builder_binop(&ctx->builder, SCC_IR_OP_EQ, zero_ref, - operand); + scc_hir_type_ref_t type_ref = + scc_hir_builder_type_i32(&ctx->builder); + scc_ap_t value; + scc_ap_set_int(&value, 0); + scc_hir_value_ref_t zero_ref = + scc_hir_builder_integer(&ctx->builder, type_ref, &value); + return scc_hir_builder_binop(&ctx->builder, SCC_HIR_OP_EQ, zero_ref, + operand); } default: LOG_FATAL("Unsupported unary operator: %d", expr->unary.op); @@ -520,44 +520,44 @@ scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, } case SCC_AST_EXPR_CALL: { // 转换参数 - scc_ir_value_ref_vec_t args; + scc_hir_value_ref_vec_t args; scc_vec_init(args); scc_vec_foreach(expr->call.args, i) { scc_ast_expr_t *arg_expr = scc_vec_at(expr->call.args, i); - scc_ir_value_ref_t arg_node; + scc_hir_value_ref_t arg_node; arg_node = scc_ast2ir_expr(ctx, arg_expr, false); scc_vec_push(args, arg_node); } // 创建调用节点(需要查找函数定义) - scc_ir_func_ref_t func = (scc_ir_value_ref_t)(usize)scc_hashtable_get( + scc_hir_func_ref_t func = (scc_hir_value_ref_t)(usize)scc_hashtable_get( &ctx->symtab, expr->call.callee->identifier._target->name); if (!func) { LOG_ERROR("Function %s not found", expr->call.callee->identifier._target->name); } - scc_ir_value_ref_t node = - scc_ir_builder_call(&ctx->builder, func, args.data, args.size); + scc_hir_value_ref_t node = + scc_hir_builder_call(&ctx->builder, func, args.data, args.size); scc_vec_free(args); return node; } case SCC_AST_EXPR_ARRAY_SUBSCRIPT: { // 1. 计算数组/指针基址(右值,得到地址) - scc_ir_value_ref_t base_ptr = + scc_hir_value_ref_t base_ptr = scc_ast2ir_expr(ctx, expr->subscript.array, true); // 2. 计算下标值 - scc_ir_value_ref_t index = + scc_hir_value_ref_t index = scc_ast2ir_expr(ctx, expr->subscript.index, false); // 3. 生成 getptr(GEP) - scc_ir_value_ref_t elem_ptr = - scc_ir_builder_get_elem_ptr(&ctx->builder, base_ptr, index); + scc_hir_value_ref_t elem_ptr = + scc_hir_builder_get_elem_ptr(&ctx->builder, base_ptr, index); // 4. 根据左值/右值返回 if (is_lvalue) { return elem_ptr; // 作为左值:返回地址 } else { - return scc_ir_builder_load(&ctx->builder, - elem_ptr); // 作为右值:加载值 + return scc_hir_builder_load(&ctx->builder, + elem_ptr); // 作为右值:加载值 } } case SCC_AST_EXPR_MEMBER: @@ -567,19 +567,14 @@ scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, case SCC_AST_EXPR_CAST: break; case SCC_AST_EXPR_SIZE_OF: { - scc_ir_const_int_t val; - // FIXME TODO(); - val.int64 = 1; // HACK - return scc_ir_builder_const_int( - &ctx->builder, scc_ir_builder_type_u64(&ctx->builder), val); + // return scc_hir_builder_integer( + // &ctx->builder, scc_hir_builder_type_u64(&ctx->builder), val); } case SCC_AST_EXPR_ALIGN_OF: { - scc_ir_const_int_t val; TODO(); - val.int64 = 8; - return scc_ir_builder_const_int( - &ctx->builder, scc_ir_builder_type_u64(&ctx->builder), val); + // return scc_hir_builder_integer( + // &ctx->builder, scc_hir_builder_type_u64(&ctx->builder), val); } case SCC_AST_EXPR_COMPOUND: break; @@ -588,15 +583,15 @@ scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, // SCC_AST_EXPR_BUILTIN,// 内置表达式 ... directive map to ir builtin case SCC_AST_EXPR_INT_LITERAL: { // FIXME maybe using some array to int; - scc_ir_type_ref_t type_ref = scc_ir_builder_type_i32(&ctx->builder); - scc_ir_const_int_t value; - parse_lexme2const_int(expr->literal.lexme, &value); - return scc_ir_builder_const_int(&ctx->builder, type_ref, value); + scc_hir_type_ref_t type_ref = scc_hir_builder_type_i32(&ctx->builder); + scc_ap_t value; + scc_ap_from_cstr(&value, expr->literal.lexme, 10); + return scc_hir_builder_integer(&ctx->builder, type_ref, &value); } // SCC_AST_EXPR_FLOAT_LITERAL, // 浮点字面量 case SCC_AST_EXPR_CHAR_LITERAL: { // FIXME just 'a' '\n' - scc_ir_type_ref_t type_ref = scc_ir_builder_type_i32(&ctx->builder); + scc_hir_type_ref_t type_ref = scc_hir_builder_type_i32(&ctx->builder); const char *lexme = expr->literal.lexme; Assert(lexme[0] == '\''); u8 int_lit = 0; @@ -620,15 +615,15 @@ scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, } else { int_lit = lexme[1]; } - scc_ir_const_int_t value; - value.int32 = int_lit; - return scc_ir_builder_const_int(&ctx->builder, type_ref, value); + scc_ap_t value; + scc_ap_set_int(&value, int_lit); + return scc_hir_builder_integer(&ctx->builder, type_ref, &value); } case SCC_AST_EXPR_STRING_LITERAL: { // FIXME - scc_ir_value_ref_t value = - scc_ir_builder_const_string(&ctx->builder, expr->literal.lexme, - scc_strlen(expr->literal.lexme)); + scc_hir_value_ref_t value = + scc_hir_builder_const_string(&ctx->builder, expr->literal.lexme, + scc_strlen(expr->literal.lexme)); if (is_lvalue) TODO(); return value; @@ -638,25 +633,25 @@ scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, LOG_ERROR("unknown identifier %s", expr->identifier.name); } // FIXME hack hashtable - scc_ir_value_ref_t in = (scc_ir_value_ref_t)(usize)scc_hashtable_get( + scc_hir_value_ref_t in = (scc_hir_value_ref_t)(usize)scc_hashtable_get( &ctx->ast2ir_cache, expr->identifier._target); Assert(in != 0); if (is_lvalue) { return in; } else { // 右值:如果是数组类型,退化为指针(返回地址) - scc_ir_type_t *ir_type = - scc_ir_module_get_type_by_value(ctx->builder.ctx.module, in); - if (ir_type->tag == SCC_IR_TYPE_PTR) { - scc_ir_type_t *target_type = scc_ir_module_get_type( - ctx->builder.ctx.module, ir_type->data.pointer.base); - if (target_type->tag == SCC_IR_TYPE_ARRAY) { + scc_hir_type_t *ir_type = scc_hir_module_get_type_by_value( + &ctx->builder.cprog->module, in); + if (ir_type->tag == SCC_HIR_TYPE_PTR) { + scc_hir_type_t *target_type = scc_hir_module_get_type( + &ctx->builder.cprog->module, ir_type->data.pointer.base); + if (target_type->tag == SCC_HIR_TYPE_ARRAY) { // 生成 getptr 获取数组首地址 - return scc_ir_builder_get_elem_ptr(&ctx->builder, in, - SCC_IR_REF_nullptr); + return scc_hir_builder_get_elem_ptr(&ctx->builder, in, + SCC_HIR_REF_nullptr); } else { // 标量类型:加载值 - return scc_ir_builder_load(&ctx->builder, in); + return scc_hir_builder_load(&ctx->builder, in); } } else { return in; @@ -711,86 +706,88 @@ void scc_ast2ir_stmt(scc_ast2ir_ctx_t *ctx, const scc_ast_stmt_t *stmt) { \ / merge_block */ - scc_ir_value_ref_t true_block = - scc_ir_builder_bblock(&ctx->builder, "if_true"); + scc_hir_value_ref_t true_block = + scc_hir_builder_bblock(&ctx->builder, "if_true"); - scc_ir_value_ref_t false_block = - scc_ir_builder_bblock(&ctx->builder, "if_false"); + scc_hir_value_ref_t false_block = + scc_hir_builder_bblock(&ctx->builder, "if_false"); - scc_ir_value_ref_t merge_block = - scc_ir_builder_bblock(&ctx->builder, "if_merge"); + scc_hir_value_ref_t merge_block = + scc_hir_builder_bblock(&ctx->builder, "if_merge"); - scc_ir_value_ref_t cond_node = + scc_hir_value_ref_t cond_node = scc_ast2ir_expr(ctx, stmt->if_stmt.cond, false); - scc_ir_builder_branch(&ctx->builder, cond_node, true_block, - false_block); + scc_hir_builder_branch(&ctx->builder, cond_node, true_block, + false_block); // 生成true分支 - scc_ir_builder_set_current_bblock(&ctx->builder, true_block); + scc_hir_builder_set_current_bblock(&ctx->builder, true_block); scc_ast2ir_stmt(ctx, stmt->if_stmt.then_stmt); - scc_ir_builder_jump(&ctx->builder, merge_block); + scc_hir_builder_jump(&ctx->builder, merge_block); // 生成false分支 if (stmt->if_stmt.opt_else_stmt) { - scc_ir_builder_set_current_bblock(&ctx->builder, false_block); + scc_hir_builder_set_current_bblock(&ctx->builder, false_block); scc_ast2ir_stmt(ctx, stmt->if_stmt.opt_else_stmt); - scc_ir_builder_jump(&ctx->builder, merge_block); + scc_hir_builder_jump(&ctx->builder, merge_block); } - scc_ir_builder_set_current_bblock(&ctx->builder, merge_block); + scc_hir_builder_set_current_bblock(&ctx->builder, merge_block); break; } case SCC_AST_STMT_WHILE: { - scc_ir_value_ref_t cond_block = - scc_ir_builder_bblock(&ctx->builder, "while_cond"); - scc_ir_value_ref_t body_block = - scc_ir_builder_bblock(&ctx->builder, "while_body"); - scc_ir_value_ref_t exit_block = - scc_ir_builder_bblock(&ctx->builder, "while_exit"); + scc_hir_value_ref_t cond_block = + scc_hir_builder_bblock(&ctx->builder, "while_cond"); + scc_hir_value_ref_t body_block = + scc_hir_builder_bblock(&ctx->builder, "while_body"); + scc_hir_value_ref_t exit_block = + scc_hir_builder_bblock(&ctx->builder, "while_exit"); - scc_ir_builder_jump(&ctx->builder, cond_block); + scc_hir_builder_jump(&ctx->builder, cond_block); - scc_ir_builder_set_current_bblock(&ctx->builder, cond_block); - scc_ir_value_ref_t cond_node = + scc_hir_builder_set_current_bblock(&ctx->builder, cond_block); + scc_hir_value_ref_t cond_node = scc_ast2ir_expr(ctx, stmt->while_stmt.cond, false); - scc_ir_builder_branch(&ctx->builder, cond_node, body_block, exit_block); + scc_hir_builder_branch(&ctx->builder, cond_node, body_block, + exit_block); - scc_ir_builder_set_current_bblock(&ctx->builder, body_block); + scc_hir_builder_set_current_bblock(&ctx->builder, body_block); scc_ast2ir_stmt(ctx, stmt->while_stmt.body); - scc_ir_builder_jump(&ctx->builder, cond_block); + scc_hir_builder_jump(&ctx->builder, cond_block); - scc_ir_builder_set_current_bblock(&ctx->builder, exit_block); + scc_hir_builder_set_current_bblock(&ctx->builder, exit_block); break; } case SCC_AST_STMT_DO_WHILE: { - scc_ir_value_ref_t cond_block = - scc_ir_builder_bblock(&ctx->builder, "do_while_cond"); - scc_ir_value_ref_t body_block = - scc_ir_builder_bblock(&ctx->builder, "do_while_body"); - scc_ir_value_ref_t exit_block = - scc_ir_builder_bblock(&ctx->builder, "do_while_exit"); + scc_hir_value_ref_t cond_block = + scc_hir_builder_bblock(&ctx->builder, "do_while_cond"); + scc_hir_value_ref_t body_block = + scc_hir_builder_bblock(&ctx->builder, "do_while_body"); + scc_hir_value_ref_t exit_block = + scc_hir_builder_bblock(&ctx->builder, "do_while_exit"); - scc_ir_builder_jump(&ctx->builder, body_block); + scc_hir_builder_jump(&ctx->builder, body_block); - scc_ir_builder_set_current_bblock(&ctx->builder, body_block); + scc_hir_builder_set_current_bblock(&ctx->builder, body_block); scc_ast2ir_stmt(ctx, stmt->while_stmt.body); - scc_ir_builder_jump(&ctx->builder, cond_block); + scc_hir_builder_jump(&ctx->builder, cond_block); - scc_ir_builder_set_current_bblock(&ctx->builder, cond_block); - scc_ir_value_ref_t cond_node = + scc_hir_builder_set_current_bblock(&ctx->builder, cond_block); + scc_hir_value_ref_t cond_node = scc_ast2ir_expr(ctx, stmt->while_stmt.cond, false); - scc_ir_builder_branch(&ctx->builder, cond_node, body_block, exit_block); + scc_hir_builder_branch(&ctx->builder, cond_node, body_block, + exit_block); - scc_ir_builder_set_current_bblock(&ctx->builder, exit_block); + scc_hir_builder_set_current_bblock(&ctx->builder, exit_block); break; } case SCC_AST_STMT_FOR: { - scc_ir_value_ref_t cond_block = - scc_ir_builder_bblock(&ctx->builder, "for_while_cond"); - scc_ir_value_ref_t body_block = - scc_ir_builder_bblock(&ctx->builder, "for_while_body"); - scc_ir_value_ref_t exit_block = - scc_ir_builder_bblock(&ctx->builder, "for_while_exit"); + scc_hir_value_ref_t cond_block = + scc_hir_builder_bblock(&ctx->builder, "for_while_cond"); + scc_hir_value_ref_t body_block = + scc_hir_builder_bblock(&ctx->builder, "for_while_body"); + scc_hir_value_ref_t exit_block = + scc_hir_builder_bblock(&ctx->builder, "for_while_exit"); if (stmt->for_stmt.init) { if (SCC_AST_IS_A(scc_ast_decl_t, stmt->for_stmt.init)) { @@ -806,26 +803,26 @@ void scc_ast2ir_stmt(scc_ast2ir_ctx_t *ctx, const scc_ast_stmt_t *stmt) { } } - scc_ir_builder_jump(&ctx->builder, cond_block); + scc_hir_builder_jump(&ctx->builder, cond_block); - scc_ir_builder_set_current_bblock(&ctx->builder, cond_block); + scc_hir_builder_set_current_bblock(&ctx->builder, cond_block); if (stmt->for_stmt.cond) { - scc_ir_value_ref_t cond_node = + scc_hir_value_ref_t cond_node = scc_ast2ir_expr(ctx, stmt->for_stmt.cond, false); - scc_ir_builder_branch(&ctx->builder, cond_node, body_block, - exit_block); + scc_hir_builder_branch(&ctx->builder, cond_node, body_block, + exit_block); } else { - scc_ir_builder_jump(&ctx->builder, body_block); + scc_hir_builder_jump(&ctx->builder, body_block); } - scc_ir_builder_set_current_bblock(&ctx->builder, body_block); + scc_hir_builder_set_current_bblock(&ctx->builder, body_block); scc_ast2ir_stmt(ctx, stmt->for_stmt.body); if (stmt->for_stmt.incr) { scc_ast2ir_expr(ctx, stmt->for_stmt.incr, false); } - scc_ir_builder_jump(&ctx->builder, cond_block); + scc_hir_builder_jump(&ctx->builder, cond_block); - scc_ir_builder_set_current_bblock(&ctx->builder, exit_block); + scc_hir_builder_set_current_bblock(&ctx->builder, exit_block); break; } // SCC_AST_STMT_SWITCH, // switch 语句 @@ -835,11 +832,11 @@ void scc_ast2ir_stmt(scc_ast2ir_ctx_t *ctx, const scc_ast_stmt_t *stmt) { // SCC_AST_STMT_CONTINUE, // continue 语句 case SCC_AST_STMT_RETURN: { if (stmt->return_stmt.expr) { - scc_ir_value_ref_t ret_val_node = + scc_hir_value_ref_t ret_val_node = scc_ast2ir_expr(ctx, stmt->return_stmt.expr, false); - scc_ir_builder_ret(&ctx->builder, ret_val_node); + scc_hir_builder_ret(&ctx->builder, ret_val_node); } else { - scc_ir_builder_ret_void(&ctx->builder); + scc_hir_builder_ret_void(&ctx->builder); } break; } @@ -867,40 +864,41 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, const scc_ast_decl_t *decl, switch (decl->base.type) { case SCC_AST_DECL_VAR: { // 1. 获取原始类型(可能数组长度为0) - scc_ir_type_ref_t orig_type_ref = scc_ast2ir_type(ctx, decl->var.type); + scc_hir_type_ref_t orig_type_ref = scc_ast2ir_type(ctx, decl->var.type); // 借用指针并拷贝类型(避免悬空) - const scc_ir_type_t *orig_type; - SCC_IR_BUILDER_BEGIN_BORROW( + const scc_hir_type_t *orig_type; + SCC_HIR_BUILDER_BEGIN_BORROW( &ctx->builder, orig_type, - scc_ir_module_get_type(ctx->builder.ctx.module, orig_type_ref)); - scc_ir_type_t final_type_desc = *orig_type; - SCC_IR_BUILDER_END_BORROW(&ctx->builder); + scc_hir_module_get_type(&ctx->builder.cprog->module, + orig_type_ref)); + scc_hir_type_t final_type_desc = *orig_type; + SCC_HIR_BUILDER_END_BORROW(&ctx->builder); // 2. 如果是未知长度数组且有初始化,解析实际长度 - scc_ir_type_ref_t final_type_ref = orig_type_ref; - if (decl->var.init && final_type_desc.tag == SCC_IR_TYPE_ARRAY && + scc_hir_type_ref_t final_type_ref = orig_type_ref; + if (decl->var.init && final_type_desc.tag == SCC_HIR_TYPE_ARRAY && final_type_desc.data.array.len == 0) { - scc_ir_type_t tmp_type_desc; + scc_hir_type_t tmp_type_desc; resolve_array_length(ctx, &final_type_desc, &tmp_type_desc, decl->var.init); final_type_desc = tmp_type_desc; final_type_ref = - scc_ir_builder_type(&ctx->builder, &final_type_desc); + scc_hir_builder_type(&ctx->builder, &final_type_desc); // 此时 final_type_desc 中的长度已经确定 } // 3. 分配变量(栈或全局) - scc_ir_value_ref_t alloc_val_node; + scc_hir_value_ref_t alloc_val_node; if (is_global) { // 全局变量:需要生成全局分配,当前代码暂未实现,保留 TODO - // alloc_val_node = scc_ir_builder_global_alloca(&ctx->builder, + // alloc_val_node = scc_hir_builder_global_alloca(&ctx->builder, // final_type_ref, decl->name); // scc_vec_push(builder->cprog->global_vals, alloc_val_node); // 这里先返回,后续补充 return; } else { - alloc_val_node = scc_ir_builder_alloca(&ctx->builder, - final_type_ref, decl->name); + alloc_val_node = scc_hir_builder_alloca(&ctx->builder, + final_type_ref, decl->name); } scc_hashtable_set(&ctx->ast2ir_cache, decl, (void *)(usize)alloc_val_node); @@ -908,32 +906,33 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, const scc_ast_decl_t *decl, // 4. 处理初始化 if (decl->var.init) { // 再次借用 final_type 以判断是否为数组 - const scc_ir_type_t *final_type; - SCC_IR_BUILDER_BEGIN_BORROW( + const scc_hir_type_t *final_type; + SCC_HIR_BUILDER_BEGIN_BORROW( &ctx->builder, final_type, - scc_ir_module_get_type(ctx->builder.ctx.module, - final_type_ref)); - scc_ir_type_t type = *final_type; - SCC_IR_BUILDER_END_BORROW(&ctx->builder); - if (type.tag == SCC_IR_TYPE_ARRAY) { + scc_hir_module_get_type(&ctx->builder.cprog->module, + final_type_ref)); + scc_hir_type_t type = *final_type; + SCC_HIR_BUILDER_END_BORROW(&ctx->builder); + if (type.tag == SCC_HIR_TYPE_ARRAY) { emit_array_initialization(ctx, alloc_val_node, &type, decl->var.init); } else { // 标量类型 - scc_ir_value_ref_t init_val = + scc_hir_value_ref_t init_val = scc_ast2ir_expr(ctx, decl->var.init, false); - scc_ir_builder_store(&ctx->builder, alloc_val_node, init_val); + scc_hir_builder_store(&ctx->builder, alloc_val_node, init_val); } } break; } case SCC_AST_DECL_FUNC: { - scc_ir_type_ref_t func_type_ref = scc_ast2ir_type(ctx, decl->func.type); - scc_ir_func_ref_t func_ref = + scc_hir_type_ref_t func_type_ref = + scc_ast2ir_type(ctx, decl->func.type); + scc_hir_func_ref_t func_ref = (usize)scc_hashtable_get(&ctx->symtab, decl->name); - if (func_ref == SCC_IR_REF_nullptr) { + if (func_ref == SCC_HIR_REF_nullptr) { func_ref = - scc_ir_builder_func(&ctx->builder, func_type_ref, decl->name); + scc_hir_builder_func(&ctx->builder, func_type_ref, decl->name); scc_hashtable_set(&ctx->symtab, decl->name, (void *)(usize)func_ref); } @@ -943,8 +942,8 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, const scc_ast_decl_t *decl, break; } - scc_ir_builder_begin_func(&ctx->builder, func_ref); - scc_ir_builder_begin_bblock(&ctx->builder, "entry"); + scc_hir_builder_begin_func(&ctx->builder, func_ref); + scc_hir_builder_begin_bblock(&ctx->builder, "entry"); scc_vec_foreach(decl->func.type->function.params, i) { scc_ast_decl_t *param = @@ -954,10 +953,10 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, const scc_ast_decl_t *decl, scc_ast2ir_stmt(ctx, decl->func.body); // FIXME need ret for none return or other default ret - scc_ir_builder_ret_void(&ctx->builder); + scc_hir_builder_ret_void(&ctx->builder); - scc_ir_builder_end_bblock(&ctx->builder); - scc_ir_builder_end_func(&ctx->builder); + scc_hir_builder_end_bblock(&ctx->builder); + scc_hir_builder_end_func(&ctx->builder); break; } case SCC_AST_DECL_LIST: { @@ -972,15 +971,15 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, const scc_ast_decl_t *decl, decl->param.type->builtin.type == SCC_AST_BUILTIN_TYPE_VOID) { break; } - scc_ir_type_ref_t parma_type_ref = + scc_hir_type_ref_t parma_type_ref = scc_ast2ir_type(ctx, decl->param.type); - scc_ir_value_ref_t param_ref = scc_ir_builder_func_arg_ref( + scc_hir_value_ref_t param_ref = scc_hir_builder_func_arg_ref( &ctx->builder, parma_type_ref, decl->name, decl->param.param_idx); if (!ctx->hint_using_value) { - scc_ir_value_ref_t val_ref = scc_ir_builder_alloca( + scc_hir_value_ref_t val_ref = scc_hir_builder_alloca( &ctx->builder, parma_type_ref, decl->name); - scc_ir_builder_store(&ctx->builder, val_ref, param_ref); + scc_hir_builder_store(&ctx->builder, val_ref, param_ref); scc_hashtable_set(&ctx->ast2ir_cache, decl, (void *)(usize)val_ref); } else { Panic("using value is not supported"); @@ -995,25 +994,26 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, const scc_ast_decl_t *decl, .record.decl = decl, .record.name = decl->name, }; - scc_ir_type_ref_t type_ref = scc_ast2ir_type(ctx, &type); - // scc_ir_builder_global_alloca(&ctx->builder, type_ref, - // SCC_IR_REF_nullptr); + scc_hir_type_ref_t type_ref = scc_ast2ir_type(ctx, &type); + // scc_hir_builder_global_alloca(&ctx->builder, type_ref, + // SCC_HIR_REF_nullptr); break; case SCC_AST_DECL_ENUM: - scc_ir_const_int_t val; - val.int32 = 0; + scc_ap_t val; + int idx = 0; + scc_ap_set_int(&val, idx); scc_vec_foreach(decl->record.fields, i) { scc_ast_decl_t *item = scc_vec_at(decl->record.fields, i); Assert(item->base.type == SCC_AST_DECL_VAR); if (item->var.init) { Assert(item->var.init->base.type == SCC_AST_EXPR_INT_LITERAL); - parse_lexme2const_int(item->var.init->literal.lexme, &val); + scc_ap_from_cstr(&val, item->var.init->literal.lexme, 10); } - scc_ir_value_ref_t item_val_ref = scc_ir_builder_const_int( - &ctx->builder, scc_ir_builder_type_i32(&ctx->builder), val); + scc_hir_value_ref_t item_val_ref = scc_hir_builder_integer( + &ctx->builder, scc_hir_builder_type_i32(&ctx->builder), &val); scc_hashtable_set(&ctx->ast2ir_cache, item, (void *)(usize)item_val_ref); - val.int32 += 1; + scc_ap_set_int(&val, ++idx); } break; case SCC_AST_DECL_TYPEDEF: @@ -1035,17 +1035,17 @@ void scc_ast2ir_translation_unit(scc_ast2ir_ctx_t *ctx, } void scc_ast2ir_ctx_init(scc_ast2ir_ctx_t *ctx, const scc_abi_type_calc_t *abi, - scc_ir_cprog_t *cprog) { + scc_hir_cprog_t *cprog) { Assert(ctx != nullptr); ctx->abi = abi; - scc_ir_builder_init(&ctx->builder, cprog); + scc_hir_builder_init(&ctx->builder, cprog); scc_hashtable_usize_init(&ctx->ast2ir_cache); scc_hashtable_cstr_init(&ctx->symtab); ctx->hint_using_value = false; } void scc_ast2ir_ctx_drop(scc_ast2ir_ctx_t *ctx) { - scc_ir_builder_drop(&ctx->builder); + scc_hir_builder_drop(&ctx->builder); scc_hashtable_drop(&ctx->ast2ir_cache); scc_hashtable_drop(&ctx->symtab); } diff --git a/libs/ir/cbuild.toml b/libs/ir/cbuild.toml deleted file mode 100644 index 6ef6640..0000000 --- a/libs/ir/cbuild.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "ir" -version = "0.1.0" -authors = [] -description = "" - -dependencies = [ - { name = "scc_utils", path = "../../runtime/scc_utils" }, - { name = "tree_dump", path = "../tree_dump" }, -] -# dependencies = [] -# features = {} -# default_features = [] diff --git a/libs/ir/cfg/cbuild.toml b/libs/ir/cfg/cbuild.toml new file mode 100644 index 0000000..4d4880f --- /dev/null +++ b/libs/ir/cfg/cbuild.toml @@ -0,0 +1,12 @@ +[package] +name = "scc_cfg" +version = "0.1.0" +authors = [] +description = "" + +dependencies = [ + { name = "scc_core", path = "../../../runtime/scc_core" }, + { name = "scc_utils", path = "../../../runtime/scc_utils" }, +] +# features = {} +# default_features = [] diff --git a/libs/ir/cfg/include/scc_cfg.h b/libs/ir/cfg/include/scc_cfg.h new file mode 100644 index 0000000..505d005 --- /dev/null +++ b/libs/ir/cfg/include/scc_cfg.h @@ -0,0 +1,108 @@ +#ifndef __SCC_CFG_H__ +#define __SCC_CFG_H__ + +#include +#include + +#define SCC_CFG_ID_nullptr (0) +typedef usize scc_cfg_id_t; +typedef scc_cfg_id_t scc_cfg_bblock_id_t; +typedef scc_cfg_id_t scc_cfg_func_id_t; + +typedef SCC_VEC(scc_cfg_bblock_id_t) scc_cfg_bblock_id_vec_t; +typedef SCC_VEC(void *) scc_cfg_value_vec_t; +typedef struct scc_cfg_module scc_cfg_module_t; +typedef struct scc_cfg_func scc_cfg_func_t; +typedef struct scc_cfg_bblock scc_cfg_bblock_t; +typedef struct scc_cfg_symbol scc_cfg_symbol_t; + +struct scc_cfg_bblock { + scc_cfg_bblock_id_t id; + const char *name; + scc_cfg_bblock_id_vec_t preds; // 前驱 + scc_cfg_bblock_id_vec_t succs; // 后继 + scc_cfg_value_vec_t values; // using cast + void *attribute; +}; + +struct scc_cfg_func { + const char *name; + + scc_cfg_bblock_id_t next_bblock_id; + scc_cfg_bblock_id_vec_t bblocks; + scc_hashtable_t bblock_map; // id -> index + + scc_cfg_bblock_id_t entry_bblock_id; // maybe it will always 0 + void *attribute; +}; + +typedef enum { + SCC_CFG_SYMBOL_KIND_FUNC, + SCC_CFG_SYMBOL_KIND_DATA, + SCC_CFG_SYMBOL_KIND_EXTERN, +} scc_cfg_symbol_kind_t; + +struct scc_cfg_symbol { + const char *name; + scc_cfg_symbol_kind_t kind; + void *attribute; +}; + +typedef SCC_VEC(scc_cfg_bblock_t) scc_cfg_bblock_vec_t; +typedef SCC_VEC(scc_cfg_func_t) scc_cfg_func_vec_t; +typedef SCC_VEC(scc_cfg_symbol_t) scc_cfg_symbol_vec_t; +struct scc_cfg_module { + scc_cfg_bblock_vec_t bblocks; + scc_cfg_func_vec_t funcs; /* 所有函数定义(按添加顺序) */ + scc_cfg_symbol_vec_t symbols; /* 全局符号表 */ + scc_hashtable_t symbol_map; /* 名称 -> 索引 */ +}; + +void scc_cfg_module_init(scc_cfg_module_t *module); +/** + * @brief + * + * @param module + * @warning 由于void*存在可能导致严重内存泄漏 + */ +void scc_cfg_module_drop(scc_cfg_module_t *module); +scc_cfg_func_id_t scc_cfg_module_add_func(scc_cfg_module_t *module, + const scc_cfg_func_t *func); +scc_cfg_func_t *scc_cfg_module_unsafe_get_func(scc_cfg_module_t *module, + scc_cfg_func_id_t id); +scc_cfg_bblock_id_t scc_cfg_module_add_bblock(scc_cfg_module_t *module, + const scc_cfg_bblock_t *bblock); +scc_cfg_bblock_t *scc_cfg_module_unsafe_get_bblock(scc_cfg_module_t *module, + scc_cfg_bblock_id_t id); +void scc_cfg_module_add_symbol(scc_cfg_module_t *module, + const scc_cfg_symbol_t *symbol); +scc_cfg_id_t scc_cfg_module_lookup_symbol(const scc_cfg_module_t *module, + const char *name); + +static inline const scc_cfg_symbol_t * +scc_cfg_module_unsafe_lookup_symbol(const scc_cfg_module_t *module, + const char *name) { + scc_cfg_id_t idx = scc_cfg_module_lookup_symbol(module, name); + if (idx == 0) { + Panic("Can't find symbol %s", name); + return nullptr; + } + return &scc_vec_at(module->symbols, idx); +} + +// scc_cfg_bblock_id_t scc_cfg_func_add_bblock(scc_cfg_func_t *func, +// const scc_cfg_bblock_t *bblock); +// scc_cfg_bblock_t *scc_cfg_func_unsafe_get_bblock(scc_cfg_func_t *func, +// scc_cfg_bblock_id_t id); +// scc_cfg_bblock_t *scc_cfg_func_unsafe_entry_bblock(scc_cfg_func_t *func); + +void scc_cfg_bblock_add_pred(scc_cfg_bblock_t *bb, scc_cfg_bblock_id_t pred_id); +void scc_cfg_bblock_remove_pred(scc_cfg_bblock_t *bb, + scc_cfg_bblock_id_t pred_id); +void scc_cfg_bblock_clear_pred(scc_cfg_bblock_t *bb); +void scc_cfg_bblock_add_succ(scc_cfg_bblock_t *bb, scc_cfg_bblock_id_t succ_id); +void scc_cfg_bblock_remove_succ(scc_cfg_bblock_t *bb, + scc_cfg_bblock_id_t succ_id); +void scc_cfg_bblock_clear_succs(scc_cfg_bblock_t *bb); + +#endif /* __SCC_CFG_H__ */ diff --git a/libs/ir/cfg/src/scc_cfg.c b/libs/ir/cfg/src/scc_cfg.c new file mode 100644 index 0000000..8c43a9d --- /dev/null +++ b/libs/ir/cfg/src/scc_cfg.c @@ -0,0 +1,81 @@ +#include + +void scc_cfg_module_init(scc_cfg_module_t *module) { + scc_vec_init(module->bblocks); + scc_vec_init(module->funcs); + scc_vec_init(module->symbols); + scc_hashtable_cstr_init(&module->symbol_map); + + // 0 for null + scc_vec_push(module->bblocks, (scc_cfg_bblock_t){0}); + scc_vec_push(module->funcs, (scc_cfg_func_t){0}); + scc_vec_push(module->symbols, (scc_cfg_symbol_t){0}); +} + +void scc_cfg_module_drop(scc_cfg_module_t *module) { + scc_vec_free(module->bblocks); + scc_vec_free(module->funcs); + scc_vec_free(module->symbols); + scc_hashtable_drop(&module->symbol_map); +} + +scc_cfg_func_id_t scc_cfg_module_add_func(scc_cfg_module_t *module, + const scc_cfg_func_t *func) { + scc_cfg_func_id_t id = scc_vec_size(module->funcs); + scc_vec_push(module->funcs, *func); + Assert(id != SCC_CFG_ID_nullptr); + return id; +} + +scc_cfg_func_t *scc_cfg_module_unsafe_get_func(scc_cfg_module_t *module, + scc_cfg_func_id_t id) { + if (id == SCC_CFG_ID_nullptr) { + Panic("nullptr func id"); + } + if (id >= scc_vec_size(module->funcs)) { + Panic("invalid func id"); + } + return &scc_vec_at(module->funcs, id); +} + +scc_cfg_bblock_id_t scc_cfg_module_add_bblock(scc_cfg_module_t *module, + const scc_cfg_bblock_t *bblock) { + scc_cfg_func_id_t id = scc_vec_size(module->bblocks); + scc_vec_push(module->bblocks, *bblock); + Assert(id != SCC_CFG_ID_nullptr); + return id; +} + +scc_cfg_bblock_t *scc_cfg_module_unsafe_get_bblock(scc_cfg_module_t *module, + scc_cfg_bblock_id_t id) { + if (id == SCC_CFG_ID_nullptr) { + Panic("nullptr bblocks id"); + } + if (id >= scc_vec_size(module->bblocks)) { + Panic("invalid bblocks id"); + } + return &scc_vec_at(module->bblocks, id); +} + +void scc_cfg_module_add_symbol(scc_cfg_module_t *module, + const scc_cfg_symbol_t *symbol) {} +scc_cfg_id_t scc_cfg_module_lookup_symbol(const scc_cfg_module_t *module, + const char *name) { + return 0; +} + +void scc_cfg_bblock_add_pred(scc_cfg_bblock_t *bb, + scc_cfg_bblock_id_t pred_id) {} + +void scc_cfg_bblock_remove_pred(scc_cfg_bblock_t *bb, + scc_cfg_bblock_id_t pred_id) {} + +void scc_cfg_bblock_clear_pred(scc_cfg_bblock_t *bb) {} + +void scc_cfg_bblock_add_succ(scc_cfg_bblock_t *bb, + scc_cfg_bblock_id_t succ_id) {} + +void scc_cfg_bblock_remove_succ(scc_cfg_bblock_t *bb, + scc_cfg_bblock_id_t succ_id) {} + +void scc_cfg_bblock_clear_succs(scc_cfg_bblock_t *bb) {} diff --git a/libs/ir/hir/cbuild.toml b/libs/ir/hir/cbuild.toml new file mode 100644 index 0000000..b26f9a4 --- /dev/null +++ b/libs/ir/hir/cbuild.toml @@ -0,0 +1,14 @@ +[package] +name = "scc_hir" +version = "0.1.0" +authors = [] +description = "" + +dependencies = [ + { name = "scc_cfg", path = "../cfg" }, + { name = "scc_utils", path = "../../../runtime/scc_utils" }, + { name = "tree_dump", path = "../../tree_dump" }, +] +# dependencies = [] +# features = {} +# default_features = [] diff --git a/libs/ir/hir/include/hir_builder.h b/libs/ir/hir/include/hir_builder.h new file mode 100644 index 0000000..6bb6e80 --- /dev/null +++ b/libs/ir/hir/include/hir_builder.h @@ -0,0 +1,281 @@ +#ifndef __SCC_HIR_BUILDER_H__ +#define __SCC_HIR_BUILDER_H__ + +#include "hir_prog.h" +#include "scc_hir.h" + +typedef struct scc_hir_builder scc_hir_builder_t; + +/** + * @brief IR 构建器上下文 + * + * 负责管理 IR 构建过程中的所有状态: + * - 类型统一化(type uniquing) + * - 符号命名分配 + * - 内存管理 + * - 当前构建位置(函数、基本块) + */ +struct scc_hir_builder { + scc_hir_cprog_t *cprog; + scc_hir_func_ref_t current_func; ///< 当前正在构建的函数 + scc_hir_bblock_ref_t current_bblock; ///< 当前基本块 + + scc_hashtable_t type_uniquing; // 类型哈希表:hash -> type_ref + scc_hashtable_t const_pool; // 常量哈希表:hash -> node_ref + scc_hashtable_t func_decl_set; // 函数声明集合:name -> func_ref +#ifndef SCC_NO_DEBUG + int borrow_depth; + const char *dbg_file; + int dbg_line; +#endif +}; + +#ifndef SCC_NO_DEBUG +#define SCC_HIR_BUILDER_BEGIN_BORROW(builder, ptr_var, ptr_expr) \ + do { \ + (builder)->borrow_depth++; \ + (builder)->dbg_file = __FILE__; \ + (builder)->dbg_line = __LINE__; \ + ptr_var = (ptr_expr); \ + } while (0) + +#define SCC_HIR_BUILDER_END_BORROW(builder) \ + do { \ + (builder)->borrow_depth--; \ + } while (0) + +#define SCC_HIR_BUILDER_CHECK_NO_BORROW(builder) \ + do { \ + if ((builder)->borrow_depth != 0) { \ + Panic("IR Builder: attempt to reallocate while borrowed at %s:%d", \ + (builder)->dbg_file, (builder)->dbg_line); \ + } \ + } while (0) +#else +#define SCC_HIR_BUILDER_BEGIN_BORROW(builder, ptr_var, ptr_expr) \ + ptr_var = (ptr_expr) +#define SCC_HIR_BUILDER_END_BORROW(builder) ((void)0) +#define SCC_HIR_BUILDER_CHECK_NO_BORROW(builder) ((void)0) +#endif + +/** + * @brief 初始化 IR 构建器 + */ +void scc_hir_builder_init(scc_hir_builder_t *builder, scc_hir_cprog_t *cprog); + +/** + * @brief 销毁 IR 构建器及其所有资源 + */ +void scc_hir_builder_drop(scc_hir_builder_t *builder); + +scc_hir_func_ref_t scc_hir_builder_func(scc_hir_builder_t *builder, + scc_hir_type_ref_t type_ref, + const char *name); + +scc_hir_type_ref_t scc_hir_builder_type(scc_hir_builder_t *builder, + const scc_hir_type_t *type_desc); + +void scc_hir_builder_add_instr(scc_hir_builder_t *builder, + scc_hir_value_ref_t instr); + +scc_hir_value_ref_t scc_hir_builder_global_alloca(scc_hir_builder_t *builder, + scc_hir_type_ref_t type, + scc_hir_value_ref_t value); + +/** + * @brief 创建alloca指令(在当前基本块中) + * @param type 分配的类型 + * @param name 变量名(可为nullptr) + */ +scc_hir_value_ref_t scc_hir_builder_alloca(scc_hir_builder_t *builder, + scc_hir_type_ref_t type, + const char *name); + +#define SCC_HIR_BUILDER_TYPE_FUNC(scc_type) \ + [[maybe_unused]] static inline scc_hir_type_ref_t \ + scc_hir_builder_type_##scc_type(scc_hir_builder_t *builder) { \ + scc_hir_type_t type_desc; \ + scc_hir_type_init(&type_desc, SCC_HIR_TYPE_##scc_type); \ + return scc_hir_builder_type(builder, &type_desc); \ + } + +SCC_HIR_BUILDER_TYPE_FUNC(unknown) +SCC_HIR_BUILDER_TYPE_FUNC(void) +SCC_HIR_BUILDER_TYPE_FUNC(i8) +SCC_HIR_BUILDER_TYPE_FUNC(i16) +SCC_HIR_BUILDER_TYPE_FUNC(i32) +SCC_HIR_BUILDER_TYPE_FUNC(i64) +SCC_HIR_BUILDER_TYPE_FUNC(i128) +SCC_HIR_BUILDER_TYPE_FUNC(u8) +SCC_HIR_BUILDER_TYPE_FUNC(u16) +SCC_HIR_BUILDER_TYPE_FUNC(u32) +SCC_HIR_BUILDER_TYPE_FUNC(u64) +SCC_HIR_BUILDER_TYPE_FUNC(u128) +// SCC_HIR_BUILDER_TYPE_FUNC(f8) +SCC_HIR_BUILDER_TYPE_FUNC(f16) +SCC_HIR_BUILDER_TYPE_FUNC(f32) +SCC_HIR_BUILDER_TYPE_FUNC(f64) +SCC_HIR_BUILDER_TYPE_FUNC(f128) + +scc_hir_value_ref_t scc_hir_builder_builtin_memcpy(scc_hir_builder_t *builder, + scc_hir_value_ref_t dest, + scc_hir_value_ref_t src, + scc_hir_value_ref_t len); + +// TODO +static inline scc_hir_value_ref_t +scc_hir_builder_integer(scc_hir_builder_t *builder, scc_hir_type_ref_t type, + scc_ap_t *val) { + scc_hir_value_t value; + scc_hir_value_init(&value, nullptr, SCC_HIR_VALUE_TAG_INTEGER); + // FIXME assign + value.data.integer = *val; + value.type = type; + return scc_hir_module_add_value(&builder->cprog->module, &value); +} + +scc_hir_value_ref_t scc_hir_builder_const_string(scc_hir_builder_t *builder, + const char *str, usize len); + +/** + * @brief 开始构建函数 + * @param func_ref 函数引用 + * @param param_names 参数名列表(可为nullptr) + * @return void + */ +void scc_hir_builder_begin_func(scc_hir_builder_t *builder, + scc_hir_func_ref_t func_ref); + +/** + * @brief 结束当前函数的构建 + */ +void scc_hir_builder_end_func(scc_hir_builder_t *builder); + +/** + * @brief 获取当前正在构建的函数 + */ +scc_hir_func_ref_t scc_hir_builder_current_func(scc_hir_builder_t *builder); + +/** + * @brief 创建一个新的基本块,并自动添加到当前函数中,但不改变当前块。 + * @param builder IR构建器 + * @param label 基本块标签(可为 nullptr,自动生成) + * @return 新基本块的引用 + */ +scc_hir_bblock_ref_t scc_hir_builder_bblock(scc_hir_builder_t *builder, + const char *label); + +/** + * @brief 开始构建新的基本块 + * @param label 基本块标签(可为nullptr,自动生成) + * @return 基本块引用 + */ +scc_hir_bblock_ref_t scc_hir_builder_begin_bblock(scc_hir_builder_t *builder, + const char *label); + +/** + * @brief 结束当前基本块的构建 + */ +void scc_hir_builder_end_bblock(scc_hir_builder_t *builder); + +scc_hir_func_ref_t scc_hir_builder_current_bblock(scc_hir_builder_t *builder); +/** + * @brief 设置当前基本块 + */ +void scc_hir_builder_set_current_bblock(scc_hir_builder_t *builder, + scc_hir_bblock_ref_t bblock); + +scc_hir_value_ref_t scc_hir_builder_func_arg_ref(scc_hir_builder_t *builder, + scc_hir_type_ref_t type, + const char *name, + usize arg_idx); + +/** + * @brief 创建load指令 + * @param ptr 指针操作数 + */ +scc_hir_value_ref_t scc_hir_builder_load(scc_hir_builder_t *builder, + scc_hir_value_ref_t ptr); + +/** + * @brief 创建store指令 + * @param ptr 目标指针 + * @param value 要存储的值 + */ +scc_hir_value_ref_t scc_hir_builder_store(scc_hir_builder_t *builder, + scc_hir_value_ref_t ptr, + scc_hir_value_ref_t value); + +/** + * @brief 创建getptr指令(指针运算) + * @param ptr 基础指针 + * @param index 索引值 + */ +scc_hir_value_ref_t scc_hir_builder_get_elem_ptr(scc_hir_builder_t *builder, + scc_hir_value_ref_t ptr, + scc_hir_value_ref_t index); + +/** + * @brief 创建二元运算指令 + * @param op 操作符 + * @param lhs 左操作数 + * @param rhs 右操作数 + */ +scc_hir_value_ref_t scc_hir_builder_binop(scc_hir_builder_t *builder, + scc_hir_op_type_t op, + scc_hir_value_ref_t lhs, + scc_hir_value_ref_t rhs); + +/** + * @brief 创建比较指令 + * @param op 比较操作符 + * @param lhs 左操作数 + * @param rhs 右操作数 + */ +scc_hir_value_ref_t scc_hir_builder_cmp(scc_hir_builder_t *builder, + scc_hir_op_type_t op, + scc_hir_value_ref_t lhs, + scc_hir_value_ref_t rhs); + +/** + * @brief 创建跳转指令(无条件) + * @param target 目标基本块 + */ +scc_hir_value_ref_t scc_hir_builder_jump(scc_hir_builder_t *builder, + scc_hir_bblock_ref_t target); + +/** + * @brief 创建条件分支指令 + * @param cond 条件值 + * @param true_target 条件为真时的目标 + * @param false_target 条件为假时的目标 + */ +scc_hir_value_ref_t scc_hir_builder_branch(scc_hir_builder_t *builder, + scc_hir_value_ref_t cond, + scc_hir_bblock_ref_t true_target, + scc_hir_bblock_ref_t false_target); + +/** + * @brief 创建函数调用指令 + * @param callee 被调用函数 + * @param args 参数列表 + * @param arg_count 参数数量 + */ +scc_hir_value_ref_t scc_hir_builder_call(scc_hir_builder_t *builder, + scc_hir_func_ref_t callee, + const scc_hir_value_ref_t *args, + usize arg_count); + +/** + * @brief 创建返回指令(带返回值) + * @param value 返回值 + */ +scc_hir_value_ref_t scc_hir_builder_ret(scc_hir_builder_t *builder, + scc_hir_value_ref_t value); + +/** + * @brief 创建返回指令(void返回) + */ +scc_hir_value_ref_t scc_hir_builder_ret_void(scc_hir_builder_t *builder); + +#endif /* __SCC_HIR_BUILDER_H__ */ diff --git a/libs/ir/hir/include/hir_def.h b/libs/ir/hir/include/hir_def.h new file mode 100644 index 0000000..3d419ed --- /dev/null +++ b/libs/ir/hir/include/hir_def.h @@ -0,0 +1,255 @@ +#ifndef __SCC_HIR_DEF_H__ +#define __SCC_HIR_DEF_H__ + +#include +#include +#include + +#define SCC_HIR_REF_nullptr SCC_CFG_ID_nullptr + +typedef SCC_VEC(u8) scc_hir_buffer_t; + +typedef scc_cfg_bblock_t scc_hir_bblock_t; +typedef scc_cfg_bblock_id_t scc_hir_bblock_ref_t; +typedef SCC_VEC(scc_hir_bblock_ref_t) scc_hir_bblock_ref_vec_t; + +typedef scc_cfg_func_t scc_hir_func_t; +typedef scc_cfg_func_id_t scc_hir_func_ref_t; +typedef SCC_VEC(scc_hir_func_ref_t) scc_hir_func_ref_vec_t; + +typedef struct scc_hir_value scc_hir_value_t; +typedef scc_cfg_id_t scc_hir_value_ref_t; +typedef SCC_VEC(scc_hir_value_ref_t) scc_hir_value_ref_vec_t; + +typedef struct scc_hir_type scc_hir_type_t; +typedef scc_cfg_id_t scc_hir_type_ref_t; +typedef SCC_VEC(scc_hir_type_ref_t) scc_hir_type_ref_vec_t; + +typedef enum scc_hir_type_tag { + SCC_HIR_TYPE_unknown, + SCC_HIR_TYPE_void, + SCC_HIR_TYPE_i8, + SCC_HIR_TYPE_i16, + SCC_HIR_TYPE_i32, + SCC_HIR_TYPE_i64, + SCC_HIR_TYPE_i128, + SCC_HIR_TYPE_u8, + SCC_HIR_TYPE_u16, + SCC_HIR_TYPE_u32, + SCC_HIR_TYPE_u64, + SCC_HIR_TYPE_u128, + SCC_HIR_TYPE_f16, + SCC_HIR_TYPE_f32, + SCC_HIR_TYPE_f64, + SCC_HIR_TYPE_f128, + SCC_HIR_TYPE_PTR, + SCC_HIR_TYPE_ARRAY, + SCC_HIR_TYPE_FUNC, + SCC_HIR_TYPE_STRUCT, + SCC_HIR_TYPE_UNION, + SCC_HIR_TYPE_VECTOR, // TODO SIMD +} scc_hir_type_tag_t; + +struct scc_hir_type { + scc_hir_type_tag_t tag; + const char *name; // For Debug + union { + struct { + scc_hir_type_ref_t base; + usize len; // TODO usize is target dependent + } array; + struct { + scc_hir_type_ref_t base; + } pointer; + struct { + scc_hir_type_ref_vec_t fields; + } aggregate; + struct { + scc_hir_type_ref_vec_t params; + scc_hir_type_ref_t ret_type; + } function; + } data; +}; + +typedef enum scc_hir_value_tag { + SCC_HIR_VALUE_TAG_NULLPTR, + SCC_HIR_VALUE_TAG_BUILTIN, + SCC_HIR_VALUE_TAG_INTEGER, + SCC_HIR_VALUE_TAG_DECIMAL, + SCC_HIR_VALUE_TAG_ARRAY, + SCC_HIR_VALUE_TAG_AGGREGATE, ///< 聚合值 + SCC_HIR_VALUE_TAG_CONV, ///< 类型转换 + SCC_HIR_VALUE_TAG_FUNC_ARG_REF, ///< 函数参数引用 + SCC_HIR_VALUE_TAG_BLOCK_ARG_REF, ///< 基本块参数引用 + SCC_HIR_VALUE_TAG_ALLOC, ///< 分配内存 + SCC_HIR_VALUE_TAG_GLOBAL_ALLOC, ///< 全局分配 + SCC_HIR_VALUE_TAG_LOAD, ///< 加载数据 + SCC_HIR_VALUE_TAG_STORE, ///< 存储数据 + SCC_HIR_VALUE_TAG_GET_ELEM_PTR, ///< 获取元素指针 + SCC_HIR_VALUE_TAG_OP, ///< 二元运算 + SCC_HIR_VALUE_TAG_BRANCH, ///< 有条件分支 + SCC_HIR_VALUE_TAG_JUMP, ///< 无条件跳转 + SCC_HIR_VALUE_TAG_CALL, ///< 调用函数 + SCC_HIR_VALUE_TAG_RET, ///< 函数返回 +} scc_hir_value_tag_t; + +typedef enum { + /// Empty op for init or nop + SCC_HIR_OP_EMPTY, + /// Not equal to. + SCC_HIR_OP_NEQ, + /// Equal to. + SCC_HIR_OP_EQ, + /// Greater than. + SCC_HIR_OP_GT, + /// Less than. + SCC_HIR_OP_LT, + /// Greater than or equal to. + SCC_HIR_OP_GE, + /// Less than or equal to. + SCC_HIR_OP_LE, + /// Addition. + SCC_HIR_OP_ADD, + /// Subtraction. + SCC_HIR_OP_SUB, + /// Multiplication. + SCC_HIR_OP_MUL, + /// Division. + SCC_HIR_OP_DIV, + /// Modulo. + SCC_HIR_OP_MOD, + /// Bitwise AND. + SCC_HIR_OP_AND, + /// Bitwise OR. + SCC_HIR_OP_OR, + /// Bitwise XOR. + SCC_HIR_OP_XOR, + /// Bitwise NOT. + SCC_HIR_OP_NOT, + /// Shift left logical. + SCC_HIR_OP_SHL, + /// Shift right logical. + SCC_HIR_OP_SHR, + /// Shift right arithmetic. + SCC_HIR_OP_SAR, +} scc_hir_op_type_t; + +typedef enum { + SCC_HIR_BUILTIN_TAG_MEMCPY, + SCC_HIR_BUILTIN_TAG_MEMSET, + SCC_HIR_BUILTIN_TAG_VA_START, + SCC_HIR_BUILTIN_TAG_VA_ARG, + SCC_HIR_BUILTIN_TAG_VA_END, + SCC_HIR_BUILTIN_TAG_VA_COPY, +} scc_hir_builtin_tag_t; + +typedef struct { + scc_hir_builtin_tag_t tag; + union { + struct { + scc_hir_value_ref_t dest; + scc_hir_value_ref_t src; + scc_hir_value_ref_t size; + } memcpy; + struct { + scc_hir_value_ref_t dest; + scc_hir_value_ref_t value; + scc_hir_value_ref_t size; + } memset; + struct { + scc_hir_value_ref_t ap; // va_list 的地址(i8* 或 struct*) + scc_hir_value_ref_t last; // 最后一个固定参数的引用(用于 va_start) + } va_start; + struct { + scc_hir_value_ref_t ap; // va_list 的地址 + scc_hir_type_ref_t type; // 要提取的参数的类型 + } va_arg; + struct { + scc_hir_value_ref_t ap; // va_list 的地址 + } va_end; + struct { + scc_hir_value_ref_t dest; // 目标 va_list 地址 + scc_hir_value_ref_t src; // 源 va_list 地址 + } va_copy; + } func; +} scc_hir_builtin_t; + +struct scc_hir_value { + scc_hir_type_ref_t type; + const char *name; + scc_hir_value_ref_vec_t used_by; + scc_hir_value_tag_t tag; + union { + scc_hir_builtin_t builtin; + scc_ap_t integer; + void *decimal; + struct { + scc_hir_value_ref_t base_type; + scc_hir_buffer_t fields; + } const_array; + struct { + scc_hir_value_ref_vec_t fields; + } aggregate; + struct { + usize idx; + } arg_ref; + struct { + scc_hir_value_ref_t value; + } global_alloc; + struct { + scc_hir_value_ref_t operand; + scc_hir_type_ref_t target_type; // 目标类型 + enum { CONV_SEXT, CONV_ZEXT, CONV_TRUNC } conv_type; + } conv; + struct { + scc_hir_value_ref_t target; + } load; + struct { + scc_hir_value_ref_t target; + scc_hir_value_ref_t value; + } store; + struct { + scc_hir_value_ref_t src_addr; + scc_hir_value_ref_t index; + } get_elem_ptr; + struct { + scc_hir_op_type_t op; + scc_hir_value_ref_t lhs; + scc_hir_value_ref_t rhs; + } op; + struct { + scc_hir_value_ref_t cond; + scc_hir_bblock_ref_t true_bblock; + scc_hir_bblock_ref_t false_bblock; + } branch; + struct { + scc_hir_bblock_ref_t target_bblock; + } jump; + struct { + scc_hir_func_ref_t callee; // TODO function pointer call + scc_hir_value_ref_vec_t args; + } call; + struct { + scc_hir_value_ref_t ret_val; + } ret; + } data; +}; + +typedef struct scc_hir_bblock_meta { + // scc_hir_value_ref_vec_t instrs; + // ir_arr_t used_by; +} scc_hir_bblock_meta_t; + +typedef struct scc_hir_func_meta { + scc_hir_type_ref_t type; + scc_hir_value_ref_vec_t params; +} scc_hir_func_meta_t; + +#define SCC_HIR_BBLOCK_VALUES(bblock) \ + (*(scc_hir_value_ref_vec_t *)&((bblock).values)) + +#define SCC_HIR_BBLOCK_META(bblock) \ + ((scc_hir_bblock_meta_t *)((bblock).attribute)) +#define SCC_HIR_FUNC_META(func) ((scc_hir_func_meta_t *)((func).attribute)) + +#endif /* __SCC_HIR_DEF_H__ */ diff --git a/libs/ir/hir/include/hir_dump.h b/libs/ir/hir/include/hir_dump.h new file mode 100644 index 0000000..187f24c --- /dev/null +++ b/libs/ir/hir/include/hir_dump.h @@ -0,0 +1,21 @@ +#ifndef __SCC_HIR_DUMP_H__ +#define __SCC_HIR_DUMP_H__ + +#include "hir_prog.h" +#include + +typedef struct { + scc_hir_cprog_t *cprog; + scc_tree_dump_t *dump_ctx; +} scc_hir_dump_t; + +void scc_hir_dump_ctx_init(scc_hir_dump_t *ctx, scc_tree_dump_t *tree_dump, + scc_hir_cprog_t *cprog); +void scc_hir_dump_value(scc_hir_dump_t *ctx, scc_hir_value_ref_t node_ref); +void scc_hir_dump_type(scc_hir_dump_t *ctx, scc_hir_type_ref_t type_ref); +void scc_hir_dump_bblock(scc_hir_dump_t *ctx, scc_hir_bblock_ref_t bblock_ref); +void scc_hir_dump_func(scc_hir_dump_t *ctx, scc_hir_func_ref_t func_ref); +void scc_hir_dump_cprog(scc_hir_dump_t *ctx); +void scc_hir_dump_cprog_linear(scc_hir_dump_t *ctx); + +#endif /* __SCC_HIR_DUMP_H__ */ diff --git a/libs/ir/hir/include/hir_module.h b/libs/ir/hir/include/hir_module.h new file mode 100644 index 0000000..7353fb7 --- /dev/null +++ b/libs/ir/hir/include/hir_module.h @@ -0,0 +1,50 @@ +#ifndef __SCC_HIR_MODULE_H__ +#define __SCC_HIR_MODULE_H__ + +#include "hir_def.h" +#include +#include + +typedef struct { + scc_cfg_module_t cfg_module; + + scc_cfg_id_t value_uid; + scc_cfg_id_t type_uid; + SCC_VEC(scc_hir_value_t) values; + SCC_VEC(scc_hir_type_t) types; + // UID -> ref index + scc_hashtable_t uid2value; + scc_hashtable_t uid2type; + + SCC_VEC(scc_hir_bblock_meta_t *) bblock_meta; + SCC_VEC(scc_hir_func_meta_t *) funcs_meta; +} scc_hir_module_t; + +void scc_hir_module_init(scc_hir_module_t *ctx); +void scc_hir_module_drop(scc_hir_module_t *ctx); +scc_hir_type_ref_t scc_hir_module_add_type(scc_hir_module_t *ctx, + const scc_hir_type_t *type); +scc_hir_value_ref_t scc_hir_module_add_value(scc_hir_module_t *ctx, + const scc_hir_value_t *node); +scc_hir_bblock_ref_t scc_hir_module_add_bblock(scc_hir_module_t *ctx, + const scc_hir_bblock_t *bblock); +scc_hir_func_ref_t scc_hir_module_add_func(scc_hir_module_t *ctx, + const scc_hir_func_t *func); +scc_hir_type_t *scc_hir_module_get_type(scc_hir_module_t *ctx, + scc_hir_type_ref_t ref); +scc_hir_value_t *scc_hir_module_get_value(scc_hir_module_t *ctx, + scc_hir_value_ref_t ref); +scc_hir_bblock_t *scc_hir_module_get_bblock(scc_hir_module_t *ctx, + scc_hir_bblock_ref_t ref); +scc_hir_func_t *scc_hir_module_get_func(scc_hir_module_t *ctx, + scc_hir_func_ref_t ref); + +static inline scc_hir_type_t * +scc_hir_module_get_type_by_value(scc_hir_module_t *ctx, + scc_hir_value_ref_t ref) { + scc_hir_value_t *value = scc_hir_module_get_value(ctx, ref); + Assert(value != nullptr); + return scc_hir_module_get_type(ctx, value->type); +} + +#endif /* __SCC_HIR_MODULE_H__ */ diff --git a/libs/ir/hir/include/hir_prog.h b/libs/ir/hir/include/hir_prog.h new file mode 100644 index 0000000..9edfebf --- /dev/null +++ b/libs/ir/hir/include/hir_prog.h @@ -0,0 +1,17 @@ +#ifndef __SCC_HIR_PROG_H__ +#define __SCC_HIR_PROG_H__ + +#include "hir_def.h" +#include "hir_module.h" + +typedef struct scc_hir_cprog { + scc_hir_module_t module; + scc_hir_value_ref_vec_t global_vals; /* 全局变量 */ + scc_hir_func_ref_vec_t func_defs; /* 所有函数定义 */ + scc_hir_func_ref_vec_t func_decls; /* 所有函数包括定义的声明 */ +} scc_hir_cprog_t; + +void scc_hir_cprog_init(scc_hir_cprog_t *in); +void scc_hir_cprog_drop(scc_hir_cprog_t *in); + +#endif /* __SCC_HIR_PROG_H__ */ diff --git a/libs/ir/hir/include/scc_hir.h b/libs/ir/hir/include/scc_hir.h new file mode 100644 index 0000000..361d824 --- /dev/null +++ b/libs/ir/hir/include/scc_hir.h @@ -0,0 +1,14 @@ +#ifndef __SCC_HIR_H__ +#define __SCC_HIR_H__ + +#include "hir_def.h" +#include "hir_prog.h" + +void scc_hir_type_init(scc_hir_type_t *in, scc_hir_type_tag_t tag); +void scc_hir_bblock_init(scc_hir_bblock_t *in, const char *label); +void scc_hir_func_init(scc_hir_func_t *in, const char *name); +// node name can be nullptr ptr +void scc_hir_value_init(scc_hir_value_t *in, const char *name, + scc_hir_value_tag_t tag); + +#endif /* __SCC_HIR_H__ */ diff --git a/libs/ir/hir/src/hir_builder.c b/libs/ir/hir/src/hir_builder.c new file mode 100644 index 0000000..eba1ef1 --- /dev/null +++ b/libs/ir/hir/src/hir_builder.c @@ -0,0 +1,691 @@ +#include +#include +#include + +#define GET_MODULE(builder) (&(builder->cprog->module)) + +/** + * @brief 哈希混合函数(类似Rust的hash combine) + * + * Rust的默认哈希实现(SipHash 1-3)使用旋转和异或, + * 这里使用简单的FNV-1a变体,类似于Rust的`#[derive(Hash)]` + */ +static inline u32 scc_hash_mix(u32 seed, u32 value) { + // FNV-1a风格混合 + return (seed ^ value) * 16777619u; +} + +static u32 hash_type(const void *_key, void *userdata) { + scc_hir_module_t *module = userdata; + const scc_hir_type_t *key = + _key == SCC_HIR_REF_nullptr + ? &scc_vec_at(module->types, 0) + : scc_hir_module_get_type(module, (usize)_key); + // 初始哈希:tag + u32 hash = (u32)key->tag; + + switch (key->tag) { + case SCC_HIR_TYPE_void: + case SCC_HIR_TYPE_u8: + case SCC_HIR_TYPE_u16: + case SCC_HIR_TYPE_u32: + case SCC_HIR_TYPE_u64: + case SCC_HIR_TYPE_u128: + case SCC_HIR_TYPE_i8: + case SCC_HIR_TYPE_i16: + case SCC_HIR_TYPE_i32: + case SCC_HIR_TYPE_i64: + case SCC_HIR_TYPE_i128: + case SCC_HIR_TYPE_f16: + case SCC_HIR_TYPE_f32: + case SCC_HIR_TYPE_f64: + case SCC_HIR_TYPE_f128: + // 基本类型,只有tag + break; + + case SCC_HIR_TYPE_PTR: + hash = scc_hash_mix(hash, (u32)key->data.array.base); + break; + + case SCC_HIR_TYPE_ARRAY: + hash = scc_hash_mix(hash, (u32)key->data.array.base); + hash = scc_hash_mix(hash, (u32)key->data.array.len); + break; + + case SCC_HIR_TYPE_FUNC: + // 注意:这里需要递归哈希参数类型 + hash = scc_hash_mix(hash, (u32)key->data.function.ret_type); + for (usize i = 0; i < key->data.function.params.size; i++) { + hash = scc_hash_mix(hash, (u32)key->data.function.params.data[i]); + } + hash = scc_hash_mix(hash, (u32)key->data.function.params.size); + break; + + case SCC_HIR_TYPE_STRUCT: + case SCC_HIR_TYPE_UNION: + return 0; + case SCC_HIR_TYPE_VECTOR: + default: + Panic("Invalid type tag %d", key->tag); + return 0; + } + + return hash; +} + +static int cmp_type(const void *_key1, const void *_key2, void *userdata) { + scc_hir_module_t *module = userdata; + const scc_hir_type_t *key1 = _key1 == SCC_HIR_REF_nullptr + ? &scc_vec_at(module->types, 0) + : scc_hir_module_get_type(module, + (usize)_key1), + *key2 = _key2 == SCC_HIR_REF_nullptr + ? &scc_vec_at(module->types, 0) + : scc_hir_module_get_type(module, + (usize)_key2); + Assert(key1 != nullptr && key2 != nullptr); + if (key1->tag == SCC_HIR_TYPE_unknown || + key2->tag == SCC_HIR_TYPE_unknown) { + return 1; + } + // tag不同 + if (key1->tag != key2->tag) { + return 1; + } + + switch (key1->tag) { + case SCC_HIR_TYPE_void: + case SCC_HIR_TYPE_u8: + case SCC_HIR_TYPE_u16: + case SCC_HIR_TYPE_u32: + case SCC_HIR_TYPE_u64: + case SCC_HIR_TYPE_u128: + case SCC_HIR_TYPE_i8: + case SCC_HIR_TYPE_i16: + case SCC_HIR_TYPE_i32: + case SCC_HIR_TYPE_i64: + case SCC_HIR_TYPE_i128: + case SCC_HIR_TYPE_f16: + case SCC_HIR_TYPE_f32: + case SCC_HIR_TYPE_f64: + case SCC_HIR_TYPE_f128: + return 0; // 基本类型,tag相同即可 + case SCC_HIR_TYPE_PTR: + return key1->data.pointer.base != key2->data.pointer.base; + case SCC_HIR_TYPE_ARRAY: + return (key1->data.array.base != key2->data.array.base) || + (key1->data.array.len != key2->data.array.len); + case SCC_HIR_TYPE_FUNC: { + if (key1->data.function.ret_type != key2->data.function.ret_type) { + return 1; + } + if (key1->data.function.params.size != + key2->data.function.params.size) { + return 1; + } + for (usize i = 0; i < key1->data.function.params.size; i++) { + if (key1->data.function.params.data[i] != + key2->data.function.params.data[i]) { + return 1; + } + } + return 0; + } + default: + Panic("Unknown key type %d", key1->tag); + return 1; + } + return 1; +} + +void scc_hir_builder_init(scc_hir_builder_t *builder, scc_hir_cprog_t *cprog) { + builder->current_bblock = SCC_HIR_REF_nullptr; + builder->current_func = SCC_HIR_REF_nullptr; + builder->cprog = cprog; + + scc_hashtable_init(&builder->type_uniquing, hash_type, cmp_type, + GET_MODULE(builder)); + // scc_hashtable_init(&builder->const_pool, /* 常量哈希函数 */, + // /* 常量比较函数 */); + scc_hashtable_cstr_init(&builder->func_decl_set); +#ifndef SCC_NO_DEBUG + builder->borrow_depth = 0; + builder->dbg_file = nullptr; + builder->dbg_line = 0; +#endif +} + +void scc_hir_builder_drop(scc_hir_builder_t *builder) { + scc_hashtable_drop(&builder->type_uniquing); + // scc_hashtable_drop(&builder->const_pool); + scc_hashtable_drop(&builder->func_decl_set); +} + +scc_hir_func_ref_t scc_hir_builder_func(scc_hir_builder_t *builder, + scc_hir_type_ref_t type_ref, + const char *name) { + SCC_HIR_BUILDER_CHECK_NO_BORROW(builder); + // 检查是否已声明 + void *found = scc_hashtable_get(&builder->func_decl_set, (void *)name); + if (found) { + return (scc_hir_func_ref_t)(usize)found; + } + + // 创建新函数 + scc_hir_func_t func; + scc_hir_func_meta_t *meta = scc_malloc(sizeof(scc_hir_func_meta_t)); + Assert(meta != nullptr); + func.attribute = meta; + scc_hir_func_init(&func, name); + meta->type = type_ref; + + scc_hir_func_ref_t func_ref = + scc_hir_module_add_func(GET_MODULE(builder), &func); + scc_hashtable_set(&builder->func_decl_set, (void *)name, + (void *)(usize)func_ref); + + scc_vec_push(builder->cprog->func_decls, func_ref); + return func_ref; +} + +scc_hir_bblock_ref_t scc_hir_builder_bblock(scc_hir_builder_t *builder, + const char *label) { + SCC_HIR_BUILDER_CHECK_NO_BORROW(builder); + scc_hir_bblock_t bblock = {0}; + if (label) { + bblock.name = label; + } + // scc_hir_bblock_meta_t bblock_meta = {0}; + // FIXME 当前没有bblock meta + bblock.attribute = nullptr; + scc_vec_init(SCC_HIR_BBLOCK_VALUES(bblock)); + + scc_hir_bblock_ref_t bblock_ref = + scc_hir_module_add_bblock(GET_MODULE(builder), &bblock); + + // 将基本块添加到当前函数 + scc_hir_func_t *current_func = nullptr; + SCC_HIR_BUILDER_BEGIN_BORROW( + builder, current_func, + scc_hir_module_get_func(GET_MODULE(builder), builder->current_func)); + if (current_func) { + // FIXME hack cfg + scc_vec_push(current_func->bblocks, bblock_ref); + } + SCC_HIR_BUILDER_END_BORROW(builder); + return bblock_ref; +} + +scc_hir_type_ref_t scc_hir_builder_type(scc_hir_builder_t *builder, + const scc_hir_type_t *type_desc) { + SCC_HIR_BUILDER_CHECK_NO_BORROW(builder); + + Assert(type_desc->tag != SCC_HIR_TYPE_unknown); + + scc_vec_at(GET_MODULE(builder)->types, 0) = *type_desc; + // 先查哈希表 + void *found = scc_hashtable_get(&builder->type_uniquing, (void *)(usize)0); + if (found) { + return (scc_hir_type_ref_t)(usize)found; + } + + // 不存在,添加新类型 + scc_hir_type_ref_t new_ref = + scc_hir_module_add_type(GET_MODULE(builder), type_desc); + scc_hashtable_set(&builder->type_uniquing, (void *)(usize)new_ref, + (void *)(usize)new_ref); + return new_ref; +} + +scc_hir_value_ref_t scc_hir_builder_const_string(scc_hir_builder_t *builder, + const char *str, usize len) { + SCC_HIR_BUILDER_CHECK_NO_BORROW(builder); + scc_hir_type_ref_t u8_type = scc_hir_builder_type_u8(builder); + scc_hir_type_t array_type = { + .tag = SCC_HIR_TYPE_ARRAY, + .data.array.base = u8_type, + .data.array.len = len - 1, // 包含 nullptr 结尾 + }; + scc_hir_type_ref_t array_type_ref = + scc_hir_builder_type(builder, &array_type); + + // 5. 创建聚合节点 + scc_hir_value_t const_array_value = { + .tag = SCC_HIR_VALUE_TAG_ARRAY, + .type = array_type_ref, + .data.const_array.base_type = u8_type, + }; + char *buff = scc_malloc(len - 1); + Assert(buff); + // FIXME content to real string + for (usize i = 1; i < len - 1; i++) { + buff[i - 1] = str[i]; + } + buff[len - 2] = '\0'; + scc_vec_unsafe_from_buffer(const_array_value.data.const_array.fields, + (u8 *)buff, len - 1); + scc_hir_value_ref_t const_array_ref = + scc_hir_module_add_value(GET_MODULE(builder), &const_array_value); + Assert(const_array_ref != SCC_HIR_REF_nullptr); + + // 3. 创建全局变量节点,类型为指针,初始值指向常量数组 + scc_hir_value_ref_t global_value_ref = + scc_hir_builder_global_alloca(builder, array_type_ref, const_array_ref); + // scc_hashtable_insert(builder); + + scc_hir_value_ref_t pointer_to_global_value = scc_hir_module_add_value( + GET_MODULE(builder), + &(scc_hir_value_t){ + .tag = SCC_HIR_VALUE_TAG_GET_ELEM_PTR, + .data.get_elem_ptr.src_addr = global_value_ref, + .data.get_elem_ptr.index = SCC_HIR_VALUE_TAG_NULLPTR, + }); + scc_hir_builder_add_instr(builder, pointer_to_global_value); + return pointer_to_global_value; +} + +void scc_hir_builder_begin_func(scc_hir_builder_t *builder, + scc_hir_func_ref_t func_ref) { + SCC_HIR_BUILDER_CHECK_NO_BORROW(builder); + builder->current_func = func_ref; + + // 借用 func_ptr 和 func_type 以获取参数类型列表 + scc_hir_func_t *func_ptr = nullptr; + scc_hir_type_t *func_type = nullptr; + SCC_HIR_BUILDER_BEGIN_BORROW( + builder, func_ptr, + scc_hir_module_get_func(GET_MODULE(builder), func_ref)); + SCC_HIR_BUILDER_BEGIN_BORROW( + builder, func_type, + scc_hir_module_get_type(GET_MODULE(builder), + SCC_HIR_FUNC_META(*func_ptr)->type)); + + if (func_type == nullptr || func_type->tag != SCC_HIR_TYPE_FUNC) { + LOG_ERROR("Invalid function type"); + SCC_HIR_BUILDER_END_BORROW(builder); // func_type + SCC_HIR_BUILDER_END_BORROW(builder); // func_ptr + return; + } + if (func_ptr == nullptr) { + LOG_ERROR("Invalid function reference"); + SCC_HIR_BUILDER_END_BORROW(builder); // func_type + SCC_HIR_BUILDER_END_BORROW(builder); // func_ptr + return; + } + if (scc_vec_size(func_ptr->bblocks) != 0 || + scc_vec_size(SCC_HIR_FUNC_META(*func_ptr)->params) != 0) { + LOG_FATAL("Multiple function definitions"); + SCC_HIR_BUILDER_END_BORROW(builder); // func_type + SCC_HIR_BUILDER_END_BORROW(builder); // func_ptr + return; + } + + // 释放借用,因为下面要调用 add_value(可能 realloc) + SCC_HIR_BUILDER_END_BORROW(builder); // func_type + SCC_HIR_BUILDER_END_BORROW(builder); // func_ptr +} + +void scc_hir_builder_end_func(scc_hir_builder_t *builder) { + SCC_HIR_BUILDER_CHECK_NO_BORROW(builder); + scc_hir_func_t *func_ptr = nullptr; + SCC_HIR_BUILDER_BEGIN_BORROW( + builder, func_ptr, + scc_hir_module_get_func(GET_MODULE(builder), builder->current_func)); + if (func_ptr == nullptr) { + LOG_FATAL("Invalid function reference"); + SCC_HIR_BUILDER_END_BORROW(builder); + return; + } + if (scc_vec_size(func_ptr->bblocks) == 0) { + scc_vec_push(builder->cprog->func_decls, builder->current_func); + } else { + scc_vec_push(builder->cprog->func_defs, builder->current_func); + } + SCC_HIR_BUILDER_END_BORROW(builder); + builder->current_func = 0; +} + +scc_hir_func_ref_t scc_hir_builder_current_func(scc_hir_builder_t *builder) { + // 只读操作,无需检查借用 + return builder->current_func; +} + +scc_hir_bblock_ref_t scc_hir_builder_begin_bblock(scc_hir_builder_t *builder, + const char *label) { + SCC_HIR_BUILDER_CHECK_NO_BORROW(builder); + builder->current_bblock = scc_hir_builder_bblock(builder, label); + return builder->current_bblock; +} + +void scc_hir_builder_end_bblock(scc_hir_builder_t *builder) { + SCC_HIR_BUILDER_CHECK_NO_BORROW(builder); + builder->current_bblock = 0; +} + +void scc_hir_builder_set_current_bblock(scc_hir_builder_t *builder, + scc_hir_bblock_ref_t bblock) { + SCC_HIR_BUILDER_CHECK_NO_BORROW(builder); + builder->current_bblock = bblock; +} + +scc_hir_func_ref_t scc_hir_builder_current_bblock(scc_hir_builder_t *builder) { + return builder->current_bblock; +} + +void scc_hir_builder_add_instr(scc_hir_builder_t *builder, + scc_hir_value_ref_t instr) { + SCC_HIR_BUILDER_CHECK_NO_BORROW(builder); + scc_hir_bblock_t *current_bblock = nullptr; + SCC_HIR_BUILDER_BEGIN_BORROW( + builder, current_bblock, + scc_hir_module_get_bblock(GET_MODULE(builder), + builder->current_bblock)); + if (current_bblock) { + scc_vec_push(SCC_HIR_BBLOCK_VALUES(*current_bblock), instr); + } else { + LOG_ERROR("Current basic block is not set"); + } + SCC_HIR_BUILDER_END_BORROW(builder); +} + +scc_hir_value_ref_t scc_hir_builder_global_alloca(scc_hir_builder_t *builder, + scc_hir_type_ref_t type, + scc_hir_value_ref_t value) { + SCC_HIR_BUILDER_CHECK_NO_BORROW(builder); + char *name = scc_malloc(32); + scc_hir_value_ref_t global_value_ref = scc_hir_module_add_value( + GET_MODULE(builder), &(scc_hir_value_t){ + .name = name, + .tag = SCC_HIR_VALUE_TAG_GLOBAL_ALLOC, + .type = type, + .data.global_alloc.value = value, + }); + scc_snprintf(name, 32, "$G%u", global_value_ref); + scc_vec_push(builder->cprog->global_vals, global_value_ref); + return global_value_ref; +} + +scc_hir_value_ref_t scc_hir_builder_alloca(scc_hir_builder_t *builder, + scc_hir_type_ref_t type, + const char *name) { + SCC_HIR_BUILDER_CHECK_NO_BORROW(builder); + scc_hir_value_t alloc_node = {0}; + alloc_node.tag = SCC_HIR_VALUE_TAG_ALLOC; + alloc_node.type = scc_hir_module_add_type( + GET_MODULE(builder), + &(scc_hir_type_t){.tag = SCC_HIR_TYPE_PTR, .data.pointer.base = type}); + alloc_node.name = name; + + scc_hir_value_ref_t value_ref = + scc_hir_module_add_value(GET_MODULE(builder), &alloc_node); + scc_hir_builder_add_instr(builder, value_ref); + return value_ref; +} + +scc_hir_value_ref_t scc_hir_builder_func_arg_ref(scc_hir_builder_t *builder, + scc_hir_type_ref_t type, + const char *name, + usize arg_idx) { + SCC_HIR_BUILDER_CHECK_NO_BORROW(builder); + scc_hir_value_t value = {0}; + value.tag = SCC_HIR_VALUE_TAG_FUNC_ARG_REF; + value.type = type; + value.name = name; + value.data.arg_ref.idx = arg_idx; + + scc_hir_value_ref_t value_ref = + scc_hir_module_add_value(GET_MODULE(builder), &value); + scc_hir_builder_add_instr(builder, value_ref); + return value_ref; +} + +scc_hir_value_ref_t scc_hir_builder_load(scc_hir_builder_t *builder, + scc_hir_value_ref_t target) { + SCC_HIR_BUILDER_CHECK_NO_BORROW(builder); + scc_hir_value_t load_node = {0}; + load_node.tag = SCC_HIR_VALUE_TAG_LOAD; + load_node.data.load.target = target; + + // 借用 ptr_node 和 ptr_type 获取类型信息 + scc_hir_value_t *ptr_node = nullptr; + SCC_HIR_BUILDER_BEGIN_BORROW( + builder, ptr_node, + scc_hir_module_get_value(GET_MODULE(builder), target)); + if (ptr_node) { + scc_hir_type_t *ptr_type = nullptr; + SCC_HIR_BUILDER_BEGIN_BORROW( + builder, ptr_type, + scc_hir_module_get_type(GET_MODULE(builder), ptr_node->type)); + if (ptr_type && ptr_type->tag == SCC_HIR_TYPE_PTR) { + load_node.type = ptr_type->data.pointer.base; + } + SCC_HIR_BUILDER_END_BORROW(builder); // ptr_type + } + SCC_HIR_BUILDER_END_BORROW(builder); // ptr_node + + scc_hir_value_ref_t value_ref = + scc_hir_module_add_value(GET_MODULE(builder), &load_node); + scc_hir_builder_add_instr(builder, value_ref); + return value_ref; +} + +scc_hir_value_ref_t scc_hir_builder_store(scc_hir_builder_t *builder, + scc_hir_value_ref_t target, + scc_hir_value_ref_t value) { + SCC_HIR_BUILDER_CHECK_NO_BORROW(builder); + Assert(target != SCC_HIR_REF_nullptr && value != SCC_HIR_REF_nullptr); + scc_hir_value_t store_node = {0}; + store_node.tag = SCC_HIR_VALUE_TAG_STORE; + store_node.data.store.target = target; + store_node.data.store.value = value; + + scc_hir_value_ref_t value_ref = + scc_hir_module_add_value(GET_MODULE(builder), &store_node); + scc_hir_builder_add_instr(builder, value_ref); + return value_ref; +} + +scc_hir_value_ref_t scc_hir_builder_get_elem_ptr(scc_hir_builder_t *builder, + scc_hir_value_ref_t target, + scc_hir_value_ref_t index) { + SCC_HIR_BUILDER_CHECK_NO_BORROW(builder); + scc_hir_value_t get_ptr_node = {0}; + get_ptr_node.tag = SCC_HIR_VALUE_TAG_GET_ELEM_PTR; + get_ptr_node.data.get_elem_ptr.src_addr = target; + get_ptr_node.data.get_elem_ptr.index = index; + + // 借用类型信息 + scc_hir_type_t *type_ref = nullptr; + SCC_HIR_BUILDER_BEGIN_BORROW( + builder, type_ref, + scc_hir_module_get_type_by_value(GET_MODULE(builder), target)); + Assert(type_ref != nullptr); + scc_hir_type_t type = *type_ref; // 拷贝一份,避免后续借用 + SCC_HIR_BUILDER_END_BORROW(builder); // type_ref + + if (type.tag == SCC_HIR_TYPE_PTR) { + scc_hir_type_t *base_type = nullptr; + SCC_HIR_BUILDER_BEGIN_BORROW( + builder, base_type, + scc_hir_module_get_type(GET_MODULE(builder), + type_ref->data.pointer.base)); + if (base_type->tag == SCC_HIR_TYPE_ARRAY) { + scc_hir_type_t type = (scc_hir_type_t){ + .tag = SCC_HIR_TYPE_PTR, + .data.pointer.base = base_type->data.array.base, + }; + SCC_HIR_BUILDER_END_BORROW(builder); // base_type + get_ptr_node.type = scc_hir_builder_type(builder, &type); + } else { + SCC_HIR_BUILDER_END_BORROW(builder); // base_type + get_ptr_node.type = scc_hir_builder_type(builder, &type); + } + } else { + get_ptr_node.type = scc_hir_builder_type(builder, &type); + } + + scc_hir_value_ref_t value_ref = + scc_hir_module_add_value(GET_MODULE(builder), &get_ptr_node); + scc_hir_builder_add_instr(builder, value_ref); + return value_ref; +} + +scc_hir_value_ref_t scc_hir_builder_binop(scc_hir_builder_t *builder, + scc_hir_op_type_t op, + scc_hir_value_ref_t lhs, + scc_hir_value_ref_t rhs) { + SCC_HIR_BUILDER_CHECK_NO_BORROW(builder); + scc_hir_value_t binop_node = {0}; + binop_node.tag = SCC_HIR_VALUE_TAG_OP; + binop_node.data.op.op = op; + binop_node.data.op.lhs = lhs; + binop_node.data.op.rhs = rhs; + + // 借用 lhs_node 获取类型 + scc_hir_value_t *lhs_node = nullptr; + SCC_HIR_BUILDER_BEGIN_BORROW( + builder, lhs_node, scc_hir_module_get_value(GET_MODULE(builder), lhs)); + if (lhs_node) { + binop_node.type = lhs_node->type; + } + SCC_HIR_BUILDER_END_BORROW(builder); // lhs_node + + scc_hir_value_ref_t value_ref = + scc_hir_module_add_value(GET_MODULE(builder), &binop_node); + scc_hir_builder_add_instr(builder, value_ref); + return value_ref; +} + +scc_hir_value_ref_t scc_hir_builder_cmp(scc_hir_builder_t *builder, + scc_hir_op_type_t op, + scc_hir_value_ref_t lhs, + scc_hir_value_ref_t rhs) { + SCC_HIR_BUILDER_CHECK_NO_BORROW(builder); + scc_hir_value_t cmp_node = {0}; + cmp_node.tag = SCC_HIR_VALUE_TAG_OP; + cmp_node.data.op.op = op; + cmp_node.data.op.lhs = lhs; + cmp_node.data.op.rhs = rhs; + cmp_node.type = 0; // FIXME + + scc_hir_value_ref_t value_ref = + scc_hir_module_add_value(GET_MODULE(builder), &cmp_node); + scc_hir_builder_add_instr(builder, value_ref); + return value_ref; +} + +scc_hir_value_ref_t scc_hir_builder_jump(scc_hir_builder_t *builder, + scc_hir_bblock_ref_t target) { + SCC_HIR_BUILDER_CHECK_NO_BORROW(builder); + scc_hir_value_t jump_node = {0}; + jump_node.tag = SCC_HIR_VALUE_TAG_JUMP; + jump_node.data.jump.target_bblock = target; + + scc_hir_value_ref_t value_ref = + scc_hir_module_add_value(GET_MODULE(builder), &jump_node); + scc_hir_builder_add_instr(builder, value_ref); + return value_ref; +} + +scc_hir_value_ref_t scc_hir_builder_branch(scc_hir_builder_t *builder, + scc_hir_value_ref_t cond, + scc_hir_bblock_ref_t true_target, + scc_hir_bblock_ref_t false_target) { + SCC_HIR_BUILDER_CHECK_NO_BORROW(builder); + scc_hir_value_t branch_node = {0}; + branch_node.tag = SCC_HIR_VALUE_TAG_BRANCH; + branch_node.data.branch.cond = cond; + branch_node.data.branch.true_bblock = true_target; + branch_node.data.branch.false_bblock = false_target; + + scc_hir_value_ref_t value_ref = + scc_hir_module_add_value(GET_MODULE(builder), &branch_node); + scc_hir_builder_add_instr(builder, value_ref); + return value_ref; +} + +scc_hir_value_ref_t scc_hir_builder_call(scc_hir_builder_t *builder, + scc_hir_func_ref_t callee, + const scc_hir_value_ref_t *args, + usize arg_count) { + SCC_HIR_BUILDER_CHECK_NO_BORROW(builder); + scc_hir_value_t call_node = {0}; + call_node.tag = SCC_HIR_VALUE_TAG_CALL; + call_node.data.call.callee = callee; + + scc_vec_init(call_node.data.call.args); + for (usize i = 0; i < arg_count; i++) { + scc_vec_push(call_node.data.call.args, args[i]); + } + + // 借用 callee_func 和 func_type 获取返回类型 + scc_hir_func_t *callee_func = nullptr; + SCC_HIR_BUILDER_BEGIN_BORROW( + builder, callee_func, + scc_hir_module_get_func(GET_MODULE(builder), callee)); + if (callee_func) { + scc_hir_type_t *func_type = nullptr; + SCC_HIR_BUILDER_BEGIN_BORROW( + builder, func_type, + scc_hir_module_get_type(GET_MODULE(builder), + SCC_HIR_FUNC_META(*callee_func)->type)); + if (func_type && func_type->tag == SCC_HIR_TYPE_FUNC) { + call_node.type = func_type->data.function.ret_type; + } + SCC_HIR_BUILDER_END_BORROW(builder); // func_type + } + SCC_HIR_BUILDER_END_BORROW(builder); // callee_func + + scc_hir_value_ref_t value_ref = + scc_hir_module_add_value(GET_MODULE(builder), &call_node); + scc_hir_builder_add_instr(builder, value_ref); + return value_ref; +} + +scc_hir_value_ref_t scc_hir_builder_ret(scc_hir_builder_t *builder, + scc_hir_value_ref_t value) { + SCC_HIR_BUILDER_CHECK_NO_BORROW(builder); + scc_hir_value_t ret_node = {0}; + ret_node.tag = SCC_HIR_VALUE_TAG_RET; + ret_node.data.ret.ret_val = value; + + scc_hir_value_ref_t value_ref = + scc_hir_module_add_value(GET_MODULE(builder), &ret_node); + scc_hir_builder_add_instr(builder, value_ref); + return value_ref; +} + +scc_hir_value_ref_t scc_hir_builder_ret_void(scc_hir_builder_t *builder) { + SCC_HIR_BUILDER_CHECK_NO_BORROW(builder); + scc_hir_value_t ret_node = {0}; + ret_node.tag = SCC_HIR_VALUE_TAG_RET; + + scc_hir_value_t ret_val_node; + scc_hir_value_init(&ret_val_node, nullptr, SCC_HIR_VALUE_TAG_NULLPTR); + ret_val_node.type = scc_hir_builder_type_void(builder); + ret_node.data.ret.ret_val = + scc_hir_module_add_value(GET_MODULE(builder), &ret_val_node); + + scc_hir_value_ref_t value_ref = + scc_hir_module_add_value(GET_MODULE(builder), &ret_node); + scc_hir_builder_add_instr(builder, value_ref); + return value_ref; +} + +scc_hir_value_ref_t scc_hir_builder_builtin_memcpy(scc_hir_builder_t *builder, + scc_hir_value_ref_t dest, + scc_hir_value_ref_t src, + scc_hir_value_ref_t len) { + Assert(builder && src && dest && len); + scc_hir_value_t value; + scc_hir_value_init(&value, nullptr, SCC_HIR_VALUE_TAG_BUILTIN); + value.type = scc_hir_builder_type_void(builder); // memcpy 返回 void* + value.data.builtin.tag = SCC_HIR_BUILTIN_TAG_MEMCPY; + value.data.builtin.func.memcpy.dest = dest; + value.data.builtin.func.memcpy.src = src; + value.data.builtin.func.memcpy.size = len; + scc_hir_value_ref_t ref = + scc_hir_module_add_value(GET_MODULE(builder), &value); + scc_hir_builder_add_instr(builder, ref); + return ref; +} diff --git a/libs/ir/src/ir_dump.c b/libs/ir/hir/src/hir_dump.c similarity index 58% rename from libs/ir/src/ir_dump.c rename to libs/ir/hir/src/hir_dump.c index bb7fad1..18c7cf5 100644 --- a/libs/ir/src/ir_dump.c +++ b/libs/ir/hir/src/hir_dump.c @@ -1,31 +1,30 @@ -#include -#include +#include +#include #include #define GET_MODULE(ctx) (&(ctx->cprog->module)) -static const char *get_node_type_str(scc_ir_value_tag_t tag) { +static const char *get_node_type_str(scc_hir_value_tag_t tag) { static const char *node_types[] = { - [SCC_IR_VALUE_TAG_NULLPTR] = "NullPtr", - [SCC_IR_VALUE_TAG_BUILTIN] = "Builtin", - [SCC_IR_VALUE_TAG_CONST_INT] = "ConstInt", - [SCC_IR_VALUE_TAG_CONST_UINT] = "ConstUint", - [SCC_IR_VALUE_TAG_CONST_FLOAT] = "ConstFloat", - [SCC_IR_VALUE_TAG_CONST_ARRAY] = "ConstArray", - [SCC_IR_VALUE_TAG_AGGREGATE] = "Aggregate", - [SCC_IR_VALUE_TAG_CONV] = "Convert", - [SCC_IR_VALUE_TAG_FUNC_ARG_REF] = "FuncArgRef", - [SCC_IR_VALUE_TAG_BLOCK_ARG_REF] = "BlockArgRef", - [SCC_IR_VALUE_TAG_ALLOC] = "Alloc", - [SCC_IR_VALUE_TAG_GLOBAL_ALLOC] = "GlobalAlloc", - [SCC_IR_VALUE_TAG_LOAD] = "Load", - [SCC_IR_VALUE_TAG_STORE] = "Store", - [SCC_IR_VALUE_TAG_GET_ELEM_PTR] = "GetElemPtr", - [SCC_IR_VALUE_TAG_OP] = "Op", - [SCC_IR_VALUE_TAG_BRANCH] = "Branch", - [SCC_IR_VALUE_TAG_JUMP] = "Jump", - [SCC_IR_VALUE_TAG_CALL] = "Call", - [SCC_IR_VALUE_TAG_RET] = "Ret", + [SCC_HIR_VALUE_TAG_NULLPTR] = "NullPtr", + [SCC_HIR_VALUE_TAG_BUILTIN] = "Builtin", + [SCC_HIR_VALUE_TAG_INTEGER] = "ConstInt", + [SCC_HIR_VALUE_TAG_DECIMAL] = "ConstFloat", + [SCC_HIR_VALUE_TAG_ARRAY] = "ConstArray", + [SCC_HIR_VALUE_TAG_AGGREGATE] = "Aggregate", + [SCC_HIR_VALUE_TAG_CONV] = "Convert", + [SCC_HIR_VALUE_TAG_FUNC_ARG_REF] = "FuncArgRef", + [SCC_HIR_VALUE_TAG_BLOCK_ARG_REF] = "BlockArgRef", + [SCC_HIR_VALUE_TAG_ALLOC] = "Alloc", + [SCC_HIR_VALUE_TAG_GLOBAL_ALLOC] = "GlobalAlloc", + [SCC_HIR_VALUE_TAG_LOAD] = "Load", + [SCC_HIR_VALUE_TAG_STORE] = "Store", + [SCC_HIR_VALUE_TAG_GET_ELEM_PTR] = "GetElemPtr", + [SCC_HIR_VALUE_TAG_OP] = "Op", + [SCC_HIR_VALUE_TAG_BRANCH] = "Branch", + [SCC_HIR_VALUE_TAG_JUMP] = "Jump", + [SCC_HIR_VALUE_TAG_CALL] = "Call", + [SCC_HIR_VALUE_TAG_RET] = "Ret", }; if (tag >= 0 && (usize)tag < sizeof(node_types) / sizeof(node_types[0]) && node_types[tag]) @@ -33,36 +32,36 @@ static const char *get_node_type_str(scc_ir_value_tag_t tag) { return "UnknownIRNode"; } -static const char *get_op_str(scc_ir_op_type_t op) { +static const char *get_op_str(scc_hir_op_type_t op) { static const char *ops[] = { - [SCC_IR_OP_EMPTY] = "empty", [SCC_IR_OP_NEQ] = "!=", - [SCC_IR_OP_EQ] = "==", [SCC_IR_OP_GT] = ">", - [SCC_IR_OP_LT] = "<", [SCC_IR_OP_GE] = ">=", - [SCC_IR_OP_LE] = "<=", [SCC_IR_OP_ADD] = "+", - [SCC_IR_OP_SUB] = "-", [SCC_IR_OP_MUL] = "*", - [SCC_IR_OP_DIV] = "/", [SCC_IR_OP_MOD] = "%", - [SCC_IR_OP_AND] = "&", [SCC_IR_OP_OR] = "|", - [SCC_IR_OP_XOR] = "^", [SCC_IR_OP_NOT] = "~", - [SCC_IR_OP_SHL] = "<<", [SCC_IR_OP_SHR] = ">>", - [SCC_IR_OP_SAR] = ">>a", + [SCC_HIR_OP_EMPTY] = "empty", [SCC_HIR_OP_NEQ] = "!=", + [SCC_HIR_OP_EQ] = "==", [SCC_HIR_OP_GT] = ">", + [SCC_HIR_OP_LT] = "<", [SCC_HIR_OP_GE] = ">=", + [SCC_HIR_OP_LE] = "<=", [SCC_HIR_OP_ADD] = "+", + [SCC_HIR_OP_SUB] = "-", [SCC_HIR_OP_MUL] = "*", + [SCC_HIR_OP_DIV] = "/", [SCC_HIR_OP_MOD] = "%", + [SCC_HIR_OP_AND] = "&", [SCC_HIR_OP_OR] = "|", + [SCC_HIR_OP_XOR] = "^", [SCC_HIR_OP_NOT] = "~", + [SCC_HIR_OP_SHL] = "<<", [SCC_HIR_OP_SHR] = ">>", + [SCC_HIR_OP_SAR] = ">>a", }; if (op >= 0 && (usize)op < sizeof(ops) / sizeof(ops[0]) && ops[op]) return ops[op]; return ""; } -static const char *get_type_tag_str(scc_ir_type_tag_t tag) { +static const char *get_type_tag_str(scc_hir_type_tag_t tag) { static const char *type_tags[] = { - [SCC_IR_TYPE_void] = "void", [SCC_IR_TYPE_u8] = "u8", - [SCC_IR_TYPE_u16] = "u16", [SCC_IR_TYPE_u32] = "u32", - [SCC_IR_TYPE_u64] = "u64", [SCC_IR_TYPE_u128] = "u128", - [SCC_IR_TYPE_i8] = "i8", [SCC_IR_TYPE_i16] = "i16", - [SCC_IR_TYPE_i32] = "i32", [SCC_IR_TYPE_i64] = "i64", - [SCC_IR_TYPE_i128] = "i128", [SCC_IR_TYPE_f16] = "f16", - [SCC_IR_TYPE_f32] = "f32", [SCC_IR_TYPE_f64] = "f64", - [SCC_IR_TYPE_f128] = "f128", [SCC_IR_TYPE_PTR] = "ptr", - [SCC_IR_TYPE_ARRAY] = "array", [SCC_IR_TYPE_FUNC] = "func", - [SCC_IR_TYPE_STRUCT] = "struct", [SCC_IR_TYPE_VECTOR] = "vector", + [SCC_HIR_TYPE_void] = "void", [SCC_HIR_TYPE_u8] = "u8", + [SCC_HIR_TYPE_u16] = "u16", [SCC_HIR_TYPE_u32] = "u32", + [SCC_HIR_TYPE_u64] = "u64", [SCC_HIR_TYPE_u128] = "u128", + [SCC_HIR_TYPE_i8] = "i8", [SCC_HIR_TYPE_i16] = "i16", + [SCC_HIR_TYPE_i32] = "i32", [SCC_HIR_TYPE_i64] = "i64", + [SCC_HIR_TYPE_i128] = "i128", [SCC_HIR_TYPE_f16] = "f16", + [SCC_HIR_TYPE_f32] = "f32", [SCC_HIR_TYPE_f64] = "f64", + [SCC_HIR_TYPE_f128] = "f128", [SCC_HIR_TYPE_PTR] = "ptr", + [SCC_HIR_TYPE_ARRAY] = "array", [SCC_HIR_TYPE_FUNC] = "func", + [SCC_HIR_TYPE_STRUCT] = "struct", [SCC_HIR_TYPE_VECTOR] = "vector", }; if (tag >= 0 && (usize)tag < sizeof(type_tags) / sizeof(type_tags[0]) && type_tags[tag]) @@ -70,25 +69,26 @@ static const char *get_type_tag_str(scc_ir_type_tag_t tag) { return ""; } -static inline void dump_child_node_ref(scc_ir_dump_ctx_t *ctx, - scc_ir_value_ref_t child, +static inline void dump_child_node_ref(scc_hir_dump_t *ctx, + scc_hir_value_ref_t child, cbool is_last) { if (!child) return; scc_tree_dump_push(ctx->dump_ctx, is_last); - scc_ir_dump_value(ctx, child); + scc_hir_dump_value(ctx, child); scc_tree_dump_pop(ctx->dump_ctx); } -static void dump_const_int_node(scc_ir_dump_ctx_t *ctx, - const scc_ir_value_t *value) { +static void dump_integer_node(scc_hir_dump_t *ctx, + const scc_hir_value_t *value) { scc_tree_dump_push(ctx->dump_ctx, true); scc_tree_dump_begin_line(ctx->dump_ctx); - scc_tree_dump_value(ctx->dump_ctx, "%d", value->data.const_int.int32); + // FIXME hack it + scc_tree_dump_value(ctx->dump_ctx, "%d", value->data.integer.data.digit); scc_tree_dump_pop(ctx->dump_ctx); } -static void dump_op_node(scc_ir_dump_ctx_t *ctx, const scc_ir_value_t *value) { +static void dump_op_node(scc_hir_dump_t *ctx, const scc_hir_value_t *value) { scc_tree_dump_push(ctx->dump_ctx, false); scc_tree_dump_begin_line(ctx->dump_ctx); scc_tree_dump_node(ctx->dump_ctx, "op: "); @@ -102,66 +102,63 @@ static void dump_op_node(scc_ir_dump_ctx_t *ctx, const scc_ir_value_t *value) { dump_child_node_ref(ctx, value->data.op.rhs, true); } -static void dump_load_node(scc_ir_dump_ctx_t *ctx, - const scc_ir_value_t *value) { +static void dump_load_node(scc_hir_dump_t *ctx, const scc_hir_value_t *value) { if (value->data.load.target) dump_child_node_ref(ctx, value->data.load.target, true); } -static void dump_store_node(scc_ir_dump_ctx_t *ctx, - const scc_ir_value_t *value) { +static void dump_store_node(scc_hir_dump_t *ctx, const scc_hir_value_t *value) { if (value->data.store.target) dump_child_node_ref(ctx, value->data.store.target, false); if (value->data.store.value) dump_child_node_ref(ctx, value->data.store.value, true); } -static void dump_get_elem_ptr_node(scc_ir_dump_ctx_t *ctx, - const scc_ir_value_t *value) { +static void dump_get_elem_ptr_node(scc_hir_dump_t *ctx, + const scc_hir_value_t *value) { if (value->data.get_elem_ptr.src_addr) dump_child_node_ref(ctx, value->data.get_elem_ptr.src_addr, false); if (value->data.get_elem_ptr.index) dump_child_node_ref(ctx, value->data.get_elem_ptr.index, true); } -static void dump_branch_node(scc_ir_dump_ctx_t *ctx, - const scc_ir_value_t *value) { +static void dump_branch_node(scc_hir_dump_t *ctx, + const scc_hir_value_t *value) { if (value->data.branch.cond) dump_child_node_ref(ctx, value->data.branch.cond, false); if (value->data.branch.true_bblock) { - scc_ir_bblock_t *true_bblock = scc_ir_module_get_bblock( + scc_hir_bblock_t *true_bblock = scc_hir_module_get_bblock( GET_MODULE(ctx), value->data.branch.true_bblock); if (true_bblock) { scc_tree_dump_begin_line(ctx->dump_ctx); scc_tree_dump_node(ctx->dump_ctx, "TrueBlock: "); scc_tree_dump_value(ctx->dump_ctx, "'%s'", - true_bblock->label ? true_bblock->label - : ""); + true_bblock->name ? true_bblock->name + : ""); } } if (value->data.branch.false_bblock) { - scc_ir_bblock_t *false_bblock = scc_ir_module_get_bblock( + scc_hir_bblock_t *false_bblock = scc_hir_module_get_bblock( GET_MODULE(ctx), value->data.branch.false_bblock); if (false_bblock) { scc_tree_dump_begin_line(ctx->dump_ctx); scc_tree_dump_node(ctx->dump_ctx, "FalseBlock: "); scc_tree_dump_value(ctx->dump_ctx, "'%s'", - false_bblock->label ? false_bblock->label - : ""); + false_bblock->name ? false_bblock->name + : ""); } } } -static void dump_jump_node(scc_ir_dump_ctx_t *ctx, - const scc_ir_value_t *value) { +static void dump_jump_node(scc_hir_dump_t *ctx, const scc_hir_value_t *value) { scc_tree_dump_begin_line(ctx->dump_ctx); if (value->data.jump.target_bblock) { - scc_ir_bblock_t *target = scc_ir_module_get_bblock( + scc_hir_bblock_t *target = scc_hir_module_get_bblock( GET_MODULE(ctx), value->data.jump.target_bblock); if (target) scc_tree_dump_value(ctx->dump_ctx, "to '%s'", - target->label ? target->label : ""); + target->name ? target->name : ""); else scc_tree_dump_value(ctx->dump_ctx, "to invalid block"); } else { @@ -169,12 +166,11 @@ static void dump_jump_node(scc_ir_dump_ctx_t *ctx, } } -static void dump_call_node(scc_ir_dump_ctx_t *ctx, - const scc_ir_value_t *value) { +static void dump_call_node(scc_hir_dump_t *ctx, const scc_hir_value_t *value) { scc_tree_dump_begin_line(ctx->dump_ctx); if (value->data.call.callee) { - scc_ir_func_t *callee = - scc_ir_module_get_func(GET_MODULE(ctx), value->data.call.callee); + scc_hir_func_t *callee = + scc_hir_module_get_func(GET_MODULE(ctx), value->data.call.callee); scc_tree_dump_value(ctx->dump_ctx, "func='%s'", callee ? (callee->name ? callee->name : "") : ""); @@ -185,25 +181,26 @@ static void dump_call_node(scc_ir_dump_ctx_t *ctx, for (usize i = 0; i < scc_vec_size(value->data.call.args); i++) { cbool is_last = (i + 1 == scc_vec_size(value->data.call.args)); scc_tree_dump_push(ctx->dump_ctx, is_last); - scc_ir_value_ref_t arg = scc_vec_at(value->data.call.args, i); + scc_hir_value_ref_t arg = scc_vec_at(value->data.call.args, i); dump_child_node_ref(ctx, arg, is_last); scc_tree_dump_pop(ctx->dump_ctx); } } -static void dump_ret_node(scc_ir_dump_ctx_t *ctx, const scc_ir_value_t *value) { +static void dump_ret_node(scc_hir_dump_t *ctx, const scc_hir_value_t *value) { if (value->data.ret.ret_val) dump_child_node_ref(ctx, value->data.ret.ret_val, true); } -void scc_ir_dump_ctx_init(scc_ir_dump_ctx_t *ctx, scc_tree_dump_t *td, - scc_ir_cprog_t *cprog) { +void scc_hir_dump_ctx_init(scc_hir_dump_t *ctx, scc_tree_dump_t *td, + scc_hir_cprog_t *cprog) { ctx->cprog = cprog; ctx->dump_ctx = td; } -void scc_ir_dump_value(scc_ir_dump_ctx_t *ctx, scc_ir_value_ref_t value_ref) { - scc_ir_value_t *value = scc_ir_module_get_value(GET_MODULE(ctx), value_ref); +void scc_hir_dump_value(scc_hir_dump_t *ctx, scc_hir_value_ref_t value_ref) { + scc_hir_value_t *value = + scc_hir_module_get_value(GET_MODULE(ctx), value_ref); if (!value) { LOG_ERROR("Invalid value ref"); return; @@ -214,8 +211,8 @@ void scc_ir_dump_value(scc_ir_dump_ctx_t *ctx, scc_ir_value_ref_t value_ref) { if (value->name && value->name[0]) scc_tree_dump_value(ctx->dump_ctx, " [%s]", value->name); if (value->type) { - scc_ir_type_t *type = - scc_ir_module_get_type(GET_MODULE(ctx), value->type); + scc_hir_type_t *type = + scc_hir_module_get_type(GET_MODULE(ctx), value->type); if (type) { scc_tree_dump_append(ctx->dump_ctx, " : "); scc_tree_dump_value(ctx->dump_ctx, "%s", @@ -224,33 +221,33 @@ void scc_ir_dump_value(scc_ir_dump_ctx_t *ctx, scc_ir_value_ref_t value_ref) { } switch (value->tag) { - case SCC_IR_VALUE_TAG_CONST_INT: - dump_const_int_node(ctx, value); + case SCC_HIR_VALUE_TAG_INTEGER: + dump_integer_node(ctx, value); break; - case SCC_IR_VALUE_TAG_ALLOC: + case SCC_HIR_VALUE_TAG_ALLOC: break; - case SCC_IR_VALUE_TAG_LOAD: + case SCC_HIR_VALUE_TAG_LOAD: dump_load_node(ctx, value); break; - case SCC_IR_VALUE_TAG_STORE: + case SCC_HIR_VALUE_TAG_STORE: dump_store_node(ctx, value); break; - case SCC_IR_VALUE_TAG_GET_ELEM_PTR: + case SCC_HIR_VALUE_TAG_GET_ELEM_PTR: dump_get_elem_ptr_node(ctx, value); break; - case SCC_IR_VALUE_TAG_OP: + case SCC_HIR_VALUE_TAG_OP: dump_op_node(ctx, value); break; - case SCC_IR_VALUE_TAG_BRANCH: + case SCC_HIR_VALUE_TAG_BRANCH: dump_branch_node(ctx, value); break; - case SCC_IR_VALUE_TAG_JUMP: + case SCC_HIR_VALUE_TAG_JUMP: dump_jump_node(ctx, value); break; - case SCC_IR_VALUE_TAG_CALL: + case SCC_HIR_VALUE_TAG_CALL: dump_call_node(ctx, value); break; - case SCC_IR_VALUE_TAG_RET: + case SCC_HIR_VALUE_TAG_RET: dump_ret_node(ctx, value); break; default: @@ -260,12 +257,12 @@ void scc_ir_dump_value(scc_ir_dump_ctx_t *ctx, scc_ir_value_ref_t value_ref) { } } -void scc_ir_dump_type(scc_ir_dump_ctx_t *ctx, scc_ir_type_ref_t type_ref) { +void scc_hir_dump_type(scc_hir_dump_t *ctx, scc_hir_type_ref_t type_ref) { if (!ctx || !type_ref) { LOG_ERROR("invalid parameter"); return; } - scc_ir_type_t *type = scc_ir_module_get_type(GET_MODULE(ctx), type_ref); + scc_hir_type_t *type = scc_hir_module_get_type(GET_MODULE(ctx), type_ref); if (!type) { LOG_ERROR("invalid type ref"); return; @@ -275,14 +272,14 @@ void scc_ir_dump_type(scc_ir_dump_ctx_t *ctx, scc_ir_type_ref_t type_ref) { scc_tree_dump_value(ctx->dump_ctx, "%s", get_type_tag_str(type->tag)); switch (type->tag) { - case SCC_IR_TYPE_PTR: + case SCC_HIR_TYPE_PTR: if (type->data.pointer.base) { scc_tree_dump_push(ctx->dump_ctx, true); - scc_ir_dump_type(ctx, type->data.pointer.base); + scc_hir_dump_type(ctx, type->data.pointer.base); scc_tree_dump_pop(ctx->dump_ctx); } break; - case SCC_IR_TYPE_ARRAY: + case SCC_HIR_TYPE_ARRAY: if (type->data.array.len > 0) { scc_tree_dump_begin_line(ctx->dump_ctx); scc_tree_dump_node(ctx->dump_ctx, "Array Length: "); @@ -291,20 +288,20 @@ void scc_ir_dump_type(scc_ir_dump_ctx_t *ctx, scc_ir_type_ref_t type_ref) { } if (type->data.array.base) { scc_tree_dump_push(ctx->dump_ctx, true); - scc_ir_dump_type(ctx, type->data.array.base); + scc_hir_dump_type(ctx, type->data.array.base); scc_tree_dump_pop(ctx->dump_ctx); } break; - case SCC_IR_TYPE_FUNC: + case SCC_HIR_TYPE_FUNC: for (usize i = 0; i < scc_vec_size(type->data.function.params); i++) { cbool is_last = (i + 1 == scc_vec_size(type->data.function.params)); scc_tree_dump_push(ctx->dump_ctx, is_last); - scc_ir_dump_type(ctx, scc_vec_at(type->data.function.params, i)); + scc_hir_dump_type(ctx, scc_vec_at(type->data.function.params, i)); scc_tree_dump_pop(ctx->dump_ctx); } if (type->data.function.ret_type) { scc_tree_dump_push(ctx->dump_ctx, true); - scc_ir_dump_type(ctx, type->data.function.ret_type); + scc_hir_dump_type(ctx, type->data.function.ret_type); scc_tree_dump_pop(ctx->dump_ctx); } break; @@ -313,14 +310,13 @@ void scc_ir_dump_type(scc_ir_dump_ctx_t *ctx, scc_ir_type_ref_t type_ref) { } } -void scc_ir_dump_bblock(scc_ir_dump_ctx_t *ctx, - scc_ir_bblock_ref_t bblock_ref) { +void scc_hir_dump_bblock(scc_hir_dump_t *ctx, scc_hir_bblock_ref_t bblock_ref) { if (!ctx || !bblock_ref) { LOG_ERROR("invalid parameter"); return; } - scc_ir_bblock_t *bblock = - scc_ir_module_get_bblock(GET_MODULE(ctx), bblock_ref); + scc_hir_bblock_t *bblock = + scc_hir_module_get_bblock(GET_MODULE(ctx), bblock_ref); if (!bblock) { LOG_ERROR("invalid bblock ref"); return; @@ -328,19 +324,19 @@ void scc_ir_dump_bblock(scc_ir_dump_ctx_t *ctx, scc_tree_dump_begin_line(ctx->dump_ctx); scc_tree_dump_node(ctx->dump_ctx, "BasicBlock: "); scc_tree_dump_value(ctx->dump_ctx, "'%s'", - bblock->label ? bblock->label : ""); + bblock->name ? bblock->name : ""); scc_tree_dump_append(ctx->dump_ctx, "\n"); - for (usize i = 0; i < scc_vec_size(bblock->instrs); i++) { - cbool is_last = (i + 1 == scc_vec_size(bblock->instrs)); + for (usize i = 0; i < scc_vec_size(SCC_HIR_BBLOCK_VALUES(*bblock)); i++) { + cbool is_last = (i + 1 == scc_vec_size(SCC_HIR_BBLOCK_VALUES(*bblock))); scc_tree_dump_push(ctx->dump_ctx, is_last); - scc_ir_dump_value(ctx, scc_vec_at(bblock->instrs, i)); + scc_hir_dump_value(ctx, scc_vec_at(SCC_HIR_BBLOCK_VALUES(*bblock), i)); scc_tree_dump_pop(ctx->dump_ctx); } } -void scc_ir_dump_func(scc_ir_dump_ctx_t *ctx, scc_ir_func_ref_t func_ref) { - scc_ir_func_t *func = scc_ir_module_get_func(GET_MODULE(ctx), func_ref); +void scc_hir_dump_func(scc_hir_dump_t *ctx, scc_hir_func_ref_t func_ref) { + scc_hir_func_t *func = scc_hir_module_get_func(GET_MODULE(ctx), func_ref); if (!ctx || !func) { LOG_ERROR("invalid parameter"); return; @@ -351,82 +347,84 @@ void scc_ir_dump_func(scc_ir_dump_ctx_t *ctx, scc_ir_func_ref_t func_ref) { func->name ? func->name : ""); scc_tree_dump_append(ctx->dump_ctx, "\n"); - if (func->type) { + if (SCC_HIR_FUNC_META(*func)->type) { scc_tree_dump_push(ctx->dump_ctx, false); - scc_ir_dump_type(ctx, func->type); + scc_hir_dump_type(ctx, SCC_HIR_FUNC_META(*func)->type); scc_tree_dump_pop(ctx->dump_ctx); } - for (usize i = 0; i < scc_vec_size(func->params); i++) { - cbool is_last = (i + 1 == scc_vec_size(func->params)); + for (usize i = 0; i < scc_vec_size(SCC_HIR_FUNC_META(*func)->params); i++) { + cbool is_last = + (i + 1 == scc_vec_size(SCC_HIR_FUNC_META(*func)->params)); scc_tree_dump_push(ctx->dump_ctx, is_last); - scc_ir_dump_value(ctx, scc_vec_at(func->params, i)); + scc_hir_dump_value(ctx, + scc_vec_at(SCC_HIR_FUNC_META(*func)->params, i)); scc_tree_dump_pop(ctx->dump_ctx); } for (usize i = 0; i < scc_vec_size(func->bblocks); i++) { cbool is_last = (i + 1 == scc_vec_size(func->bblocks)); scc_tree_dump_push(ctx->dump_ctx, is_last); - scc_ir_dump_bblock(ctx, scc_vec_at(func->bblocks, i)); + scc_hir_dump_bblock(ctx, scc_vec_at(func->bblocks, i)); scc_tree_dump_pop(ctx->dump_ctx); } } -void scc_ir_dump_cprog(scc_ir_dump_ctx_t *ctx) { +void scc_hir_dump_cprog(scc_hir_dump_t *ctx) { scc_tree_dump_node(ctx->dump_ctx, "Func defs:\n"); scc_vec_foreach(ctx->cprog->func_defs, i) { cbool is_last = (i + 1 == scc_vec_size(ctx->cprog->func_defs)); scc_tree_dump_push(ctx->dump_ctx, is_last); - scc_ir_dump_func(ctx, scc_vec_at(ctx->cprog->func_defs, i)); + scc_hir_dump_func(ctx, scc_vec_at(ctx->cprog->func_defs, i)); scc_tree_dump_pop(ctx->dump_ctx); } } // ----- 线性输出(保留原逻辑,改用新 API)----- -void scc_ir_dump_type_linear(scc_ir_dump_ctx_t *ctx, - scc_ir_type_ref_t type_ref) { - scc_ir_type_t *type = scc_ir_module_get_type(GET_MODULE(ctx), type_ref); +void scc_hir_dump_type_linear(scc_hir_dump_t *ctx, + scc_hir_type_ref_t type_ref) { + scc_hir_type_t *type = scc_hir_module_get_type(GET_MODULE(ctx), type_ref); if (!ctx || !type) { LOG_ERROR("invalid parameter"); return; } switch (type->tag) { - case SCC_IR_TYPE_unknown: - case SCC_IR_TYPE_void: - case SCC_IR_TYPE_i8: - case SCC_IR_TYPE_i16: - case SCC_IR_TYPE_i32: - case SCC_IR_TYPE_i64: - case SCC_IR_TYPE_i128: - case SCC_IR_TYPE_u8: - case SCC_IR_TYPE_u16: - case SCC_IR_TYPE_u32: - case SCC_IR_TYPE_u64: - case SCC_IR_TYPE_u128: - case SCC_IR_TYPE_f16: - case SCC_IR_TYPE_f32: - case SCC_IR_TYPE_f64: - case SCC_IR_TYPE_f128: + case SCC_HIR_TYPE_unknown: + case SCC_HIR_TYPE_void: + case SCC_HIR_TYPE_i8: + case SCC_HIR_TYPE_i16: + case SCC_HIR_TYPE_i32: + case SCC_HIR_TYPE_i64: + case SCC_HIR_TYPE_i128: + case SCC_HIR_TYPE_u8: + case SCC_HIR_TYPE_u16: + case SCC_HIR_TYPE_u32: + case SCC_HIR_TYPE_u64: + case SCC_HIR_TYPE_u128: + case SCC_HIR_TYPE_f16: + case SCC_HIR_TYPE_f32: + case SCC_HIR_TYPE_f64: + case SCC_HIR_TYPE_f128: scc_tree_dump_value(ctx->dump_ctx, "%s", get_type_tag_str(type->tag)); break; - case SCC_IR_TYPE_ARRAY: + case SCC_HIR_TYPE_ARRAY: scc_tree_dump_append(ctx->dump_ctx, "["); - scc_ir_dump_type_linear(ctx, type->data.array.base); + scc_hir_dump_type_linear(ctx, type->data.array.base); scc_tree_dump_append_fmt(ctx->dump_ctx, ", %zu]", type->data.array.len); break; - case SCC_IR_TYPE_PTR: + case SCC_HIR_TYPE_PTR: scc_tree_dump_append(ctx->dump_ctx, "*"); - scc_ir_dump_type_linear(ctx, type->data.pointer.base); + scc_hir_dump_type_linear(ctx, type->data.pointer.base); break; - case SCC_IR_TYPE_FUNC: + case SCC_HIR_TYPE_FUNC: scc_tree_dump_append(ctx->dump_ctx, "("); for (usize i = 0; i < scc_vec_size(type->data.function.params); i++) { if (i > 0) scc_tree_dump_append(ctx->dump_ctx, ", "); - scc_ir_dump_type_linear(ctx, - scc_vec_at(type->data.function.params, i)); + scc_hir_dump_type_linear(ctx, + scc_vec_at(type->data.function.params, i)); } if (type->data.function.ret_type) { scc_tree_dump_append(ctx->dump_ctx, ") -> "); - scc_ir_dump_type_linear(ctx, type->data.function.ret_type); + scc_hir_dump_type_linear(ctx, type->data.function.ret_type); } else { scc_tree_dump_append(ctx->dump_ctx, ")"); } @@ -437,41 +435,44 @@ void scc_ir_dump_type_linear(scc_ir_dump_ctx_t *ctx, } } -static void format_ref_or_value(scc_ir_dump_ctx_t *ctx, - scc_ir_value_ref_t value_ref) { - scc_ir_value_t *value = scc_ir_module_get_value(GET_MODULE(ctx), value_ref); +static void format_ref_or_value(scc_hir_dump_t *ctx, + scc_hir_value_ref_t value_ref) { + scc_hir_value_t *value = + scc_hir_module_get_value(GET_MODULE(ctx), value_ref); if (!value) { scc_tree_dump_append_fmt(ctx->dump_ctx, "%%%u", value_ref); return; } - if (value->tag == SCC_IR_VALUE_TAG_CONST_INT) { - scc_tree_dump_append_fmt(ctx->dump_ctx, "%d", - value->data.const_int.int32); - return; - } + // FIXME + // if (value->tag == SCC_HIR_VALUE_TAG_INTEGER) { + // scc_tree_dump_append_fmt(ctx->dump_ctx, "%d", + // value->data.const_int.int32); + // return; + // } if (value->name && value->name[0] != '\0') { scc_tree_dump_node(ctx->dump_ctx, "%%%u[%s]", value_ref, value->name); } else { scc_tree_dump_node(ctx->dump_ctx, "%%%u", value_ref); } - if (value->type != SCC_IR_REF_nullptr) { + if (value->type != SCC_HIR_REF_nullptr) { scc_tree_dump_append(ctx->dump_ctx, ":"); - scc_ir_dump_type_linear(ctx, value->type); + scc_hir_dump_type_linear(ctx, value->type); } } -void scc_ir_dump_value_linear(scc_ir_dump_ctx_t *ctx, - scc_ir_value_ref_t value_ref) { - scc_ir_value_t *value = scc_ir_module_get_value(GET_MODULE(ctx), value_ref); +void scc_hir_dump_value_linear(scc_hir_dump_t *ctx, + scc_hir_value_ref_t value_ref) { + scc_hir_value_t *value = + scc_hir_module_get_value(GET_MODULE(ctx), value_ref); if (!value) { scc_tree_dump_append(ctx->dump_ctx, "\n"); return; } - cbool needs_equals = (value->tag != SCC_IR_VALUE_TAG_BRANCH && - value->tag != SCC_IR_VALUE_TAG_JUMP && - value->tag != SCC_IR_VALUE_TAG_RET && - value->tag != SCC_IR_VALUE_TAG_STORE); + cbool needs_equals = (value->tag != SCC_HIR_VALUE_TAG_BRANCH && + value->tag != SCC_HIR_VALUE_TAG_JUMP && + value->tag != SCC_HIR_VALUE_TAG_RET && + value->tag != SCC_HIR_VALUE_TAG_STORE); if (needs_equals) { format_ref_or_value(ctx, value_ref); @@ -479,10 +480,10 @@ void scc_ir_dump_value_linear(scc_ir_dump_ctx_t *ctx, } switch (value->tag) { - case SCC_IR_VALUE_TAG_BUILTIN: { + case SCC_HIR_VALUE_TAG_BUILTIN: { scc_tree_dump_append(ctx->dump_ctx, "@scc::"); switch (value->data.builtin.tag) { - case SCC_IR_BUILTIN_TAG_MEMCPY: + case SCC_HIR_BUILTIN_TAG_MEMCPY: scc_tree_dump_append(ctx->dump_ctx, "memcpy"); scc_tree_dump_append(ctx->dump_ctx, "("); format_ref_or_value(ctx, value->data.builtin.func.memcpy.dest); @@ -492,19 +493,19 @@ void scc_ir_dump_value_linear(scc_ir_dump_ctx_t *ctx, format_ref_or_value(ctx, value->data.builtin.func.memcpy.size); scc_tree_dump_append(ctx->dump_ctx, ")"); break; - case SCC_IR_BUILTIN_TAG_MEMSET: + case SCC_HIR_BUILTIN_TAG_MEMSET: scc_tree_dump_append(ctx->dump_ctx, "memset"); break; - case SCC_IR_BUILTIN_TAG_VA_ARG: + case SCC_HIR_BUILTIN_TAG_VA_ARG: scc_tree_dump_append(ctx->dump_ctx, "va_arg"); break; - case SCC_IR_BUILTIN_TAG_VA_END: + case SCC_HIR_BUILTIN_TAG_VA_END: scc_tree_dump_append(ctx->dump_ctx, "va_end"); break; - case SCC_IR_BUILTIN_TAG_VA_COPY: + case SCC_HIR_BUILTIN_TAG_VA_COPY: scc_tree_dump_append(ctx->dump_ctx, "va_copy"); break; - case SCC_IR_BUILTIN_TAG_VA_START: + case SCC_HIR_BUILTIN_TAG_VA_START: scc_tree_dump_append(ctx->dump_ctx, "va_start"); break; default: @@ -513,60 +514,43 @@ void scc_ir_dump_value_linear(scc_ir_dump_ctx_t *ctx, } break; } - case SCC_IR_VALUE_TAG_CONST_INT: + case SCC_HIR_VALUE_TAG_INTEGER: // 值已经在 format 中输出,这里不需要再做 break; - case SCC_IR_VALUE_TAG_CONST_UINT: { - scc_ir_type_t *type = - scc_ir_module_get_type(GET_MODULE(ctx), value->type); - Assert(type != nullptr); - if (type->tag == SCC_IR_TYPE_u8) { - scc_tree_dump_append_fmt(ctx->dump_ctx, "%c", - value->data.const_uint.uint8); - } else { - scc_tree_dump_append_fmt(ctx->dump_ctx, "%u", - value->data.const_uint.uint32); - } - break; - } - case SCC_IR_VALUE_TAG_CONST_FLOAT: - scc_tree_dump_append_fmt(ctx->dump_ctx, "%f", - value->data.const_float.float32); - break; - case SCC_IR_VALUE_TAG_AGGREGATE: + case SCC_HIR_VALUE_TAG_AGGREGATE: // 聚合类型:递归输出每个元素(每个占一行) scc_vec_foreach(value->data.aggregate.fields, i) { - scc_ir_dump_value_linear( + scc_hir_dump_value_linear( ctx, scc_vec_at(value->data.aggregate.fields, i)); scc_tree_dump_append(ctx->dump_ctx, "\n"); } return; - case SCC_IR_VALUE_TAG_ALLOC: + case SCC_HIR_VALUE_TAG_ALLOC: scc_tree_dump_append(ctx->dump_ctx, "alloc"); break; - case SCC_IR_VALUE_TAG_LOAD: + case SCC_HIR_VALUE_TAG_LOAD: scc_tree_dump_append(ctx->dump_ctx, "load "); format_ref_or_value(ctx, value->data.load.target); break; - case SCC_IR_VALUE_TAG_STORE: + case SCC_HIR_VALUE_TAG_STORE: scc_tree_dump_append(ctx->dump_ctx, "store "); format_ref_or_value(ctx, value->data.store.value); scc_tree_dump_append(ctx->dump_ctx, " -> "); format_ref_or_value(ctx, value->data.store.target); break; - case SCC_IR_VALUE_TAG_GET_ELEM_PTR: + case SCC_HIR_VALUE_TAG_GET_ELEM_PTR: scc_tree_dump_append(ctx->dump_ctx, "getelemptr "); format_ref_or_value(ctx, value->data.get_elem_ptr.src_addr); scc_tree_dump_append(ctx->dump_ctx, ", "); format_ref_or_value(ctx, value->data.get_elem_ptr.index); break; - case SCC_IR_VALUE_TAG_OP: + case SCC_HIR_VALUE_TAG_OP: format_ref_or_value(ctx, value->data.op.lhs); scc_tree_dump_append_fmt(ctx->dump_ctx, " %s ", get_op_str(value->data.op.op)); format_ref_or_value(ctx, value->data.op.rhs); break; - case SCC_IR_VALUE_TAG_BRANCH: + case SCC_HIR_VALUE_TAG_BRANCH: if (value->data.branch.cond) { scc_tree_dump_append(ctx->dump_ctx, "br "); format_ref_or_value(ctx, value->data.branch.cond); @@ -579,13 +563,13 @@ void scc_ir_dump_value_linear(scc_ir_dump_ctx_t *ctx, value->data.branch.true_bblock); } break; - case SCC_IR_VALUE_TAG_JUMP: + case SCC_HIR_VALUE_TAG_JUMP: scc_tree_dump_append_fmt(ctx->dump_ctx, "jmp label %%L%u", value->data.jump.target_bblock); break; - case SCC_IR_VALUE_TAG_CALL: { - scc_ir_func_t *func = - scc_ir_module_get_func(GET_MODULE(ctx), value->data.call.callee); + case SCC_HIR_VALUE_TAG_CALL: { + scc_hir_func_t *func = + scc_hir_module_get_func(GET_MODULE(ctx), value->data.call.callee); scc_tree_dump_append_fmt(ctx->dump_ctx, "call @%s(", func ? (func->name ? func->name : "") : ""); @@ -597,7 +581,7 @@ void scc_ir_dump_value_linear(scc_ir_dump_ctx_t *ctx, scc_tree_dump_append(ctx->dump_ctx, ")"); break; } - case SCC_IR_VALUE_TAG_RET: + case SCC_HIR_VALUE_TAG_RET: if (value->data.ret.ret_val != 0) { scc_tree_dump_append(ctx->dump_ctx, "ret "); format_ref_or_value(ctx, value->data.ret.ret_val); @@ -605,18 +589,18 @@ void scc_ir_dump_value_linear(scc_ir_dump_ctx_t *ctx, scc_tree_dump_append(ctx->dump_ctx, "ret void"); } break; - case SCC_IR_VALUE_TAG_FUNC_ARG_REF: + case SCC_HIR_VALUE_TAG_FUNC_ARG_REF: scc_tree_dump_append_fmt(ctx->dump_ctx, "arg[%zu]", value->data.arg_ref.idx); break; - case SCC_IR_VALUE_TAG_GLOBAL_ALLOC: + case SCC_HIR_VALUE_TAG_GLOBAL_ALLOC: scc_tree_dump_append_fmt(ctx->dump_ctx, "global %s", value->name); scc_tree_dump_begin_line(ctx->dump_ctx); - scc_ir_dump_value_linear(ctx, value->data.global_alloc.value); + scc_hir_dump_value_linear(ctx, value->data.global_alloc.value); return; - case SCC_IR_VALUE_TAG_CONST_ARRAY: + case SCC_HIR_VALUE_TAG_ARRAY: scc_tree_dump_append(ctx->dump_ctx, "const_array "); - scc_ir_dump_type_linear(ctx, value->data.const_array.base_type); + scc_hir_dump_type_linear(ctx, value->data.const_array.base_type); scc_tree_dump_append(ctx->dump_ctx, " ["); scc_vec_foreach(value->data.const_array.fields, i) { u8 ch = scc_vec_at(value->data.const_array.fields, i); @@ -631,31 +615,32 @@ void scc_ir_dump_value_linear(scc_ir_dump_ctx_t *ctx, } } -void scc_ir_dump_bblock_linear(scc_ir_dump_ctx_t *ctx, - scc_ir_bblock_ref_t bblock_ref) { +void scc_hir_dump_bblock_linear(scc_hir_dump_t *ctx, + scc_hir_bblock_ref_t bblock_ref) { scc_tree_dump_begin_line(ctx->dump_ctx); - scc_ir_bblock_t *bblock = - scc_ir_module_get_bblock(GET_MODULE(ctx), bblock_ref); + scc_hir_bblock_t *bblock = + scc_hir_module_get_bblock(GET_MODULE(ctx), bblock_ref); if (!bblock) { scc_tree_dump_append(ctx->dump_ctx, ""); return; } - if (bblock->label && bblock->label[0] != '\0') + if (bblock->name && bblock->name[0] != '\0') scc_tree_dump_append_fmt(ctx->dump_ctx, "%%L%d %s:", bblock_ref, - bblock->label); + bblock->name); else scc_tree_dump_append_fmt(ctx->dump_ctx, "%%L%d :", bblock_ref); - for (usize i = 0; i < scc_vec_size(bblock->instrs); i++) { + for (usize i = 0; i < scc_vec_size(SCC_HIR_BBLOCK_VALUES(*bblock)); i++) { scc_tree_dump_begin_line(ctx->dump_ctx); scc_tree_dump_append(ctx->dump_ctx, " "); - scc_ir_dump_value_linear(ctx, scc_vec_at(bblock->instrs, i)); + scc_hir_dump_value_linear( + ctx, scc_vec_at(SCC_HIR_BBLOCK_VALUES(*bblock), i)); } } -void scc_ir_dump_func_linear(scc_ir_dump_ctx_t *ctx, scc_ir_func_ref_t func_ref, - int is_decl) { - scc_ir_func_t *func = scc_ir_module_get_func(GET_MODULE(ctx), func_ref); +void scc_hir_dump_func_linear(scc_hir_dump_t *ctx, scc_hir_func_ref_t func_ref, + int is_decl) { + scc_hir_func_t *func = scc_hir_module_get_func(GET_MODULE(ctx), func_ref); scc_tree_dump_begin_line(ctx->dump_ctx); if (!func) { scc_tree_dump_append(ctx->dump_ctx, ""); @@ -665,14 +650,16 @@ void scc_ir_dump_func_linear(scc_ir_dump_ctx_t *ctx, scc_ir_func_ref_t func_ref, (func->name && func->name[0]) ? func->name : ""); - if (scc_vec_size(func->params) > 0) { + if (scc_vec_size(SCC_HIR_FUNC_META(*func)->params) > 0) { scc_tree_dump_append(ctx->dump_ctx, "("); - for (usize i = 0; i < scc_vec_size(func->params); i++) { + for (usize i = 0; i < scc_vec_size(SCC_HIR_FUNC_META(*func)->params); + i++) { if (i > 0) scc_tree_dump_append(ctx->dump_ctx, ", "); - scc_ir_value_ref_t param_ref = scc_vec_at(func->params, i); - scc_ir_value_t *param_node = - scc_ir_module_get_value(GET_MODULE(ctx), param_ref); + scc_hir_value_ref_t param_ref = + scc_vec_at(SCC_HIR_FUNC_META(*func)->params, i); + scc_hir_value_t *param_node = + scc_hir_module_get_value(GET_MODULE(ctx), param_ref); scc_tree_dump_append(ctx->dump_ctx, "%"); if (param_node && param_node->name && param_node->name[0] != '\0') scc_tree_dump_append_fmt(ctx->dump_ctx, "%u[%s]", param_ref, @@ -686,7 +673,7 @@ void scc_ir_dump_func_linear(scc_ir_dump_ctx_t *ctx, scc_ir_func_ref_t func_ref, } scc_tree_dump_append(ctx->dump_ctx, ": "); - scc_ir_dump_type_linear(ctx, func->type); + scc_hir_dump_type_linear(ctx, SCC_HIR_FUNC_META(*func)->type); if (is_decl) { scc_tree_dump_append(ctx->dump_ctx, ";"); @@ -695,26 +682,26 @@ void scc_ir_dump_func_linear(scc_ir_dump_ctx_t *ctx, scc_ir_func_ref_t func_ref, scc_tree_dump_append(ctx->dump_ctx, " {"); for (usize i = 0; i < scc_vec_size(func->bblocks); i++) { - scc_ir_dump_bblock_linear(ctx, scc_vec_at(func->bblocks, i)); + scc_hir_dump_bblock_linear(ctx, scc_vec_at(func->bblocks, i)); scc_tree_dump_append(ctx->dump_ctx, ""); } scc_tree_dump_begin_line(ctx->dump_ctx); scc_tree_dump_append(ctx->dump_ctx, "}"); } -void scc_ir_dump_cprog_linear(scc_ir_dump_ctx_t *ctx) { +void scc_hir_dump_cprog_linear(scc_hir_dump_t *ctx) { for (usize i = 0; i < scc_vec_size(ctx->cprog->global_vals); i++) { scc_tree_dump_begin_line(ctx->dump_ctx); - scc_ir_dump_value_linear(ctx, scc_vec_at(ctx->cprog->global_vals, i)); + scc_hir_dump_value_linear(ctx, scc_vec_at(ctx->cprog->global_vals, i)); } for (usize i = 0; i < scc_vec_size(ctx->cprog->func_decls); i++) { - scc_ir_func_ref_t func_decl = scc_vec_at(ctx->cprog->func_decls, i); - scc_ir_func_t *func = - scc_ir_module_get_func(GET_MODULE(ctx), func_decl); + scc_hir_func_ref_t func_decl = scc_vec_at(ctx->cprog->func_decls, i); + scc_hir_func_t *func = + scc_hir_module_get_func(GET_MODULE(ctx), func_decl); if (func && scc_vec_size(func->bblocks) == 0) - scc_ir_dump_func_linear(ctx, func_decl, 1); + scc_hir_dump_func_linear(ctx, func_decl, 1); } for (usize i = 0; i < scc_vec_size(ctx->cprog->func_defs); i++) { - scc_ir_dump_func_linear(ctx, scc_vec_at(ctx->cprog->func_defs, i), 0); + scc_hir_dump_func_linear(ctx, scc_vec_at(ctx->cprog->func_defs, i), 0); } } diff --git a/libs/ir/hir/src/hir_module.c b/libs/ir/hir/src/hir_module.c new file mode 100644 index 0000000..034296f --- /dev/null +++ b/libs/ir/hir/src/hir_module.c @@ -0,0 +1,128 @@ +#include + +void scc_hir_module_init(scc_hir_module_t *ctx) { + scc_cfg_module_init(&ctx->cfg_module); + + scc_vec_init(ctx->values); + scc_vec_init(ctx->types); + scc_hashtable_usize_init(&ctx->uid2value); + scc_hashtable_usize_init(&ctx->uid2type); + // 预留UID 0 作为无效引用 + scc_vec_push(ctx->values, (scc_hir_value_t){0}); + scc_vec_push(ctx->types, (scc_hir_type_t){0}); + ctx->value_uid = 1; + ctx->type_uid = 1; + + scc_vec_init(ctx->funcs_meta); + scc_vec_init(ctx->bblock_meta); +} + +void scc_hir_module_drop(scc_hir_module_t *ctx) { + scc_cfg_module_drop(&ctx->cfg_module); + + // 释放所有实体的内部内存 + for (usize i = 1; i < ctx->values.size; i++) { + scc_hir_value_t *node = &ctx->values.data[i]; + scc_vec_free(node->used_by); + if (node->tag == SCC_HIR_VALUE_TAG_CALL) { + scc_vec_free(node->data.call.args); + } + } + + for (usize i = 1; i < ctx->types.size; i++) { + scc_hir_type_t *type = &ctx->types.data[i]; + if (type->tag == SCC_HIR_TYPE_FUNC) { + scc_vec_free(type->data.function.params); + } + } + + // TODO free + // ctx->cfg_module.funcs; + // for (usize i = 1; i < ctx->bblocks.size; i++) { + // scc_hir_bblock_t *bblock = &ctx->bblocks.data[i]; + // scc_vec_free(bblock->instrs); + // } + + // for (usize i = 1; i < ctx->funcs.size; i++) { + // scc_hir_func_t *func = &ctx->funcs.data[i]; + // scc_vec_free(func->params); + // scc_vec_free(func->bblocks); + // } + + scc_vec_free(ctx->values); + scc_vec_free(ctx->types); + scc_hashtable_drop(&ctx->uid2value); + scc_hashtable_drop(&ctx->uid2type); +} + +// 辅助宏:创建实体并添加到哈希表 +#define CREATE_ENTITY(ctx, vec, uid, data, hashtable) \ + do { \ + /* 分配新UID */ \ + unsigned new_uid = (ctx)->uid++; \ + /* 添加到哈希表 */ \ + scc_hashtable_set(&(ctx)->hashtable, (const void *)(usize)new_uid, \ + (void *)(usize)(scc_vec_size(vec))); \ + /* 添加到向量 */ \ + scc_vec_push((vec), *(data)); \ + return new_uid; \ + } while (0) + +scc_hir_type_ref_t scc_hir_module_add_type(scc_hir_module_t *ctx, + const scc_hir_type_t *type) { + CREATE_ENTITY(ctx, ctx->types, type_uid, type, uid2type); +} + +scc_hir_value_ref_t scc_hir_module_add_value(scc_hir_module_t *ctx, + const scc_hir_value_t *node) { + CREATE_ENTITY(ctx, ctx->values, value_uid, node, uid2value); +} + +scc_hir_bblock_ref_t scc_hir_module_add_bblock(scc_hir_module_t *ctx, + const scc_hir_bblock_t *bblock) { + scc_hir_bblock_ref_t ref = + scc_cfg_module_add_bblock(&ctx->cfg_module, bblock); + // TODO + return ref; +} + +scc_hir_func_ref_t scc_hir_module_add_func(scc_hir_module_t *ctx, + const scc_hir_func_t *func) { + scc_hir_func_ref_t ref = scc_cfg_module_add_func(&ctx->cfg_module, func); + scc_vec_push(ctx->funcs_meta, func->attribute); + return ref; +} + +// 辅助宏:从哈希表获取索引 +#define GET_ENTITY_INDEX(ctx, ref, hashtable) \ + ((usize)scc_hashtable_get(&(ctx)->hashtable, (void *)(usize)ref)) + +scc_hir_type_t *scc_hir_module_get_type(scc_hir_module_t *ctx, + scc_hir_type_ref_t ref) { + if (ref == 0) + return nullptr; + usize idx = GET_ENTITY_INDEX(ctx, ref, uid2type); + if (idx >= ctx->types.size) + return nullptr; + return &ctx->types.data[idx]; +} + +scc_hir_value_t *scc_hir_module_get_value(scc_hir_module_t *ctx, + scc_hir_value_ref_t ref) { + if (ref == 0) + return nullptr; + usize idx = GET_ENTITY_INDEX(ctx, ref, uid2value); + if (idx >= ctx->values.size) + return nullptr; + return &ctx->values.data[idx]; +} + +scc_hir_bblock_t *scc_hir_module_get_bblock(scc_hir_module_t *ctx, + scc_hir_bblock_ref_t ref) { + return scc_cfg_module_unsafe_get_bblock(&ctx->cfg_module, ref); +} + +scc_hir_func_t *scc_hir_module_get_func(scc_hir_module_t *ctx, + scc_hir_func_ref_t ref) { + return scc_cfg_module_unsafe_get_func(&ctx->cfg_module, ref); +} diff --git a/libs/ir/src/ir_prog.c b/libs/ir/hir/src/hir_prog.c similarity index 52% rename from libs/ir/src/ir_prog.c rename to libs/ir/hir/src/hir_prog.c index 2db49c3..8c2d529 100644 --- a/libs/ir/src/ir_prog.c +++ b/libs/ir/hir/src/hir_prog.c @@ -1,15 +1,15 @@ -#include +#include -void scc_ir_cprog_init(scc_ir_cprog_t *in) { +void scc_hir_cprog_init(scc_hir_cprog_t *in) { scc_vec_init(in->func_decls); scc_vec_init(in->func_defs); scc_vec_init(in->global_vals); - scc_ir_module_init(&in->module); + scc_hir_module_init(&in->module); } -void scc_ir_cprog_drop(scc_ir_cprog_t *in) { +void scc_hir_cprog_drop(scc_hir_cprog_t *in) { scc_vec_free(in->func_decls); scc_vec_free(in->func_defs); scc_vec_free(in->global_vals); - scc_ir_module_drop(&in->module); + scc_hir_module_drop(&in->module); } diff --git a/libs/ir/hir/src/scc_hir.c b/libs/ir/hir/src/scc_hir.c new file mode 100644 index 0000000..591f925 --- /dev/null +++ b/libs/ir/hir/src/scc_hir.c @@ -0,0 +1,117 @@ +#include + +void scc_hir_type_init(scc_hir_type_t *in, scc_hir_type_tag_t tag) { + Assert(in != nullptr); + in->tag = tag; + in->name = nullptr; + switch (tag) { + case SCC_HIR_TYPE_unknown: + case SCC_HIR_TYPE_void: + case SCC_HIR_TYPE_i8: + case SCC_HIR_TYPE_i16: + case SCC_HIR_TYPE_i32: + case SCC_HIR_TYPE_i64: + case SCC_HIR_TYPE_i128: + case SCC_HIR_TYPE_u8: + case SCC_HIR_TYPE_u16: + case SCC_HIR_TYPE_u32: + case SCC_HIR_TYPE_u64: + case SCC_HIR_TYPE_u128: + case SCC_HIR_TYPE_f16: + case SCC_HIR_TYPE_f32: + case SCC_HIR_TYPE_f64: + case SCC_HIR_TYPE_f128: + break; + case SCC_HIR_TYPE_ARRAY: + in->data.array.base = 0; + in->data.array.len = 0; + break; + case SCC_HIR_TYPE_PTR: + in->data.pointer.base = 0; + break; + case SCC_HIR_TYPE_FUNC: + scc_vec_init(in->data.function.params); + in->data.function.ret_type = 0; + break; + case SCC_HIR_TYPE_UNION: + case SCC_HIR_TYPE_STRUCT: + scc_vec_init(in->data.aggregate.fields); + break; + default: + UNREACHABLE(); + break; + } +} + +void scc_hir_bblock_init(scc_hir_bblock_t *in, const char *label) { + Assert(in != nullptr); + Assert(label != nullptr); + in->name = label; + scc_vec_init(in->values); +} + +void scc_hir_func_init(scc_hir_func_t *in, const char *name) { + Assert(in != nullptr); + Assert(name != nullptr); + in->name = name; + scc_hir_func_meta_t *meta = SCC_HIR_FUNC_META(*in); + meta->type = SCC_HIR_REF_nullptr; + scc_vec_init(in->bblocks); + scc_vec_init(meta->params); +} + +void scc_hir_value_init(scc_hir_value_t *in, const char *name, + scc_hir_value_tag_t tag) { + Assert(in != nullptr); + in->name = name; + in->tag = tag; + scc_vec_init(in->used_by); + in->type = 0; + + switch (tag) { + case SCC_HIR_VALUE_TAG_NULLPTR: + break; + case SCC_HIR_VALUE_TAG_BUILTIN: + break; + case SCC_HIR_VALUE_TAG_INTEGER: + scc_ap_init(&in->data.integer); + break; + case SCC_HIR_VALUE_TAG_ALLOC: + // TODO(); + break; + case SCC_HIR_VALUE_TAG_LOAD: + in->data.load.target = 0; + break; + case SCC_HIR_VALUE_TAG_STORE: + in->data.store.target = 0; + in->data.store.value = 0; + break; + case SCC_HIR_VALUE_TAG_GET_ELEM_PTR: + in->data.get_elem_ptr.src_addr = 0; + in->data.get_elem_ptr.index = 0; + break; + case SCC_HIR_VALUE_TAG_OP: + in->data.op.op = SCC_HIR_OP_EMPTY; + in->data.op.lhs = 0; + in->data.op.rhs = 0; + break; + case SCC_HIR_VALUE_TAG_BRANCH: + in->data.branch.cond = 0; + in->data.branch.true_bblock = 0; + in->data.branch.false_bblock = 0; + break; + case SCC_HIR_VALUE_TAG_JUMP: + in->data.jump.target_bblock = 0; + break; + case SCC_HIR_VALUE_TAG_CALL: + scc_vec_init(in->data.call.args); + in->data.call.callee = 0; + break; + case SCC_HIR_VALUE_TAG_RET: + in->data.ret.ret_val = 0; + break; + default: + UNREACHABLE(); + break; + } +} diff --git a/libs/ir/tests/test_ir_unit.c b/libs/ir/hir/tests/test_ir_unit.c similarity index 100% rename from libs/ir/tests/test_ir_unit.c rename to libs/ir/hir/tests/test_ir_unit.c diff --git a/libs/ir/include/ir_builder.h b/libs/ir/include/ir_builder.h deleted file mode 100644 index 6d03e76..0000000 --- a/libs/ir/include/ir_builder.h +++ /dev/null @@ -1,289 +0,0 @@ -#ifndef __SCC_IR_BUILDER_H__ -#define __SCC_IR_BUILDER_H__ - -#include "ir_ctx.h" -#include "scc_ir.h" - -typedef struct scc_ir_builder scc_ir_builder_t; - -/** - * @brief IR 构建器上下文 - * - * 负责管理 IR 构建过程中的所有状态: - * - 类型统一化(type uniquing) - * - 符号命名分配 - * - 内存管理 - * - 当前构建位置(函数、基本块) - */ -struct scc_ir_builder { - scc_ir_cprog_t *cprog; - scc_ir_ctx_t ctx; ///< 核心上下文 - scc_ir_func_ref_t current_func; ///< 当前正在构建的函数 - scc_ir_bblock_ref_t current_bblock; ///< 当前基本块 -#ifndef SCC_NO_DEBUG - int borrow_depth; - const char *dbg_file; - int dbg_line; -#endif -}; - -#ifndef SCC_NO_DEBUG -#define SCC_IR_BUILDER_BEGIN_BORROW(builder, ptr_var, ptr_expr) \ - do { \ - (builder)->borrow_depth++; \ - (builder)->dbg_file = __FILE__; \ - (builder)->dbg_line = __LINE__; \ - ptr_var = (ptr_expr); \ - } while (0) - -#define SCC_IR_BUILDER_END_BORROW(builder) \ - do { \ - (builder)->borrow_depth--; \ - } while (0) - -#define SCC_IR_BUILDER_CHECK_NO_BORROW(builder) \ - do { \ - if ((builder)->borrow_depth != 0) { \ - Panic("IR Builder: attempt to reallocate while borrowed at %s:%d", \ - (builder)->dbg_file, (builder)->dbg_line); \ - } \ - } while (0) -#else -#define SCC_IR_BUILDER_BEGIN_BORROW(builder, ptr_var, ptr_expr) \ - ptr_var = (ptr_expr) -#define SCC_IR_BUILDER_END_BORROW(builder) ((void)0) -#define SCC_IR_BUILDER_CHECK_NO_BORROW(builder) ((void)0) -#endif - -/** - * @brief 初始化 IR 构建器 - */ -void scc_ir_builder_init(scc_ir_builder_t *builder, scc_ir_cprog_t *cprog); - -/** - * @brief 销毁 IR 构建器及其所有资源 - */ -void scc_ir_builder_drop(scc_ir_builder_t *builder); - -scc_ir_func_ref_t scc_ir_builder_func(scc_ir_builder_t *builder, - scc_ir_type_ref_t type_ref, - const char *name); - -scc_ir_type_ref_t scc_ir_builder_type(scc_ir_builder_t *builder, - const scc_ir_type_t *type_desc); - -void scc_ir_builder_add_instr(scc_ir_builder_t *builder, - scc_ir_value_ref_t instr); - -scc_ir_value_ref_t scc_ir_builder_global_alloca(scc_ir_builder_t *builder, - scc_ir_type_ref_t type, - scc_ir_value_ref_t value); - -/** - * @brief 创建alloca指令(在当前基本块中) - * @param type 分配的类型 - * @param name 变量名(可为nullptr) - */ -scc_ir_value_ref_t scc_ir_builder_alloca(scc_ir_builder_t *builder, - scc_ir_type_ref_t type, - const char *name); - -#define SCC_IR_BUILDER_TYPE_FUNC(scc_type) \ - [[maybe_unused]] static inline scc_ir_type_ref_t \ - scc_ir_builder_type_##scc_type(scc_ir_builder_t *builder) { \ - scc_ir_type_t type_desc; \ - scc_ir_type_init(&type_desc, SCC_IR_TYPE_##scc_type); \ - return scc_ir_ctx_get_type(&builder->ctx, &type_desc); \ - } - -SCC_IR_BUILDER_TYPE_FUNC(unknown) -SCC_IR_BUILDER_TYPE_FUNC(void) -SCC_IR_BUILDER_TYPE_FUNC(i8) -SCC_IR_BUILDER_TYPE_FUNC(i16) -SCC_IR_BUILDER_TYPE_FUNC(i32) -SCC_IR_BUILDER_TYPE_FUNC(i64) -SCC_IR_BUILDER_TYPE_FUNC(i128) -SCC_IR_BUILDER_TYPE_FUNC(u8) -SCC_IR_BUILDER_TYPE_FUNC(u16) -SCC_IR_BUILDER_TYPE_FUNC(u32) -SCC_IR_BUILDER_TYPE_FUNC(u64) -SCC_IR_BUILDER_TYPE_FUNC(u128) -// SCC_IR_BUILDER_TYPE_FUNC(f8) -SCC_IR_BUILDER_TYPE_FUNC(f16) -SCC_IR_BUILDER_TYPE_FUNC(f32) -SCC_IR_BUILDER_TYPE_FUNC(f64) -SCC_IR_BUILDER_TYPE_FUNC(f128) - -static inline scc_ir_value_ref_t -scc_ir_builder_builtin_memcpy(scc_ir_builder_t *builder, - scc_ir_value_ref_t dest, scc_ir_value_ref_t src, - scc_ir_value_ref_t len) { - Assert(builder && src && dest && len); - scc_ir_value_t value; - scc_ir_value_init(&value, nullptr, SCC_IR_VALUE_TAG_BUILTIN); - value.type = scc_ir_builder_type_void(builder); // memcpy 返回 void* - value.data.builtin.tag = SCC_IR_BUILTIN_TAG_MEMCPY; - value.data.builtin.func.memcpy.dest = dest; - value.data.builtin.func.memcpy.src = src; - value.data.builtin.func.memcpy.size = len; - scc_ir_value_ref_t ref = - scc_ir_module_add_value(builder->ctx.module, &value); - scc_ir_builder_add_instr(builder, ref); - return ref; -} - -// TODO -static inline scc_ir_value_ref_t -scc_ir_builder_const_int(scc_ir_builder_t *builder, scc_ir_type_ref_t type, - scc_ir_const_int_t val) { - scc_ir_value_t value; - scc_ir_value_init(&value, nullptr, SCC_IR_VALUE_TAG_CONST_INT); - value.data.const_int = val; - value.type = type; - return scc_ir_module_add_value(&builder->cprog->module, &value); -} - -scc_ir_value_ref_t scc_ir_builder_const_string(scc_ir_builder_t *builder, - const char *str, usize len); - -/** - * @brief 开始构建函数 - * @param func_ref 函数引用 - * @param param_names 参数名列表(可为nullptr) - * @return void - */ -void scc_ir_builder_begin_func(scc_ir_builder_t *builder, - scc_ir_func_ref_t func_ref); - -/** - * @brief 结束当前函数的构建 - */ -void scc_ir_builder_end_func(scc_ir_builder_t *builder); - -/** - * @brief 获取当前正在构建的函数 - */ -scc_ir_func_ref_t scc_ir_builder_current_func(scc_ir_builder_t *builder); - -/** - * @brief 创建一个新的基本块,并自动添加到当前函数中,但不改变当前块。 - * @param builder IR构建器 - * @param label 基本块标签(可为 nullptr,自动生成) - * @return 新基本块的引用 - */ -scc_ir_bblock_ref_t scc_ir_builder_bblock(scc_ir_builder_t *builder, - const char *label); - -/** - * @brief 开始构建新的基本块 - * @param label 基本块标签(可为nullptr,自动生成) - * @return 基本块引用 - */ -scc_ir_bblock_ref_t scc_ir_builder_begin_bblock(scc_ir_builder_t *builder, - const char *label); - -/** - * @brief 结束当前基本块的构建 - */ -void scc_ir_builder_end_bblock(scc_ir_builder_t *builder); - -scc_ir_func_ref_t scc_ir_builder_current_bblock(scc_ir_builder_t *builder); -/** - * @brief 设置当前基本块 - */ -void scc_ir_builder_set_current_bblock(scc_ir_builder_t *builder, - scc_ir_bblock_ref_t bblock); - -scc_ir_value_ref_t scc_ir_builder_func_arg_ref(scc_ir_builder_t *builder, - scc_ir_type_ref_t type, - const char *name, usize arg_idx); - -/** - * @brief 创建load指令 - * @param ptr 指针操作数 - */ -scc_ir_value_ref_t scc_ir_builder_load(scc_ir_builder_t *builder, - scc_ir_value_ref_t ptr); - -/** - * @brief 创建store指令 - * @param ptr 目标指针 - * @param value 要存储的值 - */ -scc_ir_value_ref_t scc_ir_builder_store(scc_ir_builder_t *builder, - scc_ir_value_ref_t ptr, - scc_ir_value_ref_t value); - -/** - * @brief 创建getptr指令(指针运算) - * @param ptr 基础指针 - * @param index 索引值 - */ -scc_ir_value_ref_t scc_ir_builder_get_elem_ptr(scc_ir_builder_t *builder, - scc_ir_value_ref_t ptr, - scc_ir_value_ref_t index); - -/** - * @brief 创建二元运算指令 - * @param op 操作符 - * @param lhs 左操作数 - * @param rhs 右操作数 - */ -scc_ir_value_ref_t scc_ir_builder_binop(scc_ir_builder_t *builder, - scc_ir_op_type_t op, - scc_ir_value_ref_t lhs, - scc_ir_value_ref_t rhs); - -/** - * @brief 创建比较指令 - * @param op 比较操作符 - * @param lhs 左操作数 - * @param rhs 右操作数 - */ -scc_ir_value_ref_t scc_ir_builder_cmp(scc_ir_builder_t *builder, - scc_ir_op_type_t op, - scc_ir_value_ref_t lhs, - scc_ir_value_ref_t rhs); - -/** - * @brief 创建跳转指令(无条件) - * @param target 目标基本块 - */ -scc_ir_value_ref_t scc_ir_builder_jump(scc_ir_builder_t *builder, - scc_ir_bblock_ref_t target); - -/** - * @brief 创建条件分支指令 - * @param cond 条件值 - * @param true_target 条件为真时的目标 - * @param false_target 条件为假时的目标 - */ -scc_ir_value_ref_t scc_ir_builder_branch(scc_ir_builder_t *builder, - scc_ir_value_ref_t cond, - scc_ir_bblock_ref_t true_target, - scc_ir_bblock_ref_t false_target); - -/** - * @brief 创建函数调用指令 - * @param callee 被调用函数 - * @param args 参数列表 - * @param arg_count 参数数量 - */ -scc_ir_value_ref_t scc_ir_builder_call(scc_ir_builder_t *builder, - scc_ir_func_ref_t callee, - const scc_ir_value_ref_t *args, - usize arg_count); - -/** - * @brief 创建返回指令(带返回值) - * @param value 返回值 - */ -scc_ir_value_ref_t scc_ir_builder_ret(scc_ir_builder_t *builder, - scc_ir_value_ref_t value); - -/** - * @brief 创建返回指令(void返回) - */ -scc_ir_value_ref_t scc_ir_builder_ret_void(scc_ir_builder_t *builder); - -#endif /* __SCC_IR_BUILDER_H__ */ diff --git a/libs/ir/include/ir_ctx.h b/libs/ir/include/ir_ctx.h deleted file mode 100644 index 96149d7..0000000 --- a/libs/ir/include/ir_ctx.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef __SCC_IR_CTX_H__ -#define __SCC_IR_CTX_H__ - -#include "ir_def.h" -#include "ir_prog.h" -#include - -typedef struct { - scc_ir_module_t *module; // 关联的模块(用于实际存储) - scc_hashtable_t type_uniquing; // 类型哈希表:hash -> type_ref - scc_hashtable_t const_pool; // 常量哈希表:hash -> node_ref - scc_hashtable_t func_decl_set; // 函数声明集合:name -> func_ref -} scc_ir_ctx_t; - -void scc_ir_ctx_init(scc_ir_ctx_t *ctx, scc_ir_module_t *module); -void scc_ir_ctx_drop(scc_ir_ctx_t *ctx); - -// 获取唯一类型,若不存在则创建并返回新引用 -scc_ir_type_ref_t scc_ir_ctx_get_type(scc_ir_ctx_t *ctx, - const scc_ir_type_t *type_desc); - -// 注册函数声明,若已存在则返回已有引用 -scc_ir_func_ref_t scc_ir_ctx_declare_func(scc_ir_ctx_t *ctx, - scc_ir_type_ref_t type, - const char *name); - -#endif /* __SCC_IR_CTX_H__ */ diff --git a/libs/ir/include/ir_def.h b/libs/ir/include/ir_def.h deleted file mode 100644 index fa1b14b..0000000 --- a/libs/ir/include/ir_def.h +++ /dev/null @@ -1,287 +0,0 @@ -#ifndef __SCC_IR_DEF_H__ -#define __SCC_IR_DEF_H__ - -#include - -#define SCC_IR_REF_nullptr 0 - -typedef unsigned int ir_handle_t; -typedef const char *scc_ir_label_t; - -typedef SCC_VEC(u8) scc_ir_buffer_t; - -typedef struct scc_ir_value scc_ir_value_t; -typedef ir_handle_t scc_ir_value_ref_t; -typedef SCC_VEC(scc_ir_value_ref_t) scc_ir_value_ref_vec_t; - -typedef struct scc_ir_type scc_ir_type_t; -typedef ir_handle_t scc_ir_type_ref_t; -typedef SCC_VEC(scc_ir_type_ref_t) scc_ir_type_ref_vec_t; - -typedef struct scc_ir_bblock scc_ir_bblock_t; -typedef ir_handle_t scc_ir_bblock_ref_t; -typedef SCC_VEC(scc_ir_bblock_ref_t) scc_ir_bblock_ref_vec_t; - -typedef struct scc_ir_func scc_ir_func_t; -typedef ir_handle_t scc_ir_func_ref_t; -typedef SCC_VEC(scc_ir_func_ref_t) scc_ir_func_ref_vec_t; - -typedef enum scc_ir_type_tag { - SCC_IR_TYPE_unknown, - SCC_IR_TYPE_void, - SCC_IR_TYPE_i8, - SCC_IR_TYPE_i16, - SCC_IR_TYPE_i32, - SCC_IR_TYPE_i64, - SCC_IR_TYPE_i128, - SCC_IR_TYPE_u8, - SCC_IR_TYPE_u16, - SCC_IR_TYPE_u32, - SCC_IR_TYPE_u64, - SCC_IR_TYPE_u128, - SCC_IR_TYPE_f16, - SCC_IR_TYPE_f32, - SCC_IR_TYPE_f64, - SCC_IR_TYPE_f128, - SCC_IR_TYPE_PTR, - SCC_IR_TYPE_ARRAY, - SCC_IR_TYPE_FUNC, - SCC_IR_TYPE_STRUCT, - SCC_IR_TYPE_UNION, - SCC_IR_TYPE_VECTOR, // TODO SIMD -} scc_ir_type_tag_t; - -struct scc_ir_type { - scc_ir_type_tag_t tag; - const char *name; // For Debug - union { - struct { - scc_ir_type_ref_t base; - usize len; // TODO usize is target dependent - } array; - struct { - scc_ir_type_ref_t base; - } pointer; - struct { - scc_ir_type_ref_vec_t fields; - } aggregate; - struct { - scc_ir_type_ref_vec_t params; - scc_ir_type_ref_t ret_type; - } function; - } data; -}; - -struct scc_ir_bblock { - scc_ir_label_t label; - scc_ir_value_ref_vec_t instrs; - // ir_arr_t used_by; -}; // basic block - -struct scc_ir_func { - scc_ir_label_t name; - scc_ir_type_ref_t type; - scc_ir_value_ref_vec_t params; - scc_ir_bblock_ref_vec_t bblocks; -}; - -typedef enum scc_ir_value_tag { - SCC_IR_VALUE_TAG_NULLPTR, - SCC_IR_VALUE_TAG_BUILTIN, - SCC_IR_VALUE_TAG_CONST_INT, - SCC_IR_VALUE_TAG_CONST_UINT, - SCC_IR_VALUE_TAG_CONST_FLOAT, - SCC_IR_VALUE_TAG_CONST_ARRAY, - SCC_IR_VALUE_TAG_AGGREGATE, ///< 聚合值 - SCC_IR_VALUE_TAG_CONV, ///< 类型转换 - SCC_IR_VALUE_TAG_FUNC_ARG_REF, ///< 函数参数引用 - SCC_IR_VALUE_TAG_BLOCK_ARG_REF, ///< 基本块参数引用 - SCC_IR_VALUE_TAG_ALLOC, ///< 分配内存 - SCC_IR_VALUE_TAG_GLOBAL_ALLOC, ///< 全局分配 - SCC_IR_VALUE_TAG_LOAD, ///< 加载数据 - SCC_IR_VALUE_TAG_STORE, ///< 存储数据 - SCC_IR_VALUE_TAG_GET_ELEM_PTR, ///< 获取元素指针 - SCC_IR_VALUE_TAG_OP, ///< 二元运算 - SCC_IR_VALUE_TAG_BRANCH, ///< 有条件分支 - SCC_IR_VALUE_TAG_JUMP, ///< 无条件跳转 - SCC_IR_VALUE_TAG_CALL, ///< 调用函数 - SCC_IR_VALUE_TAG_RET, ///< 函数返回 -} scc_ir_value_tag_t; - -typedef enum { - /// Empty op for init or nop - SCC_IR_OP_EMPTY, - /// Not equal to. - SCC_IR_OP_NEQ, - /// Equal to. - SCC_IR_OP_EQ, - /// Greater than. - SCC_IR_OP_GT, - /// Less than. - SCC_IR_OP_LT, - /// Greater than or equal to. - SCC_IR_OP_GE, - /// Less than or equal to. - SCC_IR_OP_LE, - /// Addition. - SCC_IR_OP_ADD, - /// Subtraction. - SCC_IR_OP_SUB, - /// Multiplication. - SCC_IR_OP_MUL, - /// Division. - SCC_IR_OP_DIV, - /// Modulo. - SCC_IR_OP_MOD, - /// Bitwise AND. - SCC_IR_OP_AND, - /// Bitwise OR. - SCC_IR_OP_OR, - /// Bitwise XOR. - SCC_IR_OP_XOR, - /// Bitwise NOT. - SCC_IR_OP_NOT, - /// Shift left logical. - SCC_IR_OP_SHL, - /// Shift right logical. - SCC_IR_OP_SHR, - /// Shift right arithmetic. - SCC_IR_OP_SAR, -} scc_ir_op_type_t; - -typedef union { - i8 int8; - i16 int16; - i32 int32; - i64 int64; - // TODO int128 - i8 int_any[16]; -} scc_ir_const_int_t; - -typedef union { - u8 uint8; - u16 uint16; - u32 uint32; - u64 uint64; - // TODO uint128; - u8 uint_any[16]; -} scc_ir_const_uint_t; - -typedef union { - // f16 float16; - f32 float32; - f64 float64; - // TODO float128; - u8 float_any[16]; -} scc_ir_const_float_t; - -typedef enum { - SCC_IR_BUILTIN_TAG_MEMCPY, - SCC_IR_BUILTIN_TAG_MEMSET, - SCC_IR_BUILTIN_TAG_VA_START, - SCC_IR_BUILTIN_TAG_VA_ARG, - SCC_IR_BUILTIN_TAG_VA_END, - SCC_IR_BUILTIN_TAG_VA_COPY, -} scc_ir_builtin_tag_t; - -typedef struct { - scc_ir_builtin_tag_t tag; - union { - struct { - scc_ir_value_ref_t dest; - scc_ir_value_ref_t src; - scc_ir_value_ref_t size; - } memcpy; - struct { - scc_ir_value_ref_t dest; - scc_ir_value_ref_t value; - scc_ir_value_ref_t size; - } memset; - struct { - scc_ir_value_ref_t ap; // va_list 的地址(i8* 或 struct*) - scc_ir_value_ref_t last; // 最后一个固定参数的引用(用于 va_start) - } va_start; - struct { - scc_ir_value_ref_t ap; // va_list 的地址 - scc_ir_type_ref_t type; // 要提取的参数的类型 - } va_arg; - struct { - scc_ir_value_ref_t ap; // va_list 的地址 - } va_end; - struct { - scc_ir_value_ref_t dest; // 目标 va_list 地址 - scc_ir_value_ref_t src; // 源 va_list 地址 - } va_copy; - } func; -} scc_ir_builtin_t; - -typedef enum { - SCC_IR_LINKAGE_EXTERNAL, - SCC_IR_LINKAGE_INTERNAL, - SCC_IR_LINKAGE_PRIVATE, - SCC_IR_LINKAGE_WEAK, -} scc_ir_linkage_t; - -struct scc_ir_value { - scc_ir_type_ref_t type; - scc_ir_label_t name; - scc_ir_value_ref_vec_t used_by; - scc_ir_value_tag_t tag; - union { - scc_ir_builtin_t builtin; - scc_ir_const_int_t const_int; - scc_ir_const_uint_t const_uint; - scc_ir_const_float_t const_float; - struct { - scc_ir_value_ref_t base_type; - scc_ir_buffer_t fields; - } const_array; - struct { - scc_ir_value_ref_vec_t fields; - } aggregate; - struct { - usize idx; - } arg_ref; - struct { - scc_ir_value_ref_t value; - } global_alloc; - struct { - scc_ir_value_ref_t operand; - scc_ir_type_ref_t target_type; // 目标类型 - enum { CONV_SEXT, CONV_ZEXT, CONV_TRUNC } conv_type; - } conv; - struct { - scc_ir_value_ref_t target; - } load; - struct { - scc_ir_value_ref_t target; - scc_ir_value_ref_t value; - } store; - struct { - scc_ir_value_ref_t src_addr; - scc_ir_value_ref_t index; - } get_elem_ptr; - struct { - scc_ir_op_type_t op; - scc_ir_value_ref_t lhs; - scc_ir_value_ref_t rhs; - } op; - struct { - scc_ir_value_ref_t cond; - scc_ir_bblock_ref_t true_bblock; - scc_ir_bblock_ref_t false_bblock; - } branch; - struct { - scc_ir_bblock_ref_t target_bblock; - } jump; - struct { - scc_ir_func_ref_t callee; // TODO function pointer call - scc_ir_value_ref_vec_t args; - } call; - struct { - scc_ir_value_ref_t ret_val; - } ret; - } data; -}; - -#endif /* __SCC_IR_DEF_H__ */ diff --git a/libs/ir/include/ir_dump.h b/libs/ir/include/ir_dump.h deleted file mode 100644 index 44ee370..0000000 --- a/libs/ir/include/ir_dump.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef __SCC_IR_DUMP_H__ -#define __SCC_IR_DUMP_H__ - -#include "ir_prog.h" -#include - -typedef struct { - scc_ir_cprog_t *cprog; - scc_tree_dump_t *dump_ctx; -} scc_ir_dump_ctx_t; - -void scc_ir_dump_ctx_init(scc_ir_dump_ctx_t *ctx, scc_tree_dump_t *tree_dump, - scc_ir_cprog_t *cprog); -void scc_ir_dump_value(scc_ir_dump_ctx_t *ctx, scc_ir_value_ref_t node_ref); -void scc_ir_dump_type(scc_ir_dump_ctx_t *ctx, scc_ir_type_ref_t type_ref); -void scc_ir_dump_bblock(scc_ir_dump_ctx_t *ctx, scc_ir_bblock_ref_t bblock_ref); -void scc_ir_dump_func(scc_ir_dump_ctx_t *ctx, scc_ir_func_ref_t func_ref); -void scc_ir_dump_cprog(scc_ir_dump_ctx_t *ctx); - -void scc_ir_dump_cprog_linear(scc_ir_dump_ctx_t *ctx); - -#endif /* __SCC_IR_DUMP_H__ */ diff --git a/libs/ir/include/ir_module.h b/libs/ir/include/ir_module.h deleted file mode 100644 index 74b77d7..0000000 --- a/libs/ir/include/ir_module.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef __SCC_IR_MODULE_H__ -#define __SCC_IR_MODULE_H__ - -#include "ir_def.h" -#include - -typedef struct { - unsigned int value_uid; - unsigned int type_uid; - unsigned int bblock_uid; - unsigned int func_uid; - SCC_VEC(scc_ir_value_t) values; - SCC_VEC(scc_ir_type_t) types; - SCC_VEC(scc_ir_bblock_t) bblocks; - SCC_VEC(scc_ir_func_t) funcs; - // UID -> ref index - scc_hashtable_t uid2value; - scc_hashtable_t uid2type; - scc_hashtable_t uid2bblock; - scc_hashtable_t uid2func; -} scc_ir_module_t; - -void scc_ir_module_init(scc_ir_module_t *ctx); -void scc_ir_module_drop(scc_ir_module_t *ctx); -scc_ir_type_ref_t scc_ir_module_add_type(scc_ir_module_t *ctx, - const scc_ir_type_t *type); -scc_ir_value_ref_t scc_ir_module_add_value(scc_ir_module_t *ctx, - const scc_ir_value_t *node); -scc_ir_bblock_ref_t scc_ir_module_add_bblock(scc_ir_module_t *ctx, - const scc_ir_bblock_t *bblock); -scc_ir_func_ref_t scc_ir_module_add_func(scc_ir_module_t *ctx, - const scc_ir_func_t *func); -scc_ir_type_t *scc_ir_module_get_type(scc_ir_module_t *ctx, - scc_ir_type_ref_t ref); -scc_ir_value_t *scc_ir_module_get_value(scc_ir_module_t *ctx, - scc_ir_value_ref_t ref); -scc_ir_bblock_t *scc_ir_module_get_bblock(scc_ir_module_t *ctx, - scc_ir_bblock_ref_t ref); -scc_ir_func_t *scc_ir_module_get_func(scc_ir_module_t *ctx, - scc_ir_func_ref_t ref); - -static inline scc_ir_type_t * -scc_ir_module_get_type_by_value(scc_ir_module_t *ctx, scc_ir_value_ref_t ref) { - scc_ir_value_t *value = scc_ir_module_get_value(ctx, ref); - Assert(value != nullptr); - return scc_ir_module_get_type(ctx, value->type); -} - -#endif /* __SCC_IR_MODULE_H__ */ diff --git a/libs/ir/include/ir_prog.h b/libs/ir/include/ir_prog.h deleted file mode 100644 index 94d278c..0000000 --- a/libs/ir/include/ir_prog.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __SCC_IR_PROG_H__ -#define __SCC_IR_PROG_H__ - -#include "ir_def.h" -#include "ir_module.h" - -typedef struct scc_ir_cprog { - scc_ir_module_t module; - scc_ir_value_ref_vec_t global_vals; /* 全局变量 */ - scc_ir_func_ref_vec_t func_defs; /* 所有函数定义 */ - scc_ir_func_ref_vec_t func_decls; /* 所有函数包括定义的声明 */ -} scc_ir_cprog_t; - -void scc_ir_cprog_init(scc_ir_cprog_t *in); -void scc_ir_cprog_drop(scc_ir_cprog_t *in); - -#endif /* __SCC_IR_PROG_H__ */ diff --git a/libs/ir/include/scc_ir.h b/libs/ir/include/scc_ir.h deleted file mode 100644 index 2dcfbf3..0000000 --- a/libs/ir/include/scc_ir.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __SCC_IR_H__ -#define __SCC_IR_H__ - -#include "ir_def.h" -#include "ir_prog.h" - -void scc_ir_type_init(scc_ir_type_t *in, scc_ir_type_tag_t tag); -void scc_ir_bblock_init(scc_ir_bblock_t *in, const char *label); -void scc_ir_func_init(scc_ir_func_t *in, const char *name); - -// node name can be nullptr ptr -void scc_ir_value_init(scc_ir_value_t *in, const char *name, - scc_ir_value_tag_t tag); - -#endif /* __SCC_IR_H__ */ diff --git a/libs/ir/src/ir_builder.c b/libs/ir/src/ir_builder.c deleted file mode 100644 index fd84a56..0000000 --- a/libs/ir/src/ir_builder.c +++ /dev/null @@ -1,493 +0,0 @@ -#include "ir_def.h" -#include -#include - -#define GET_MODULE(builder) (&(builder->cprog->module)) - -void scc_ir_builder_init(scc_ir_builder_t *builder, scc_ir_cprog_t *cprog) { - builder->current_bblock = SCC_IR_REF_nullptr; - builder->current_func = SCC_IR_REF_nullptr; - builder->cprog = cprog; - - scc_ir_ctx_init(&builder->ctx, GET_MODULE(builder)); -#ifndef SCC_NO_DEBUG - builder->borrow_depth = 0; - builder->dbg_file = nullptr; - builder->dbg_line = 0; -#endif -} - -void scc_ir_builder_drop(scc_ir_builder_t *builder) { - scc_ir_ctx_drop(&builder->ctx); -} - -scc_ir_func_ref_t scc_ir_builder_func(scc_ir_builder_t *builder, - scc_ir_type_ref_t type_ref, - const char *name) { - SCC_IR_BUILDER_CHECK_NO_BORROW(builder); - scc_ir_func_ref_t func_ref = - scc_ir_ctx_declare_func(&builder->ctx, type_ref, name); - scc_vec_push(builder->cprog->func_decls, func_ref); - return func_ref; -} - -scc_ir_type_ref_t scc_ir_builder_type(scc_ir_builder_t *builder, - const scc_ir_type_t *type_desc) { - SCC_IR_BUILDER_CHECK_NO_BORROW(builder); - return scc_ir_ctx_get_type(&builder->ctx, type_desc); -} - -scc_ir_value_ref_t scc_ir_builder_const_string(scc_ir_builder_t *builder, - const char *str, usize len) { - SCC_IR_BUILDER_CHECK_NO_BORROW(builder); - scc_ir_type_ref_t u8_type = scc_ir_builder_type_u8(builder); - scc_ir_type_t array_type = { - .tag = SCC_IR_TYPE_ARRAY, - .data.array.base = u8_type, - .data.array.len = len - 1, // 包含 nullptr 结尾 - }; - scc_ir_type_ref_t array_type_ref = - scc_ir_ctx_get_type(&builder->ctx, &array_type); - - // 5. 创建聚合节点 - scc_ir_value_t const_array_value = { - .tag = SCC_IR_VALUE_TAG_CONST_ARRAY, - .type = array_type_ref, - .data.const_array.base_type = u8_type, - }; - char *buff = scc_malloc(len - 1); - Assert(buff); - // FIXME content to real string - for (usize i = 1; i < len - 1; i++) { - buff[i - 1] = str[i]; - } - buff[len - 2] = '\0'; - scc_vec_unsafe_from_buffer(const_array_value.data.const_array.fields, - (u8 *)buff, len - 1); - scc_ir_value_ref_t const_array_ref = - scc_ir_module_add_value(builder->ctx.module, &const_array_value); - Assert(const_array_ref != SCC_IR_REF_nullptr); - - // 3. 创建全局变量节点,类型为指针,初始值指向常量数组 - scc_ir_value_ref_t global_value_ref = - scc_ir_builder_global_alloca(builder, array_type_ref, const_array_ref); - // scc_hashtable_insert(builder); - - scc_ir_value_ref_t pointer_to_global_value = scc_ir_module_add_value( - builder->ctx.module, - &(scc_ir_value_t){ - .tag = SCC_IR_VALUE_TAG_GET_ELEM_PTR, - .data.get_elem_ptr.src_addr = global_value_ref, - .data.get_elem_ptr.index = SCC_IR_VALUE_TAG_NULLPTR, - }); - scc_ir_builder_add_instr(builder, pointer_to_global_value); - return pointer_to_global_value; -} - -void scc_ir_builder_begin_func(scc_ir_builder_t *builder, - scc_ir_func_ref_t func_ref) { - SCC_IR_BUILDER_CHECK_NO_BORROW(builder); - builder->current_func = func_ref; - - // 借用 func_ptr 和 func_type 以获取参数类型列表 - scc_ir_func_t *func_ptr = nullptr; - scc_ir_type_t *func_type = nullptr; - SCC_IR_BUILDER_BEGIN_BORROW( - builder, func_ptr, - scc_ir_module_get_func(GET_MODULE(builder), func_ref)); - SCC_IR_BUILDER_BEGIN_BORROW( - builder, func_type, - scc_ir_module_get_type(GET_MODULE(builder), func_ptr->type)); - - if (func_type == nullptr || func_type->tag != SCC_IR_TYPE_FUNC) { - LOG_ERROR("Invalid function type"); - SCC_IR_BUILDER_END_BORROW(builder); // func_type - SCC_IR_BUILDER_END_BORROW(builder); // func_ptr - return; - } - if (func_ptr == nullptr) { - LOG_ERROR("Invalid function reference"); - SCC_IR_BUILDER_END_BORROW(builder); // func_type - SCC_IR_BUILDER_END_BORROW(builder); // func_ptr - return; - } - if (scc_vec_size(func_ptr->bblocks) != 0 || - scc_vec_size(func_ptr->params) != 0) { - LOG_FATAL("Multiple function definitions"); - SCC_IR_BUILDER_END_BORROW(builder); // func_type - SCC_IR_BUILDER_END_BORROW(builder); // func_ptr - return; - } - - // 释放借用,因为下面要调用 add_value(可能 realloc) - SCC_IR_BUILDER_END_BORROW(builder); // func_type - SCC_IR_BUILDER_END_BORROW(builder); // func_ptr -} - -void scc_ir_builder_end_func(scc_ir_builder_t *builder) { - SCC_IR_BUILDER_CHECK_NO_BORROW(builder); - scc_ir_func_t *func_ptr = nullptr; - SCC_IR_BUILDER_BEGIN_BORROW( - builder, func_ptr, - scc_ir_module_get_func(GET_MODULE(builder), builder->current_func)); - if (func_ptr == nullptr) { - LOG_FATAL("Invalid function reference"); - SCC_IR_BUILDER_END_BORROW(builder); - return; - } - if (scc_vec_size(func_ptr->bblocks) == 0) { - scc_vec_push(builder->cprog->func_decls, builder->current_func); - } else { - scc_vec_push(builder->cprog->func_defs, builder->current_func); - } - SCC_IR_BUILDER_END_BORROW(builder); - builder->current_func = 0; -} - -scc_ir_func_ref_t scc_ir_builder_current_func(scc_ir_builder_t *builder) { - // 只读操作,无需检查借用 - return builder->current_func; -} - -scc_ir_bblock_ref_t scc_ir_builder_bblock(scc_ir_builder_t *builder, - const char *label) { - SCC_IR_BUILDER_CHECK_NO_BORROW(builder); - scc_ir_bblock_t bblock = {0}; - if (label) { - bblock.label = label; - } - scc_vec_init(bblock.instrs); - scc_ir_bblock_ref_t bblock_ref = - scc_ir_module_add_bblock(GET_MODULE(builder), &bblock); - - // 将基本块添加到当前函数 - scc_ir_func_t *current_func = nullptr; - SCC_IR_BUILDER_BEGIN_BORROW( - builder, current_func, - scc_ir_module_get_func(GET_MODULE(builder), builder->current_func)); - if (current_func) { - scc_vec_push(current_func->bblocks, bblock_ref); - } - SCC_IR_BUILDER_END_BORROW(builder); - return bblock_ref; -} - -scc_ir_bblock_ref_t scc_ir_builder_begin_bblock(scc_ir_builder_t *builder, - const char *label) { - SCC_IR_BUILDER_CHECK_NO_BORROW(builder); - builder->current_bblock = scc_ir_builder_bblock(builder, label); - return builder->current_bblock; -} - -void scc_ir_builder_end_bblock(scc_ir_builder_t *builder) { - SCC_IR_BUILDER_CHECK_NO_BORROW(builder); - builder->current_bblock = 0; -} - -void scc_ir_builder_set_current_bblock(scc_ir_builder_t *builder, - scc_ir_bblock_ref_t bblock) { - SCC_IR_BUILDER_CHECK_NO_BORROW(builder); - builder->current_bblock = bblock; -} - -scc_ir_func_ref_t scc_ir_builder_current_bblock(scc_ir_builder_t *builder) { - return builder->current_bblock; -} - -void scc_ir_builder_add_instr(scc_ir_builder_t *builder, - scc_ir_value_ref_t instr) { - SCC_IR_BUILDER_CHECK_NO_BORROW(builder); - scc_ir_bblock_t *current_bblock = nullptr; - SCC_IR_BUILDER_BEGIN_BORROW( - builder, current_bblock, - scc_ir_module_get_bblock(GET_MODULE(builder), builder->current_bblock)); - if (current_bblock) { - scc_vec_push(current_bblock->instrs, instr); - } else { - LOG_ERROR("Current basic block is not set"); - } - SCC_IR_BUILDER_END_BORROW(builder); -} - -scc_ir_value_ref_t scc_ir_builder_global_alloca(scc_ir_builder_t *builder, - scc_ir_type_ref_t type, - scc_ir_value_ref_t value) { - SCC_IR_BUILDER_CHECK_NO_BORROW(builder); - char *name = scc_malloc(32); - scc_ir_value_ref_t global_value_ref = scc_ir_module_add_value( - builder->ctx.module, &(scc_ir_value_t){ - .name = name, - .tag = SCC_IR_VALUE_TAG_GLOBAL_ALLOC, - .type = type, - .data.global_alloc.value = value, - }); - scc_snprintf(name, 32, "$G%u", global_value_ref); - scc_vec_push(builder->cprog->global_vals, global_value_ref); - return global_value_ref; -} - -scc_ir_value_ref_t scc_ir_builder_alloca(scc_ir_builder_t *builder, - scc_ir_type_ref_t type, - const char *name) { - SCC_IR_BUILDER_CHECK_NO_BORROW(builder); - scc_ir_value_t alloc_node = {0}; - alloc_node.tag = SCC_IR_VALUE_TAG_ALLOC; - alloc_node.type = scc_ir_module_add_type( - GET_MODULE(builder), - &(scc_ir_type_t){.tag = SCC_IR_TYPE_PTR, .data.pointer.base = type}); - alloc_node.name = name; - - scc_ir_value_ref_t value_ref = - scc_ir_module_add_value(GET_MODULE(builder), &alloc_node); - scc_ir_builder_add_instr(builder, value_ref); - return value_ref; -} - -scc_ir_value_ref_t scc_ir_builder_func_arg_ref(scc_ir_builder_t *builder, - scc_ir_type_ref_t type, - const char *name, - usize arg_idx) { - SCC_IR_BUILDER_CHECK_NO_BORROW(builder); - scc_ir_value_t value = {0}; - value.tag = SCC_IR_VALUE_TAG_FUNC_ARG_REF; - value.type = type; - value.name = name; - value.data.arg_ref.idx = arg_idx; - - scc_ir_value_ref_t value_ref = - scc_ir_module_add_value(GET_MODULE(builder), &value); - scc_ir_builder_add_instr(builder, value_ref); - return value_ref; -} - -scc_ir_value_ref_t scc_ir_builder_load(scc_ir_builder_t *builder, - scc_ir_value_ref_t target) { - SCC_IR_BUILDER_CHECK_NO_BORROW(builder); - scc_ir_value_t load_node = {0}; - load_node.tag = SCC_IR_VALUE_TAG_LOAD; - load_node.data.load.target = target; - - // 借用 ptr_node 和 ptr_type 获取类型信息 - scc_ir_value_t *ptr_node = nullptr; - SCC_IR_BUILDER_BEGIN_BORROW( - builder, ptr_node, - scc_ir_module_get_value(GET_MODULE(builder), target)); - if (ptr_node) { - scc_ir_type_t *ptr_type = nullptr; - SCC_IR_BUILDER_BEGIN_BORROW( - builder, ptr_type, - scc_ir_module_get_type(GET_MODULE(builder), ptr_node->type)); - if (ptr_type && ptr_type->tag == SCC_IR_TYPE_PTR) { - load_node.type = ptr_type->data.pointer.base; - } - SCC_IR_BUILDER_END_BORROW(builder); // ptr_type - } - SCC_IR_BUILDER_END_BORROW(builder); // ptr_node - - scc_ir_value_ref_t value_ref = - scc_ir_module_add_value(GET_MODULE(builder), &load_node); - scc_ir_builder_add_instr(builder, value_ref); - return value_ref; -} - -scc_ir_value_ref_t scc_ir_builder_store(scc_ir_builder_t *builder, - scc_ir_value_ref_t target, - scc_ir_value_ref_t value) { - SCC_IR_BUILDER_CHECK_NO_BORROW(builder); - Assert(target != SCC_IR_REF_nullptr && value != SCC_IR_REF_nullptr); - scc_ir_value_t store_node = {0}; - store_node.tag = SCC_IR_VALUE_TAG_STORE; - store_node.data.store.target = target; - store_node.data.store.value = value; - - scc_ir_value_ref_t value_ref = - scc_ir_module_add_value(GET_MODULE(builder), &store_node); - scc_ir_builder_add_instr(builder, value_ref); - return value_ref; -} - -scc_ir_value_ref_t scc_ir_builder_get_elem_ptr(scc_ir_builder_t *builder, - scc_ir_value_ref_t target, - scc_ir_value_ref_t index) { - SCC_IR_BUILDER_CHECK_NO_BORROW(builder); - scc_ir_value_t get_ptr_node = {0}; - get_ptr_node.tag = SCC_IR_VALUE_TAG_GET_ELEM_PTR; - get_ptr_node.data.get_elem_ptr.src_addr = target; - get_ptr_node.data.get_elem_ptr.index = index; - - // 借用类型信息 - scc_ir_type_t *type_ref = nullptr; - SCC_IR_BUILDER_BEGIN_BORROW( - builder, type_ref, - scc_ir_module_get_type_by_value(GET_MODULE(builder), target)); - Assert(type_ref != nullptr); - scc_ir_type_t type = *type_ref; // 拷贝一份,避免后续借用 - SCC_IR_BUILDER_END_BORROW(builder); // type_ref - - if (type.tag == SCC_IR_TYPE_PTR) { - scc_ir_type_t *base_type = nullptr; - SCC_IR_BUILDER_BEGIN_BORROW( - builder, base_type, - scc_ir_module_get_type(GET_MODULE(builder), - type_ref->data.pointer.base)); - if (base_type->tag == SCC_IR_TYPE_ARRAY) { - scc_ir_type_t type = (scc_ir_type_t){ - .tag = SCC_IR_TYPE_PTR, - .data.pointer.base = base_type->data.array.base, - }; - SCC_IR_BUILDER_END_BORROW(builder); // base_type - get_ptr_node.type = scc_ir_builder_type(builder, &type); - } else { - SCC_IR_BUILDER_END_BORROW(builder); // base_type - get_ptr_node.type = scc_ir_builder_type(builder, &type); - } - } else { - get_ptr_node.type = scc_ir_builder_type(builder, &type); - } - - scc_ir_value_ref_t value_ref = - scc_ir_module_add_value(GET_MODULE(builder), &get_ptr_node); - scc_ir_builder_add_instr(builder, value_ref); - return value_ref; -} - -scc_ir_value_ref_t scc_ir_builder_binop(scc_ir_builder_t *builder, - scc_ir_op_type_t op, - scc_ir_value_ref_t lhs, - scc_ir_value_ref_t rhs) { - SCC_IR_BUILDER_CHECK_NO_BORROW(builder); - scc_ir_value_t binop_node = {0}; - binop_node.tag = SCC_IR_VALUE_TAG_OP; - binop_node.data.op.op = op; - binop_node.data.op.lhs = lhs; - binop_node.data.op.rhs = rhs; - - // 借用 lhs_node 获取类型 - scc_ir_value_t *lhs_node = nullptr; - SCC_IR_BUILDER_BEGIN_BORROW( - builder, lhs_node, scc_ir_module_get_value(GET_MODULE(builder), lhs)); - if (lhs_node) { - binop_node.type = lhs_node->type; - } - SCC_IR_BUILDER_END_BORROW(builder); // lhs_node - - scc_ir_value_ref_t value_ref = - scc_ir_module_add_value(GET_MODULE(builder), &binop_node); - scc_ir_builder_add_instr(builder, value_ref); - return value_ref; -} - -scc_ir_value_ref_t scc_ir_builder_cmp(scc_ir_builder_t *builder, - scc_ir_op_type_t op, - scc_ir_value_ref_t lhs, - scc_ir_value_ref_t rhs) { - SCC_IR_BUILDER_CHECK_NO_BORROW(builder); - scc_ir_value_t cmp_node = {0}; - cmp_node.tag = SCC_IR_VALUE_TAG_OP; - cmp_node.data.op.op = op; - cmp_node.data.op.lhs = lhs; - cmp_node.data.op.rhs = rhs; - cmp_node.type = 0; // FIXME - - scc_ir_value_ref_t value_ref = - scc_ir_module_add_value(GET_MODULE(builder), &cmp_node); - scc_ir_builder_add_instr(builder, value_ref); - return value_ref; -} - -scc_ir_value_ref_t scc_ir_builder_jump(scc_ir_builder_t *builder, - scc_ir_bblock_ref_t target) { - SCC_IR_BUILDER_CHECK_NO_BORROW(builder); - scc_ir_value_t jump_node = {0}; - jump_node.tag = SCC_IR_VALUE_TAG_JUMP; - jump_node.data.jump.target_bblock = target; - - scc_ir_value_ref_t value_ref = - scc_ir_module_add_value(GET_MODULE(builder), &jump_node); - scc_ir_builder_add_instr(builder, value_ref); - return value_ref; -} - -scc_ir_value_ref_t scc_ir_builder_branch(scc_ir_builder_t *builder, - scc_ir_value_ref_t cond, - scc_ir_bblock_ref_t true_target, - scc_ir_bblock_ref_t false_target) { - SCC_IR_BUILDER_CHECK_NO_BORROW(builder); - scc_ir_value_t branch_node = {0}; - branch_node.tag = SCC_IR_VALUE_TAG_BRANCH; - branch_node.data.branch.cond = cond; - branch_node.data.branch.true_bblock = true_target; - branch_node.data.branch.false_bblock = false_target; - - scc_ir_value_ref_t value_ref = - scc_ir_module_add_value(GET_MODULE(builder), &branch_node); - scc_ir_builder_add_instr(builder, value_ref); - return value_ref; -} - -scc_ir_value_ref_t scc_ir_builder_call(scc_ir_builder_t *builder, - scc_ir_func_ref_t callee, - const scc_ir_value_ref_t *args, - usize arg_count) { - SCC_IR_BUILDER_CHECK_NO_BORROW(builder); - scc_ir_value_t call_node = {0}; - call_node.tag = SCC_IR_VALUE_TAG_CALL; - call_node.data.call.callee = callee; - - scc_vec_init(call_node.data.call.args); - for (usize i = 0; i < arg_count; i++) { - scc_vec_push(call_node.data.call.args, args[i]); - } - - // 借用 callee_func 和 func_type 获取返回类型 - scc_ir_func_t *callee_func = nullptr; - SCC_IR_BUILDER_BEGIN_BORROW( - builder, callee_func, - scc_ir_module_get_func(GET_MODULE(builder), callee)); - if (callee_func) { - scc_ir_type_t *func_type = nullptr; - SCC_IR_BUILDER_BEGIN_BORROW( - builder, func_type, - scc_ir_module_get_type(GET_MODULE(builder), callee_func->type)); - if (func_type && func_type->tag == SCC_IR_TYPE_FUNC) { - call_node.type = func_type->data.function.ret_type; - } - SCC_IR_BUILDER_END_BORROW(builder); // func_type - } - SCC_IR_BUILDER_END_BORROW(builder); // callee_func - - scc_ir_value_ref_t value_ref = - scc_ir_module_add_value(GET_MODULE(builder), &call_node); - scc_ir_builder_add_instr(builder, value_ref); - return value_ref; -} - -scc_ir_value_ref_t scc_ir_builder_ret(scc_ir_builder_t *builder, - scc_ir_value_ref_t value) { - SCC_IR_BUILDER_CHECK_NO_BORROW(builder); - scc_ir_value_t ret_node = {0}; - ret_node.tag = SCC_IR_VALUE_TAG_RET; - ret_node.data.ret.ret_val = value; - - scc_ir_value_ref_t value_ref = - scc_ir_module_add_value(GET_MODULE(builder), &ret_node); - scc_ir_builder_add_instr(builder, value_ref); - return value_ref; -} - -scc_ir_value_ref_t scc_ir_builder_ret_void(scc_ir_builder_t *builder) { - SCC_IR_BUILDER_CHECK_NO_BORROW(builder); - scc_ir_value_t ret_node = {0}; - ret_node.tag = SCC_IR_VALUE_TAG_RET; - - scc_ir_value_t ret_val_node; - scc_ir_value_init(&ret_val_node, nullptr, SCC_IR_VALUE_TAG_NULLPTR); - ret_val_node.type = scc_ir_builder_type_void(builder); - ret_node.data.ret.ret_val = - scc_ir_module_add_value(GET_MODULE(builder), &ret_val_node); - - scc_ir_value_ref_t value_ref = - scc_ir_module_add_value(GET_MODULE(builder), &ret_node); - scc_ir_builder_add_instr(builder, value_ref); - return value_ref; -} diff --git a/libs/ir/src/ir_ctx.c b/libs/ir/src/ir_ctx.c deleted file mode 100644 index cb2017a..0000000 --- a/libs/ir/src/ir_ctx.c +++ /dev/null @@ -1,194 +0,0 @@ -#include - -/** - * @brief 哈希混合函数(类似Rust的hash combine) - * - * Rust的默认哈希实现(SipHash 1-3)使用旋转和异或, - * 这里使用简单的FNV-1a变体,类似于Rust的`#[derive(Hash)]` - */ -static inline u32 scc_hash_mix(u32 seed, u32 value) { - // FNV-1a风格混合 - return (seed ^ value) * 16777619u; -} - -static u32 hash_type(const void *_key, void *userdata) { - scc_ir_module_t *module = userdata; - const scc_ir_type_t *key = - _key == SCC_IR_REF_nullptr - ? &scc_vec_at(module->types, 0) - : scc_ir_module_get_type(module, (usize)_key); - // 初始哈希:tag - u32 hash = (u32)key->tag; - - switch (key->tag) { - case SCC_IR_TYPE_void: - case SCC_IR_TYPE_u8: - case SCC_IR_TYPE_u16: - case SCC_IR_TYPE_u32: - case SCC_IR_TYPE_u64: - case SCC_IR_TYPE_u128: - case SCC_IR_TYPE_i8: - case SCC_IR_TYPE_i16: - case SCC_IR_TYPE_i32: - case SCC_IR_TYPE_i64: - case SCC_IR_TYPE_i128: - case SCC_IR_TYPE_f16: - case SCC_IR_TYPE_f32: - case SCC_IR_TYPE_f64: - case SCC_IR_TYPE_f128: - // 基本类型,只有tag - break; - - case SCC_IR_TYPE_PTR: - hash = scc_hash_mix(hash, (u32)key->data.array.base); - break; - - case SCC_IR_TYPE_ARRAY: - hash = scc_hash_mix(hash, (u32)key->data.array.base); - hash = scc_hash_mix(hash, (u32)key->data.array.len); - break; - - case SCC_IR_TYPE_FUNC: - // 注意:这里需要递归哈希参数类型 - hash = scc_hash_mix(hash, (u32)key->data.function.ret_type); - for (usize i = 0; i < key->data.function.params.size; i++) { - hash = scc_hash_mix(hash, (u32)key->data.function.params.data[i]); - } - hash = scc_hash_mix(hash, (u32)key->data.function.params.size); - break; - - case SCC_IR_TYPE_STRUCT: - case SCC_IR_TYPE_UNION: - return 0; - case SCC_IR_TYPE_VECTOR: - default: - Panic("Invalid type tag %d", key->tag); - return 0; - } - - return hash; -} - -static int cmp_type(const void *_key1, const void *_key2, void *userdata) { - scc_ir_module_t *module = userdata; - const scc_ir_type_t *key1 = - _key1 == SCC_IR_REF_nullptr - ? &scc_vec_at(module->types, 0) - : scc_ir_module_get_type(module, (usize)_key1), - *key2 = - _key2 == SCC_IR_REF_nullptr - ? &scc_vec_at(module->types, 0) - : scc_ir_module_get_type(module, (usize)_key2); - Assert(key1 != nullptr && key2 != nullptr); - if (key1->tag == SCC_IR_TYPE_unknown || key2->tag == SCC_IR_TYPE_unknown) { - return 1; - } - // tag不同 - if (key1->tag != key2->tag) { - return 1; - } - - switch (key1->tag) { - case SCC_IR_TYPE_void: - case SCC_IR_TYPE_u8: - case SCC_IR_TYPE_u16: - case SCC_IR_TYPE_u32: - case SCC_IR_TYPE_u64: - case SCC_IR_TYPE_u128: - case SCC_IR_TYPE_i8: - case SCC_IR_TYPE_i16: - case SCC_IR_TYPE_i32: - case SCC_IR_TYPE_i64: - case SCC_IR_TYPE_i128: - case SCC_IR_TYPE_f16: - case SCC_IR_TYPE_f32: - case SCC_IR_TYPE_f64: - case SCC_IR_TYPE_f128: - return 0; // 基本类型,tag相同即可 - case SCC_IR_TYPE_PTR: - return key1->data.pointer.base != key2->data.pointer.base; - case SCC_IR_TYPE_ARRAY: - return (key1->data.array.base != key2->data.array.base) || - (key1->data.array.len != key2->data.array.len); - case SCC_IR_TYPE_FUNC: { - if (key1->data.function.ret_type != key2->data.function.ret_type) { - return 1; - } - if (key1->data.function.params.size != - key2->data.function.params.size) { - return 1; - } - for (usize i = 0; i < key1->data.function.params.size; i++) { - if (key1->data.function.params.data[i] != - key2->data.function.params.data[i]) { - return 1; - } - } - return 0; - } - default: - Panic("Unknown key type %d", key1->tag); - return 1; - } - return 1; -} - -void scc_ir_ctx_init(scc_ir_ctx_t *ctx, scc_ir_module_t *module) { - ctx->module = module; - scc_hashtable_init(&ctx->type_uniquing, hash_type, cmp_type, module); - // scc_hashtable_init(&ctx->const_pool, /* 常量哈希函数 */, - // /* 常量比较函数 */); - scc_hashtable_cstr_init(&ctx->func_decl_set); -} - -void scc_ir_ctx_drop(scc_ir_ctx_t *ctx) { - scc_hashtable_drop(&ctx->type_uniquing); - // scc_hashtable_drop(&ctx->const_pool); - scc_hashtable_drop(&ctx->func_decl_set); -} - -scc_ir_type_ref_t scc_ir_ctx_get_type(scc_ir_ctx_t *ctx, - const scc_ir_type_t *type_desc) { - Assert(type_desc->tag != SCC_IR_TYPE_unknown); - - scc_vec_at(ctx->module->types, 0) = *type_desc; - // 先查哈希表 - void *found = scc_hashtable_get(&ctx->type_uniquing, (void *)(usize)0); - if (found) { - return (scc_ir_type_ref_t)(usize)found; - } - - // 不存在,添加新类型 - scc_ir_type_ref_t new_ref = scc_ir_module_add_type(ctx->module, type_desc); - scc_hashtable_set(&ctx->type_uniquing, (void *)(usize)new_ref, - (void *)(usize)new_ref); - return new_ref; -} - -// scc_ir_value_ref_t scc_ir_ctx_get_const_int(scc_ir_ctx_t *ctx, -// scc_ir_type_ref_t type, i64 value) -// { -// return scc_ir_value_ref_t(); -// } - -scc_ir_func_ref_t scc_ir_ctx_declare_func(scc_ir_ctx_t *ctx, - scc_ir_type_ref_t type, - const char *name) { - // 检查是否已声明 - void *found = scc_hashtable_get(&ctx->func_decl_set, (void *)name); - if (found) { - return (scc_ir_func_ref_t)(usize)found; - } - - // 创建新函数 - scc_ir_func_t func = { - .name = name, - .type = type, - }; - scc_vec_init(func.params); - scc_vec_init(func.bblocks); - scc_ir_func_ref_t new_ref = scc_ir_module_add_func(ctx->module, &func); - scc_hashtable_set(&ctx->func_decl_set, (void *)name, - (void *)(usize)new_ref); - return new_ref; -} diff --git a/libs/ir/src/ir_module.c b/libs/ir/src/ir_module.c deleted file mode 100644 index ac38f61..0000000 --- a/libs/ir/src/ir_module.c +++ /dev/null @@ -1,136 +0,0 @@ -#include - -void scc_ir_module_init(scc_ir_module_t *ctx) { - scc_vec_init(ctx->values); - scc_vec_init(ctx->types); - scc_vec_init(ctx->bblocks); - scc_vec_init(ctx->funcs); - scc_hashtable_usize_init(&ctx->uid2value); - scc_hashtable_usize_init(&ctx->uid2type); - scc_hashtable_usize_init(&ctx->uid2bblock); - scc_hashtable_usize_init(&ctx->uid2func); - // 预留UID 0 作为无效引用 - scc_vec_push(ctx->values, (scc_ir_value_t){0}); - scc_vec_push(ctx->types, (scc_ir_type_t){0}); - scc_vec_push(ctx->bblocks, (scc_ir_bblock_t){0}); - scc_vec_push(ctx->funcs, (scc_ir_func_t){0}); - ctx->value_uid = 1; - ctx->type_uid = 1; - ctx->bblock_uid = 1; - ctx->func_uid = 1; -} - -void scc_ir_module_drop(scc_ir_module_t *ctx) { - // 释放所有实体的内部内存 - for (usize i = 1; i < ctx->values.size; i++) { - scc_ir_value_t *node = &ctx->values.data[i]; - scc_vec_free(node->used_by); - if (node->tag == SCC_IR_VALUE_TAG_CALL) { - scc_vec_free(node->data.call.args); - } - } - - for (usize i = 1; i < ctx->types.size; i++) { - scc_ir_type_t *type = &ctx->types.data[i]; - if (type->tag == SCC_IR_TYPE_FUNC) { - scc_vec_free(type->data.function.params); - } - } - - for (usize i = 1; i < ctx->bblocks.size; i++) { - scc_ir_bblock_t *bblock = &ctx->bblocks.data[i]; - scc_vec_free(bblock->instrs); - } - - for (usize i = 1; i < ctx->funcs.size; i++) { - scc_ir_func_t *func = &ctx->funcs.data[i]; - scc_vec_free(func->params); - scc_vec_free(func->bblocks); - } - - scc_vec_free(ctx->values); - scc_vec_free(ctx->types); - scc_vec_free(ctx->bblocks); - scc_vec_free(ctx->funcs); - scc_hashtable_drop(&ctx->uid2value); - scc_hashtable_drop(&ctx->uid2type); - scc_hashtable_drop(&ctx->uid2bblock); - scc_hashtable_drop(&ctx->uid2func); -} - -// 辅助宏:创建实体并添加到哈希表 -#define CREATE_ENTITY(ctx, vec, uid, data, hashtable) \ - do { \ - /* 分配新UID */ \ - unsigned new_uid = (ctx)->uid++; \ - /* 添加到哈希表 */ \ - scc_hashtable_set(&(ctx)->hashtable, (const void *)(usize)new_uid, \ - (void *)(usize)(scc_vec_size(vec))); \ - /* 添加到向量 */ \ - scc_vec_push((vec), *(data)); \ - return new_uid; \ - } while (0) - -scc_ir_type_ref_t scc_ir_module_add_type(scc_ir_module_t *ctx, - const scc_ir_type_t *type) { - CREATE_ENTITY(ctx, ctx->types, type_uid, type, uid2type); -} - -scc_ir_value_ref_t scc_ir_module_add_value(scc_ir_module_t *ctx, - const scc_ir_value_t *node) { - CREATE_ENTITY(ctx, ctx->values, value_uid, node, uid2value); -} - -scc_ir_bblock_ref_t scc_ir_module_add_bblock(scc_ir_module_t *ctx, - const scc_ir_bblock_t *bblock) { - CREATE_ENTITY(ctx, ctx->bblocks, bblock_uid, bblock, uid2bblock); -} - -scc_ir_func_ref_t scc_ir_module_add_func(scc_ir_module_t *ctx, - const scc_ir_func_t *func) { - CREATE_ENTITY(ctx, ctx->funcs, func_uid, func, uid2func); -} - -// 辅助宏:从哈希表获取索引 -#define GET_ENTITY_INDEX(ctx, ref, hashtable) \ - ((usize)scc_hashtable_get(&(ctx)->hashtable, (void *)(usize)ref)) - -scc_ir_type_t *scc_ir_module_get_type(scc_ir_module_t *ctx, - scc_ir_type_ref_t ref) { - if (ref == 0) - return nullptr; - usize idx = GET_ENTITY_INDEX(ctx, ref, uid2type); - if (idx >= ctx->types.size) - return nullptr; - return &ctx->types.data[idx]; -} - -scc_ir_value_t *scc_ir_module_get_value(scc_ir_module_t *ctx, - scc_ir_value_ref_t ref) { - if (ref == 0) - return nullptr; - usize idx = GET_ENTITY_INDEX(ctx, ref, uid2value); - if (idx >= ctx->values.size) - return nullptr; - return &ctx->values.data[idx]; -} - -scc_ir_bblock_t *scc_ir_module_get_bblock(scc_ir_module_t *ctx, - scc_ir_bblock_ref_t ref) { - if (ref == 0) - return nullptr; - usize idx = GET_ENTITY_INDEX(ctx, ref, uid2bblock); - if (idx >= ctx->bblocks.size) - return nullptr; - return &ctx->bblocks.data[idx]; -} - -scc_ir_func_t *scc_ir_module_get_func(scc_ir_module_t *ctx, - scc_ir_func_ref_t ref) { - if (ref == 0) - return nullptr; - usize idx = GET_ENTITY_INDEX(ctx, ref, uid2func); - if (idx >= ctx->funcs.size) - return nullptr; - return &ctx->funcs.data[idx]; -} diff --git a/libs/ir/src/scc_ir.c b/libs/ir/src/scc_ir.c deleted file mode 100644 index ff31fb1..0000000 --- a/libs/ir/src/scc_ir.c +++ /dev/null @@ -1,117 +0,0 @@ -#include - -void scc_ir_type_init(scc_ir_type_t *in, scc_ir_type_tag_t tag) { - Assert(in != nullptr); - in->tag = tag; - in->name = nullptr; - switch (tag) { - case SCC_IR_TYPE_unknown: - case SCC_IR_TYPE_void: - case SCC_IR_TYPE_i8: - case SCC_IR_TYPE_i16: - case SCC_IR_TYPE_i32: - case SCC_IR_TYPE_i64: - case SCC_IR_TYPE_i128: - case SCC_IR_TYPE_u8: - case SCC_IR_TYPE_u16: - case SCC_IR_TYPE_u32: - case SCC_IR_TYPE_u64: - case SCC_IR_TYPE_u128: - case SCC_IR_TYPE_f16: - case SCC_IR_TYPE_f32: - case SCC_IR_TYPE_f64: - case SCC_IR_TYPE_f128: - break; - case SCC_IR_TYPE_ARRAY: - in->data.array.base = 0; - in->data.array.len = 0; - break; - case SCC_IR_TYPE_PTR: - in->data.pointer.base = 0; - break; - case SCC_IR_TYPE_FUNC: - scc_vec_init(in->data.function.params); - in->data.function.ret_type = 0; - break; - case SCC_IR_TYPE_UNION: - case SCC_IR_TYPE_STRUCT: - scc_vec_init(in->data.aggregate.fields); - break; - default: - UNREACHABLE(); - break; - } -} - -void scc_ir_bblock_init(scc_ir_bblock_t *in, const char *label) { - Assert(in != nullptr); - Assert(label != nullptr); - in->label = label; - scc_vec_init(in->instrs); -} - -void scc_ir_func_init(scc_ir_func_t *in, const char *name) { - Assert(in != nullptr); - Assert(name != nullptr); - in->name = name; - in->type = 0; - scc_vec_init(in->bblocks); - scc_vec_init(in->params); -} - -void scc_ir_value_init(scc_ir_value_t *in, const char *name, - scc_ir_value_tag_t tag) { - Assert(in != nullptr); - in->name = name; - in->tag = tag; - scc_vec_init(in->used_by); - in->type = 0; - - switch (tag) { - case SCC_IR_VALUE_TAG_NULLPTR: - break; - case SCC_IR_VALUE_TAG_BUILTIN: - break; - case SCC_IR_VALUE_TAG_CONST_INT: - // TODO - in->data.const_int.int64 = 0; - break; - case SCC_IR_VALUE_TAG_ALLOC: - // TODO(); - break; - case SCC_IR_VALUE_TAG_LOAD: - in->data.load.target = 0; - break; - case SCC_IR_VALUE_TAG_STORE: - in->data.store.target = 0; - in->data.store.value = 0; - break; - case SCC_IR_VALUE_TAG_GET_ELEM_PTR: - in->data.get_elem_ptr.src_addr = 0; - in->data.get_elem_ptr.index = 0; - break; - case SCC_IR_VALUE_TAG_OP: - in->data.op.op = SCC_IR_OP_EMPTY; - in->data.op.lhs = 0; - in->data.op.rhs = 0; - break; - case SCC_IR_VALUE_TAG_BRANCH: - in->data.branch.cond = 0; - in->data.branch.true_bblock = 0; - in->data.branch.false_bblock = 0; - break; - case SCC_IR_VALUE_TAG_JUMP: - in->data.jump.target_bblock = 0; - break; - case SCC_IR_VALUE_TAG_CALL: - scc_vec_init(in->data.call.args); - in->data.call.callee = 0; - break; - case SCC_IR_VALUE_TAG_RET: - in->data.ret.ret_val = 0; - break; - default: - UNREACHABLE(); - break; - } -} diff --git a/libs/lir/cbuild.toml b/libs/lir/cbuild.toml deleted file mode 100644 index 796dfcb..0000000 --- a/libs/lir/cbuild.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "scc_lir" -version = "0.1.0" -authors = [] -description = "" - -dependencies = [ - { name = "scc_ir", path = "../ir" }, - { name = "scc_utils", path = "../../runtime/scc_utils" }, - { name = "tree_dump", path = "../tree_dump" }, -] -# features = {} -# default_features = [] diff --git a/libs/lir/include/scc_ir2lir.h b/libs/lir/include/scc_ir2lir.h deleted file mode 100644 index 8d6c6de..0000000 --- a/libs/lir/include/scc_ir2lir.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __SCC_IR2LIR_H__ -#define __SCC_IR2LIR_H__ - -#include "scc_lir.h" -#include "scc_lir_builder.h" -#include "scc_lir_module.h" -#include - -scc_lir_module_t *scc_ir2lir(scc_lir_builder_t *builder, - const scc_ir_cprog_t *cprog); - -#endif /* __SCC_IR2LIR_H__ */ diff --git a/libs/lir/include/scc_lir.h b/libs/lir/include/scc_lir.h deleted file mode 100644 index c963eee..0000000 --- a/libs/lir/include/scc_lir.h +++ /dev/null @@ -1,263 +0,0 @@ -/** - * @file scc_lir.h - * @brief 低层中间表示 (Low-Level IR) - 实用精简版 - * - * 设计原则: - * - 依赖 scc_core.h 和 scc_utils.h (仅使用哈希表) - * - 保留所有核心功能:复杂地址、并行复制、VA 支持、符号引用 - * - 基本块使用稳定 ID,通过哈希表快速查找 - * - 预留属性位掩码 (attr),未来可扩展 align、packed、weak 等 - * - 无字符串池、无类型缓存,保持简单 - */ - -#ifndef __SCC_LIR_H__ -#define __SCC_LIR_H__ - -#include -#include -#include - -typedef enum scc_lir_attr { - SCC_LIR_ATTR_NONE = 0, - SCC_LIR_ATTR_STATIC = 1 << 0, // 内部链接 - SCC_LIR_ATTR_WEAK = 1 << 1, // 弱符号 - SCC_LIR_ATTR_VIS_HIDDEN = 1 << 2, // 符号可见性 hidden - SCC_LIR_ATTR_NOINLINE = 1 << 3, - SCC_LIR_ATTR_ALWAYSINLINE = 1 << 4, - // 对齐值可编码在 attr 的高位,例如: - // #define SCC_LIR_ATTR_ALIGN(n) (((n) << 8) | SCC_LIR_ATTR_ALIGN_FLAG) -} scc_lir_attr_t; - -typedef enum { - SCC_LIR_INSTR_KIND_NONE, // 无操作数 - SCC_LIR_INSTR_KIND_VREG, // 虚拟寄存器 - SCC_LIR_INSTR_KIND_PREG, // 物理寄存器 (后端定义编号) - SCC_LIR_INSTR_KIND_IMM, // 整数立即数 - SCC_LIR_INSTR_KIND_FIMM, // 浮点立即数 - SCC_LIR_INSTR_KIND_SYMBOL, // 全局符号 (函数名、全局变量、字符串常量) - SCC_LIR_INSTR_KIND_ADDR // 复杂地址表达式 (base + index*scale + offset) -} scc_lir_instr_kind_t; - -/** - * @brief 复杂地址表达式 - * base + index * scale + offset - */ -typedef struct scc_lir_addr { - int base; // 基址寄存器,-1 表示无 - int index; // 索引寄存器,-1 表示无 - int scale; // 比例因子 (1, 2, 4, 8) - i64 offset; // 常量偏移 -} scc_lir_addr_t; - -typedef struct scc_lir_instr { - scc_lir_instr_kind_t kind; - union { - unsigned int reg; // VREG 或 PREG 索引 - i64 imm; // 整型立即数 - f64 fimm; // 浮点立即数 - const char *symbol; // 符号名 (生命周期由前端管理) - scc_lir_addr_t addr; // 复杂地址 - } data; -} scc_lir_val_t; - -/* 构造宏 */ -#define SCC_LIR_NONE() ((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_NONE}) -#define SCC_LIR_VREG(n) \ - ((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_VREG, .data.reg = (n)}) -#define SCC_LIR_PREG(r) \ - ((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_PREG, .data.reg = (r)}) -#define SCC_LIR_IMM(v) \ - ((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_IMM, .data.imm = (v)}) -#define SCC_LIR_FIMM(v) \ - ((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_FIMM, .data.fimm = (v)}) -#define SCC_LIR_SYMBOL(s) \ - ((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_SYMBOL, .data.symbol = (s)}) -#define SCC_LIR_ADDR(b, i, s, o) \ - ((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_ADDR, \ - .data.addr = {b, i, s, o}}) - -#define SCC_LIR_SIZE_8 1 -#define SCC_LIR_SIZE_16 2 -#define SCC_LIR_SIZE_32 4 -#define SCC_LIR_SIZE_64 8 - -typedef enum { - SCC_LIR_EXT_NONE, - SCC_LIR_EXT_SEXT, - SCC_LIR_EXT_ZEXT, - SCC_LIR_EXT_FLOAT -} scc_lir_ext_t; - -typedef enum { - /* 数据移动 */ - SCC_LIR_MOV, - SCC_LIR_LOAD, - SCC_LIR_LOAD_ADDR, - SCC_LIR_STORE, - SCC_LIR_STORE_ADDR, - SCC_LIR_LEA, - - /* 整数算术 */ - SCC_LIR_ADD, - SCC_LIR_SUB, - SCC_LIR_MUL, - SCC_LIR_DIV_S, - SCC_LIR_DIV_U, - SCC_LIR_REM_S, - SCC_LIR_REM_U, - SCC_LIR_AND, - SCC_LIR_OR, - SCC_LIR_XOR, - SCC_LIR_SHL, - SCC_LIR_SHR, - SCC_LIR_SAR, - SCC_LIR_NEG, - SCC_LIR_NOT, - - /* 浮点算术 */ - SCC_LIR_FADD, - SCC_LIR_FSUB, - SCC_LIR_FMUL, - SCC_LIR_FDIV, - SCC_LIR_FNEG, - SCC_LIR_FCVT, - - /* 比较 */ - SCC_LIR_CMP, - - /* 控制流 */ - SCC_LIR_BR, - SCC_LIR_JMP, - SCC_LIR_JMP_INDIRECT, - SCC_LIR_CALL, - SCC_LIR_CALL_INDIRECT, - SCC_LIR_RET, - - /* 并行复制 */ - SCC_LIR_PARALLEL_COPY, - - /* 可变参数 */ - SCC_LIR_VA_START, - SCC_LIR_VA_ARG, - SCC_LIR_VA_END, - SCC_LIR_VA_COPY, - - /* 栈管理 */ - SCC_LIR_ALLOCA, - - SCC_LIR_NOP -} scc_lir_op_t; - -typedef enum { - SCC_LIR_COND_EQ, - SCC_LIR_COND_NE, - SCC_LIR_COND_SLT, - SCC_LIR_COND_SLE, - SCC_LIR_COND_SGT, - SCC_LIR_COND_SGE, - SCC_LIR_COND_ULT, - SCC_LIR_COND_ULE, - SCC_LIR_COND_UGT, - SCC_LIR_COND_UGE, - SCC_LIR_COND_FEQ, - SCC_LIR_COND_FNE, - SCC_LIR_COND_FLT, - SCC_LIR_COND_FLE, - SCC_LIR_COND_FGT, - SCC_LIR_COND_FGE -} scc_lir_cond_t; - -typedef usize scc_lir_bblock_uid_t; - -typedef struct scc_lir_ins { - scc_lir_op_t op; - u8 size; - scc_lir_ext_t ext; - scc_lir_val_t to; - scc_lir_val_t arg0; - scc_lir_val_t arg1; - /// @brief debug 信息 - scc_pos_t src_loc; - - union { - scc_lir_cond_t cond; - - struct scc_lir_br { - scc_lir_bblock_uid_t true_target; - scc_lir_bblock_uid_t false_target; - } br; - - scc_lir_bblock_uid_t jmp_target; - - struct scc_lir_call { - const char *callee; - scc_lir_val_t *args; - int arg_count; - scc_lir_val_t ret_vreg; - u64 clobber_mask; - } call; - - struct scc_lir_call_indirect { - scc_lir_val_t target; - scc_lir_val_t *args; - int arg_count; - scc_lir_val_t ret_vreg; - u64 clobber_mask; - } call_indirect; - - scc_lir_val_t ret_val; - - struct scc_lir_parallel_copy { - scc_lir_val_t *dests; - scc_lir_val_t *srcs; - int num_copies; - } parallel_copy; - - struct scc_lir_alloca { - int size_bytes; - int align_bytes; - } alloca; - - struct { - scc_lir_val_t ap; - scc_lir_val_t last; - } va_start; - - struct { - scc_lir_val_t ap; - int type_size; - int type_align; - char is_float; - scc_lir_val_t to; - } va_arg; - - struct { - scc_lir_val_t ap; - } va_end; - - struct { - scc_lir_val_t dest; - scc_lir_val_t src; - } va_copy; - } metadata; -} scc_lir_instr_t; - -typedef SCC_VEC(scc_lir_instr_t) scc_lir_instr_vec_t; -typedef struct scc_lir_bblock { - scc_lir_bblock_uid_t id; // 稳定唯一 ID - const char *label; // 可读标签 - scc_lir_instr_vec_t ins; // 指令序列 -} scc_lir_bblock_t; - -typedef SCC_VEC(scc_lir_bblock_t) scc_lir_bblock_vec_t; -typedef struct scc_lir_func { - const char *name; - scc_lir_bblock_vec_t bblocks; - scc_hashtable_t bb_map; // ID -> 基本块索引 (usize) - scc_lir_bblock_uid_t next_bb_uid; - unsigned int vregs_count; - int frame_size; - scc_lir_attr_t attr; -} scc_lir_func_t; - -#endif /* __SCC_LIR_H__ */ diff --git a/libs/lir/include/scc_lir_builder.h b/libs/lir/include/scc_lir_builder.h deleted file mode 100644 index 229e6d2..0000000 --- a/libs/lir/include/scc_lir_builder.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef __SCC_LIR_BUILDER_H__ -#define __SCC_LIR_BUILDER_H__ - -#include "scc_lir.h" -#include "scc_lir_module.h" -#include - -typedef struct scc_lir_builder { - scc_lir_func_t *func; - scc_lir_bblock_t *cur_bb; - scc_hashtable_t value_to_vreg; // 高层 IR 值 -> 虚拟寄存器 - scc_lir_module_t *module; -} scc_lir_builder_t; - -void scc_lir_builder_init(scc_lir_builder_t *builder, scc_lir_module_t *module); -void scc_lir_builder_drop(scc_lir_builder_t *builder); -void scc_lir_builder_begin_func(scc_lir_builder_t *builder, const char *name); -void scc_lir_builder_end_func(scc_lir_builder_t *builder); -void scc_lir_builder_begin_bblock(scc_lir_builder_t *builder, - const char *label); -void scc_lir_builder_end_bblock(scc_lir_builder_t *builder); -void scc_lir_builder_add_instr(scc_lir_builder_t *builder, - const scc_lir_instr_t *instr); -unsigned int scc_lir_builder_new_vreg(scc_lir_builder_t *builder); - -#endif /* __SCC_LIR_BUILDER_H__ */ diff --git a/libs/lir/include/scc_lir_dump.h b/libs/lir/include/scc_lir_dump.h deleted file mode 100644 index 86b8a6d..0000000 --- a/libs/lir/include/scc_lir_dump.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef __SCC_LIR_DUMP_H__ -#define __SCC_LIR_DUMP_H__ - -#include "scc_lir.h" -#include "scc_lir_module.h" -#include - -typedef struct { - scc_tree_dump_t *dump_ctx; -} scc_lir_dump_ctx_t; - -static inline void scc_lir_dump_init(scc_lir_dump_ctx_t *ctx, - scc_tree_dump_t *dump_ctx) { - ctx->dump_ctx = dump_ctx; -} -void scc_lir_dump_ins(scc_lir_dump_ctx_t *ctx, const scc_lir_instr_t *ins); -void scc_lir_dump_bblock(scc_lir_dump_ctx_t *ctx, const scc_lir_bblock_t *bb); -void scc_lir_dump_func(scc_lir_dump_ctx_t *ctx, const scc_lir_func_t *func); -void scc_lir_dump_module(scc_lir_dump_ctx_t *ctx, - const scc_lir_module_t *module); - -#endif /* __SCC_LIR_DUMP_H__ */ diff --git a/libs/lir/include/scc_lir_module.h b/libs/lir/include/scc_lir_module.h deleted file mode 100644 index ed91b8e..0000000 --- a/libs/lir/include/scc_lir_module.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - * @file scc_lir_module.h - * @brief LIR 模块:管理函数定义、全局符号和声明 - */ - -#ifndef __SCC_LIR_MODULE_H__ -#define __SCC_LIR_MODULE_H__ - -#include "scc_lir.h" -#include -#include - -typedef enum scc_lir_symbol_kind { - SCC_LIR_SYMBOL_FUNC, // 函数符号 - SCC_LIR_SYMBOL_DATA, // 数据符号(全局变量、常量) - SCC_LIR_SYMBOL_EXTERN, // 外部符号(未定义,需链接器解析) -} scc_lir_symbol_kind_t; - -typedef struct scc_lir_symbol { - const char *name; // 符号名(驻留字符串或前端管理) - scc_lir_symbol_kind_t kind; // 符号类型 - scc_lir_attr_t attr; // 属性(static, weak 等) - - union { - struct { - scc_lir_func_t *func; // 指向函数体(若为定义) - } func; - struct { - u8 *init_data; // 初始化数据(若为 NULL 则零初始化) - usize size; // 数据大小(字节) - int align; // 对齐要求 - } data; - }; -} scc_lir_symbol_t; - -typedef struct scc_lir_module { - SCC_VEC(scc_lir_func_t *) funcs; // 所有函数定义(按添加顺序) - SCC_VEC(scc_lir_symbol_t) symbols; // 所有全局符号(包含声明和定义) - scc_hashtable_t symbol_map; // name -> 索引 (usize) 在 symbols 向量中 -} scc_lir_module_t; - -/** - * @brief 初始化 LIR 模块 - */ -void scc_lir_module_init(scc_lir_module_t *module); - -/** - * @brief 销毁 LIR 模块,释放所有函数和符号资源 - */ -void scc_lir_module_drop(scc_lir_module_t *module); - -/** - * @brief 添加一个函数定义到模块 - * @param mod 模块 - * @param func 函数定义(所有权转移给模块) - * @return 符号指针(内部持有,不可释放) - */ -const scc_lir_symbol_t *scc_lir_module_add_func_def(scc_lir_module_t *module, - scc_lir_func_t *func); - -/** - * @brief 添加一个函数声明(外部或未定义) - * @param mod 模块 - * @param name 函数名 - * @param attr 属性 - * @return 符号指针 - */ -const scc_lir_symbol_t *scc_lir_module_add_func_decl(scc_lir_module_t *module, - const char *name, - scc_lir_attr_t attr); - -/** - * @brief 添加一个全局数据符号(定义或外部) - * @param mod 模块 - * @param name 符号名 - * @param kind 种类(DATA 或 EXTERN) - * @param init_data 初始化数据(若为 DATA 定义;若为 NULL 则零初始化) - * @param size 数据大小(若为 EXTERN 可为 0) - * @param align 对齐要求 - * @param attr 属性 - * @return 符号指针 - */ -const scc_lir_symbol_t *scc_lir_module_add_data(scc_lir_module_t *module, - const char *name, - scc_lir_symbol_kind_t kind, - const u8 *init_data, usize size, - u32 align, scc_lir_attr_t attr); - -/** - * @brief 通过名称查找符号 - * @param mod 模块 - * @param name 符号名 - * @return 符号指针,未找到返回 nullptr - */ -const scc_lir_symbol_t * -scc_lir_module_lookup_symbol(const scc_lir_module_t *module, const char *name); - -#endif /* __SCC_LIR_MODULE_H__ */ diff --git a/libs/lir/src/scc_ir2lir.c b/libs/lir/src/scc_ir2lir.c deleted file mode 100644 index 5d09996..0000000 --- a/libs/lir/src/scc_ir2lir.c +++ /dev/null @@ -1,599 +0,0 @@ -/** - * @file scc_ir2lir.c - * @brief 将高级 IR (scc_ir) 降级为低层 LIR (scc_lir) - */ - -#include -#include - -/* ---------- 转换上下文 ---------- */ -typedef struct { - scc_lir_builder_t *builder; - scc_ir_module_t *ir_module; - scc_hashtable_t bb_map; // ir_bblock_ref_t -> scc_lir_bblock_uid_t - scc_hashtable_t value_to_vreg; // ir_value_ref_t -> unsigned int vreg - scc_hashtable_t func_decl_map; // ir_func_ref_t -> const char* (用于调用) -} ir2lir_ctx_t; - -static void ir2lir_ctx_init(ir2lir_ctx_t *ctx, scc_lir_builder_t *builder, - scc_ir_module_t *ir_module) { - ctx->builder = builder; - ctx->ir_module = ir_module; - scc_hashtable_usize_init(&ctx->bb_map); - scc_hashtable_usize_init(&ctx->value_to_vreg); - scc_hashtable_usize_init(&ctx->func_decl_map); -} - -static void ir2lir_ctx_drop(ir2lir_ctx_t *ctx) { - scc_hashtable_drop(&ctx->bb_map); - scc_hashtable_drop(&ctx->value_to_vreg); - scc_hashtable_drop(&ctx->func_decl_map); -} - -/* ---------- 工具函数 ---------- */ - -// 获取 IR 类型对应的 LIR 大小和扩展属性 -static void ir_type_to_lir_size_ext(scc_ir_type_t *type, u8 *out_size, - scc_lir_ext_t *out_ext) { - switch (type->tag) { - case SCC_IR_TYPE_i8: - *out_size = SCC_LIR_SIZE_8; - *out_ext = SCC_LIR_EXT_SEXT; - break; - case SCC_IR_TYPE_u8: - *out_size = SCC_LIR_SIZE_8; - *out_ext = SCC_LIR_EXT_ZEXT; - break; - case SCC_IR_TYPE_i16: - *out_size = SCC_LIR_SIZE_16; - *out_ext = SCC_LIR_EXT_SEXT; - break; - case SCC_IR_TYPE_u16: - *out_size = SCC_LIR_SIZE_16; - *out_ext = SCC_LIR_EXT_ZEXT; - break; - case SCC_IR_TYPE_i32: - *out_size = SCC_LIR_SIZE_32; - *out_ext = SCC_LIR_EXT_SEXT; - break; - case SCC_IR_TYPE_u32: - *out_size = SCC_LIR_SIZE_32; - *out_ext = SCC_LIR_EXT_ZEXT; - break; - case SCC_IR_TYPE_i64: - *out_size = SCC_LIR_SIZE_64; - *out_ext = SCC_LIR_EXT_SEXT; - break; - case SCC_IR_TYPE_u64: - *out_size = SCC_LIR_SIZE_64; - *out_ext = SCC_LIR_EXT_ZEXT; - break; - case SCC_IR_TYPE_f32: - *out_size = SCC_LIR_SIZE_32; - *out_ext = SCC_LIR_EXT_FLOAT; - break; - case SCC_IR_TYPE_f64: - *out_size = SCC_LIR_SIZE_64; - *out_ext = SCC_LIR_EXT_FLOAT; - break; - case SCC_IR_TYPE_PTR: - *out_size = SCC_LIR_SIZE_64; - *out_ext = SCC_LIR_EXT_NONE; - break; - case SCC_IR_TYPE_void: - *out_size = 0; - *out_ext = SCC_LIR_EXT_NONE; - break; - default: - Panic("unsupported IR type in lowering"); - } -} - -// 获取或创建 IR 值对应的虚拟寄存器 -static unsigned int get_vreg_for_value(ir2lir_ctx_t *ctx, - scc_ir_value_ref_t val_ref) { - void *found = - scc_hashtable_get(&ctx->value_to_vreg, (void *)(uintptr_t)val_ref); - if (found) - return (unsigned int)(uintptr_t)found; - - unsigned int vreg = scc_lir_builder_new_vreg(ctx->builder); - scc_hashtable_set(&ctx->value_to_vreg, (void *)(uintptr_t)val_ref, - (void *)(uintptr_t)vreg); - return vreg; -} - -// 将 IR 值转换为 LIR 操作数 (可能递归触发指令生成) -static scc_lir_val_t ir_value_to_lir_operand(ir2lir_ctx_t *ctx, - scc_ir_value_ref_t val_ref); - -// 前向声明 -static void translate_ir_value(ir2lir_ctx_t *ctx, scc_ir_value_t *value, - scc_ir_value_ref_t value_ref); - -// 获取 LIR 操作数:若为常量/全局符号则直接构造,否则返回对应 vreg -static scc_lir_val_t ir_value_to_lir_operand(ir2lir_ctx_t *ctx, - scc_ir_value_ref_t val_ref) { - scc_ir_value_t *val = scc_ir_module_get_value(ctx->ir_module, val_ref); - Assert(val != nullptr); - - switch (val->tag) { - case SCC_IR_VALUE_TAG_CONST_INT: { - scc_ir_type_t *ty = scc_ir_module_get_type(ctx->ir_module, val->type); - i64 imm = 0; - if (ty->tag == SCC_IR_TYPE_i8 || ty->tag == SCC_IR_TYPE_u8) - imm = val->data.const_int.int8; - else if (ty->tag == SCC_IR_TYPE_i16 || ty->tag == SCC_IR_TYPE_u16) - imm = val->data.const_int.int16; - else if (ty->tag == SCC_IR_TYPE_i32 || ty->tag == SCC_IR_TYPE_u32) - imm = val->data.const_int.int32; - else if (ty->tag == SCC_IR_TYPE_i64 || ty->tag == SCC_IR_TYPE_u64) - imm = val->data.const_int.int64; - else - imm = val->data.const_int.int64; - return SCC_LIR_IMM(imm); - } - case SCC_IR_VALUE_TAG_CONST_FLOAT: { - scc_ir_type_t *ty = scc_ir_module_get_type(ctx->ir_module, val->type); - f64 fimm = (ty->tag == SCC_IR_TYPE_f32) ? val->data.const_float.float32 - : val->data.const_float.float64; - return SCC_LIR_FIMM(fimm); - } - case SCC_IR_VALUE_TAG_GLOBAL_ALLOC: { - // 全局变量地址作为符号 - scc_ir_value_t *global_val = scc_ir_module_get_value( - ctx->ir_module, val->data.global_alloc.value); - return SCC_LIR_SYMBOL(global_val->name); - } - case SCC_IR_VALUE_TAG_FUNC_ARG_REF: { - // 函数参数:预先已分配 vreg - unsigned int vreg = get_vreg_for_value(ctx, val_ref); - return SCC_LIR_VREG(vreg); - } - case SCC_IR_VALUE_TAG_NULLPTR: { - return SCC_LIR_IMM(0); - } - default: { - // 其他所有产生值的指令:确保其指令已生成,然后返回 vreg - // 注意:这里可能会递归调用 translate_ir_value,因此需要先检查是否已翻译 - void *found = - scc_hashtable_get(&ctx->value_to_vreg, (void *)(uintptr_t)val_ref); - if (!found) { - translate_ir_value(ctx, val, val_ref); - } - unsigned int vreg = (unsigned int)(uintptr_t)scc_hashtable_get( - &ctx->value_to_vreg, (void *)(uintptr_t)val_ref); - return SCC_LIR_VREG(vreg); - } - } -} - -/* ---------- 操作码映射 ---------- */ - -static scc_lir_cond_t map_cmp_cond(scc_ir_op_type_t op, cbool is_float) { - if (is_float) { - switch (op) { - case SCC_IR_OP_EQ: - return SCC_LIR_COND_FEQ; - case SCC_IR_OP_NEQ: - return SCC_LIR_COND_FNE; - case SCC_IR_OP_LT: - return SCC_LIR_COND_FLT; - case SCC_IR_OP_LE: - return SCC_LIR_COND_FLE; - case SCC_IR_OP_GT: - return SCC_LIR_COND_FGT; - case SCC_IR_OP_GE: - return SCC_LIR_COND_FGE; - default: - Panic("invalid float cmp"); - } - } else { - // 默认为有符号比较 (无符号需额外处理类型) - switch (op) { - case SCC_IR_OP_EQ: - return SCC_LIR_COND_EQ; - case SCC_IR_OP_NEQ: - return SCC_LIR_COND_NE; - case SCC_IR_OP_LT: - return SCC_LIR_COND_SLT; - case SCC_IR_OP_LE: - return SCC_LIR_COND_SLE; - case SCC_IR_OP_GT: - return SCC_LIR_COND_SGT; - case SCC_IR_OP_GE: - return SCC_LIR_COND_SGE; - default: - Panic("invalid int cmp"); - } - } - return SCC_LIR_COND_EQ; -} - -static scc_lir_op_t map_binop(scc_ir_op_type_t op, bool is_float) { - if (is_float) { - switch (op) { - case SCC_IR_OP_ADD: - return SCC_LIR_FADD; - case SCC_IR_OP_SUB: - return SCC_LIR_FSUB; - case SCC_IR_OP_MUL: - return SCC_LIR_FMUL; - case SCC_IR_OP_DIV: - return SCC_LIR_FDIV; - default: - Panic("unsupported float binop"); - } - } else { - switch (op) { - case SCC_IR_OP_ADD: - return SCC_LIR_ADD; - case SCC_IR_OP_SUB: - return SCC_LIR_SUB; - case SCC_IR_OP_MUL: - return SCC_LIR_MUL; - case SCC_IR_OP_DIV: - return SCC_LIR_DIV_S; - case SCC_IR_OP_MOD: - return SCC_LIR_REM_S; - case SCC_IR_OP_AND: - return SCC_LIR_AND; - case SCC_IR_OP_OR: - return SCC_LIR_OR; - case SCC_IR_OP_XOR: - return SCC_LIR_XOR; - case SCC_IR_OP_SHL: - return SCC_LIR_SHL; - case SCC_IR_OP_SHR: - return SCC_LIR_SHR; - case SCC_IR_OP_SAR: - return SCC_LIR_SAR; - default: - return map_cmp_cond(op, is_float); - } - } - return SCC_LIR_NOP; -} - -/* ---------- 单条 IR 指令翻译 ---------- */ - -static void translate_ir_value(ir2lir_ctx_t *ctx, scc_ir_value_t *value, - scc_ir_value_ref_t value_ref) { - // 防止重复翻译 - if (scc_hashtable_get(&ctx->value_to_vreg, (void *)(uintptr_t)value_ref)) - return; - - scc_ir_type_t *ty = scc_ir_module_get_type(ctx->ir_module, value->type); - u8 size = 0; - scc_lir_ext_t ext = SCC_LIR_EXT_NONE; - if (ty != nullptr) { - ir_type_to_lir_size_ext(ty, &size, &ext); - } - bool is_float = (ext == SCC_LIR_EXT_FLOAT); - - // 为当前指令分配目标虚拟寄存器 - unsigned int dst_vreg = get_vreg_for_value(ctx, value_ref); - - switch (value->tag) { - case SCC_IR_VALUE_TAG_OP: { - scc_lir_val_t lhs = ir_value_to_lir_operand(ctx, value->data.op.lhs); - scc_lir_val_t rhs = ir_value_to_lir_operand(ctx, value->data.op.rhs); - scc_lir_op_t op = map_binop(value->data.op.op, is_float); - - scc_lir_instr_t instr = {.op = op, - .size = size, - .ext = ext, - .to = SCC_LIR_VREG(dst_vreg), - .arg0 = lhs, - .arg1 = rhs}; - scc_lir_builder_add_instr(ctx->builder, &instr); - break; - } - case SCC_IR_VALUE_TAG_LOAD: { - scc_lir_val_t addr = - ir_value_to_lir_operand(ctx, value->data.load.target); - scc_lir_instr_t instr = {.op = SCC_LIR_LOAD, - .size = size, - .ext = ext, - .to = SCC_LIR_VREG(dst_vreg), - .arg0 = addr}; - scc_lir_builder_add_instr(ctx->builder, &instr); - break; - } - case SCC_IR_VALUE_TAG_STORE: { - scc_lir_val_t data = - ir_value_to_lir_operand(ctx, value->data.store.value); - scc_lir_val_t addr = - ir_value_to_lir_operand(ctx, value->data.store.target); - scc_lir_instr_t instr = { - .op = SCC_LIR_STORE, .size = size, .arg0 = data, .arg1 = addr}; - scc_lir_builder_add_instr(ctx->builder, &instr); - break; - } - case SCC_IR_VALUE_TAG_GET_ELEM_PTR: { - // 将指针运算转换为 LEA - scc_lir_val_t base = - ir_value_to_lir_operand(ctx, value->data.get_elem_ptr.src_addr); - scc_lir_val_t index = SCC_LIR_IMM(0); - if (value->data.get_elem_ptr.index) - ir_value_to_lir_operand(ctx, value->data.get_elem_ptr.index); - - // 计算元素大小 - scc_ir_type_t *ptr_ty = scc_ir_module_get_type_by_value( - ctx->ir_module, value->data.get_elem_ptr.src_addr); - scc_ir_type_t *elem_ty = nullptr; - if (ptr_ty->tag == SCC_IR_TYPE_PTR) { - elem_ty = scc_ir_module_get_type(ctx->ir_module, - ptr_ty->data.pointer.base); - } else if (ptr_ty->tag == SCC_IR_TYPE_ARRAY) { - elem_ty = - scc_ir_module_get_type(ctx->ir_module, ptr_ty->data.array.base); - } - Assert(elem_ty != nullptr); - int elem_size = 0; - // 简化:仅处理基本类型 - if (elem_ty->tag == SCC_IR_TYPE_i32 || elem_ty->tag == SCC_IR_TYPE_u32) - elem_size = 4; - else if (elem_ty->tag == SCC_IR_TYPE_i64 || - elem_ty->tag == SCC_IR_TYPE_u64) - elem_size = 8; - else if (elem_ty->tag == SCC_IR_TYPE_i8 || - elem_ty->tag == SCC_IR_TYPE_u8) - elem_size = 1; - else if (elem_ty->tag == SCC_IR_TYPE_ARRAY) - elem_size = 8; // FIXME ptr size - else - Panic("unsupported element type for getelemptr"); - - // 构造地址表达式:base + index * elem_size - scc_lir_val_t addr = - SCC_LIR_ADDR(dst_vreg, -1, index.data.reg, elem_size); - // 更简单的做法:使用 LEA 指令,参数为 base 和 index,由后端展开 - scc_lir_instr_t instr = {.op = SCC_LIR_LEA, - .size = SCC_LIR_SIZE_64, - .to = SCC_LIR_VREG(dst_vreg), - .arg0 = base, - .arg1 = index}; - // 实际需要将 index * elem_size 的信息编码,这里简化,假设后端处理 - scc_lir_builder_add_instr(ctx->builder, &instr); - break; - } - case SCC_IR_VALUE_TAG_ALLOC: { - // alloca 指令:分配栈空间 - scc_ir_type_t *alloc_ty = - scc_ir_module_get_type(ctx->ir_module, ty->data.pointer.base); - // 计算大小和对齐(简化) - int alloc_size = 8; // 默认 - if (alloc_ty->tag == SCC_IR_TYPE_i32) - alloc_size = 4; - scc_lir_instr_t instr = {.op = SCC_LIR_ALLOCA, - .size = SCC_LIR_SIZE_64, - .to = SCC_LIR_VREG(dst_vreg), - .metadata.alloca = {alloc_size, alloc_size}}; - scc_lir_builder_add_instr(ctx->builder, &instr); - break; - } - case SCC_IR_VALUE_TAG_CALL: { - scc_ir_func_t *callee = - scc_ir_module_get_func(ctx->ir_module, value->data.call.callee); - int arg_count = scc_vec_size(value->data.call.args); - scc_lir_val_t *lir_args = scc_malloc(sizeof(scc_lir_val_t) * arg_count); - for (int i = 0; i < arg_count; i++) { - scc_ir_value_ref_t arg_ref = scc_vec_at(value->data.call.args, i); - lir_args[i] = ir_value_to_lir_operand(ctx, arg_ref); - } - - scc_lir_instr_t instr = { - .op = SCC_LIR_CALL, - .size = size, - .to = SCC_LIR_VREG(dst_vreg), - .metadata.call = {.callee = callee->name, - .args = lir_args, - .arg_count = arg_count, - .ret_vreg = SCC_LIR_VREG(dst_vreg), - .clobber_mask = 0}}; - scc_lir_builder_add_instr(ctx->builder, &instr); - // 注意:lir_args 内存将随指令结构体复制到基本块向量中,但 - // metadata.call.args 指针仍指向 malloc 内存, - // 这会导致内存泄漏。实际实现中应使用 arena - // 分配或随函数释放。此处为示例简化。 - break; - } - case SCC_IR_VALUE_TAG_BRANCH: { - scc_lir_val_t cond = - ir_value_to_lir_operand(ctx, value->data.branch.cond); - scc_lir_bblock_uid_t true_bb = - (scc_lir_bblock_uid_t)(uintptr_t)scc_hashtable_get( - &ctx->bb_map, - (void *)(uintptr_t)value->data.branch.true_bblock); - scc_lir_bblock_uid_t false_bb = - (scc_lir_bblock_uid_t)(uintptr_t)scc_hashtable_get( - &ctx->bb_map, - (void *)(uintptr_t)value->data.branch.false_bblock); - scc_lir_instr_t instr = { - .op = SCC_LIR_BR, .arg0 = cond, .metadata.br = {true_bb, false_bb}}; - scc_lir_builder_add_instr(ctx->builder, &instr); - break; - } - case SCC_IR_VALUE_TAG_JUMP: { - scc_lir_bblock_uid_t target = - (scc_lir_bblock_uid_t)(uintptr_t)scc_hashtable_get( - &ctx->bb_map, - (void *)(uintptr_t)value->data.jump.target_bblock); - scc_lir_instr_t instr = {.op = SCC_LIR_JMP, - .metadata.jmp_target = target}; - scc_lir_builder_add_instr(ctx->builder, &instr); - break; - } - case SCC_IR_VALUE_TAG_RET: { - scc_lir_val_t ret_val; - if (value->data.ret.ret_val != SCC_IR_REF_nullptr) { - ret_val = ir_value_to_lir_operand(ctx, value->data.ret.ret_val); - } else { - ret_val = SCC_LIR_NONE(); - } - scc_lir_instr_t instr = {.op = SCC_LIR_RET, - .metadata.ret_val = ret_val}; - scc_lir_builder_add_instr(ctx->builder, &instr); - break; - } - case SCC_IR_VALUE_TAG_CONV: { - // 类型转换:使用 MOV 指令配合扩展/截断 - scc_lir_val_t src = - ir_value_to_lir_operand(ctx, value->data.conv.operand); - scc_lir_ext_t conv_ext = SCC_LIR_EXT_NONE; - if (value->data.conv.conv_type == CONV_SEXT) - conv_ext = SCC_LIR_EXT_SEXT; - else if (value->data.conv.conv_type == CONV_ZEXT) - conv_ext = SCC_LIR_EXT_ZEXT; - // TRUNC 用 NONE 即可(MOV 截断) - scc_lir_instr_t instr = {.op = SCC_LIR_MOV, - .size = size, - .ext = conv_ext, - .to = SCC_LIR_VREG(dst_vreg), - .arg0 = src}; - scc_lir_builder_add_instr(ctx->builder, &instr); - break; - } - // case SCC_IR_VALUE_TAG_CMP: { - // // 注意:IR 中没有单独的 CMP - // // 节点,比较通常作为二元运算的一种或分支条件的一部分。 - // // 此处假设比较操作已由前端处理为条件分支,无需生成 LIR 指令。 - // break; - // } - // 常量、参数、全局变量等已在 ir_value_to_lir_operand - // 中直接返回,不会进入此处 - default: - // 不生成指令的节点(如 CONST_INT, FUNC_ARG_REF)不会调用本函数 - break; - } -} - -/* ---------- 基本块翻译 ---------- */ - -static void translate_bblock(ir2lir_ctx_t *ctx, scc_ir_bblock_t *bblock, - scc_ir_bblock_ref_t bblock_ref) { - // 创建 LIR 基本块并记录映射 - scc_lir_builder_begin_bblock(ctx->builder, bblock->label); - scc_lir_bblock_uid_t lir_bb_id = ctx->builder->cur_bb->id; - scc_hashtable_set(&ctx->bb_map, (void *)(uintptr_t)bblock_ref, - (void *)(uintptr_t)lir_bb_id); - - // 翻译每条指令 - for (usize i = 0; i < scc_vec_size(bblock->instrs); i++) { - scc_ir_value_ref_t val_ref = scc_vec_at(bblock->instrs, i); - scc_ir_value_t *val = scc_ir_module_get_value(ctx->ir_module, val_ref); - translate_ir_value(ctx, val, val_ref); - } - - scc_lir_builder_end_bblock(ctx->builder); -} - -/* ---------- 函数翻译 ---------- */ - -static void translate_func(ir2lir_ctx_t *ctx, scc_ir_func_t *ir_func) { - scc_lir_builder_begin_func(ctx->builder, ir_func->name); - - // 预先为所有参数分配虚拟寄存器 - for (usize i = 0; i < scc_vec_size(ir_func->params); i++) { - scc_ir_value_ref_t param_ref = scc_vec_at(ir_func->params, i); - get_vreg_for_value(ctx, param_ref); - } - - // 第一遍:创建所有基本块(空壳),建立映射 - for (usize i = 0; i < scc_vec_size(ir_func->bblocks); i++) { - scc_ir_bblock_ref_t bb_ref = scc_vec_at(ir_func->bblocks, i); - scc_ir_bblock_t *bb = scc_ir_module_get_bblock(ctx->ir_module, bb_ref); - - scc_lir_builder_begin_bblock(ctx->builder, bb->label); - scc_lir_bblock_uid_t lir_bb_id = ctx->builder->cur_bb->id; - scc_hashtable_set(&ctx->bb_map, (void *)(uintptr_t)bb_ref, - (void *)(uintptr_t)lir_bb_id); - scc_lir_builder_end_bblock(ctx->builder); - } - - // 第二遍:填充每个基本块的指令 - for (usize i = 0; i < scc_vec_size(ir_func->bblocks); i++) { - scc_ir_bblock_ref_t bb_ref = scc_vec_at(ir_func->bblocks, i); - scc_ir_bblock_t *bb = scc_ir_module_get_bblock(ctx->ir_module, bb_ref); - scc_lir_bblock_uid_t lir_bb_id = - (scc_lir_bblock_uid_t)(uintptr_t)scc_hashtable_get( - &ctx->bb_map, (void *)(uintptr_t)bb_ref); - - // 切换到该基本块 - scc_lir_bblock_t *lir_bb = nullptr; - for (usize j = 0; j < scc_vec_size(ctx->builder->func->bblocks); j++) { - if (scc_vec_at(ctx->builder->func->bblocks, j).id == lir_bb_id) { - lir_bb = &scc_vec_at(ctx->builder->func->bblocks, j); - break; - } - } - Assert(lir_bb != nullptr); - ctx->builder->cur_bb = lir_bb; - - // 翻译指令 - for (usize j = 0; j < scc_vec_size(bb->instrs); j++) { - scc_ir_value_ref_t val_ref = scc_vec_at(bb->instrs, j); - scc_ir_value_t *val = - scc_ir_module_get_value(ctx->ir_module, val_ref); - translate_ir_value(ctx, val, val_ref); - } - } - - scc_lir_builder_end_func(ctx->builder); - - // 清理本次函数翻译的临时映射 - scc_hashtable_drop(&ctx->bb_map); - scc_hashtable_drop(&ctx->value_to_vreg); -} - -/* ---------- 公开接口 ---------- */ - -scc_lir_module_t *scc_ir2lir(scc_lir_builder_t *builder, - const scc_ir_cprog_t *cprog) { - Assert(builder && builder->module && cprog); - - ir2lir_ctx_t ctx; - ir2lir_ctx_init(&ctx, builder, &cprog->module); - - // 1. 处理全局变量 - for (usize i = 0; i < scc_vec_size(cprog->global_vals); i++) { - scc_ir_value_ref_t gv_ref = scc_vec_at(cprog->global_vals, i); - scc_ir_value_t *galloc = - scc_ir_module_get_value(&cprog->module, gv_ref); - Assert(galloc->tag == SCC_IR_VALUE_TAG_GLOBAL_ALLOC); - scc_ir_value_t *val = scc_ir_module_get_value( - &cprog->module, galloc->data.global_alloc.value); - scc_ir_buffer_t *data = &val->data.const_array.fields; - const scc_lir_symbol_t *sym = scc_lir_module_add_data( - builder->module, galloc->name, SCC_LIR_SYMBOL_DATA, - scc_vec_unsafe_get_data(*data), scc_vec_size(*data), 0, 0); - Assert(sym != nullptr); - } - - // 2. 处理函数声明 (外部函数) - for (usize i = 0; i < scc_vec_size(cprog->func_decls); i++) { - scc_ir_func_ref_t func_ref = scc_vec_at(cprog->func_decls, i); - scc_ir_func_t *func = scc_ir_module_get_func(&cprog->module, func_ref); - if (!func) - continue; - const scc_lir_symbol_t *sym = - scc_lir_module_add_func_decl(builder->module, func->name, 0); - Assert(sym); - // 记录映射,供调用时使用 - scc_hashtable_set(&ctx.func_decl_map, (void *)(uintptr_t)func_ref, - (void *)func->name); - } - - // 3. 处理函数定义 - for (usize i = 0; i < scc_vec_size(cprog->func_defs); i++) { - scc_ir_func_ref_t func_ref = scc_vec_at(cprog->func_defs, i); - scc_ir_func_t *func = scc_ir_module_get_func(&cprog->module, func_ref); - if (!func) - continue; - translate_func(&ctx, func); - } - - ir2lir_ctx_drop(&ctx); - return builder->module; -} diff --git a/libs/lir/src/scc_lir_builder.c b/libs/lir/src/scc_lir_builder.c deleted file mode 100644 index 9d3097c..0000000 --- a/libs/lir/src/scc_lir_builder.c +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include - -void scc_lir_builder_init(scc_lir_builder_t *builder, - scc_lir_module_t *module) { - Assert(module != nullptr); - builder->cur_bb = nullptr; - builder->func = nullptr; - builder->module = module; - scc_hashtable_usize_init(&builder->value_to_vreg); -} - -void scc_lir_builder_drop(scc_lir_builder_t *builder) { - scc_hashtable_drop(&builder->value_to_vreg); -} - -void scc_lir_builder_begin_func(scc_lir_builder_t *builder, const char *name) { - Assert(builder != nullptr); - scc_lir_func_t *func = scc_malloc(sizeof(scc_lir_func_t)); - builder->func = func; - Assert(builder->func != nullptr); - builder->cur_bb = nullptr; - - // Init; - func->next_bb_uid = 1; - func->vregs_count = 0; - func->name = nullptr; - func->frame_size = 0; - func->attr = 0; - func->name = name; - scc_vec_init(func->bblocks); - scc_hashtable_usize_init(&func->bb_map); -} - -void scc_lir_builder_end_func(scc_lir_builder_t *builder) { - Assert(builder != nullptr && builder->module != nullptr); - scc_lir_module_add_func_def(builder->module, builder->func); - builder->func = nullptr; -} - -void scc_lir_builder_begin_bblock(scc_lir_builder_t *builder, - const char *label) { - Assert(builder != nullptr && builder->module != nullptr && - builder->func != nullptr); - Assert(builder->cur_bb == nullptr); - scc_vec_push(builder->func->bblocks, (scc_lir_bblock_t){0}); - builder->cur_bb = &scc_vec_at(builder->func->bblocks, - scc_vec_size(builder->func->bblocks) - 1); - - builder->cur_bb->id = builder->func->next_bb_uid++; - scc_vec_init(builder->cur_bb->ins); - builder->cur_bb->label = label; -} - -void scc_lir_builder_end_bblock(scc_lir_builder_t *builder) { - builder->cur_bb = nullptr; -} - -void scc_lir_builder_add_instr(scc_lir_builder_t *builder, - const scc_lir_instr_t *instr) { - Assert(builder != nullptr && builder->cur_bb != nullptr && - instr != nullptr); - scc_vec_push(builder->cur_bb->ins, *instr); -} - -unsigned int scc_lir_builder_new_vreg(scc_lir_builder_t *builder) { - return builder->func->vregs_count++; -} diff --git a/libs/lir/src/scc_lir_dump.c b/libs/lir/src/scc_lir_dump.c deleted file mode 100644 index a8a29b9..0000000 --- a/libs/lir/src/scc_lir_dump.c +++ /dev/null @@ -1,452 +0,0 @@ -/** - * @file scc_lir_dump.c - * @brief LIR 文本 dump 实现 - */ - -#include "scc_lir_dump.h" -#include - -static const char *op_to_string(scc_lir_op_t op) { - switch (op) { - case SCC_LIR_MOV: - return "mov"; - case SCC_LIR_LOAD: - return "load"; - case SCC_LIR_LOAD_ADDR: - return "load.addr"; - case SCC_LIR_STORE: - return "store"; - case SCC_LIR_STORE_ADDR: - return "store.addr"; - case SCC_LIR_LEA: - return "lea"; - case SCC_LIR_ADD: - return "add"; - case SCC_LIR_SUB: - return "sub"; - case SCC_LIR_MUL: - return "mul"; - case SCC_LIR_DIV_S: - return "div.s"; - case SCC_LIR_DIV_U: - return "div.u"; - case SCC_LIR_REM_S: - return "rem.s"; - case SCC_LIR_REM_U: - return "rem.u"; - case SCC_LIR_AND: - return "and"; - case SCC_LIR_OR: - return "or"; - case SCC_LIR_XOR: - return "xor"; - case SCC_LIR_SHL: - return "shl"; - case SCC_LIR_SHR: - return "shr"; - case SCC_LIR_SAR: - return "sar"; - case SCC_LIR_NEG: - return "neg"; - case SCC_LIR_NOT: - return "not"; - case SCC_LIR_FADD: - return "fadd"; - case SCC_LIR_FSUB: - return "fsub"; - case SCC_LIR_FMUL: - return "fmul"; - case SCC_LIR_FDIV: - return "fdiv"; - case SCC_LIR_FNEG: - return "fneg"; - case SCC_LIR_FCVT: - return "fcvt"; - case SCC_LIR_CMP: - return "cmp"; - case SCC_LIR_BR: - return "br"; - case SCC_LIR_JMP: - return "jmp"; - case SCC_LIR_JMP_INDIRECT: - return "jmp.indirect"; - case SCC_LIR_CALL: - return "call"; - case SCC_LIR_CALL_INDIRECT: - return "call.indirect"; - case SCC_LIR_RET: - return "ret"; - case SCC_LIR_PARALLEL_COPY: - return "parallel_copy"; - case SCC_LIR_VA_START: - return "va_start"; - case SCC_LIR_VA_ARG: - return "va_arg"; - case SCC_LIR_VA_END: - return "va_end"; - case SCC_LIR_VA_COPY: - return "va_copy"; - case SCC_LIR_ALLOCA: - return "alloca"; - case SCC_LIR_NOP: - return "nop"; - default: - return "???"; - } -} - -static const char *cond_to_string(scc_lir_cond_t cond) { - switch (cond) { - case SCC_LIR_COND_EQ: - return "eq"; - case SCC_LIR_COND_NE: - return "ne"; - case SCC_LIR_COND_SLT: - return "slt"; - case SCC_LIR_COND_SLE: - return "sle"; - case SCC_LIR_COND_SGT: - return "sgt"; - case SCC_LIR_COND_SGE: - return "sge"; - case SCC_LIR_COND_ULT: - return "ult"; - case SCC_LIR_COND_ULE: - return "ule"; - case SCC_LIR_COND_UGT: - return "ugt"; - case SCC_LIR_COND_UGE: - return "uge"; - case SCC_LIR_COND_FEQ: - return "feq"; - case SCC_LIR_COND_FNE: - return "fne"; - case SCC_LIR_COND_FLT: - return "flt"; - case SCC_LIR_COND_FLE: - return "fle"; - case SCC_LIR_COND_FGT: - return "fgt"; - case SCC_LIR_COND_FGE: - return "fge"; - default: - return "???"; - } -} - -static void dump_operand(scc_lir_dump_ctx_t *ctx, const scc_lir_val_t *op) { - scc_tree_dump_t *td = ctx->dump_ctx; - - switch (op->kind) { - case SCC_LIR_INSTR_KIND_NONE: - scc_tree_dump_append(td, "_"); - break; - case SCC_LIR_INSTR_KIND_VREG: - scc_tree_dump_append_fmt(td, "%%%u", op->data.reg); - break; - case SCC_LIR_INSTR_KIND_PREG: - scc_tree_dump_append_fmt(td, "Phy%u", op->data.reg); - break; - case SCC_LIR_INSTR_KIND_IMM: - scc_tree_dump_append_fmt(td, "%lld", op->data.imm); - break; - case SCC_LIR_INSTR_KIND_FIMM: - scc_tree_dump_append_fmt(td, "%lf", op->data.fimm); - break; - case SCC_LIR_INSTR_KIND_SYMBOL: - scc_tree_dump_append_fmt(td, "@%s", - op->data.symbol ? op->data.symbol : ""); - break; - case SCC_LIR_INSTR_KIND_ADDR: { - const scc_lir_addr_t *addr = &op->data.addr; - scc_tree_dump_append(td, "["); - if (addr->base != -1) { - scc_tree_dump_append_fmt(td, "%%%d", addr->base); - } - if (addr->index != -1) { - scc_tree_dump_append_fmt(td, " + %%%d * %d", addr->index, - addr->scale); - } - if (addr->offset != 0) { - if (addr->offset > 0) - scc_tree_dump_append_fmt(td, " + %lld", - (long long)addr->offset); - else - scc_tree_dump_append_fmt(td, " - %lld", - -(long long)addr->offset); - } - if (addr->base == -1 && addr->index == -1 && addr->offset == 0) - scc_tree_dump_append(td, "0"); - scc_tree_dump_append(td, "]"); - break; - } - default: - scc_tree_dump_append(td, ""); - } -} - -static void dump_size_ext(scc_lir_dump_ctx_t *ctx, u8 size, scc_lir_ext_t ext) { - scc_tree_dump_t *td = ctx->dump_ctx; - const char *size_str = ""; - if (size == SCC_LIR_SIZE_8) - size_str = "8"; - else if (size == SCC_LIR_SIZE_16) - size_str = "16"; - else if (size == SCC_LIR_SIZE_32) - size_str = "32"; - else if (size == SCC_LIR_SIZE_64) - size_str = "64"; - - const char *ext_str = ""; - if (ext == SCC_LIR_EXT_SEXT) - ext_str = ".s"; - else if (ext == SCC_LIR_EXT_ZEXT) - ext_str = ".u"; - else if (ext == SCC_LIR_EXT_FLOAT) - ext_str = ".f"; - - if (size_str[0] || ext_str[0]) { - scc_tree_dump_append_fmt(td, ".%s%s", size_str, ext_str); - } -} - -void scc_lir_dump_ins(scc_lir_dump_ctx_t *ctx, const scc_lir_instr_t *ins) { - Assert(ctx != nullptr && ins != nullptr); - scc_tree_dump_t *td = ctx->dump_ctx; - - scc_tree_dump_begin_line(td); - scc_tree_dump_append(td, " "); - // 输出操作码(带节点颜色) - scc_tree_dump_node(td, "%s", op_to_string(ins->op)); - - // 输出宽度和扩展标志 - dump_size_ext(ctx, ins->size, ins->ext); - scc_tree_dump_append(td, " "); - - switch (ins->op) { - case SCC_LIR_MOV: - case SCC_LIR_LOAD: - case SCC_LIR_LOAD_ADDR: - dump_operand(ctx, &ins->to); - scc_tree_dump_append(td, " <- "); - dump_operand(ctx, &ins->arg0); - break; - case SCC_LIR_LEA: - case SCC_LIR_NEG: - case SCC_LIR_NOT: - case SCC_LIR_FNEG: - case SCC_LIR_FCVT: - case SCC_LIR_ALLOCA: - dump_operand(ctx, &ins->to); - if (ins->op != SCC_LIR_ALLOCA) { - scc_tree_dump_append(td, ", "); - dump_operand(ctx, &ins->arg0); - // alloca 额外信息在 metadata 中,但通常只关注 to - } - break; - - case SCC_LIR_STORE: - case SCC_LIR_STORE_ADDR: - dump_operand(ctx, &ins->arg0); - scc_tree_dump_append(td, " -> "); - dump_operand(ctx, &ins->arg1); - break; - - case SCC_LIR_ADD: - case SCC_LIR_SUB: - case SCC_LIR_MUL: - case SCC_LIR_DIV_S: - case SCC_LIR_DIV_U: - case SCC_LIR_REM_S: - case SCC_LIR_REM_U: - case SCC_LIR_AND: - case SCC_LIR_OR: - case SCC_LIR_XOR: - case SCC_LIR_SHL: - case SCC_LIR_SHR: - case SCC_LIR_SAR: - case SCC_LIR_FADD: - case SCC_LIR_FSUB: - case SCC_LIR_FMUL: - case SCC_LIR_FDIV: - dump_operand(ctx, &ins->to); - scc_tree_dump_append(td, ", "); - dump_operand(ctx, &ins->arg0); - scc_tree_dump_append(td, ", "); - dump_operand(ctx, &ins->arg1); - break; - - case SCC_LIR_CMP: - dump_operand(ctx, &ins->to); - scc_tree_dump_append_fmt(td, ", %s, ", - cond_to_string(ins->metadata.cond)); - dump_operand(ctx, &ins->arg0); - scc_tree_dump_append(td, ", "); - dump_operand(ctx, &ins->arg1); - break; - - case SCC_LIR_BR: - dump_operand(ctx, &ins->arg0); - scc_tree_dump_append_fmt(td, ", BB#%zu, BB#%zu", - ins->metadata.br.true_target, - ins->metadata.br.false_target); - break; - - case SCC_LIR_JMP: - scc_tree_dump_append_fmt(td, "BB#%zu", ins->metadata.jmp_target); - break; - - case SCC_LIR_JMP_INDIRECT: - dump_operand(ctx, &ins->arg0); - break; - - case SCC_LIR_CALL: { - const struct scc_lir_call *c = &ins->metadata.call; - if (c->ret_vreg.kind != SCC_LIR_INSTR_KIND_NONE) { - dump_operand(ctx, &c->ret_vreg); - scc_tree_dump_append(td, " = "); - } - scc_tree_dump_append_fmt(td, "call @%s(", - c->callee ? c->callee : ""); - for (u8 i = 0; i < c->arg_count; i++) { - if (i > 0) - scc_tree_dump_append(td, ", "); - dump_operand(ctx, &c->args[i]); - } - scc_tree_dump_append_fmt(td, ") clobber=0x%llx", - (unsigned long long)c->clobber_mask); - break; - } - - case SCC_LIR_CALL_INDIRECT: { - const struct scc_lir_call_indirect *c = &ins->metadata.call_indirect; - if (c->ret_vreg.kind != SCC_LIR_INSTR_KIND_NONE) { - dump_operand(ctx, &c->ret_vreg); - scc_tree_dump_append(td, " = "); - } - scc_tree_dump_append(td, "call "); - dump_operand(ctx, &c->target); - scc_tree_dump_append(td, "("); - for (u8 i = 0; i < c->arg_count; i++) { - if (i > 0) - scc_tree_dump_append(td, ", "); - dump_operand(ctx, &c->args[i]); - } - scc_tree_dump_append_fmt(td, ") clobber=0x%llx", - (unsigned long long)c->clobber_mask); - break; - } - - case SCC_LIR_RET: - if (ins->metadata.ret_val.kind != SCC_LIR_INSTR_KIND_NONE) { - dump_operand(ctx, &ins->metadata.ret_val); - } - break; - - case SCC_LIR_PARALLEL_COPY: { - const struct scc_lir_parallel_copy *pc = &ins->metadata.parallel_copy; - scc_tree_dump_append(td, "["); - for (u8 i = 0; i < pc->num_copies; i++) { - if (i > 0) - scc_tree_dump_append(td, ", "); - dump_operand(ctx, &pc->dests[i]); - scc_tree_dump_append(td, " <- "); - dump_operand(ctx, &pc->srcs[i]); - } - scc_tree_dump_append(td, "]"); - break; - } - - case SCC_LIR_VA_START: - dump_operand(ctx, &ins->metadata.va_start.ap); - scc_tree_dump_append(td, ", "); - dump_operand(ctx, &ins->metadata.va_start.last); - break; - - case SCC_LIR_VA_ARG: - dump_operand(ctx, &ins->metadata.va_arg.to); - scc_tree_dump_append(td, " = va_arg "); - dump_operand(ctx, &ins->metadata.va_arg.ap); - scc_tree_dump_append_fmt( - td, ", size=%u, align=%u, float=%d", ins->metadata.va_arg.type_size, - ins->metadata.va_arg.type_align, ins->metadata.va_arg.is_float); - break; - - case SCC_LIR_VA_END: - dump_operand(ctx, &ins->metadata.va_end.ap); - break; - - case SCC_LIR_VA_COPY: - dump_operand(ctx, &ins->metadata.va_copy.dest); - scc_tree_dump_append(td, ", "); - dump_operand(ctx, &ins->metadata.va_copy.src); - break; - - case SCC_LIR_NOP: - break; - } -} - -void scc_lir_dump_bblock(scc_lir_dump_ctx_t *ctx, const scc_lir_bblock_t *bb) { - Assert(ctx != nullptr && bb != nullptr); - scc_tree_dump_t *td = ctx->dump_ctx; - - // 基本块头部 - scc_tree_dump_begin_line(td); - scc_tree_dump_node(td, "BB%zu", bb->id); - if (bb->label) { - scc_tree_dump_append_fmt(td, " (%s)", bb->label); - } - scc_tree_dump_append(td, ":"); - - // 输出每条指令 - for (usize i = 0; i < scc_vec_size(bb->ins); ++i) { - const scc_lir_instr_t *ins = &scc_vec_at(bb->ins, i); - scc_lir_dump_ins(ctx, ins); - } -} - -void scc_lir_dump_func(scc_lir_dump_ctx_t *ctx, const scc_lir_func_t *func) { - Assert(ctx != nullptr && func != nullptr); - scc_tree_dump_t *td = ctx->dump_ctx; - - // 函数头部 - scc_tree_dump_begin_line(td); - scc_tree_dump_node(td, "func @%s", func->name ? func->name : ""); - scc_tree_dump_append_fmt(td, " (vregs: %u, frame: %d)", func->vregs_count, - func->frame_size); - if (func->attr != SCC_LIR_ATTR_NONE) { - scc_tree_dump_append(td, " [attr:"); - if (func->attr & SCC_LIR_ATTR_STATIC) - scc_tree_dump_append(td, " static"); - if (func->attr & SCC_LIR_ATTR_WEAK) - scc_tree_dump_append(td, " weak"); - scc_tree_dump_append(td, " ]"); - } - scc_tree_dump_append(td, " {"); - - // 输出所有基本块 - for (usize i = 0; i < scc_vec_size(func->bblocks); ++i) { - const scc_lir_bblock_t *bb = &scc_vec_at(func->bblocks, i); - scc_lir_dump_bblock(ctx, bb); - } - - scc_tree_dump_begin_line(td); - scc_tree_dump_append(td, "}"); -} - -void scc_lir_dump_module(scc_lir_dump_ctx_t *ctx, - const scc_lir_module_t *module) { - scc_vec_foreach(module->symbols, i) { - // FIXME 0 is null - if (i == 0) - continue; - scc_lir_symbol_t *sym = &scc_vec_at(module->symbols, i); - scc_tree_dump_begin_line(ctx->dump_ctx); - scc_tree_dump_node(ctx->dump_ctx, "symbol"); - scc_tree_dump_append_fmt(ctx->dump_ctx, " %s", sym->name); - } - scc_vec_foreach(module->funcs, i) { - scc_lir_dump_func(ctx, scc_vec_at(module->funcs, i)); - } -} diff --git a/libs/lir/src/scc_lir_module.c b/libs/lir/src/scc_lir_module.c deleted file mode 100644 index 0ccfc0b..0000000 --- a/libs/lir/src/scc_lir_module.c +++ /dev/null @@ -1,172 +0,0 @@ -#include - -static void scc_lir_func_drop(scc_lir_func_t *func) { - if (!func) - return; - - /* 释放每个基本块内的指令向量 */ - for (usize i = 0; i < scc_vec_size(func->bblocks); ++i) { - scc_lir_bblock_t *bb = &func->bblocks.data[i]; - scc_vec_free(bb->ins); - } - scc_vec_free(func->bblocks); - scc_hashtable_drop(&func->bb_map); - scc_free(func); -} - -static scc_lir_symbol_t *lookup_symbol(const scc_lir_module_t *module, - const char *name) { - if (!module || !name) - return nullptr; - /* 注意:scc_hashtable_get 返回的是 (void*) 存储的 usize 索引 */ - void *idx_val = - scc_hashtable_get((scc_hashtable_t *)&module->symbol_map, (void *)name); - if (!idx_val) - return nullptr; - usize idx = (usize)idx_val; - if (idx >= scc_vec_size(module->symbols)) - return nullptr; - return &module->symbols.data[idx]; -} - -void scc_lir_module_init(scc_lir_module_t *module) { - scc_vec_init(module->funcs); - scc_vec_init(module->symbols); - scc_hashtable_cstr_init(&module->symbol_map); - - // /* 预留索引 0 作为无效 func_id */ - // scc_vec_push(module->funcs, nullptr); - scc_vec_push(module->symbols, (scc_lir_symbol_t){0}); -} - -void scc_lir_module_drop(scc_lir_module_t *module) { - /* 释放所有函数对象 */ - for (usize i = 0; i < scc_vec_size(module->funcs); ++i) { - scc_lir_func_drop(module->funcs.data[i]); - } - scc_vec_free(module->funcs); - - /* 释放数据符号中动态分配的初始化数据 */ - for (usize i = 0; i < scc_vec_size(module->symbols); ++i) { - scc_lir_symbol_t *sym = &module->symbols.data[i]; - if ((sym->kind == SCC_LIR_SYMBOL_DATA) && sym->data.init_data) { - scc_free(sym->data.init_data); - } - } - scc_vec_free(module->symbols); - - scc_hashtable_drop(&module->symbol_map); -} - -static const scc_lir_symbol_t *register_symbol(scc_lir_module_t *module, - scc_lir_symbol_t *sym) { - /* 检查是否已存在同名符号 */ - void *existing = scc_hashtable_get(&module->symbol_map, (void *)sym->name); - if (existing) { - LOG_ERROR("symbol '%s' already defined", sym->name); - return nullptr; - } - - usize idx = scc_vec_size(module->symbols); - scc_vec_push(module->symbols, *sym); - scc_hashtable_set(&module->symbol_map, (void *)sym->name, (void *)idx); - return &scc_vec_at(module->symbols, idx); -} - -const scc_lir_symbol_t *scc_lir_module_add_func_def(scc_lir_module_t *module, - scc_lir_func_t *func) { - if (!module || !func || !func->name) - return nullptr; - - scc_vec_push(module->funcs, func); - - scc_lir_symbol_t *func_decl_sym = lookup_symbol(module, (void *)func->name); - if (func_decl_sym) { - if (func_decl_sym->kind != SCC_LIR_SYMBOL_FUNC || - func_decl_sym->func.func != nullptr) { - Panic("Symbol already exists"); - } - func_decl_sym->func.func = func; - return func_decl_sym; - } - - /* 构建符号 */ - scc_lir_symbol_t sym = {.name = func->name, - .kind = SCC_LIR_SYMBOL_FUNC, - .attr = func->attr, - .func.func = func}; - - const scc_lir_symbol_t *result = register_symbol(module, &sym); - if (!result) { - /* 符号冲突:回滚函数添加并释放 func */ - module->funcs.size--; - scc_lir_func_drop(func); - return nullptr; - } - return result; -} - -const scc_lir_symbol_t *scc_lir_module_add_func_decl(scc_lir_module_t *module, - const char *name, - scc_lir_attr_t attr) { - if (!module || !name) - return nullptr; - - scc_lir_symbol_t sym = {.name = name, - .kind = SCC_LIR_SYMBOL_FUNC, - .attr = attr, - .func.func = nullptr}; - - return register_symbol(module, &sym); -} - -const scc_lir_symbol_t * -scc_lir_module_add_data(scc_lir_module_t *module, const char *name, - scc_lir_symbol_kind_t kind, const u8 *init_data, - usize size, u32 align, scc_lir_attr_t attr) { - if (!module || !name) - return nullptr; - if (kind != SCC_LIR_SYMBOL_DATA && kind != SCC_LIR_SYMBOL_EXTERN) - return nullptr; - - scc_lir_symbol_t sym = { - .name = name, - .kind = kind, - .attr = attr, - .data = {.init_data = nullptr, .size = size, .align = align}}; - - /* 对于数据定义,复制初始化数据(若有) */ - if (kind == SCC_LIR_SYMBOL_DATA && init_data && size > 0) { - sym.data.init_data = scc_malloc(size); - if (!sym.data.init_data) { - LOG_FATAL("out of memory for data symbol '%s'", name); - } - scc_memcpy(sym.data.init_data, init_data, size); - } else if (kind == SCC_LIR_SYMBOL_DATA && !init_data) { - /* 零初始化:分配并清零 */ - sym.data.init_data = scc_calloc(1, size); - if (!sym.data.init_data) { - LOG_FATAL("out of memory for data symbol '%s'", name); - } - } - - const scc_lir_symbol_t *result = register_symbol(module, &sym); - if (!result) { - /* 冲突时释放已分配的数据 */ - scc_free(sym.data.init_data); - return nullptr; - } - return result; -} - -const scc_lir_symbol_t * -scc_lir_module_lookup_symbol(const scc_lir_module_t *module, const char *name) { - return lookup_symbol(module, name); -} - -scc_lir_func_t *scc_lir_module_get_func(const scc_lir_module_t *module, - unsigned func_id) { - if (!module || func_id == 0 || func_id >= scc_vec_size(module->funcs)) - return nullptr; - return module->funcs.data[func_id]; -} \ No newline at end of file diff --git a/runtime/ap/cbuild.toml b/runtime/ap/cbuild.toml new file mode 100644 index 0000000..45e6b27 --- /dev/null +++ b/runtime/ap/cbuild.toml @@ -0,0 +1,9 @@ +[package] +name = "ap" +version = "0.1.0" +authors = [] +description = "" + +# dependencies = [] +# features = {} +# default_features = [] diff --git a/runtime/ap/include/ap.h b/runtime/ap/include/ap.h new file mode 100644 index 0000000..b0d7681 --- /dev/null +++ b/runtime/ap/include/ap.h @@ -0,0 +1,92 @@ +#ifndef __SCC_AP_H__ +#define __SCC_AP_H__ +/** + * @brief Arbitrary Precision Library + * + */ +#ifdef __AP_SCC__ +#include +#define SCC_AP_DIGIT u64 +#define SCC_AP_PANIC Panic +#define SCC_AP_ASSERT Assert +#define SCC_AP_MALLOC scc_malloc +#define SCC_AP_REALLOC scc_realloc +#define SCC_AP_FREE scc_free +#else +#include +#include +#include +#include +#define SCC_AP_DIGIT uint64_t +#define SCC_AP_PANIC(...) \ + do { \ + fprintf(stderr, __VA_ARGS__); \ + abort(); \ + } while (0) +#define SCC_AP_ASSERT assert +#define SCC_AP_MALLOC malloc +#define SCC_AP_REALLOC realloc +#define SCC_AP_FREE free +#endif + +#ifndef SCC_AP_DIGIT +#error "SCC_AP_DIGIT is not defined" +#endif +#define SCC_AP_DIGIT_BITS (sizeof(SCC_AP_DIGIT)) + +#ifndef nullptr +#define nullptr ((void *)0) +#endif + +typedef SCC_AP_DIGIT scc_ap_digit; +typedef struct { + int capacity; // maybe power of 2 (-1 means using digit) + int len; // data length (sign with in) + union { + scc_ap_digit *array; + scc_ap_digit digit; + } data; +} scc_ap_t; + +static inline void scc_ap_init(scc_ap_t *ap) { + ap->len = 0; + ap->capacity = -1; + ap->len = 1; + ap->data.digit = 0; +} + +static inline void scc_ap_set_int(scc_ap_t *ap, int val) { + if (val < 0) { + ap->len = -1; + } else { + ap->len = 1; + } + SCC_AP_ASSERT(sizeof(scc_ap_digit) >= sizeof(int)); + ap->capacity = -1; + ap->data.digit = val; +} + +void scc_ap_drop(scc_ap_t *ap); +void scc_ap_with_bits(scc_ap_t *ap, int bits); +void scc_ap_from_string(scc_ap_t *ap, const char *str, int len, int base); +void scc_ap_set_digit(scc_ap_t *ap, scc_ap_digit digit); + +void scc_ap_add(scc_ap_t *to, const scc_ap_t *from_a, const scc_ap_t *from_b); +void scc_ap_sub(scc_ap_t *to, const scc_ap_t *from_a, const scc_ap_t *from_b); +void scc_ap_mul(scc_ap_t *to, const scc_ap_t *from_a, const scc_ap_t *from_b); +void scc_ap_div(scc_ap_t *to, const scc_ap_t *from_a, const scc_ap_t *from_b); +void scc_ap_mod(scc_ap_t *to, const scc_ap_t *from_a, const scc_ap_t *from_b); + +/** + * @brief equal + * + * @param a + * @param b + * @return int + */ +int scc_ap_eql(const scc_ap_t *a, const scc_ap_t *b); + +typedef void (*ap_dump_fn)(const char ch, void *user_data); +int scc_ap_dump(scc_ap_t *ap, ap_dump_fn dump_fn, void *user_data); + +#endif /* __SCC_AP_H__ */ diff --git a/runtime/ap/src/ap.c b/runtime/ap/src/ap.c new file mode 100644 index 0000000..358db28 --- /dev/null +++ b/runtime/ap/src/ap.c @@ -0,0 +1,48 @@ +#include + +static void *scc_ap_alloc(size_t size) { + void *p = SCC_AP_MALLOC(size); + SCC_AP_ASSERT(p != NULL); + return p; +} + +/* 重新分配内存 */ +static void *scc_ap_realloc_data(void *old, size_t new_size) { + void *p = SCC_AP_REALLOC(old, new_size); + SCC_AP_ASSERT(p != NULL); + return p; +} + +void scc_ap_drop(scc_ap_t *ap) { + SCC_AP_ASSERT(ap); + // SCC_AP_FREE(ap->data); + scc_ap_init(ap); +} + +void scc_ap_with_bits(scc_ap_t *ap, int bits) {} + +void scc_ap_from_string(scc_ap_t *ap, const char *str, int len, int base) { + SCC_AP_ASSERT(base == 10); + SCC_AP_ASSERT(ap && str); + if (len == 0) { + scc_ap_set_int(ap, 0); + } + // FIXME + int int_lit = 0; + for (int i = 0; i < len; i += 1) { + int_lit = int_lit * 10 + (str[i] - '0'); + } + scc_ap_set_int(ap, int_lit); +} + +void scc_ap_set_digit(scc_ap_t *ap, scc_ap_digit digit) {} + +void scc_ap_add_impl(scc_ap_t *to, const scc_ap_t *from_a, + const scc_ap_t *from_b) {} + +void scc_ap_add(scc_ap_t *to, const scc_ap_t *from_a, const scc_ap_t *from_b) {} + +void scc_ap_sub(scc_ap_t *to, const scc_ap_t *from_a, const scc_ap_t *from_b) {} + +typedef void (*ap_dump_fn)(const char ch, void *user_data); +int scc_ap_dump(scc_ap_t *ap, ap_dump_fn dump_fn, void *user_data) { return 0; } diff --git a/runtime/ap/src/lib.c b/runtime/ap/src/lib.c new file mode 100644 index 0000000..76f5fba --- /dev/null +++ b/runtime/ap/src/lib.c @@ -0,0 +1,5 @@ +#include + +void hello_from_lib() { + printf("Hello from library!\n"); +} diff --git a/runtime/scc_utils/include/scc_ap.h b/runtime/scc_utils/include/scc_ap.h new file mode 100644 index 0000000..821c5c6 --- /dev/null +++ b/runtime/scc_utils/include/scc_ap.h @@ -0,0 +1,16 @@ +#ifndef __SCC_UTILS_AP_H__ +#define __SCC_UTILS_AP_H__ +#include +#define __AP_SCC__ +#include + +static inline void scc_ap_from_str(scc_ap_t *ap, scc_str_t *str, int base) { + scc_ap_from_string(ap, scc_vec_unsafe_get_data(*str), scc_vec_size(*str), + base); +} + +static inline void scc_ap_from_cstr(scc_ap_t *ap, const char *str, int base) { + scc_ap_from_string(ap, str, scc_strlen(str), base); +} + +#endif /* __SCC_UTILS_AP_H__ */ diff --git a/src/config.h b/src/config.h index cf2e5f5..fd493ce 100644 --- a/src/config.h +++ b/src/config.h @@ -14,7 +14,7 @@ typedef struct { cbool emit_lex; cbool emit_pp; cbool emit_ast; - cbool emit_ir; + cbool emit_hir; cbool emit_lir; } scc_config_t; @@ -35,8 +35,9 @@ static void setup_argparse(scc_argparse_t *argparse, scc_config_t *config, SCC_HINT_EMIT_LEX, SCC_HINT_EMIT_PP, SCC_HINT_EMIT_AST, - SCC_HINT_EMIT_IR, + SCC_HINT_EMIT_HIR, SCC_HINT_EMIT_LIR, + SCC_HINT_EMIT_MIR, }; static const char *scc_hints_en[] = { [SCC_HINT_PROG_NAME] = "scc", @@ -55,8 +56,9 @@ static void setup_argparse(scc_argparse_t *argparse, scc_config_t *config, [SCC_HINT_EMIT_LEX] = "Generate lexer sources tokens and exit", [SCC_HINT_EMIT_PP] = "Generate preprocessed tokens and exit", [SCC_HINT_EMIT_AST] = "Generate AST and exit", - [SCC_HINT_EMIT_IR] = "Generate IR and exit", - [SCC_HINT_EMIT_LIR] = "Generate LIR and exit", + [SCC_HINT_EMIT_HIR] = "Generate High-level IR and exit", + [SCC_HINT_EMIT_LIR] = "Generate Low-level IR and exit", + [SCC_HINT_EMIT_MIR] = "Generate Machine IR and exit", }; static const char *scc_hints_zh[] = { @@ -74,8 +76,9 @@ static void setup_argparse(scc_argparse_t *argparse, scc_config_t *config, [SCC_HINT_EMIT_LEX] = "生成`源代码的词法单元`并退出", [SCC_HINT_EMIT_PP] = "生成`预处理后的词法单元`并退出", [SCC_HINT_EMIT_AST] = "生成`抽象语法树`并退出", - [SCC_HINT_EMIT_IR] = "生成`中间代码`并退出", + [SCC_HINT_EMIT_HIR] = "生成`高级中间代码`并退出", [SCC_HINT_EMIT_LIR] = "生成`低级中间代码`并退出", + [SCC_HINT_EMIT_MIR] = "生成`机器中间代码`并退出", }; const char **scc_hints; @@ -167,11 +170,12 @@ static void setup_argparse(scc_argparse_t *argparse, scc_config_t *config, scc_argparse_spec_setup_bool(&opt_ast.spec, &(config->emit_ast)); scc_argparse_cmd_add_opt(root, &opt_ast); - // -R, --emit-ir - scc_argparse_opt_t opt_ir; - scc_argparse_opt_init(&opt_ir, 'R', "emit-ir", scc_hints[SCC_HINT_EMIT_IR]); - scc_argparse_spec_setup_bool(&opt_ir.spec, &(config->emit_ir)); - scc_argparse_cmd_add_opt(root, &opt_ir); + // -H, --emit-hir + scc_argparse_opt_t opt_hir; + scc_argparse_opt_init(&opt_hir, 'H', "emit-hir", + scc_hints[SCC_HINT_EMIT_HIR]); + scc_argparse_spec_setup_bool(&opt_hir.spec, &(config->emit_hir)); + scc_argparse_cmd_add_opt(root, &opt_hir); // -L, --emit-lir scc_argparse_opt_t opt_lir; diff --git a/src/main.c b/src/main.c index 7cfdb85..504b748 100644 --- a/src/main.c +++ b/src/main.c @@ -4,11 +4,11 @@ #include #include -#include +#include #include -#include -#include +// #include +// #include // #include // #include @@ -85,7 +85,7 @@ int main(int argc, const char **argv, const char **envp) { .output_file = nullptr, .entry_point_symbol = nullptr, .emit_ast = false, - .emit_ir = false, + .emit_hir = false, .target_description = "x86_64-pc-windows-msvc", }; scc_vec_init(config.include_paths); @@ -217,23 +217,23 @@ sstream_drop: scc_ast2ir_ctx_t ast2ir_ctx; #include - scc_ir_cprog_t cprog; - scc_ir_cprog_init(&cprog); + scc_hir_cprog_t cprog; + scc_hir_cprog_init(&cprog); scc_ast2ir_ctx_init(&ast2ir_ctx, &scc_ast_abi_impl, &cprog); scc_ast2ir_translation_unit(&ast2ir_ctx, translation_unit); scc_ast2ir_ctx_drop(&ast2ir_ctx); - if (config.emit_ir) { - scc_ir_dump_ctx_t ir_dump_ctx; + if (config.emit_hir) { + scc_hir_dump_t ir_dump_ctx; scc_tree_dump_t tree_dump; if (fp == nullptr) { scc_tree_dump_init(&tree_dump, true); } else { scc_tree_dump_init(&tree_dump, false); } - scc_ir_dump_ctx_init(&ir_dump_ctx, &tree_dump, &cprog); + scc_hir_dump_ctx_init(&ir_dump_ctx, &tree_dump, &cprog); // scc_ir_dump_cprog(&ir_dump_ctx); - scc_ir_dump_cprog_linear(&ir_dump_ctx); + scc_hir_dump_cprog_linear(&ir_dump_ctx); scc_tree_dump_flush(&tree_dump, tree_dump_output, fp == nullptr ? scc_stdout : fp); @@ -241,28 +241,28 @@ sstream_drop: return 0; } - scc_lir_builder_t lir_builder; - scc_lir_module_t lir_module; - scc_lir_module_init(&lir_module); - scc_lir_builder_init(&lir_builder, &lir_module); - scc_ir2lir(&lir_builder, &cprog); - if (config.emit_lir) { - scc_lir_dump_ctx_t lir_dump_ctx; - scc_tree_dump_t tree_dump; - if (fp == nullptr) { - scc_tree_dump_init(&tree_dump, true); - } else { - scc_tree_dump_init(&tree_dump, false); - } - scc_lir_dump_init(&lir_dump_ctx, &tree_dump); - // scc_ir_dump_cprog(&ir_dump_ctx); - scc_lir_dump_module(&lir_dump_ctx, &lir_module); + // scc_lir_builder_t lir_builder; + // scc_lir_module_t lir_module; + // scc_lir_module_init(&lir_module); + // scc_lir_builder_init(&lir_builder, &lir_module); + // scc_ir2lir(&lir_builder, &cprog); + // if (config.emit_lir) { + // scc_lir_dump_ctx_t lir_dump_ctx; + // scc_tree_dump_t tree_dump; + // if (fp == nullptr) { + // scc_tree_dump_init(&tree_dump, true); + // } else { + // scc_tree_dump_init(&tree_dump, false); + // } + // scc_lir_dump_init(&lir_dump_ctx, &tree_dump); + // // scc_ir_dump_cprog(&ir_dump_ctx); + // scc_lir_dump_module(&lir_dump_ctx, &lir_module); - scc_tree_dump_flush(&tree_dump, tree_dump_output, - fp == nullptr ? scc_stdout : fp); - scc_tree_dump_drop(&tree_dump); - return 0; - } + // scc_tree_dump_flush(&tree_dump, tree_dump_output, + // fp == nullptr ? scc_stdout : fp); + // scc_tree_dump_drop(&tree_dump); + // return 0; + // } // scc_ir2mcode_ctx_t ir2mcode_ctx; // sccf_builder_t sccf_builder;