From 8c7af571c2bca154aec979fb939eb3754658fab4 Mon Sep 17 00:00:00 2001 From: zzy <2450266535@qq.com> Date: Wed, 25 Mar 2026 11:59:27 +0800 Subject: [PATCH] =?UTF-8?q?refactor(ast2ir):=20=E6=9B=B4=E6=96=B0IR?= =?UTF-8?q?=E6=9E=84=E5=BB=BA=E5=99=A8=E6=8E=A5=E5=8F=A3=E5=B9=B6=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E7=B1=BB=E5=9E=8B=E6=98=A0=E5=B0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将IR构建器初始化函数修改为接受cprog参数 - 添加scc_ast2ir_ctx_drop函数用于资源清理 - 更新类型标识符命名规范,从大写改为小写形式 - 替换scc_ir_ctx_get_*函数调用为scc_ir_module_get_*函数 - 移除对ir_builtin.h的依赖,改用ir_builder.h中的构建器函数 - 为整数常量创建添加专门的构建器辅助函数 fix(ir): 重构IR上下文和模块管理结构 - 将原有的scc_ir_cprog_ctx_t拆分为scc_ir_module_t和scc_ir_ctx_t - 添加scc_ir_module_t结构用于统一管理IR对象存储 - 更新IR类型枚举名称格式,从SCC_IR_TYPE_XXX改为SCC_IR_TYPE_xxx - 添加整数、无符号整数和浮点数常量联合体定义 - 移除ir_base.h和ir_builtin.h头文件,整合到scc_ir.h中 feat(ir_builder): 添加类型构建器函数和常量创建功能 - 为各种基础类型添加scc_ir_builder_type_*内联函数 - 实现scc_ir_builder_const_int函数用于创建整数常量 - 修改构建器初始化函数签名以接受cprog参数 - 更新构建器内部结构,使用指向cprog的指针而非嵌入式结构 --- libs/ast2ir/include/abi/win_x64_type_abi.h | 42 +-- libs/ast2ir/include/scc_ast2ir.h | 5 +- libs/ast2ir/src/scc_ast2ir.c | 68 +++-- libs/ir/include/ir_base.h | 17 -- libs/ir/include/ir_builder.h | 55 +++- libs/ir/include/ir_builtin.h | 9 - libs/ir/include/ir_ctx.h | 200 ++----------- libs/ir/include/ir_def.h | 97 +++--- libs/ir/include/ir_dump.h | 9 +- libs/ir/include/ir_prog.h | 52 ++++ libs/ir/include/scc_ir.h | 12 +- libs/ir/src/ir_builder.c | 100 ++++--- libs/ir/src/ir_builtin.c | 10 - libs/ir/src/ir_ctx.c | 327 ++++++--------------- libs/ir/src/ir_dump.c | 79 ++--- libs/ir/src/ir_prog.c | 151 ++++++++++ libs/ir/src/{ir_base.c => scc_ir.c} | 37 +-- libs/ir2mcode/include/reg_alloc.h | 4 +- libs/ir2mcode/include/scc_ir2mcode.h | 11 +- libs/ir2mcode/src/ir2amd64.c | 198 +++++++------ libs/ir2mcode/src/reg_alloc.c | 18 +- libs/ir2mcode/src/scc_ir2mcode.c | 12 +- libs/ir2mcode/tests/test_run.c | 37 ++- src/main.c | 21 +- 24 files changed, 779 insertions(+), 792 deletions(-) delete mode 100644 libs/ir/include/ir_base.h delete mode 100644 libs/ir/include/ir_builtin.h create mode 100644 libs/ir/include/ir_prog.h delete mode 100644 libs/ir/src/ir_builtin.c create mode 100644 libs/ir/src/ir_prog.c rename libs/ir/src/{ir_base.c => scc_ir.c} (81%) diff --git a/libs/ast2ir/include/abi/win_x64_type_abi.h b/libs/ast2ir/include/abi/win_x64_type_abi.h index 0753182..65f7299 100644 --- a/libs/ast2ir/include/abi/win_x64_type_abi.h +++ b/libs/ast2ir/include/abi/win_x64_type_abi.h @@ -11,128 +11,128 @@ static const scc_type_abi_t scc_win_x64_type_abi[] = { { .ast_type = SCC_AST_BUILTIN_TYPE_UNKNOWN, - .ir_type = SCC_IR_TYPE_UNKNOWN, + .ir_type = SCC_IR_TYPE_unknown, .size = 0, .alignment = 0, }, { .ast_type = SCC_AST_BUILTIN_TYPE_VOID, - .ir_type = SCC_IR_TYPE_VOID, + .ir_type = SCC_IR_TYPE_void, .size = 0, .alignment = 0, }, { .ast_type = SCC_AST_BUILTIN_TYPE_BOOL, - .ir_type = SCC_IR_TYPE_U8, + .ir_type = SCC_IR_TYPE_u8, .size = 1, .alignment = 1, }, { .ast_type = SCC_AST_BUILTIN_TYPE_CHAR, - .ir_type = SCC_IR_TYPE_I8, + .ir_type = SCC_IR_TYPE_i8, .size = 1, .alignment = 1, }, { .ast_type = SCC_AST_BUILTIN_TYPE_SIGNED_CHAR, - .ir_type = SCC_IR_TYPE_I8, + .ir_type = SCC_IR_TYPE_i8, .size = 1, .alignment = 1, }, { .ast_type = SCC_AST_BUILTIN_TYPE_UNSIGNED_CHAR, - .ir_type = SCC_IR_TYPE_U8, + .ir_type = SCC_IR_TYPE_u8, .size = 1, .alignment = 1, }, { .ast_type = SCC_AST_BUILTIN_TYPE_SHORT, - .ir_type = SCC_IR_TYPE_I16, + .ir_type = SCC_IR_TYPE_i16, .size = 2, .alignment = 2, }, { .ast_type = SCC_AST_BUILTIN_TYPE_SIGNED_SHORT, - .ir_type = SCC_IR_TYPE_I16, + .ir_type = SCC_IR_TYPE_i16, .size = 2, .alignment = 2, }, { .ast_type = SCC_AST_BUILTIN_TYPE_UNSIGNED_SHORT, - .ir_type = SCC_IR_TYPE_U16, + .ir_type = SCC_IR_TYPE_u16, .size = 2, .alignment = 2, }, { .ast_type = SCC_AST_BUILTIN_TYPE_INT, - .ir_type = SCC_IR_TYPE_I32, + .ir_type = SCC_IR_TYPE_i32, .size = 4, .alignment = 4, }, { .ast_type = SCC_AST_BUILTIN_TYPE_SIGNED_INT, - .ir_type = SCC_IR_TYPE_I32, + .ir_type = SCC_IR_TYPE_i32, .size = 4, .alignment = 4, }, { .ast_type = SCC_AST_BUILTIN_TYPE_UNSIGNED_INT, - .ir_type = SCC_IR_TYPE_U32, + .ir_type = SCC_IR_TYPE_u32, .size = 4, .alignment = 4, }, { .ast_type = SCC_AST_BUILTIN_TYPE_LONG, - .ir_type = SCC_IR_TYPE_I32, + .ir_type = SCC_IR_TYPE_i32, .size = 4, .alignment = 4, }, { .ast_type = SCC_AST_BUILTIN_TYPE_SIGNED_LONG, - .ir_type = SCC_IR_TYPE_I32, + .ir_type = SCC_IR_TYPE_i32, .size = 4, .alignment = 4, }, { .ast_type = SCC_AST_BUILTIN_TYPE_UNSIGNED_LONG, - .ir_type = SCC_IR_TYPE_U32, + .ir_type = SCC_IR_TYPE_u32, .size = 4, .alignment = 4, }, { .ast_type = SCC_AST_BUILTIN_TYPE_LONG_LONG, - .ir_type = SCC_IR_TYPE_I64, + .ir_type = SCC_IR_TYPE_i64, .size = 8, .alignment = 8, }, { .ast_type = SCC_AST_BUILTIN_TYPE_SIGNED_LONG_LONG, - .ir_type = SCC_IR_TYPE_I64, + .ir_type = SCC_IR_TYPE_i64, .size = 8, .alignment = 8, }, { .ast_type = SCC_AST_BUILTIN_TYPE_UNSIGNED_LONG_LONG, - .ir_type = SCC_IR_TYPE_I64, + .ir_type = SCC_IR_TYPE_i64, .size = 8, .alignment = 8, }, { .ast_type = SCC_AST_BUILTIN_TYPE_FLOAT, - .ir_type = SCC_IR_TYPE_F32, + .ir_type = SCC_IR_TYPE_f32, .size = 4, .alignment = 4, }, { .ast_type = SCC_AST_BUILTIN_TYPE_DOUBLE, - .ir_type = SCC_IR_TYPE_F64, + .ir_type = SCC_IR_TYPE_f64, .size = 8, .alignment = 8, }, { // NULL .ast_type = SCC_AST_BUILTIN_TYPE_UNKNOWN, - .ir_type = SCC_IR_TYPE_UNKNOWN, + .ir_type = SCC_IR_TYPE_unknown, .size = 0, .alignment = 0, }, diff --git a/libs/ast2ir/include/scc_ast2ir.h b/libs/ast2ir/include/scc_ast2ir.h index 011e5b6..cbcf8a0 100644 --- a/libs/ast2ir/include/scc_ast2ir.h +++ b/libs/ast2ir/include/scc_ast2ir.h @@ -2,6 +2,7 @@ #define __SCC_AST2IR_H__ #include "scc_type_abi.h" +#include #include #include @@ -13,7 +14,9 @@ typedef struct { const scc_type_abi_t *abi; } scc_ast2ir_ctx_t; -void scc_ast2ir_ctx_init(scc_ast2ir_ctx_t *ctx, const scc_type_abi_t *abi); +void scc_ast2ir_ctx_init(scc_ast2ir_ctx_t *ctx, const scc_type_abi_t *abi, + scc_ir_cprog_t *cprog); +void scc_ast2ir_ctx_drop(scc_ast2ir_ctx_t *ctx); void scc_ast2ir_translation_unit(scc_ast2ir_ctx_t *ctx, scc_ast_translation_unit_t *tu); diff --git a/libs/ast2ir/src/scc_ast2ir.c b/libs/ast2ir/src/scc_ast2ir.c index 1a96136..415e8ea 100644 --- a/libs/ast2ir/src/scc_ast2ir.c +++ b/libs/ast2ir/src/scc_ast2ir.c @@ -1,4 +1,3 @@ -#include #include scc_ir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx, @@ -12,7 +11,7 @@ scc_ir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx, switch (ast_type->base.type) { case SCC_AST_TYPE_BUILTIN: { // 映射内置类型 - scc_ir_type_init(&ir_type, SCC_IR_TYPE_I32); + scc_ir_type_init(&ir_type, SCC_IR_TYPE_i32); // TODO: 根据具体内置类型设置 break; } @@ -64,20 +63,17 @@ scc_ir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx, break; } - // SCC_AST_TYPE_BUILTIN, // 内置类型 - // SCC_AST_TYPE_POINTER, // 指针类型 - // SCC_AST_TYPE_ARRAY, // 数组类型 - // SCC_AST_TYPE_FUNCTION, // 函数类型 // SCC_AST_TYPE_STRUCT, // 结构体类型 // SCC_AST_TYPE_UNION, // 联合类型 // SCC_AST_TYPE_ENUM, // 枚举类型 - // SCC_AST_TYPE_TYPEDEF, // typedef 类型 + case SCC_AST_TYPE_TYPEDEF: + break; default: LOG_FATAL("Unsupported AST type: %d", ast_type->base.type); return 0; } - return scc_ir_ctx_new_type(&ctx->builder.ctx, &ir_type); + return scc_ir_builder_type(&ctx->builder, &ir_type); } /** @@ -230,22 +226,32 @@ scc_ir_node_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr, // SCC_AST_OP_POSTFIX_INCREMENT, // ++ (后缀) // SCC_AST_OP_POSTFIX_DECREMENT, // -- (后缀) switch (expr->unary.op) { - case SCC_AST_OP_UNARY_MINUS: + case SCC_AST_OP_UNARY_MINUS: { // 负号 // 实现为0 - operand - return scc_ir_builder_binop( - &ctx->builder, SCC_IR_OP_SUB, - scc_ir_ctx_get_builtin_zero(&ctx->builder.ctx), 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_node_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); + } case SCC_AST_OP_BITWISE_NOT: // 按位取反 return scc_ir_builder_binop(&ctx->builder, SCC_IR_OP_NOT, operand, 0); - case SCC_AST_OP_LOGICAL_NOT: + case SCC_AST_OP_LOGICAL_NOT: { // 逻辑非 // 实现为与0比较 - return scc_ir_builder_binop( - &ctx->builder, SCC_IR_OP_EQ, - scc_ir_ctx_get_builtin_zero(&ctx->builder.ctx), 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_node_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); + } default: LOG_FATAL("Unsupported unary operator: %d", expr->unary.op); return 0; @@ -272,6 +278,10 @@ scc_ir_node_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr, // 创建调用节点(需要查找函数定义) scc_ir_func_ref_t func = (scc_ir_node_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_node_ref_t node = scc_ir_builder_call(&ctx->builder, func, args.data, args.size); scc_vec_free(args); @@ -294,13 +304,18 @@ scc_ir_node_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr, for (usize i = 0; i < scc_strlen(expr->literal.lexme); i++) { int_lit = int_lit * 10 + (expr->literal.lexme[i] - '0'); } - return scc_ir_ctx_get_i32_const(&ctx->builder.ctx, int_lit); + scc_ir_type_ref_t type_ref = scc_ir_builder_type_i32(&ctx->builder); + scc_ir_const_int_t value; + value.int32 = int_lit; + return scc_ir_builder_const_int(&ctx->builder, type_ref, value); } // SCC_AST_EXPR_INT_LITERAL, // 整数字面量 // SCC_AST_EXPR_FLOAT_LITERAL, // 浮点字面量 // SCC_AST_EXPR_CHAR_LITERAL, // 字符字面量 - // SCC_AST_EXPR_STRING_LITERAL, // 字符串字面量 + // case SCC_AST_EXPR_STRING_LITERAL: { + // return scc_ir_builder_store(); + // } case SCC_AST_EXPR_IDENTIFIER: { if (expr->identifier._target == null) { @@ -550,7 +565,6 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, scc_ast_decl_t *decl) { scc_ir_builder_func(&ctx->builder, func_type_ref, decl->name); scc_hashtable_set(&ctx->symtab, decl->name, (void *)(usize)func_ref); - scc_vec_push(ctx->builder.cprog.func_decls, func_ref); } if (decl->func.body == null) { @@ -559,7 +573,8 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, scc_ast_decl_t *decl) { } scc_ir_builder_begin_func(&ctx->builder, func_ref, null); - scc_ir_func_t *func = scc_ir_ctx_get_func(&ctx->builder.ctx, func_ref); + scc_ir_func_t *func = + scc_ir_module_get_func(ctx->builder.ctx.module, func_ref); Assert(func != null); scc_ir_builder_begin_bblock(&ctx->builder, "entry"); scc_vec_foreach(decl->func.type->function.params, i) { @@ -568,7 +583,7 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, scc_ast_decl_t *decl) { scc_ir_node_ref_t param_node_ref = scc_vec_at(func->params, i); scc_ir_node_t *param_node = - scc_ir_ctx_get_node(&ctx->builder.ctx, param_node_ref); + scc_ir_module_get_node(ctx->builder.ctx.module, param_node_ref); Assert(param_node != null); param_node->name = param->name; scc_hashtable_set(&ctx->node2ir, param, @@ -620,11 +635,18 @@ static int scc_cmp_node(const void *key1, const void *key2) { return (u32)(usize)key1 - (u32)(usize)key2; } -void scc_ast2ir_ctx_init(scc_ast2ir_ctx_t *ctx, const scc_type_abi_t *abi) { +void scc_ast2ir_ctx_init(scc_ast2ir_ctx_t *ctx, const scc_type_abi_t *abi, + scc_ir_cprog_t *cprog) { Assert(ctx != null); ctx->abi = abi; - scc_ir_builder_init(&ctx->builder); + scc_ir_builder_init(&ctx->builder, cprog); scc_hashtable_init(&ctx->node2ir, scc_hash_node, scc_cmp_node); scc_hashtable_init(&ctx->symtab, (scc_hashtable_hash_func_t)scc_strhash32, (scc_hashtable_equal_func_t)scc_strcmp); } + +void scc_ast2ir_ctx_drop(scc_ast2ir_ctx_t *ctx) { + scc_ir_builder_drop(&ctx->builder); + scc_hashtable_drop(&ctx->node2ir); + scc_hashtable_drop(&ctx->symtab); +} diff --git a/libs/ir/include/ir_base.h b/libs/ir/include/ir_base.h deleted file mode 100644 index c8ff72e..0000000 --- a/libs/ir/include/ir_base.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __SCC_IR_BASE_H__ -#define __SCC_IR_BASE_H__ - -#include "ir_def.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 null ptr -void scc_ir_node_init(scc_ir_node_t *in, const char *name, - scc_ir_node_tag_t tag); - -void scc_ir_cprog_init(scc_ir_cprog_t *in); -void scc_ir_cprog_drop(scc_ir_cprog_t *in); - -#endif /* __SCC_IR_BASE_H__ */ diff --git a/libs/ir/include/ir_builder.h b/libs/ir/include/ir_builder.h index 5d734b0..9cdd21d 100644 --- a/libs/ir/include/ir_builder.h +++ b/libs/ir/include/ir_builder.h @@ -2,8 +2,7 @@ #define __SCC_IR_BUILDER_H__ #include "ir_ctx.h" -#include "ir_def.h" -#include +#include "scc_ir.h" typedef struct scc_ir_builder scc_ir_builder_t; @@ -17,18 +16,16 @@ typedef struct scc_ir_builder scc_ir_builder_t; * - 当前构建位置(函数、基本块) */ struct scc_ir_builder { - scc_ir_cprog_ctx_t ctx; /**< 核心上下文 */ - scc_ir_cprog_t cprog; - scc_hashtable_t func_decl_set; - // 当前构建位置 - scc_ir_func_ref_t current_func; /**< 当前正在构建的函数 */ - scc_ir_bblock_ref_t current_bblock; /**< 当前基本块 */ + scc_ir_cprog_t *cprog; + scc_ir_ctx_t ctx; ///< 核心上下文 + scc_ir_func_ref_t current_func; ///< 当前正在构建的函数 + scc_ir_bblock_ref_t current_bblock; ///< 当前基本块 }; /** * @brief 初始化 IR 构建器 */ -void scc_ir_builder_init(scc_ir_builder_t *builder); +void scc_ir_builder_init(scc_ir_builder_t *builder, scc_ir_cprog_t *cprog); /** * @brief 销毁 IR 构建器及其所有资源 @@ -39,6 +36,46 @@ 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); + +// TODO +static inline scc_ir_node_ref_t +scc_ir_builder_const_int(scc_ir_builder_t *builder, scc_ir_type_ref_t type, + scc_ir_const_int_t value) { + scc_ir_node_t node; + scc_ir_node_init(&node, null, SCC_IR_NODE_CONST_INT); + node.data.const_int = value; + node.type = type; + return scc_ir_module_add_node(&builder->cprog->module, &node); +} + +#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) + /** * @brief 开始构建函数 * @param func_ref 函数引用 diff --git a/libs/ir/include/ir_builtin.h b/libs/ir/include/ir_builtin.h deleted file mode 100644 index 96c4a15..0000000 --- a/libs/ir/include/ir_builtin.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __SCC_IR_BUILTIN_H__ -#define __SCC_IR_BUILTIN_H__ - -#include "ir_def.h" - -extern scc_ir_type_t scc_ir_builtin_i32; -extern scc_ir_node_t scc_ir_builtin_zero; - -#endif /* __SCC_IR_BUILTIN_H__ */ diff --git a/libs/ir/include/ir_ctx.h b/libs/ir/include/ir_ctx.h index ecf4b57..889478c 100644 --- a/libs/ir/include/ir_ctx.h +++ b/libs/ir/include/ir_ctx.h @@ -1,194 +1,32 @@ #ifndef __SCC_IR_CTX_H__ #define __SCC_IR_CTX_H__ -#include "ir_base.h" #include "ir_def.h" +#include "ir_prog.h" #include -#define SCC_IR_REF_NULL 0 - typedef struct { - unsigned int node_uid; - unsigned int type_uid; - unsigned int bblock_uid; - unsigned int func_uid; + 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; - SCC_VEC(scc_ir_node_t) nodes; - SCC_VEC(scc_ir_type_t) types; - SCC_VEC(scc_ir_bblock_t) bblocks; - SCC_VEC(scc_ir_func_t) funcs; +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); - // UID -> 索引 映射 - scc_hashtable_t uid2nodes; - scc_hashtable_t uid2types; - scc_hashtable_t uid2bblocks; - scc_hashtable_t uid2funcs; +// 获取唯一类型,若不存在则创建并返回新引用 +scc_ir_type_ref_t scc_ir_ctx_get_type(scc_ir_ctx_t *ctx, + const scc_ir_type_t *type_desc); - // 类型去重表(类型键 -> 类型引用) - scc_hashtable_t type_uniquing; +// 获取唯一常量(例如整数常量) +// scc_ir_node_ref_t scc_ir_ctx_get_const_int(scc_ir_ctx_t *ctx, +// scc_ir_type_ref_t type, i64 +// value); - // 常量池(常量键 -> 节点引用) - scc_hashtable_t const_pool; -} scc_ir_cprog_ctx_t; - -/** - * @brief 初始化IR上下文 - * @param ctx 上下文指针 - */ -void scc_ir_ctx_init(scc_ir_cprog_ctx_t *ctx); - -/** - * @brief 销毁IR上下文及其所有资源 - * @param ctx 上下文指针 - */ -void scc_ir_ctx_drop(scc_ir_cprog_ctx_t *ctx); - -/** - * @brief 重置IR上下文(清空所有数据但保留内存) - * @param ctx 上下文指针 - */ -void scc_ir_ctx_reset(scc_ir_cprog_ctx_t *ctx); - -/** - * @brief 创建新的类型 - * @param ctx 上下文指针 - * @param type 类型数据(会被拷贝) - * @return 类型引用(0表示失败) - */ -scc_ir_type_ref_t scc_ir_ctx_new_type(scc_ir_cprog_ctx_t *ctx, - const scc_ir_type_t *type); - -/** - * @brief 创建新的节点 - * @param ctx 上下文指针 - * @param node 节点数据(会被拷贝) - * @return 节点引用(0表示失败) - */ -scc_ir_node_ref_t scc_ir_ctx_new_node(scc_ir_cprog_ctx_t *ctx, - const scc_ir_node_t *node); - -/** - * @brief 创建新的基本块 - * @param ctx 上下文指针 - * @param bblock 基本块数据(会被拷贝) - * @return 基本块引用(0表示失败) - */ -scc_ir_bblock_ref_t scc_ir_ctx_new_bblock(scc_ir_cprog_ctx_t *ctx, - const scc_ir_bblock_t *bblock); - -/** - * @brief 创建新的函数 - * @param ctx 上下文指针 - * @param func 函数数据(会被拷贝) - * @return 函数引用(0表示失败) - */ -scc_ir_func_ref_t scc_ir_ctx_new_func(scc_ir_cprog_ctx_t *ctx, - const scc_ir_func_t *func); - -/** - * @brief 根据引用获取类型 - * @param ctx 上下文指针 - * @param ref 类型引用 - * @return 类型指针(NULL表示无效引用) - */ -scc_ir_type_t *scc_ir_ctx_get_type(scc_ir_cprog_ctx_t *ctx, - scc_ir_type_ref_t ref); - -/** - * @brief 根据引用获取节点 - * @param ctx 上下文指针 - * @param ref 节点引用 - * @return 节点指针(NULL表示无效引用) - */ -scc_ir_node_t *scc_ir_ctx_get_node(scc_ir_cprog_ctx_t *ctx, - scc_ir_node_ref_t ref); - -/** - * @brief 根据引用获取基本块 - * @param ctx 上下文指针 - * @param ref 基本块引用 - * @return 基本块指针(NULL表示无效引用) - */ -scc_ir_bblock_t *scc_ir_ctx_get_bblock(scc_ir_cprog_ctx_t *ctx, - scc_ir_bblock_ref_t ref); - -/** - * @brief 根据引用获取函数 - * @param ctx 上下文指针 - * @param ref 函数引用 - * @return 函数指针(NULL表示无效引用) - */ -scc_ir_func_t *scc_ir_ctx_get_func(scc_ir_cprog_ctx_t *ctx, - scc_ir_func_ref_t ref); - -// /** -// * @brief 遍历所有类型 -// * @param ctx 上下文指针 -// * @param callback 回调函数 -// * @param userdata 用户数据 -// */ -// void scc_ir_ctx_foreach_type(scc_ir_cprog_ctx_t *ctx, -// void (*callback)(scc_ir_type_ref_t ref, -// scc_ir_type_t *type, -// void *userdata), -// void *userdata); - -// /** -// * @brief 遍历所有节点 -// */ -// void scc_ir_ctx_foreach_node(scc_ir_cprog_ctx_t *ctx, -// void (*callback)(scc_ir_node_ref_t ref, -// scc_ir_node_t *node, -// void *userdata), -// void *userdata); - -// /** -// * @brief 遍历所有基本块 -// */ -// void scc_ir_ctx_foreach_bblock(scc_ir_cprog_ctx_t *ctx, -// void (*callback)(scc_ir_bblock_ref_t ref, -// scc_ir_bblock_t *bblock, -// void *userdata), -// void *userdata); - -// /** -// * @brief 遍历所有函数 -// */ -// void scc_ir_ctx_foreach_func(scc_ir_cprog_ctx_t *ctx, -// void (*callback)(scc_ir_func_ref_t ref, -// scc_ir_func_t *func, -// void *userdata), -// void *userdata); - -/** - * @brief 获取内置i32类型 - * @param ctx 上下文指针 - * @return i32类型引用 - */ -scc_ir_type_ref_t scc_ir_ctx_get_builtin_i32(scc_ir_cprog_ctx_t *ctx); - -/** - * @brief 获取内置零常量 - * @param ctx 上下文指针 - * @return 零常量节点引用 - */ -scc_ir_node_ref_t scc_ir_ctx_get_builtin_zero(scc_ir_cprog_ctx_t *ctx); - -/** - * @brief 创建或获取i32常量 - * @param ctx 上下文指针 - * @param value 常量值 - * @return 常量节点引用 - */ -scc_ir_node_ref_t scc_ir_ctx_get_i32_const(scc_ir_cprog_ctx_t *ctx, i32 value); - -/** - * @brief 创建或获取null常量 - * @param ctx 上下文指针 - * @param ptr_type 指针类型引用 - * @return null常量节点引用 - */ -scc_ir_node_ref_t scc_ir_ctx_get_null_const(scc_ir_cprog_ctx_t *ctx, - scc_ir_type_ref_t ptr_type); +// 注册函数声明,若已存在则返回已有引用 +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 index 47ed31a..a101e30 100644 --- a/libs/ir/include/ir_def.h +++ b/libs/ir/include/ir_def.h @@ -3,6 +3,8 @@ #include +#define SCC_IR_REF_NULL 0 + typedef unsigned int ir_handle_t; typedef const char *scc_ir_label_t; @@ -23,37 +25,34 @@ 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_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_VECTOR, + 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; - int size; // 字节大小 - int align; // 对齐要求 + const char *name; // For Debug union { struct { scc_ir_type_ref_t base; @@ -62,6 +61,9 @@ struct scc_ir_type { struct { scc_ir_type_ref_t base; } pointer; + struct { + scc_ir_type_ref_vec_t elements; + } aggregate; struct { scc_ir_type_ref_vec_t params; scc_ir_type_ref_t ret_type; @@ -144,28 +146,41 @@ typedef enum { 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; + struct scc_ir_node { scc_ir_type_ref_t type; scc_ir_label_t name; scc_ir_node_ref_vec_t used_by; scc_ir_node_tag_t tag; union { - union { - i8 int8; - i16 int16; - i32 int32; - i64 int64; - // TODO int128 - i8 int_any[16]; - } const_int; - union { - u8 uint8; - u16 uint16; - u32 uint32; - u64 uint64; - // TODO uint128; - u8 uint_any[16]; - } const_uint; + scc_ir_const_int_t const_int; + scc_ir_const_uint_t const_uint; + scc_ir_const_float_t const_float; // aggregate; struct { usize idx; @@ -216,10 +231,4 @@ struct scc_ir_node { } data; }; -typedef struct scc_ir_cprog { - scc_ir_node_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; - #endif /* __SCC_IR_DEF_H__ */ diff --git a/libs/ir/include/ir_dump.h b/libs/ir/include/ir_dump.h index 4bf70b5..f3d1305 100644 --- a/libs/ir/include/ir_dump.h +++ b/libs/ir/include/ir_dump.h @@ -1,20 +1,17 @@ #ifndef __SCC_IR_DUMP_H__ #define __SCC_IR_DUMP_H__ -#include "ir_ctx.h" -#include "ir_def.h" +#include "ir_prog.h" #include typedef struct { - scc_ir_cprog_ctx_t *ir_ctx; scc_ir_cprog_t *cprog; scc_tree_dump_ctx_t *dump_ctx; } scc_ir_dump_ctx_t; void scc_ir_dump_ctx_init(scc_ir_dump_ctx_t *ctx, - scc_tree_dump_ctx_t *tree_dump, scc_ir_cprog_t *cprog, - scc_ir_cprog_ctx_t *ir_ctx); - + scc_tree_dump_ctx_t *tree_dump, + scc_ir_cprog_t *cprog); void scc_ir_dump_node(scc_ir_dump_ctx_t *ctx, scc_ir_node_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); diff --git a/libs/ir/include/ir_prog.h b/libs/ir/include/ir_prog.h new file mode 100644 index 0000000..0e0f7fa --- /dev/null +++ b/libs/ir/include/ir_prog.h @@ -0,0 +1,52 @@ +#ifndef __SCC_IR_PROG_H__ +#define __SCC_IR_PROG_H__ + +#include "ir_def.h" +#include + +typedef struct { + unsigned int node_uid; + unsigned int type_uid; + unsigned int bblock_uid; + unsigned int func_uid; + SCC_VEC(scc_ir_node_t) nodes; + 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 uid2nodes; + scc_hashtable_t uid2types; + scc_hashtable_t uid2bblocks; + scc_hashtable_t uid2funcs; +} 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_node_ref_t scc_ir_module_add_node(scc_ir_module_t *ctx, + const scc_ir_node_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_node_t *scc_ir_module_get_node(scc_ir_module_t *ctx, + scc_ir_node_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); + +typedef struct scc_ir_cprog { + scc_ir_module_t module; + scc_ir_node_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 index 4680e40..a5f726d 100644 --- a/libs/ir/include/scc_ir.h +++ b/libs/ir/include/scc_ir.h @@ -1,9 +1,15 @@ #ifndef __SCC_IR_H__ #define __SCC_IR_H__ -#include "ir_builder.h" -#include "ir_ctx.h" #include "ir_def.h" -#include +#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 null ptr +void scc_ir_node_init(scc_ir_node_t *in, const char *name, + scc_ir_node_tag_t tag); #endif /* __SCC_IR_H__ */ diff --git a/libs/ir/src/ir_builder.c b/libs/ir/src/ir_builder.c index 440e116..15e5aab 100644 --- a/libs/ir/src/ir_builder.c +++ b/libs/ir/src/ir_builder.c @@ -1,42 +1,44 @@ #include -#include +#include -void scc_ir_builder_init(scc_ir_builder_t *builder) { +#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_NULL; builder->current_func = SCC_IR_REF_NULL; + builder->cprog = cprog; - scc_ir_cprog_init(&builder->cprog); - scc_ir_ctx_init(&builder->ctx); + scc_ir_ctx_init(&builder->ctx, GET_MODULE(builder)); } void scc_ir_builder_drop(scc_ir_builder_t *builder) { - scc_ir_cprog_drop(&builder->cprog); 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_func_t func = { - .name = name, - .type = type_ref, - }; - scc_vec_init(func.params); - scc_vec_init(func.bblocks); - - scc_ir_func_ref_t func_ref = scc_ir_ctx_new_func(&builder->ctx, &func); + 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) { + return scc_ir_ctx_get_type(&builder->ctx, type_desc); +} + void scc_ir_builder_begin_func(scc_ir_builder_t *builder, scc_ir_func_ref_t func_ref, const char **param_names) { // 创建函数并设置为当前函数 builder->current_func = func_ref; - scc_ir_func_t *func_ptr = scc_ir_ctx_get_func(&builder->ctx, func_ref); + scc_ir_func_t *func_ptr = + scc_ir_module_get_func(GET_MODULE(builder), func_ref); scc_ir_type_t *func_type = - scc_ir_ctx_get_type(&builder->ctx, func_ptr->type); + scc_ir_module_get_type(GET_MODULE(builder), func_ptr->type); if (func_type == null || func_type->tag != SCC_IR_TYPE_FUNC) { LOG_ERROR("Invalid function type"); @@ -66,7 +68,7 @@ void scc_ir_builder_begin_func(scc_ir_builder_t *builder, scc_vec_init(param_node.used_by); scc_ir_node_ref_t param_ref = - scc_ir_ctx_new_node(&builder->ctx, ¶m_node); + scc_ir_module_add_node(GET_MODULE(builder), ¶m_node); scc_vec_push(func_ptr->params, param_ref); } @@ -75,15 +77,16 @@ void scc_ir_builder_begin_func(scc_ir_builder_t *builder, void scc_ir_builder_end_func(scc_ir_builder_t *builder) { scc_ir_func_t *func_ptr = - scc_ir_ctx_get_func(&builder->ctx, builder->current_func); + scc_ir_module_get_func(GET_MODULE(builder), builder->current_func); if (func_ptr == null) { LOG_FATAL("Invalid function reference"); return; } if (scc_vec_size(func_ptr->bblocks) == 0) { - scc_vec_push(builder->cprog.func_decls, builder->current_func); + // FIXME + scc_vec_push(builder->cprog->func_decls, builder->current_func); } else { - scc_vec_push(builder->cprog.func_defs, builder->current_func); + scc_vec_push(builder->cprog->func_defs, builder->current_func); } builder->current_func = 0; } @@ -100,10 +103,10 @@ scc_ir_bblock_ref_t scc_ir_builder_bblock(scc_ir_builder_t *builder, } scc_vec_init(bblock.instrs); scc_ir_bblock_ref_t bblock_ref = - scc_ir_ctx_new_bblock(&builder->ctx, &bblock); + scc_ir_module_add_bblock(GET_MODULE(builder), &bblock); scc_ir_func_t *current_func = - scc_ir_ctx_get_func(&builder->ctx, 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); } @@ -129,7 +132,7 @@ void scc_ir_builder_set_current_bblock(scc_ir_builder_t *builder, static void scc_ir_builder_add_instr(scc_ir_builder_t *builder, scc_ir_node_ref_t node) { scc_ir_bblock_t *current_bblock = - scc_ir_ctx_get_bblock(&builder->ctx, builder->current_bblock); + scc_ir_module_get_bblock(GET_MODULE(builder), builder->current_bblock); if (current_bblock) { scc_vec_push(current_bblock->instrs, node); } else { @@ -142,13 +145,13 @@ scc_ir_node_ref_t scc_ir_builder_alloca(scc_ir_builder_t *builder, const char *name) { scc_ir_node_t alloc_node = {0}; alloc_node.tag = SCC_IR_NODE_ALLOC; - alloc_node.type = scc_ir_ctx_new_type( - &builder->ctx, + 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_node_ref_t node_ref = - scc_ir_ctx_new_node(&builder->ctx, &alloc_node); + scc_ir_module_add_node(GET_MODULE(builder), &alloc_node); // 添加到当前基本块 scc_ir_builder_add_instr(builder, node_ref); @@ -165,7 +168,8 @@ scc_ir_node_ref_t scc_ir_builder_func_arg_ref(scc_ir_builder_t *builder, node.name = name; node.data.arg_ref.idx = arg_idx; - scc_ir_node_ref_t node_ref = scc_ir_ctx_new_node(&builder->ctx, &node); + scc_ir_node_ref_t node_ref = + scc_ir_module_add_node(GET_MODULE(builder), &node); // 添加到当前基本块 scc_ir_builder_add_instr(builder, node_ref); return node_ref; @@ -178,16 +182,18 @@ scc_ir_node_ref_t scc_ir_builder_load(scc_ir_builder_t *builder, load_node.data.load.target = target; // 设置类型为指针指向的类型 - scc_ir_node_t *ptr_node = scc_ir_ctx_get_node(&builder->ctx, target); + scc_ir_node_t *ptr_node = + scc_ir_module_get_node(GET_MODULE(builder), target); if (ptr_node) { scc_ir_type_t *ptr_type = - scc_ir_ctx_get_type(&builder->ctx, ptr_node->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_node_ref_t node_ref = scc_ir_ctx_new_node(&builder->ctx, &load_node); + scc_ir_node_ref_t node_ref = + scc_ir_module_add_node(GET_MODULE(builder), &load_node); // 添加到当前基本块 scc_ir_builder_add_instr(builder, node_ref); @@ -204,7 +210,7 @@ scc_ir_node_ref_t scc_ir_builder_store(scc_ir_builder_t *builder, store_node.data.store.value = value; scc_ir_node_ref_t node_ref = - scc_ir_ctx_new_node(&builder->ctx, &store_node); + scc_ir_module_add_node(GET_MODULE(builder), &store_node); // 添加到当前基本块 scc_ir_builder_add_instr(builder, node_ref); @@ -221,13 +227,14 @@ scc_ir_node_ref_t scc_ir_builder_get_ptr(scc_ir_builder_t *builder, get_ptr_node.data.get_ptr.index = index; // 类型应与源地址相同(都是指针) - scc_ir_node_t *src_node = scc_ir_ctx_get_node(&builder->ctx, target); + scc_ir_node_t *src_node = + scc_ir_module_get_node(GET_MODULE(builder), target); if (src_node) { get_ptr_node.type = src_node->type; } scc_ir_node_ref_t node_ref = - scc_ir_ctx_new_node(&builder->ctx, &get_ptr_node); + scc_ir_module_add_node(GET_MODULE(builder), &get_ptr_node); // 添加到当前基本块 scc_ir_builder_add_instr(builder, node_ref); @@ -246,13 +253,13 @@ scc_ir_node_ref_t scc_ir_builder_binop(scc_ir_builder_t *builder, binop_node.data.op.rhs = rhs; // 类型通常与操作数相同(对于算术运算) - scc_ir_node_t *lhs_node = scc_ir_ctx_get_node(&builder->ctx, lhs); + scc_ir_node_t *lhs_node = scc_ir_module_get_node(GET_MODULE(builder), lhs); if (lhs_node) { binop_node.type = lhs_node->type; } scc_ir_node_ref_t node_ref = - scc_ir_ctx_new_node(&builder->ctx, &binop_node); + scc_ir_module_add_node(GET_MODULE(builder), &binop_node); // 添加到当前基本块 scc_ir_builder_add_instr(builder, node_ref); @@ -270,9 +277,11 @@ scc_ir_node_ref_t scc_ir_builder_cmp(scc_ir_builder_t *builder, cmp_node.data.op.rhs = rhs; // 比较操作的结果通常是布尔值 - cmp_node.type = scc_ir_ctx_get_builtin_i32(&builder->ctx); + cmp_node.type = + 0; // FIXME scc_ir_module_get_builtin_i32(GET_MODULE(builder)); - scc_ir_node_ref_t node_ref = scc_ir_ctx_new_node(&builder->ctx, &cmp_node); + scc_ir_node_ref_t node_ref = + scc_ir_module_add_node(GET_MODULE(builder), &cmp_node); // 添加到当前基本块 scc_ir_builder_add_instr(builder, node_ref); @@ -286,7 +295,8 @@ scc_ir_node_ref_t scc_ir_builder_jump(scc_ir_builder_t *builder, jump_node.tag = SCC_IR_NODE_JUMP; jump_node.data.jump.target_bblock = target; - scc_ir_node_ref_t node_ref = scc_ir_ctx_new_node(&builder->ctx, &jump_node); + scc_ir_node_ref_t node_ref = + scc_ir_module_add_node(GET_MODULE(builder), &jump_node); // 添加到当前基本块 scc_ir_builder_add_instr(builder, node_ref); @@ -305,7 +315,7 @@ scc_ir_node_ref_t scc_ir_builder_branch(scc_ir_builder_t *builder, branch_node.data.branch.false_bblock = false_target; scc_ir_node_ref_t node_ref = - scc_ir_ctx_new_node(&builder->ctx, &branch_node); + scc_ir_module_add_node(GET_MODULE(builder), &branch_node); // 添加到当前基本块 scc_ir_builder_add_instr(builder, node_ref); @@ -327,16 +337,18 @@ scc_ir_node_ref_t scc_ir_builder_call(scc_ir_builder_t *builder, } // 设置返回类型为被调用函数的返回类型 - scc_ir_func_t *callee_func = scc_ir_ctx_get_func(&builder->ctx, callee); + scc_ir_func_t *callee_func = + scc_ir_module_get_func(GET_MODULE(builder), callee); if (callee_func) { scc_ir_type_t *func_type = - scc_ir_ctx_get_type(&builder->ctx, callee_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_node_ref_t node_ref = scc_ir_ctx_new_node(&builder->ctx, &call_node); + scc_ir_node_ref_t node_ref = + scc_ir_module_add_node(GET_MODULE(builder), &call_node); // 添加到当前基本块 scc_ir_builder_add_instr(builder, node_ref); @@ -350,7 +362,8 @@ scc_ir_node_ref_t scc_ir_builder_ret(scc_ir_builder_t *builder, ret_node.tag = SCC_IR_NODE_RET; ret_node.data.ret.ret_val = value; - scc_ir_node_ref_t node_ref = scc_ir_ctx_new_node(&builder->ctx, &ret_node); + scc_ir_node_ref_t node_ref = + scc_ir_module_add_node(GET_MODULE(builder), &ret_node); // 添加到当前基本块 scc_ir_builder_add_instr(builder, node_ref); @@ -363,7 +376,8 @@ scc_ir_node_ref_t scc_ir_builder_ret_void(scc_ir_builder_t *builder) { ret_node.tag = SCC_IR_NODE_RET; ret_node.data.ret.ret_val = 0; // 无返回值 - scc_ir_node_ref_t node_ref = scc_ir_ctx_new_node(&builder->ctx, &ret_node); + scc_ir_node_ref_t node_ref = + scc_ir_module_add_node(GET_MODULE(builder), &ret_node); // 添加到当前基本块 scc_ir_builder_add_instr(builder, node_ref); diff --git a/libs/ir/src/ir_builtin.c b/libs/ir/src/ir_builtin.c deleted file mode 100644 index d6344fc..0000000 --- a/libs/ir/src/ir_builtin.c +++ /dev/null @@ -1,10 +0,0 @@ -#include - -scc_ir_type_t scc_ir_builtin_i32 = { - .tag = SCC_IR_TYPE_I32, -}; - -scc_ir_node_t scc_ir_builtin_zero = { - .tag = SCC_IR_NODE_CONST_INT, - .data.const_int.int_any = {0}, -}; diff --git a/libs/ir/src/ir_ctx.c b/libs/ir/src/ir_ctx.c index d872cd8..acf1303 100644 --- a/libs/ir/src/ir_ctx.c +++ b/libs/ir/src/ir_ctx.c @@ -1,5 +1,4 @@ -#include "ir_ctx.h" -#include "ir_builtin.h" +#include /** * @brief 哈希混合函数(类似Rust的hash combine) @@ -12,30 +11,27 @@ static inline u32 scc_hash_mix(u32 seed, u32 value) { return (seed ^ value) * 16777619u; } -static u32 hash_key(const void *key) { return (u32)(usize)key; } -static int cmp_key(const void *key1, const void *key2) { - return (u32)(usize)key1 != (u32)(usize)key2; -} -static u32 hash_type(const scc_ir_type_t *key) { +static u32 hash_type(const void *_key) { + const scc_ir_type_t *key = _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: + 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; @@ -66,28 +62,29 @@ static u32 hash_type(const scc_ir_type_t *key) { return hash; } -static int cmp_type(const scc_ir_type_t *key1, const scc_ir_type_t *key2) { +static int cmp_type(const void *_key1, const void *_key2) { + const scc_ir_type_t *key1 = _key1, *key2 = _key2; // 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: + 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; @@ -121,213 +118,61 @@ static int cmp_type(const scc_ir_type_t *key1, const scc_ir_type_t *key2) { return 1; } -void scc_ir_ctx_init(scc_ir_cprog_ctx_t *ctx) { - // 初始化向量 - scc_vec_init(ctx->nodes); - scc_vec_init(ctx->types); - scc_vec_init(ctx->bblocks); - scc_vec_init(ctx->funcs); - - // 初始化哈希表 - scc_hashtable_init(&ctx->uid2nodes, hash_key, cmp_key); - scc_hashtable_init(&ctx->uid2types, hash_key, cmp_key); - scc_hashtable_init(&ctx->uid2bblocks, hash_key, cmp_key); - scc_hashtable_init(&ctx->uid2funcs, hash_key, cmp_key); - - scc_hashtable_init(&ctx->type_uniquing, - (scc_hashtable_hash_func_t)hash_type, - (scc_hashtable_equal_func_t)cmp_type); - - // 预留UID 0 作为无效引用 - ctx->node_uid = 1; - ctx->type_uid = 1; - ctx->bblock_uid = 1; - ctx->func_uid = 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); + // scc_hashtable_init(&ctx->const_pool, /* 常量哈希函数 */, + // /* 常量比较函数 */); + scc_hashtable_init(&ctx->func_decl_set, + (scc_hashtable_hash_func_t)scc_strhash32, + (scc_hashtable_equal_func_t)scc_strcmp); } -void scc_ir_ctx_drop(scc_ir_cprog_ctx_t *ctx) { - // 释放所有实体的内部内存 - for (usize i = 0; i < ctx->nodes.size; i++) { - scc_ir_node_t *node = &ctx->nodes.data[i]; - scc_vec_free(node->used_by); - if (node->tag == SCC_IR_NODE_CALL) { - scc_vec_free(node->data.call.args); - } +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) { + // 先查哈希表 + void *found = scc_hashtable_get(&ctx->type_uniquing, (void *)type_desc); + if (found) { + return (scc_ir_type_ref_t)(usize)found; } - for (usize i = 0; 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); - } + // 不存在,添加新类型 + scc_ir_type_ref_t new_ref = scc_ir_module_add_type(ctx->module, type_desc); + scc_hashtable_set(&ctx->type_uniquing, (void *)type_desc, + (void *)(usize)new_ref); + return new_ref; +} + +// scc_ir_node_ref_t scc_ir_ctx_get_const_int(scc_ir_ctx_t *ctx, +// scc_ir_type_ref_t type, i64 value) +// { +// return scc_ir_node_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; } - for (usize i = 0; i < ctx->bblocks.size; i++) { - scc_ir_bblock_t *bblock = &ctx->bblocks.data[i]; - scc_vec_free(bblock->instrs); - } - - for (usize i = 0; 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->nodes); - scc_vec_free(ctx->types); - scc_vec_free(ctx->bblocks); - scc_vec_free(ctx->funcs); - - // 释放哈希表 - scc_hashtable_drop(&ctx->uid2nodes); - scc_hashtable_drop(&ctx->uid2types); - scc_hashtable_drop(&ctx->uid2bblocks); - scc_hashtable_drop(&ctx->uid2funcs); -} - -void scc_ir_ctx_reset(scc_ir_cprog_ctx_t *ctx) { - // 先销毁再重新初始化 - scc_ir_ctx_drop(ctx); - scc_ir_ctx_init(ctx); -} - -// 辅助宏:创建实体并添加到哈希表 -#define CREATE_ENTITY(ctx, vec, uid, data, hashtable) \ - do { \ - /* 分配新UID */ \ - unsigned new_uid = (ctx)->uid++; \ - /* 添加到向量 */ \ - scc_vec_push((vec), *(data)); \ - /* 添加到哈希表 */ \ - scc_hashtable_set(&(ctx)->hashtable, (const void *)(usize)new_uid, \ - (void *)(usize)(scc_vec_size(vec) - 1)); \ - return new_uid; \ - } while (0) - -scc_ir_type_ref_t scc_ir_ctx_new_type(scc_ir_cprog_ctx_t *ctx, - const scc_ir_type_t *type) { - // 首先检查去重表 - void *existing = scc_hashtable_get(&ctx->type_uniquing, type); - if (existing) { - return (scc_ir_type_ref_t)(uintptr_t)existing; - } - - CREATE_ENTITY(ctx, ctx->types, type_uid, type, uid2types); -} - -scc_ir_node_ref_t scc_ir_ctx_new_node(scc_ir_cprog_ctx_t *ctx, - const scc_ir_node_t *node) { - CREATE_ENTITY(ctx, ctx->nodes, node_uid, node, uid2nodes); -} - -scc_ir_bblock_ref_t scc_ir_ctx_new_bblock(scc_ir_cprog_ctx_t *ctx, - const scc_ir_bblock_t *bblock) { - CREATE_ENTITY(ctx, ctx->bblocks, bblock_uid, bblock, uid2bblocks); -} - -scc_ir_func_ref_t scc_ir_ctx_new_func(scc_ir_cprog_ctx_t *ctx, - const scc_ir_func_t *func) { - CREATE_ENTITY(ctx, ctx->funcs, func_uid, func, uid2funcs); -} - -#undef CREATE_ENTITY - -// 辅助宏:从哈希表获取索引 -#define GET_ENTITY_INDEX(ctx, ref, hashtable) \ - ((usize)scc_hashtable_get(&(ctx)->hashtable, (void *)(usize)ref)) - -scc_ir_type_t *scc_ir_ctx_get_type(scc_ir_cprog_ctx_t *ctx, - scc_ir_type_ref_t ref) { - if (ref == 0) - return null; - usize idx = GET_ENTITY_INDEX(ctx, ref, uid2types); - if (idx >= ctx->types.size) - return null; - return &ctx->types.data[idx]; -} - -scc_ir_node_t *scc_ir_ctx_get_node(scc_ir_cprog_ctx_t *ctx, - scc_ir_node_ref_t ref) { - if (ref == 0) - return null; - usize idx = GET_ENTITY_INDEX(ctx, ref, uid2nodes); - if (idx >= ctx->nodes.size) - return null; - return &ctx->nodes.data[idx]; -} - -scc_ir_bblock_t *scc_ir_ctx_get_bblock(scc_ir_cprog_ctx_t *ctx, - scc_ir_bblock_ref_t ref) { - if (ref == 0) - return null; - usize idx = GET_ENTITY_INDEX(ctx, ref, uid2bblocks); - if (idx >= ctx->bblocks.size) - return null; - return &ctx->bblocks.data[idx]; -} - -scc_ir_func_t *scc_ir_ctx_get_func(scc_ir_cprog_ctx_t *ctx, - scc_ir_func_ref_t ref) { - if (ref == 0) - return null; - usize idx = GET_ENTITY_INDEX(ctx, ref, uid2funcs); - if (idx >= ctx->funcs.size) - return null; - return &ctx->funcs.data[idx]; -} - -#undef GET_ENTITY_INDEX - -// // 内置类型和常量缓存 -// static scc_ir_type_ref_t cached_i32_type = 0; -// static scc_ir_node_ref_t cached_zero_const = 0; - -scc_ir_type_ref_t scc_ir_ctx_get_builtin_i32(scc_ir_cprog_ctx_t *ctx) { - scc_ir_type_ref_t cached_i32_type = 0; - if (cached_i32_type == 0) { - scc_ir_type_t i32_type = {.tag = SCC_IR_TYPE_I32}; - cached_i32_type = scc_ir_ctx_new_type(ctx, &i32_type); - } - return cached_i32_type; -} - -scc_ir_node_ref_t scc_ir_ctx_get_builtin_zero(scc_ir_cprog_ctx_t *ctx) { - scc_ir_node_ref_t cached_zero_const = 0; - if (cached_zero_const == 0) { - scc_ir_node_t zero_node = {.tag = SCC_IR_NODE_CONST_INT, - .type = scc_ir_ctx_get_builtin_i32(ctx), - .name = "zero", - .data.const_int.int32 = 0}; - cached_zero_const = scc_ir_ctx_new_node(ctx, &zero_node); - } - return cached_zero_const; -} - -// 常量池(简化版) -typedef struct { - i32 value; - scc_ir_node_ref_t ref; -} i32_const_entry_t; - -scc_ir_node_ref_t scc_ir_ctx_get_i32_const(scc_ir_cprog_ctx_t *ctx, i32 value) { - // 如果是0,使用内置zero - if (value == 0) { - return scc_ir_ctx_get_builtin_zero(ctx); - } - - // TODO: 实现常量池哈希表 - // 这里简化实现,每次都创建新常量 - scc_ir_node_t const_node = {.tag = SCC_IR_NODE_CONST_INT, - .type = scc_ir_ctx_get_builtin_i32(ctx), - .data.const_int.int32 = value}; - - const_node.name = null; - - return scc_ir_ctx_new_node(ctx, &const_node); -} - -scc_ir_node_ref_t scc_ir_ctx_get_null_const(scc_ir_cprog_ctx_t *ctx, - scc_ir_type_ref_t ptr_type) { - return 1; + // 创建新函数 + 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_dump.c b/libs/ir/src/ir_dump.c index ef0c4e0..4a61809 100644 --- a/libs/ir/src/ir_dump.c +++ b/libs/ir/src/ir_dump.c @@ -1,5 +1,7 @@ -#include #include +#include + +#define GET_MODULE(ctx) (&(ctx->cprog->module)) #define PRINT_VALUE(ctx, fmt, value) \ SCC_TREE_DUMP_PRINT_PURE(ctx, ctx->value_color, fmt, value) @@ -66,14 +68,14 @@ static const char *get_op_str(scc_ir_op_type_t op) { // 获取类型标签字符串 static const char *get_type_tag_str(scc_ir_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_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", }; @@ -176,8 +178,8 @@ static void dump_branch_node(scc_ir_dump_ctx_t *ctx, // 输出真分支块 if (node->data.branch.true_bblock) { - scc_ir_bblock_t *true_bblock = - scc_ir_ctx_get_bblock(ctx->ir_ctx, node->data.branch.true_bblock); + scc_ir_bblock_t *true_bblock = scc_ir_module_get_bblock( + GET_MODULE(ctx), node->data.branch.true_bblock); if (true_bblock) { scc_tree_print_indent(ctx->dump_ctx); PRINT_NODE(ctx->dump_ctx, "TrueBlock: "); @@ -189,8 +191,8 @@ static void dump_branch_node(scc_ir_dump_ctx_t *ctx, // 输出假分支块 if (node->data.branch.false_bblock) { - scc_ir_bblock_t *false_bblock = - scc_ir_ctx_get_bblock(ctx->ir_ctx, node->data.branch.false_bblock); + scc_ir_bblock_t *false_bblock = scc_ir_module_get_bblock( + GET_MODULE(ctx), node->data.branch.false_bblock); if (false_bblock) { scc_tree_print_indent(ctx->dump_ctx); PRINT_NODE(ctx->dump_ctx, "FalseBlock: "); @@ -205,8 +207,8 @@ static void dump_branch_node(scc_ir_dump_ctx_t *ctx, static void dump_jump_node(scc_ir_dump_ctx_t *ctx, const scc_ir_node_t *node) { // PRINT_NODE(ctx->dump_ctx, "jump"); if (node->data.jump.target_bblock) { - scc_ir_bblock_t *target_bblock = - scc_ir_ctx_get_bblock(ctx->ir_ctx, node->data.jump.target_bblock); + scc_ir_bblock_t *target_bblock = scc_ir_module_get_bblock( + GET_MODULE(ctx), node->data.jump.target_bblock); if (target_bblock) { scc_tree_dump_printf(ctx->dump_ctx, "to '%s'", target_bblock->label ? target_bblock->label @@ -224,7 +226,7 @@ static void dump_call_node(scc_ir_dump_ctx_t *ctx, const scc_ir_node_t *node) { // PRINT_NODE(ctx->dump_ctx, "call"); if (node->data.call.callee) { scc_ir_func_t *callee = - scc_ir_ctx_get_func(ctx->ir_ctx, node->data.call.callee); + scc_ir_module_get_func(GET_MODULE(ctx), node->data.call.callee); if (callee) { scc_tree_dump_printf(ctx->dump_ctx, "func='%s'", callee->name ? callee->name : ""); @@ -260,15 +262,14 @@ static void dump_ret_node(scc_ir_dump_ctx_t *ctx, const scc_ir_node_t *node) { } void scc_ir_dump_ctx_init(scc_ir_dump_ctx_t *ctx, - scc_tree_dump_ctx_t *tree_dump, scc_ir_cprog_t *cprog, - scc_ir_cprog_ctx_t *ir_ctx) { + scc_tree_dump_ctx_t *tree_dump, + scc_ir_cprog_t *cprog) { ctx->cprog = cprog; ctx->dump_ctx = tree_dump; - ctx->ir_ctx = ir_ctx; } void scc_ir_dump_node(scc_ir_dump_ctx_t *ctx, scc_ir_node_ref_t node_ref) { - scc_ir_node_t *node = scc_ir_ctx_get_node(ctx->ir_ctx, node_ref); + scc_ir_node_t *node = scc_ir_module_get_node(GET_MODULE(ctx), node_ref); if (!node) { LOG_ERROR("Invalid node ref"); return; @@ -283,7 +284,8 @@ void scc_ir_dump_node(scc_ir_dump_ctx_t *ctx, scc_ir_node_ref_t node_ref) { if (node->type) { scc_tree_dump_printf(ctx->dump_ctx, " : "); - scc_ir_type_t *type = scc_ir_ctx_get_type(ctx->ir_ctx, node->type); + scc_ir_type_t *type = + scc_ir_module_get_type(GET_MODULE(ctx), node->type); if (type) { PRINT_VALUE(ctx->dump_ctx, "%s", get_type_tag_str(type->tag)); } @@ -338,7 +340,7 @@ void scc_ir_dump_type(scc_ir_dump_ctx_t *ctx, scc_ir_type_ref_t type_ref) { return; } - scc_ir_type_t *type = scc_ir_ctx_get_type(ctx->ir_ctx, type_ref); + scc_ir_type_t *type = scc_ir_module_get_type(GET_MODULE(ctx), type_ref); if (!type) { LOG_ERROR("invalid type ref"); return; @@ -409,7 +411,8 @@ void scc_ir_dump_bblock(scc_ir_dump_ctx_t *ctx, return; } - scc_ir_bblock_t *bblock = scc_ir_ctx_get_bblock(ctx->ir_ctx, bblock_ref); + scc_ir_bblock_t *bblock = + scc_ir_module_get_bblock(GET_MODULE(ctx), bblock_ref); if (!bblock) { LOG_ERROR("invalid bblock ref"); return; @@ -434,7 +437,7 @@ void scc_ir_dump_bblock(scc_ir_dump_ctx_t *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_ctx_get_func(ctx->ir_ctx, func_ref); + scc_ir_func_t *func = scc_ir_module_get_func(GET_MODULE(ctx), func_ref); if (!ctx || !func) { LOG_ERROR("invalid parameter"); return; @@ -489,7 +492,7 @@ void scc_ir_dump_cprog(scc_ir_dump_ctx_t *ctx) { // scc_ir_node_ref_t global_ref = // scc_vec_at(program->global_vals, i); scc_ir_node_t // *global_node = - // scc_ir_ctx_get_node(ir_ctx, global_ref); + // scc_ir_module_get_node(ir_ctx, global_ref); // if (global_node) { // scc_ir_dump_node(ctx, ir_ctx, global_node); // } @@ -526,17 +529,17 @@ void scc_ir_dump_cprog(scc_ir_dump_ctx_t *ctx) { 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_ctx_get_type(ctx->ir_ctx, type_ref); + scc_ir_type_t *type = scc_ir_module_get_type(GET_MODULE(ctx), type_ref); if (!ctx || !type) { LOG_ERROR("invalid parameter"); return; } #define PRINT_TYPE(ctx, name) PRINT_VALUE(ctx, "%s", name) switch (type->tag) { - case SCC_IR_TYPE_I32: + case SCC_IR_TYPE_i32: PRINT_TYPE(ctx->dump_ctx, "i32"); break; - case SCC_IR_TYPE_VOID: + case SCC_IR_TYPE_void: PRINT_TYPE(ctx->dump_ctx, "void"); break; case SCC_IR_TYPE_ARRAY: @@ -577,7 +580,7 @@ void scc_ir_dump_type_linear(scc_ir_dump_ctx_t *ctx, // 辅助函数:输出节点引用或值到缓冲区 static usize format_node_ref_or_value(scc_ir_dump_ctx_t *ctx, char *buf, usize size, scc_ir_node_ref_t node_ref) { - scc_ir_node_t *node = scc_ir_ctx_get_node(ctx->ir_ctx, node_ref); + scc_ir_node_t *node = scc_ir_module_get_node(GET_MODULE(ctx), node_ref); if (!node) { return scc_snprintf(buf, size, "%%%u", node_ref); } @@ -598,7 +601,7 @@ static usize format_node_ref_or_value(scc_ir_dump_ctx_t *ctx, char *buf, // 线性输出节点信息(SSA IR风格) void scc_ir_dump_node_linear(scc_ir_dump_ctx_t *ctx, scc_ir_node_ref_t node_ref) { - scc_ir_node_t *node = scc_ir_ctx_get_node(ctx->ir_ctx, node_ref); + scc_ir_node_t *node = scc_ir_module_get_node(GET_MODULE(ctx), node_ref); if (node == null) { LOG_ERROR("invalid node ref"); return; @@ -707,8 +710,8 @@ void scc_ir_dump_node_linear(scc_ir_dump_ctx_t *ctx, break; case SCC_IR_NODE_CALL: { - char node_name[256] = ""; - char args_buf[256] = ""; + char node_name[256] = {0}; + char args_buf[256] = {0}; char *args_p = args_buf; usize args_remaining = sizeof(args_buf); @@ -727,7 +730,7 @@ void scc_ir_dump_node_linear(scc_ir_dump_ctx_t *ctx, } scc_ir_func_t *func = - scc_ir_ctx_get_func(ctx->ir_ctx, node->data.call.callee); + scc_ir_module_get_func(GET_MODULE(ctx), node->data.call.callee); p += scc_snprintf(p, remaining, "call @%s(%s)", func ? func->name : null, args_buf); break; @@ -762,7 +765,8 @@ void scc_ir_dump_node_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) { - scc_ir_bblock_t *bblock = scc_ir_ctx_get_bblock(ctx->ir_ctx, bblock_ref); + scc_ir_bblock_t *bblock = + scc_ir_module_get_bblock(GET_MODULE(ctx), bblock_ref); if (bblock == null) { PRINT_NODE(ctx->dump_ctx, "\n"); @@ -791,7 +795,7 @@ void scc_ir_dump_bblock_linear(scc_ir_dump_ctx_t *ctx, // 线性输出函数信息 void scc_ir_dump_func_linear(scc_ir_dump_ctx_t *ctx, scc_ir_func_ref_t func_ref) { - scc_ir_func_t *func = scc_ir_ctx_get_func(ctx->ir_ctx, func_ref); + scc_ir_func_t *func = scc_ir_module_get_func(GET_MODULE(ctx), func_ref); if (!func) { LOG_ERROR("invalid function reference"); return; @@ -816,7 +820,7 @@ void scc_ir_dump_func_linear(scc_ir_dump_ctx_t *ctx, scc_ir_node_ref_t param_ref = scc_vec_at(func->params, i); PRINT_NODE(ctx->dump_ctx, "%"); scc_ir_node_t *param_node = - scc_ir_ctx_get_node(ctx->ir_ctx, param_ref); + scc_ir_module_get_node(GET_MODULE(ctx), param_ref); if (param_node && param_node->name && param_node->name[0] != '\0') { scc_snprintf(buff, sizeof(buff), "%u[%s]", param_ref, param_node->name); @@ -850,7 +854,8 @@ void scc_ir_dump_func_linear(scc_ir_dump_ctx_t *ctx, void scc_ir_dump_cprog_linear(scc_ir_dump_ctx_t *ctx) { scc_vec_foreach(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_ctx_get_func(ctx->ir_ctx, func_decl); + scc_ir_func_t *func = + scc_ir_module_get_func(GET_MODULE(ctx), func_decl); Assert(func != null); if (scc_vec_size(func->bblocks) == 0) scc_ir_dump_func_linear(ctx, func_decl); diff --git a/libs/ir/src/ir_prog.c b/libs/ir/src/ir_prog.c new file mode 100644 index 0000000..cf26b9c --- /dev/null +++ b/libs/ir/src/ir_prog.c @@ -0,0 +1,151 @@ +#include + +void scc_ir_cprog_init(scc_ir_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); +} + +void scc_ir_cprog_drop(scc_ir_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); +} + +static u32 hash_key(const void *key) { return (u32)(usize)key; } +static int cmp_key(const void *key1, const void *key2) { + return (u32)(usize)key1 != (u32)(usize)key2; +} + +void scc_ir_module_init(scc_ir_module_t *ctx) { + scc_vec_init(ctx->nodes); + scc_vec_init(ctx->types); + scc_vec_init(ctx->bblocks); + scc_vec_init(ctx->funcs); + scc_hashtable_init(&ctx->uid2nodes, hash_key, cmp_key); + scc_hashtable_init(&ctx->uid2types, hash_key, cmp_key); + scc_hashtable_init(&ctx->uid2bblocks, hash_key, cmp_key); + scc_hashtable_init(&ctx->uid2funcs, hash_key, cmp_key); + // 预留UID 0 作为无效引用 + ctx->node_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 = 0; i < ctx->nodes.size; i++) { + scc_ir_node_t *node = &ctx->nodes.data[i]; + scc_vec_free(node->used_by); + if (node->tag == SCC_IR_NODE_CALL) { + scc_vec_free(node->data.call.args); + } + } + + for (usize i = 0; 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 = 0; i < ctx->bblocks.size; i++) { + scc_ir_bblock_t *bblock = &ctx->bblocks.data[i]; + scc_vec_free(bblock->instrs); + } + + for (usize i = 0; 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->nodes); + scc_vec_free(ctx->types); + scc_vec_free(ctx->bblocks); + scc_vec_free(ctx->funcs); + scc_hashtable_drop(&ctx->uid2nodes); + scc_hashtable_drop(&ctx->uid2types); + scc_hashtable_drop(&ctx->uid2bblocks); + scc_hashtable_drop(&ctx->uid2funcs); +} + +// 辅助宏:创建实体并添加到哈希表 +#define CREATE_ENTITY(ctx, vec, uid, data, hashtable) \ + do { \ + /* 分配新UID */ \ + unsigned new_uid = (ctx)->uid++; \ + /* 添加到向量 */ \ + scc_vec_push((vec), *(data)); \ + /* 添加到哈希表 */ \ + scc_hashtable_set(&(ctx)->hashtable, (const void *)(usize)new_uid, \ + (void *)(usize)(scc_vec_size(vec) - 1)); \ + 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, uid2types); +} + +scc_ir_node_ref_t scc_ir_module_add_node(scc_ir_module_t *ctx, + const scc_ir_node_t *node) { + CREATE_ENTITY(ctx, ctx->nodes, node_uid, node, uid2nodes); +} + +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, uid2bblocks); +} + +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, uid2funcs); +} + +// 辅助宏:从哈希表获取索引 +#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 null; + usize idx = GET_ENTITY_INDEX(ctx, ref, uid2types); + if (idx >= ctx->types.size) + return null; + return &ctx->types.data[idx]; +} + +scc_ir_node_t *scc_ir_module_get_node(scc_ir_module_t *ctx, + scc_ir_node_ref_t ref) { + if (ref == 0) + return null; + usize idx = GET_ENTITY_INDEX(ctx, ref, uid2nodes); + if (idx >= ctx->nodes.size) + return null; + return &ctx->nodes.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 null; + usize idx = GET_ENTITY_INDEX(ctx, ref, uid2bblocks); + if (idx >= ctx->bblocks.size) + return null; + 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 null; + usize idx = GET_ENTITY_INDEX(ctx, ref, uid2funcs); + if (idx >= ctx->funcs.size) + return null; + return &ctx->funcs.data[idx]; +} diff --git a/libs/ir/src/ir_base.c b/libs/ir/src/scc_ir.c similarity index 81% rename from libs/ir/src/ir_base.c rename to libs/ir/src/scc_ir.c index 8b6ab06..8270d1b 100644 --- a/libs/ir/src/ir_base.c +++ b/libs/ir/src/scc_ir.c @@ -1,9 +1,27 @@ -#include +#include void scc_ir_type_init(scc_ir_type_t *in, scc_ir_type_tag_t tag) { Assert(in != null); in->tag = tag; + in->name = null; 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; @@ -15,9 +33,6 @@ void scc_ir_type_init(scc_ir_type_t *in, scc_ir_type_tag_t tag) { scc_vec_init(in->data.function.params); in->data.function.ret_type = 0; break; - case SCC_IR_TYPE_VOID: - case SCC_IR_TYPE_I32: - break; default: UNREACHABLE(); break; @@ -53,7 +68,7 @@ void scc_ir_node_init(scc_ir_node_t *in, const char *name, break; case SCC_IR_NODE_CONST_INT: // TODO - in->data.const_int.int32 = 0; + in->data.const_int.int64 = 0; break; case SCC_IR_NODE_ALLOC: // TODO(); @@ -94,15 +109,3 @@ void scc_ir_node_init(scc_ir_node_t *in, const char *name, break; } } - -void scc_ir_cprog_init(scc_ir_cprog_t *in) { - scc_vec_init(in->func_decls); - scc_vec_init(in->func_defs); - scc_vec_init(in->global_vals); -} - -void scc_ir_cprog_drop(scc_ir_cprog_t *in) { - scc_vec_free(in->func_decls); - scc_vec_free(in->func_defs); - scc_vec_free(in->global_vals); -} diff --git a/libs/ir2mcode/include/reg_alloc.h b/libs/ir2mcode/include/reg_alloc.h index 0555709..40bac2d 100644 --- a/libs/ir2mcode/include/reg_alloc.h +++ b/libs/ir2mcode/include/reg_alloc.h @@ -29,7 +29,7 @@ typedef scc_hashtable_t *(*scc_reg_alloc_func_t)( ); typedef struct scc_reg_alloc { - scc_ir_cprog_ctx_t *ir_ctx; ///< IR上下文 + scc_ir_module_t *ir_module; ///< IR存储节点 scc_hashtable_t node_ref2reg_loc; ///< 输出结果哈希表 scc_reg_loc_vec_t reg_loc_vec; int gpr_caller_saved; ///< 函数可以随意修改,调用者如果在意需自行保护. @@ -41,7 +41,7 @@ typedef struct scc_reg_alloc { #define scc_reg_alloc(ctx, func) ((ctx)->reg_alloc_func(ctx, func)) void scc_reg_alloc_init(scc_reg_alloc_t *ctx, scc_reg_alloc_func_t func, - scc_ir_cprog_ctx_t *ir_ctx); + scc_ir_module_t *ir_module); scc_hashtable_t *scc_reg_alloc_with_stack(scc_reg_alloc_t *ctx, scc_ir_func_t *func); diff --git a/libs/ir2mcode/include/scc_ir2mcode.h b/libs/ir2mcode/include/scc_ir2mcode.h index 28c43b6..9e1bf8b 100644 --- a/libs/ir2mcode/include/scc_ir2mcode.h +++ b/libs/ir2mcode/include/scc_ir2mcode.h @@ -6,11 +6,12 @@ #include #include #include + typedef struct { scc_ir_cprog_t *cprog; - scc_ir_cprog_ctx_t *ir_ctx; - scc_mcode_t mcode; - sccf_builder_t builder; + sccf_builder_t *builder; + scc_mcode_t sect_mcode; + sccf_sect_data_t sect_data; // FIXME usize stack_size; @@ -21,7 +22,9 @@ typedef struct { // amd64 void scc_ir2mcode_init(scc_ir2mcode_ctx_t *ctx, scc_ir_cprog_t *cprog, - scc_ir_cprog_ctx_t *ir_ctx, scc_mcode_arch_t arch); + sccf_builder_t *builder, scc_mcode_arch_t arch); +void scc_ir2mcode_drop(scc_ir2mcode_ctx_t *ctx); + void scc_ir2mcode(scc_ir2mcode_ctx_t *ctx); #endif /* __SCC_IR2MCODE_H__ */ diff --git a/libs/ir2mcode/src/ir2amd64.c b/libs/ir2mcode/src/ir2amd64.c index 1b35389..cfd741f 100644 --- a/libs/ir2mcode/src/ir2amd64.c +++ b/libs/ir2mcode/src/ir2amd64.c @@ -3,10 +3,12 @@ #include #include +#define GET_MODULE(ctx) (&(ctx->cprog->module)) + static void parse_location(scc_ir2mcode_ctx_t *ctx, scc_reg_loc_t *loc, scc_ir_node_ref_t node_ref) { Assert(ctx != null && loc != null); - scc_ir_node_t *node = scc_ir_ctx_get_node(ctx->ir_ctx, node_ref); + scc_ir_node_t *node = scc_ir_module_get_node(GET_MODULE(ctx), node_ref); if (node == null) { LOG_FATAL("invalid node ref"); UNREACHABLE(); @@ -15,9 +17,10 @@ static void parse_location(scc_ir2mcode_ctx_t *ctx, scc_reg_loc_t *loc, usize idx = 0; switch (node->tag) { case SCC_IR_NODE_CONST_INT: - scc_ir_type_t *type = scc_ir_ctx_get_type(ctx->ir_ctx, node->type); + scc_ir_type_t *type = + scc_ir_module_get_type(GET_MODULE(ctx), node->type); Assert(type != 0); - Assert(type->tag == SCC_IR_TYPE_U32 || type->tag == SCC_IR_TYPE_I32); + Assert(type->tag == SCC_IR_TYPE_u32 || type->tag == SCC_IR_TYPE_i32); *loc = (scc_reg_loc_t){ .kind = SCC_REG_KIND_IMM, .idx = (usize)node->data.const_int.int32, @@ -28,7 +31,8 @@ static void parse_location(scc_ir2mcode_ctx_t *ctx, scc_reg_loc_t *loc, TODO(); break; case SCC_IR_NODE_FUNC_ARG_REF: { - scc_ir_type_t *type = scc_ir_ctx_get_type(ctx->ir_ctx, node->type); + scc_ir_type_t *type = + scc_ir_module_get_type(GET_MODULE(ctx), node->type); Assert(type != 0); scc_reg_loc_t arg_loc; // arg_loc.kind = SCC_REG_KIND_FUNC_ARG; @@ -101,7 +105,7 @@ typedef SCC_VEC(patch_t) patch_vec_t; static void parse_node(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref, patch_vec_t *patches) { - scc_ir_node_t *node = scc_ir_ctx_get_node(ctx->ir_ctx, node_ref); + scc_ir_node_t *node = scc_ir_module_get_node(GET_MODULE(ctx), node_ref); if (node == null) { LOG_ERROR("invalid node ref"); return; @@ -126,8 +130,8 @@ static void parse_node(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref, scc_reg_loc_t to; parse_location(ctx, &from, node->data.load.target); parse_location(ctx, &to, node_ref); - load_value_to_reg(&ctx->mcode, &from, SCC_AMD64_RAX); - store_value_from_reg(&ctx->mcode, &to, SCC_AMD64_RAX); + load_value_to_reg(&ctx->sect_mcode, &from, SCC_AMD64_RAX); + store_value_from_reg(&ctx->sect_mcode, &to, SCC_AMD64_RAX); break; } case SCC_IR_NODE_STORE: ///< 存储数据 @@ -136,8 +140,8 @@ static void parse_node(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref, scc_reg_loc_t to; parse_location(ctx, &from, node->data.store.value); parse_location(ctx, &to, node->data.store.target); - load_value_to_reg(&ctx->mcode, &from, SCC_AMD64_RAX); - store_value_from_reg(&ctx->mcode, &to, SCC_AMD64_RAX); + load_value_to_reg(&ctx->sect_mcode, &from, SCC_AMD64_RAX); + store_value_from_reg(&ctx->sect_mcode, &to, SCC_AMD64_RAX); break; } case SCC_IR_NODE_GET_PTR: ///< 获取指针 @@ -153,20 +157,20 @@ static void parse_node(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref, parse_location(ctx, &loc_res, node_ref); // 将左操作数加载到 RAX(临时结果寄存器) - load_value_to_reg(&ctx->mcode, &loc_lhs, SCC_AMD64_RAX); + load_value_to_reg(&ctx->sect_mcode, &loc_lhs, SCC_AMD64_RAX); // 将右操作数加载到 RCX - load_value_to_reg(&ctx->mcode, &loc_rhs, SCC_AMD64_RCX); + load_value_to_reg(&ctx->sect_mcode, &loc_rhs, SCC_AMD64_RCX); switch (node->data.op.op) { case SCC_IR_OP_ADD: - scc_mcode_amd64_add_r64_r64(&ctx->mcode, SCC_AMD64_RAX, + scc_mcode_amd64_add_r64_r64(&ctx->sect_mcode, SCC_AMD64_RAX, SCC_AMD64_RCX); break; case SCC_IR_OP_SUB: - scc_mcode_amd64_sub_r64_r64(&ctx->mcode, SCC_AMD64_RAX, + scc_mcode_amd64_sub_r64_r64(&ctx->sect_mcode, SCC_AMD64_RAX, SCC_AMD64_RCX); break; case SCC_IR_OP_MUL: - scc_mcode_amd64_mul_r64(&ctx->mcode, SCC_AMD64_RCX); + scc_mcode_amd64_mul_r64(&ctx->sect_mcode, SCC_AMD64_RCX); break; // [SCC_IR_OP_EMPTY] = "empty", [SCC_IR_OP_NEQ] = "!=", // [SCC_IR_OP_EQ] = "==", [SCC_IR_OP_GT] = ">", @@ -179,51 +183,51 @@ static void parse_node(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref, // [SCC_IR_OP_SHL] = "<<", [SCC_IR_OP_SHR] = ">>", // [SCC_IR_OP_SAR] = ">>a", // Arithmetic shift right case SCC_IR_OP_NEQ: - scc_mcode_amd64_cmp_r64_r64(&ctx->mcode, SCC_AMD64_RAX, + scc_mcode_amd64_cmp_r64_r64(&ctx->sect_mcode, SCC_AMD64_RAX, SCC_AMD64_RCX); - scc_mcode_amd64_setcc_r8(&ctx->mcode, SCC_AMD64_COND_NE, + scc_mcode_amd64_setcc_r8(&ctx->sect_mcode, SCC_AMD64_COND_NE, SCC_AMD64_RAX); - scc_mcode_amd64_movzx_r64_r8(&ctx->mcode, SCC_AMD64_RAX, + scc_mcode_amd64_movzx_r64_r8(&ctx->sect_mcode, SCC_AMD64_RAX, SCC_AMD64_RAX); break; case SCC_IR_OP_EQ: - scc_mcode_amd64_cmp_r64_r64(&ctx->mcode, SCC_AMD64_RAX, + scc_mcode_amd64_cmp_r64_r64(&ctx->sect_mcode, SCC_AMD64_RAX, SCC_AMD64_RCX); - scc_mcode_amd64_setcc_r8(&ctx->mcode, SCC_AMD64_COND_E, + scc_mcode_amd64_setcc_r8(&ctx->sect_mcode, SCC_AMD64_COND_E, SCC_AMD64_RAX); - scc_mcode_amd64_movzx_r64_r8(&ctx->mcode, SCC_AMD64_RAX, + scc_mcode_amd64_movzx_r64_r8(&ctx->sect_mcode, SCC_AMD64_RAX, SCC_AMD64_RAX); break; case SCC_IR_OP_GT: - scc_mcode_amd64_cmp_r64_r64(&ctx->mcode, SCC_AMD64_RAX, + scc_mcode_amd64_cmp_r64_r64(&ctx->sect_mcode, SCC_AMD64_RAX, SCC_AMD64_RCX); - scc_mcode_amd64_setcc_r8(&ctx->mcode, SCC_AMD64_COND_G, + scc_mcode_amd64_setcc_r8(&ctx->sect_mcode, SCC_AMD64_COND_G, SCC_AMD64_RAX); - scc_mcode_amd64_movzx_r64_r8(&ctx->mcode, SCC_AMD64_RAX, + scc_mcode_amd64_movzx_r64_r8(&ctx->sect_mcode, SCC_AMD64_RAX, SCC_AMD64_RAX); break; case SCC_IR_OP_LT: - scc_mcode_amd64_cmp_r64_r64(&ctx->mcode, SCC_AMD64_RAX, + scc_mcode_amd64_cmp_r64_r64(&ctx->sect_mcode, SCC_AMD64_RAX, SCC_AMD64_RCX); - scc_mcode_amd64_setcc_r8(&ctx->mcode, SCC_AMD64_COND_L, + scc_mcode_amd64_setcc_r8(&ctx->sect_mcode, SCC_AMD64_COND_L, SCC_AMD64_RAX); - scc_mcode_amd64_movzx_r64_r8(&ctx->mcode, SCC_AMD64_RAX, + scc_mcode_amd64_movzx_r64_r8(&ctx->sect_mcode, SCC_AMD64_RAX, SCC_AMD64_RAX); break; case SCC_IR_OP_GE: - scc_mcode_amd64_cmp_r64_r64(&ctx->mcode, SCC_AMD64_RAX, + scc_mcode_amd64_cmp_r64_r64(&ctx->sect_mcode, SCC_AMD64_RAX, SCC_AMD64_RCX); - scc_mcode_amd64_setcc_r8(&ctx->mcode, SCC_AMD64_COND_GE, + scc_mcode_amd64_setcc_r8(&ctx->sect_mcode, SCC_AMD64_COND_GE, SCC_AMD64_RAX); - scc_mcode_amd64_movzx_r64_r8(&ctx->mcode, SCC_AMD64_RAX, + scc_mcode_amd64_movzx_r64_r8(&ctx->sect_mcode, SCC_AMD64_RAX, SCC_AMD64_RAX); break; case SCC_IR_OP_LE: - scc_mcode_amd64_cmp_r64_r64(&ctx->mcode, SCC_AMD64_RAX, + scc_mcode_amd64_cmp_r64_r64(&ctx->sect_mcode, SCC_AMD64_RAX, SCC_AMD64_RCX); - scc_mcode_amd64_setcc_r8(&ctx->mcode, SCC_AMD64_COND_LE, + scc_mcode_amd64_setcc_r8(&ctx->sect_mcode, SCC_AMD64_COND_LE, SCC_AMD64_RAX); - scc_mcode_amd64_movzx_r64_r8(&ctx->mcode, SCC_AMD64_RAX, + scc_mcode_amd64_movzx_r64_r8(&ctx->sect_mcode, SCC_AMD64_RAX, SCC_AMD64_RAX); break; default: @@ -231,7 +235,7 @@ static void parse_node(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref, break; } // 将 RAX 中的结果存储到 res 位置 - store_value_from_reg(&ctx->mcode, &loc_res, SCC_AMD64_RAX); + store_value_from_reg(&ctx->sect_mcode, &loc_res, SCC_AMD64_RAX); break; } ///< 有条件分支 @@ -239,16 +243,16 @@ static void parse_node(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref, scc_reg_loc_t loc; parse_location(ctx, &loc, node->data.branch.cond); // (void)loc; - load_value_to_reg(&ctx->mcode, &loc, SCC_AMD64_RAX); - scc_mcode_amd64_cmp_r64_imm32(&ctx->mcode, SCC_AMD64_RAX, 0); + load_value_to_reg(&ctx->sect_mcode, &loc, SCC_AMD64_RAX); + scc_mcode_amd64_cmp_r64_imm32(&ctx->sect_mcode, SCC_AMD64_RAX, 0); - scc_mcode_amd64_jcc_rel32(&ctx->mcode, SCC_AMD64_COND_NE, 0); - patch_t patch_true = {.pos = scc_vec_size(ctx->mcode.mcode), + scc_mcode_amd64_jcc_rel32(&ctx->sect_mcode, SCC_AMD64_COND_NE, 0); + patch_t patch_true = {.pos = scc_vec_size(ctx->sect_mcode.mcode), .target_bb_ref = (usize)node->data.branch.true_bblock}; scc_vec_push(*patches, patch_true); - scc_mcode_amd64_jmp_rel32(&ctx->mcode, 0); - patch_t patch_false = {.pos = scc_vec_size(ctx->mcode.mcode), + scc_mcode_amd64_jmp_rel32(&ctx->sect_mcode, 0); + patch_t patch_false = {.pos = scc_vec_size(ctx->sect_mcode.mcode), .target_bb_ref = (usize)node->data.branch.false_bblock}; scc_vec_push(*patches, patch_false); @@ -256,8 +260,8 @@ static void parse_node(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref, } ///< 无条件跳转 case SCC_IR_NODE_JUMP: { - scc_mcode_amd64_jmp_rel32(&ctx->mcode, 0); - usize pos = scc_vec_size(ctx->mcode.mcode); + scc_mcode_amd64_jmp_rel32(&ctx->sect_mcode, 0); + usize pos = scc_vec_size(ctx->sect_mcode.mcode); patch_t patch = {.pos = pos, .target_bb_ref = (usize)node->data.jump.target_bblock}; scc_vec_push(*patches, patch); @@ -277,13 +281,13 @@ static void parse_node(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref, scc_vec_foreach(node->data.call.args, i) { parse_location(ctx, &loc, scc_vec_at(node->data.call.args, i)); if (i == 0) { - load_value_to_reg(&ctx->mcode, &loc, SCC_AMD64_RCX); + load_value_to_reg(&ctx->sect_mcode, &loc, SCC_AMD64_RCX); } else if (i == 1) { - load_value_to_reg(&ctx->mcode, &loc, SCC_AMD64_RDX); + load_value_to_reg(&ctx->sect_mcode, &loc, SCC_AMD64_RDX); } else if (i == 2) { - load_value_to_reg(&ctx->mcode, &loc, SCC_AMD64_R8); + load_value_to_reg(&ctx->sect_mcode, &loc, SCC_AMD64_R8); } else if (i == 3) { - load_value_to_reg(&ctx->mcode, &loc, SCC_AMD64_R9); + load_value_to_reg(&ctx->sect_mcode, &loc, SCC_AMD64_R9); } else { LOG_FATAL("not support more than 4 args"); } @@ -291,32 +295,33 @@ static void parse_node(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref, } scc_ir_func_t *func = - scc_ir_ctx_get_func(ctx->ir_ctx, node->data.call.callee); + scc_ir_module_get_func(GET_MODULE(ctx), node->data.call.callee); if (!func) { LOG_ERROR("invalid function reference"); return; } - scc_mcode_amd64_call_rel32(&ctx->mcode, 0); - usize sym_idx = sccf_builder_get_symbol_idx(&ctx->builder, func->name); + scc_mcode_amd64_call_rel32(&ctx->sect_mcode, 0); + usize sym_idx = sccf_builder_get_symbol_idx(ctx->builder, func->name); Assert(sym_idx != 0); - sccf_builder_add_reloc(&ctx->builder, - (sccf_reloc_t){ - .reloc_type = SCCF_RELOC_TYPE_REL, - .offset = scc_vec_size(ctx->mcode.mcode) - 4, - .addend = 4, - .sect_type = SCCF_SECT_CODE, - .sym_idx = sym_idx, - }); + sccf_builder_add_reloc( + ctx->builder, (sccf_reloc_t){ + .reloc_type = SCCF_RELOC_TYPE_REL, + .offset = scc_vec_size(ctx->sect_mcode.mcode) - 4, + .addend = 4, + .sect_type = SCCF_SECT_CODE, + .sym_idx = sym_idx, + }); // 处理返回值 - scc_ir_type_t *func_type = scc_ir_ctx_get_type(ctx->ir_ctx, func->type); + scc_ir_type_t *func_type = + scc_ir_module_get_type(GET_MODULE(ctx), func->type); Assert(func_type); - scc_ir_type_t *ret_type = - scc_ir_ctx_get_type(ctx->ir_ctx, func_type->data.function.ret_type); - if (ret_type && ret_type->tag != SCC_IR_TYPE_VOID) { + scc_ir_type_t *ret_type = scc_ir_module_get_type( + GET_MODULE(ctx), func_type->data.function.ret_type); + if (ret_type && ret_type->tag != SCC_IR_TYPE_void) { parse_location(ctx, &loc, node_ref); - store_value_from_reg(&ctx->mcode, &loc, SCC_AMD64_RAX); + store_value_from_reg(&ctx->sect_mcode, &loc, SCC_AMD64_RAX); } break; } @@ -325,11 +330,11 @@ static void parse_node(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref, if (node->data.ret.ret_val) { scc_reg_loc_t loc; parse_location(ctx, &loc, node->data.ret.ret_val); - load_value_to_reg(&ctx->mcode, &loc, SCC_AMD64_RAX); + load_value_to_reg(&ctx->sect_mcode, &loc, SCC_AMD64_RAX); } - scc_mcode_amd64_add_rsp_imm32(&ctx->mcode, ctx->stack_size); - scc_mcode_amd64_pop_r64(&ctx->mcode, SCC_AMD64_RBP); - scc_mcode_amd64_ret(&ctx->mcode); + scc_mcode_amd64_add_rsp_imm32(&ctx->sect_mcode, ctx->stack_size); + scc_mcode_amd64_pop_r64(&ctx->sect_mcode, SCC_AMD64_RBP); + scc_mcode_amd64_ret(&ctx->sect_mcode); break; } default: @@ -374,24 +379,24 @@ static void parse_function(scc_ir2mcode_ctx_t *ctx, scc_ir_func_t *func) { patch_vec_t patches; scc_vec_init(patches); - scc_mcode_amd64_push_r64(&ctx->mcode, SCC_AMD64_RBP); - scc_mcode_amd64_sub_rsp_imm32(&ctx->mcode, ctx->stack_size); - scc_mcode_amd64_lea_r64_m64_disp32(&ctx->mcode, SCC_AMD64_RBP, + scc_mcode_amd64_push_r64(&ctx->sect_mcode, SCC_AMD64_RBP); + scc_mcode_amd64_sub_rsp_imm32(&ctx->sect_mcode, ctx->stack_size); + scc_mcode_amd64_lea_r64_m64_disp32(&ctx->sect_mcode, SCC_AMD64_RBP, SCC_AMD64_RSP, ctx->stack_size); scc_reg_loc_t loc; scc_vec_foreach(func->params, i) { // scc_ir_node_t *param = - // scc_ir_ctx_get_node(ctx->ir_ctx, ); + // scc_ir_module_get_node(GET_MODULE(ctx), ); scc_ir_node_ref_t node_ref = scc_vec_at(func->params, i); parse_location(ctx, &loc, node_ref); if (i == 0) { - store_value_from_reg(&ctx->mcode, &loc, SCC_AMD64_RCX); + store_value_from_reg(&ctx->sect_mcode, &loc, SCC_AMD64_RCX); } else if (i == 1) { - store_value_from_reg(&ctx->mcode, &loc, SCC_AMD64_RDX); + store_value_from_reg(&ctx->sect_mcode, &loc, SCC_AMD64_RDX); } else if (i == 2) { - store_value_from_reg(&ctx->mcode, &loc, SCC_AMD64_R8); + store_value_from_reg(&ctx->sect_mcode, &loc, SCC_AMD64_R8); } else if (i == 3) { - store_value_from_reg(&ctx->mcode, &loc, SCC_AMD64_R9); + store_value_from_reg(&ctx->sect_mcode, &loc, SCC_AMD64_R9); } else { LOG_FATAL("not support more than 4 args"); } @@ -401,19 +406,19 @@ static void parse_function(scc_ir2mcode_ctx_t *ctx, scc_ir_func_t *func) { for (usize i = 0; i < scc_vec_size(func->bblocks); i++) { scc_ir_bblock_ref_t bblock_ref = scc_vec_at(func->bblocks, i); scc_ir_bblock_t *bblock = - scc_ir_ctx_get_bblock(ctx->ir_ctx, bblock_ref); + scc_ir_module_get_bblock(GET_MODULE(ctx), bblock_ref); if (bblock == null) { LOG_FATAL("\n"); return; } - bblock_offsets[i] = scc_vec_size(ctx->mcode.mcode); + bblock_offsets[i] = scc_vec_size(ctx->sect_mcode.mcode); parse_bblock(ctx, bblock, &patches); } // 回填所有跳转偏移 - u8 *buf = scc_vec_unsafe_get_data(ctx->mcode.mcode); + u8 *buf = scc_vec_unsafe_get_data(ctx->sect_mcode.mcode); scc_vec_foreach(patches, idx) { patch_t *p = &scc_vec_at(patches, idx); usize target_id = @@ -430,11 +435,12 @@ static void parse_function(scc_ir2mcode_ctx_t *ctx, scc_ir_func_t *func) { } void scc_ir2amd64(scc_ir2mcode_ctx_t *ctx) { - scc_reg_alloc_init(&ctx->reg_alloc, scc_reg_alloc_with_stack, ctx->ir_ctx); + scc_reg_alloc_init(&ctx->reg_alloc, scc_reg_alloc_with_stack, + GET_MODULE(ctx)); scc_vec_foreach(ctx->cprog->func_decls, i) { scc_ir_node_ref_t func_ref = scc_vec_at(ctx->cprog->func_decls, i); - scc_ir_func_t *func = scc_ir_ctx_get_func(ctx->ir_ctx, func_ref); + scc_ir_func_t *func = scc_ir_module_get_func(GET_MODULE(ctx), func_ref); if (!func) { LOG_ERROR("invalid function reference"); return; @@ -460,40 +466,31 @@ void scc_ir2amd64(scc_ir2mcode_ctx_t *ctx) { .sccf_sym_vis = SCCF_SYM_VIS_DEFAULT, }; } - usize sym_idx = - sccf_builder_add_symbol(&ctx->builder, func->name, &sym); + usize sym_idx = sccf_builder_add_symbol(ctx->builder, func->name, &sym); Assert(sym_idx != 0); } scc_vec_foreach(ctx->cprog->func_defs, i) { scc_ir_node_ref_t func_ref = scc_vec_at(ctx->cprog->func_defs, i); - scc_ir_func_t *func = scc_ir_ctx_get_func(ctx->ir_ctx, func_ref); + scc_ir_func_t *func = scc_ir_module_get_func(GET_MODULE(ctx), func_ref); if (!func) { LOG_ERROR("invalid function reference"); return; } sccf_sym_t *sym = - sccf_builder_get_symbol_unsafe(&ctx->builder, func->name); + sccf_builder_get_symbol_unsafe(ctx->builder, func->name); Assert(sym != null); - sym->sccf_sect_offset = scc_vec_size(ctx->mcode.mcode); + sym->sccf_sect_offset = scc_vec_size(ctx->sect_mcode.mcode); parse_function(ctx, func); } - sccf_sect_data_t text_section; - scc_vec_unsafe_from_buffer(text_section, - scc_vec_unsafe_get_data(ctx->mcode.mcode), - scc_vec_size(ctx->mcode.mcode)); - sccf_builder_add_text_section(&ctx->builder, &text_section); - sccf_sect_data_t data_section; - scc_vec_init(data_section); - sccf_builder_add_data_section(&ctx->builder, &data_section); - u8 *buf = scc_vec_unsafe_get_data(ctx->mcode.mcode); - scc_vec_foreach(ctx->builder.relocs, i) { - sccf_reloc_t *reloc = &scc_vec_at(ctx->builder.relocs, i); + u8 *buf = scc_vec_unsafe_get_data(ctx->sect_mcode.mcode); + scc_vec_foreach(ctx->builder->relocs, i) { + sccf_reloc_t *reloc = &scc_vec_at(ctx->builder->relocs, i); if (reloc->sym_idx == 0) { Panic("relocate to an invalid symbol"); } - sccf_sym_t *sym = &scc_vec_at(ctx->builder.symtab, reloc->sym_idx); + sccf_sym_t *sym = &scc_vec_at(ctx->builder->symtab, reloc->sym_idx); if (sym->sccf_sym_type != SCCF_SYM_TYPE_EXTERN) { Assert(reloc->reloc_type == SCCF_RELOC_TYPE_REL); @@ -508,6 +505,15 @@ void scc_ir2amd64(scc_ir2mcode_ctx_t *ctx) { reloc->reloc_type = SCCF_RELOC_TYPE_EMPTY; } } + + sccf_sect_data_t text_section; + scc_vec_unsafe_from_buffer(text_section, + scc_vec_unsafe_get_data(ctx->sect_mcode.mcode), + scc_vec_size(ctx->sect_mcode.mcode)); + sccf_builder_add_text_section(ctx->builder, &text_section); + sccf_sect_data_t data_section; + scc_vec_init(data_section); + sccf_builder_add_data_section(ctx->builder, &data_section); // FIXME - ctx->builder.entry_symbol_name = "main"; + ctx->builder->entry_symbol_name = "main"; } diff --git a/libs/ir2mcode/src/reg_alloc.c b/libs/ir2mcode/src/reg_alloc.c index 024b72f..a747a2e 100644 --- a/libs/ir2mcode/src/reg_alloc.c +++ b/libs/ir2mcode/src/reg_alloc.c @@ -6,10 +6,10 @@ int equal_func(const void *key1, const void *key2) { } void scc_reg_alloc_init(scc_reg_alloc_t *ctx, scc_reg_alloc_func_t func, - scc_ir_cprog_ctx_t *ir_ctx) { + scc_ir_module_t *ir_module) { ctx->gpr_caller_saved = 0; ctx->gpr_callee_saved = 0; - ctx->ir_ctx = ir_ctx; + ctx->ir_module = ir_module; ctx->reg_alloc_func = func; ctx->alloc_stack_size = 0; @@ -37,16 +37,18 @@ scc_hashtable_t *scc_reg_alloc_with_stack(scc_reg_alloc_t *ctx, scc_vec_foreach(func->bblocks, i) { scc_ir_bblock_ref_t bblock_ref = scc_vec_at(func->bblocks, i); scc_ir_bblock_t *bblock = - scc_ir_ctx_get_bblock(ctx->ir_ctx, bblock_ref); + scc_ir_module_get_bblock(ctx->ir_module, bblock_ref); Assert(bblock != null); scc_vec_foreach(bblock->instrs, j) { scc_ir_node_ref_t node_ref = scc_vec_at(bblock->instrs, j); - scc_ir_node_t *node = scc_ir_ctx_get_node(ctx->ir_ctx, node_ref); + scc_ir_node_t *node = + scc_ir_module_get_node(ctx->ir_module, node_ref); Assert(node != null); loc.kind = SCC_REG_KIND_UNDEF; switch (node->tag) { case SCC_IR_NODE_LOAD: case SCC_IR_NODE_OP: + case SCC_IR_NODE_ALLOC: { loc.kind = SCC_REG_KIND_STACK; loc.idx = ctx->alloc_stack_size; @@ -61,11 +63,11 @@ scc_hashtable_t *scc_reg_alloc_with_stack(scc_reg_alloc_t *ctx, case SCC_IR_NODE_CALL: { // 处理返回值 scc_ir_type_t *func_type = - scc_ir_ctx_get_type(ctx->ir_ctx, func->type); + scc_ir_module_get_type(ctx->ir_module, func->type); Assert(func_type); - scc_ir_type_t *ret_type = scc_ir_ctx_get_type( - ctx->ir_ctx, func_type->data.function.ret_type); - if (ret_type && ret_type->tag != SCC_IR_TYPE_VOID) { + scc_ir_type_t *ret_type = scc_ir_module_get_type( + ctx->ir_module, func_type->data.function.ret_type); + if (ret_type && ret_type->tag != SCC_IR_TYPE_void) { loc.kind = SCC_REG_KIND_STACK; loc.idx = ctx->alloc_stack_size; ctx->alloc_stack_size += 8; diff --git a/libs/ir2mcode/src/scc_ir2mcode.c b/libs/ir2mcode/src/scc_ir2mcode.c index 7bf2c49..a5b661b 100644 --- a/libs/ir2mcode/src/scc_ir2mcode.c +++ b/libs/ir2mcode/src/scc_ir2mcode.c @@ -1,12 +1,16 @@ #include void scc_ir2mcode_init(scc_ir2mcode_ctx_t *ctx, scc_ir_cprog_t *cprog, - scc_ir_cprog_ctx_t *ir_ctx, scc_mcode_arch_t arch) { + sccf_builder_t *builder, scc_mcode_arch_t arch) { ctx->cprog = cprog; - ctx->ir_ctx = ir_ctx; - scc_mcode_init(&ctx->mcode, arch); - sccf_builder_init(&ctx->builder); + ctx->builder = builder; + scc_mcode_init(&ctx->sect_mcode, arch); + scc_vec_init(ctx->sect_data); + sccf_builder_init(ctx->builder); } +void scc_ir2mcode_drop(scc_ir2mcode_ctx_t *ctx) {} + void scc_ir2amd64(scc_ir2mcode_ctx_t *ctx); + void scc_ir2mcode(scc_ir2mcode_ctx_t *ctx) { scc_ir2amd64(ctx); } diff --git a/libs/ir2mcode/tests/test_run.c b/libs/ir2mcode/tests/test_run.c index a8bb1eb..df3a0e0 100644 --- a/libs/ir2mcode/tests/test_run.c +++ b/libs/ir2mcode/tests/test_run.c @@ -31,15 +31,20 @@ void test_example(const char *input, cbool need_sema, const char *name) { scc_ast2ir_ctx_t ast2ir_ctx; #include - scc_ast2ir_ctx_init(&ast2ir_ctx, scc_win_x64_type_abi); + scc_ir_cprog_t cprog; + scc_ir_cprog_init(&cprog); + scc_ast2ir_ctx_init(&ast2ir_ctx, scc_win_x64_type_abi, &cprog); scc_ast2ir_translation_unit(&ast2ir_ctx, tu); + scc_ast2ir_ctx_drop(&ast2ir_ctx); - scc_ir2mcode_ctx_t mcode_ctx; - scc_ir2mcode_init(&mcode_ctx, &ast2ir_ctx.builder.cprog, - &ast2ir_ctx.builder.ctx, SCC_MCODE_ARCH_AMD64); - scc_ir2mcode(&mcode_ctx); + scc_ir2mcode_ctx_t ir2mcode_ctx; + sccf_builder_t sccf_builder; + scc_ir2mcode_init(&ir2mcode_ctx, &cprog, &sccf_builder, + SCC_MCODE_ARCH_AMD64); + scc_ir2mcode(&ir2mcode_ctx); + scc_ir2mcode_drop(&ir2mcode_ctx); - const sccf_t *sccf = sccf_builder_to_sccf(&mcode_ctx.builder); + const sccf_t *sccf = sccf_builder_to_sccf(&sccf_builder); scc_pe_builder_t pe_builder; sccf2pe(&pe_builder, sccf); @@ -82,6 +87,24 @@ int main() { "int main(void) {\n" " return add(1, 2);\n" "}\n", - true, "10_call.exe"); + true, "10_main.exe"); + test_example("int factorial(int);\n" + "\n" + "int main() {\n" + " int num = 5;\n" + " int result = factorial(num);\n" + " // printf(\"%d\", result);\n" + " return result;\n" + "}\n" + "\n" + "int factorial(int num) {\n" + " if (num == 0) {\n" + " return 1;\n" + " } else {\n" + " return num * factorial(num - 1);\n" + " }\n" + "}\n", + true, "11_recursion.exe"); + return 0; } diff --git a/src/main.c b/src/main.c index 8090a1c..b349e05 100644 --- a/src/main.c +++ b/src/main.c @@ -208,8 +208,11 @@ sstream_drop: scc_ast2ir_ctx_t ast2ir_ctx; #include - scc_ast2ir_ctx_init(&ast2ir_ctx, scc_win_x64_type_abi); + scc_ir_cprog_t cprog; + scc_ir_cprog_init(&cprog); + scc_ast2ir_ctx_init(&ast2ir_ctx, scc_win_x64_type_abi, &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; @@ -221,21 +224,21 @@ sstream_drop: scc_tree_dump_ctx_init(&tree_dump, false, (void *)scc_fprintf, (void *)fp); } - scc_ir_dump_ctx_init(&ir_dump_ctx, &tree_dump, - &ast2ir_ctx.builder.cprog, - &ast2ir_ctx.builder.ctx); + scc_ir_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_tree_dump_ctx_drop(&tree_dump); return 0; } - scc_ir2mcode_ctx_t mcode_ctx; - scc_ir2mcode_init(&mcode_ctx, &ast2ir_ctx.builder.cprog, - &ast2ir_ctx.builder.ctx, SCC_MCODE_ARCH_AMD64); - scc_ir2mcode(&mcode_ctx); + scc_ir2mcode_ctx_t ir2mcode_ctx; + sccf_builder_t sccf_builder; + scc_ir2mcode_init(&ir2mcode_ctx, &cprog, &sccf_builder, + SCC_MCODE_ARCH_AMD64); + scc_ir2mcode(&ir2mcode_ctx); + scc_ir2mcode_drop(&ir2mcode_ctx); - const sccf_t *sccf = sccf_builder_to_sccf(&mcode_ctx.builder); + const sccf_t *sccf = sccf_builder_to_sccf(&sccf_builder); scc_pe_builder_t pe_builder; sccf2pe(&pe_builder, sccf);