From b06c4fe3cc628a3300f040fd3032972fb331e38c Mon Sep 17 00:00:00 2001 From: zzy <2450266535@qq.com> Date: Fri, 1 May 2026 22:51:31 +0800 Subject: [PATCH] =?UTF-8?q?feat(ast2ir):=20=E6=B7=BB=E5=8A=A0AST=E4=B8=8A?= =?UTF-8?q?=E4=B8=8B=E6=96=87=E6=94=AF=E6=8C=81=E5=B9=B6=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E8=BD=AC=E6=8D=A2=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在scc_ast2ir_ctx_t中添加ast_ctx字段用于访问AST上下文 - 修改scc_ast2ir_ctx_init函数签名以接收ast_ctx参数 - 修复enum类型的处理逻辑,使用正确的内置类型获取方式 - 修正for循环控制流中错误的跳转目标 - 移除未使用的parse_struct_union_layout函数 refactor(cfg): 优化模块接口的const正确性 - 将scc_cfg_module_unsafe_get_*系列函数的module参数标记为const - 提高接口的安全性和一致性 refactor(lir): 简化寄存器定义宏 - 移除未使用的SCC_LIR_PREG宏定义 - 简化头文件中的冗余声明 fix(hir2lir): 修复空指针常量的表示方式 - 修正NULL值的AP整数表示,正确初始化ap结构体字段 - 确保空指针在低级IR中被正确表示 refactor(mir): 重构函数元数据结构 - 为MIR函数元数据添加栈槽位和寄存器分配相关字段 - 定义新的栈槽位数据结构scc_mir_stack_slot_t - 添加函数元数据初始化函数scc_mir_func_meta_init refactor(x86): 改进后端代码生成 - 修正ret指令生成,使用近返回指令RET_NEAR - 修复伪alloca指令的形式转换问题 - 改进选择函数的const正确性 - 正确初始化函数元数据结构 style(config): 添加MIR阶段配置选项 - 为MIR各个处理阶段添加配置标志 - 包括寄存器分配、栈布局和前言后记生成的输出选项 fix(parser): 改进错误处理机制 - 修正语义分析上下文变量命名 - 添加解析错误码检查,及时返回错误状态 --- libs/ast2ir/include/scc_ast2ir.h | 4 +++- libs/ast2ir/src/scc_ast2ir.c | 26 +++++++++++++------------- libs/ir/cfg/include/scc_cfg.h | 12 +++++++----- libs/ir/cfg/src/scc_cfg.c | 12 +++++++----- libs/ir/lir/include/scc_lir.h | 2 -- libs/ir/lir/src/scc_hir2lir.c | 5 ++++- libs/ir/mir/include/scc_lir2mir.h | 3 +++ libs/ir/mir/include/scc_mir.h | 15 ++++++++++++++- libs/ir/mir/src/mir_x86.c | 19 ++++++++++++++----- libs/ir/mir/src/scc_lir2mir.c | 2 +- libs/ir/mir/src/scc_mir.c | 9 +++++++++ libs/ir/mir/src/scc_mir_pass.c | 2 ++ src/config.h | 4 ++++ src/main.c | 13 ++++++++----- 14 files changed, 89 insertions(+), 39 deletions(-) diff --git a/libs/ast2ir/include/scc_ast2ir.h b/libs/ast2ir/include/scc_ast2ir.h index b2d7a79..ec6ac75 100644 --- a/libs/ast2ir/include/scc_ast2ir.h +++ b/libs/ast2ir/include/scc_ast2ir.h @@ -14,10 +14,12 @@ typedef struct { // scc_strpool_t strpool; ///< string pool const scc_abi_type_calc_t *abi; cbool hint_using_value; // 转换时尽可能使用value而不是alloc + + scc_ast_ctx_t *ast_ctx; } scc_ast2ir_ctx_t; void scc_ast2ir_ctx_init(scc_ast2ir_ctx_t *ctx, const scc_abi_type_calc_t *abi, - scc_hir_cprog_t *cprog); + scc_ast_ctx_t *ast_ctx, scc_hir_cprog_t *cprog); void scc_ast2ir_ctx_drop(scc_ast2ir_ctx_t *ctx); void scc_ast2ir_run(scc_ast2ir_ctx_t *ctx, diff --git a/libs/ast2ir/src/scc_ast2ir.c b/libs/ast2ir/src/scc_ast2ir.c index ff35174..23d85c7 100644 --- a/libs/ast2ir/src/scc_ast2ir.c +++ b/libs/ast2ir/src/scc_ast2ir.c @@ -27,7 +27,7 @@ static scc_hir_type_ref_t parse_base_type(scc_ast2ir_ctx_t *ctx, return SCC_HIR_REF_nullptr; } -static inline void parse_struct_union_layout(scc_ast_qual_type_t *type) {} +// static inline void parse_struct_union_layout(scc_ast_qual_type_t *type) {} // 辅助函数:计算数组实际长度(如果原长度为0) static void resolve_array_length(scc_ast2ir_ctx_t *ctx, @@ -163,8 +163,7 @@ scc_hir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx, // FIXME hack ir_type.data.array.len = value.data.digit; } - break; - } + } break; case SCC_AST_TYPE_FUNCTION: { scc_hir_type_init(&ir_type, SCC_HIR_TYPE_FUNC); @@ -187,8 +186,7 @@ scc_hir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx, scc_vec_push(params, tmp_type); } ir_type.data.function.params = params; - break; - } + } break; case SCC_AST_TYPE_STRUCT: case SCC_AST_TYPE_UNION: { scc_hir_type_init(&ir_type, ast_type->base.type == SCC_AST_TYPE_STRUCT @@ -207,15 +205,13 @@ scc_hir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx, scc_ast2ir_type(ctx, decl_field->var.type); scc_vec_push(ir_type.data.aggregate.fields, field_type); } - break; - } + } break; case SCC_AST_TYPE_ENUM: - scc_ast_canon_type_t int_canon_type = { - .builtin = SCC_AST_BUILTIN_TYPE_INT, - }; + scc_ast_canon_type_t *int_canon_type = scc_ast_ctx_get_builtin_type( + ctx->ast_ctx, SCC_AST_BUILTIN_TYPE_INT); scc_ast_qual_type_t int_type = { .base.type = SCC_AST_TYPE_BUILTIN, - .type = &int_canon_type, + .type = int_canon_type, }; return parse_base_type(ctx, &int_type); case SCC_AST_TYPE_TYPEDEF: @@ -883,7 +879,7 @@ void scc_ast2ir_stmt(scc_ast2ir_ctx_t *ctx, const scc_ast_stmt_t *stmt) { if (stmt->for_stmt.incr) { scc_ast2ir_expr(ctx, stmt->for_stmt.incr, false); } - scc_hir_builder_jump(&ctx->builder, exit_block); + scc_hir_builder_jump(&ctx->builder, cond_block); scc_hir_builder_set_current_bblock(&ctx->builder, exit_block); break; @@ -1124,9 +1120,13 @@ void scc_ast2ir_run(scc_ast2ir_ctx_t *ctx, } void scc_ast2ir_ctx_init(scc_ast2ir_ctx_t *ctx, const scc_abi_type_calc_t *abi, - scc_hir_cprog_t *cprog) { + scc_ast_ctx_t *ast_ctx, scc_hir_cprog_t *cprog) { Assert(ctx != nullptr); + Assert(abi != nullptr); + Assert(ast_ctx != nullptr); + Assert(cprog != nullptr); ctx->abi = abi; + ctx->ast_ctx = ast_ctx; scc_hir_builder_init(&ctx->builder, cprog); scc_hashtable_usize_init(&ctx->ast2ir_cache); scc_hashtable_usize_init(&ctx->break_cache); diff --git a/libs/ir/cfg/include/scc_cfg.h b/libs/ir/cfg/include/scc_cfg.h index 524a7cc..5cb8577 100644 --- a/libs/ir/cfg/include/scc_cfg.h +++ b/libs/ir/cfg/include/scc_cfg.h @@ -75,16 +75,18 @@ void scc_cfg_module_init(scc_cfg_module_t *module); 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_t *scc_cfg_module_unsafe_get_func(const 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); +scc_cfg_bblock_t * +scc_cfg_module_unsafe_get_bblock(const scc_cfg_module_t *module, + scc_cfg_bblock_id_t id); scc_cfg_symbol_id_t scc_cfg_module_add_symbol(scc_cfg_module_t *module, const scc_cfg_symbol_t *symbol); -scc_cfg_symbol_t *scc_cfg_module_unsafe_get_symbol(scc_cfg_module_t *module, - scc_cfg_symbol_id_t id); +scc_cfg_symbol_t * +scc_cfg_module_unsafe_get_symbol(const scc_cfg_module_t *module, + scc_cfg_symbol_id_t id); scc_cfg_symbol_id_t scc_cfg_module_lookup_symbol(const scc_cfg_module_t *module, const char *name); diff --git a/libs/ir/cfg/src/scc_cfg.c b/libs/ir/cfg/src/scc_cfg.c index 077f260..cbe1539 100644 --- a/libs/ir/cfg/src/scc_cfg.c +++ b/libs/ir/cfg/src/scc_cfg.c @@ -27,7 +27,7 @@ scc_cfg_func_id_t scc_cfg_module_add_func(scc_cfg_module_t *module, return id; } -scc_cfg_func_t *scc_cfg_module_unsafe_get_func(scc_cfg_module_t *module, +scc_cfg_func_t *scc_cfg_module_unsafe_get_func(const scc_cfg_module_t *module, scc_cfg_func_id_t id) { if (id == SCC_CFG_ID_nullptr) { Panic("nullptr func id"); @@ -48,8 +48,9 @@ scc_cfg_bblock_id_t scc_cfg_module_add_bblock(scc_cfg_module_t *module, return id; } -scc_cfg_bblock_t *scc_cfg_module_unsafe_get_bblock(scc_cfg_module_t *module, - scc_cfg_bblock_id_t id) { +scc_cfg_bblock_t * +scc_cfg_module_unsafe_get_bblock(const scc_cfg_module_t *module, + scc_cfg_bblock_id_t id) { if (id == SCC_CFG_ID_nullptr) { Panic("nullptr bblocks id"); } @@ -68,8 +69,9 @@ scc_cfg_symbol_id_t scc_cfg_module_add_symbol(scc_cfg_module_t *module, return id; } -scc_cfg_symbol_t *scc_cfg_module_unsafe_get_symbol(scc_cfg_module_t *module, - scc_cfg_symbol_id_t id) { +scc_cfg_symbol_t * +scc_cfg_module_unsafe_get_symbol(const scc_cfg_module_t *module, + scc_cfg_symbol_id_t id) { if (id == SCC_CFG_ID_nullptr) { Panic("nullptr symbol id"); } diff --git a/libs/ir/lir/include/scc_lir.h b/libs/ir/lir/include/scc_lir.h index 2fc6322..06cf589 100644 --- a/libs/ir/lir/include/scc_lir.h +++ b/libs/ir/lir/include/scc_lir.h @@ -66,8 +66,6 @@ typedef struct scc_lir_instr { #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) \ diff --git a/libs/ir/lir/src/scc_hir2lir.c b/libs/ir/lir/src/scc_hir2lir.c index b9d275b..c81a85e 100644 --- a/libs/ir/lir/src/scc_hir2lir.c +++ b/libs/ir/lir/src/scc_hir2lir.c @@ -136,7 +136,10 @@ static scc_lir_val_t ir_value_to_lir_operand(ir2lir_ctx_t *ctx, return SCC_LIR_VREG(vreg); } case SCC_HIR_VALUE_TAG_NULLPTR: { - return SCC_LIR_IMM(0); + scc_ap_t ap; + ap.data.digit = 0; + ap.capacity = -1; + return SCC_LIR_IMM(ap); } default: { // 其他所有产生值的指令:确保其指令已生成,然后返回 vreg diff --git a/libs/ir/mir/include/scc_lir2mir.h b/libs/ir/mir/include/scc_lir2mir.h index dd6d522..9dd0450 100644 --- a/libs/ir/mir/include/scc_lir2mir.h +++ b/libs/ir/mir/include/scc_lir2mir.h @@ -7,4 +7,7 @@ void scc_lir2mir(scc_mir_module_t *mir_module, const scc_lir_module_t *lir_module); +// TODO +void scc_mir_pass(scc_mir_module_t *mir_module); + #endif /* __SCC_LIR2MIR_H__ */ diff --git a/libs/ir/mir/include/scc_mir.h b/libs/ir/mir/include/scc_mir.h index ab165f2..b2c604e 100644 --- a/libs/ir/mir/include/scc_mir.h +++ b/libs/ir/mir/include/scc_mir.h @@ -47,14 +47,27 @@ typedef struct scc_mir_bblock_meta { #define SCC_MIR_BBLOCK_VALUES(bblock) \ ((scc_mir_instr_vec_t *)&((bblock)->values)) +typedef struct scc_mir_stack_slot { + int slot_id; + int size; // 通常是 8 字节 (指针大小) + int alignment; // 对齐要求 + int offset; // 相对于 RSP 的偏移 (最终确定) +} scc_mir_stack_slot_t; +typedef SCC_VEC(scc_mir_stack_slot_t) scc_mir_stack_slot_vec_t; + typedef scc_cfg_func_t scc_mir_func_t; typedef struct scc_mir_func_meta { // 栈帧信息 (由 FrameLayout Pass 填充) int frame_size; int stack_alignment; + // 寄存器分配信息 - SCC_VEC(int) vreg_alloc; // vreg -> phys reg 映射 + scc_mir_stack_slot_vec_t stack_slots; + scc_hashtable_t vreg2preg; // vreg -> phys reg,-1 表示溢出 + scc_hashtable_t vreg2slot; // vreg -> stack slot index } scc_mir_func_meta_t; #define SCC_MIR_FUNC_META(func) ((scc_mir_func_meta_t *)(func)->meta) +void scc_mir_func_meta_init(scc_mir_func_meta_t *func_meta); + #endif /* __SCC_MIR_H__ */ diff --git a/libs/ir/mir/src/mir_x86.c b/libs/ir/mir/src/mir_x86.c index 59bb0d9..5050505 100644 --- a/libs/ir/mir/src/mir_x86.c +++ b/libs/ir/mir/src/mir_x86.c @@ -8,7 +8,7 @@ static const char *preg_name(int preg_id) { if (preg_id < 1 || preg_id >= SCC_X86_REG_COUNT) return "???"; - return scc_x86_reg_table[preg_id].name; + return scc_x86_reg_table[preg_id].display_str; } void scc_x86_instr_dump(scc_tree_dump_t *td, const scc_mir_instr_t *instr) { @@ -130,7 +130,8 @@ static void sel_mir(x86_isel_t *isel, const scc_lir_instr_t *instr) { // case SCC_LIR_FNEG: // case SCC_LIR_FCVT: case SCC_LIR_ALLOCA: { - add_instr_2(isel, SCC_MIR_PSUEDO_ALLOCA, lir_val_to_mir_op(&instr->to), + add_instr_2(isel, (scc_x86_iform_t)SCC_MIR_PSUEDO_ALLOCA, + lir_val_to_mir_op(&instr->to), (scc_mir_operand_t){ .kind = SCC_MIR_OP_IMM, .imm = instr->size, @@ -310,7 +311,7 @@ static void sel_mir(x86_isel_t *isel, const scc_lir_instr_t *instr) { lir_val_to_mir_op(&instr->metadata.ret_val)); } - add_instr_0(isel, SCC_X86_IFORM_RET_FAR); + add_instr_0(isel, SCC_X86_IFORM_RET_NEAR); } break; // case SCC_LIR_PARALLEL_COPY: { @@ -362,7 +363,8 @@ static void sel_mir(x86_isel_t *isel, const scc_lir_instr_t *instr) { break; } } -static void sel_func(scc_lir_module_t *lir_module, const scc_lir_func_t *func) { +static void sel_func(const scc_lir_module_t *lir_module, + const scc_lir_func_t *func) { x86_isel_t isel; scc_vec_foreach(func->bblocks, i) { @@ -383,11 +385,18 @@ static void sel_func(scc_lir_module_t *lir_module, const scc_lir_func_t *func) { } void scc_isel_x86_64(scc_mir_module_t *mir_module, - scc_lir_module_t *lir_module) { + const scc_lir_module_t *lir_module) { scc_vec_foreach(lir_module->cfg_module.funcs, i) { if (i == 0) continue; scc_lir_func_t *func = &scc_vec_at(lir_module->cfg_module.funcs, i); + + scc_mir_func_meta_t *func_meta = + scc_malloc(sizeof(scc_mir_func_meta_t)); + Assert(func_meta != nullptr); + scc_mir_func_meta_init(func_meta); + scc_vec_push(mir_module->func_metas, func_meta); + func->meta = func_meta; sel_func(lir_module, func); } } diff --git a/libs/ir/mir/src/scc_lir2mir.c b/libs/ir/mir/src/scc_lir2mir.c index 150a422..ec96cce 100644 --- a/libs/ir/mir/src/scc_lir2mir.c +++ b/libs/ir/mir/src/scc_lir2mir.c @@ -1,7 +1,7 @@ #include extern void scc_isel_x86_64(scc_mir_module_t *mir_module, - scc_lir_module_t *lir_module); + const scc_lir_module_t *lir_module); void scc_lir2mir(scc_mir_module_t *mir_module, const scc_lir_module_t *lir_module) { diff --git a/libs/ir/mir/src/scc_mir.c b/libs/ir/mir/src/scc_mir.c index e69de29..f4116be 100644 --- a/libs/ir/mir/src/scc_mir.c +++ b/libs/ir/mir/src/scc_mir.c @@ -0,0 +1,9 @@ +#include "scc_mir.h" + +void scc_mir_func_meta_init(scc_mir_func_meta_t *func_meta) { + func_meta->frame_size = 0; + func_meta->stack_alignment = 0; + scc_vec_init(func_meta->stack_slots); + scc_hashtable_usize_init(&func_meta->vreg2preg); + scc_hashtable_usize_init(&func_meta->vreg2slot); +} diff --git a/libs/ir/mir/src/scc_mir_pass.c b/libs/ir/mir/src/scc_mir_pass.c index e69de29..eac1d61 100644 --- a/libs/ir/mir/src/scc_mir_pass.c +++ b/libs/ir/mir/src/scc_mir_pass.c @@ -0,0 +1,2 @@ +#include +void scc_mir_pass(scc_mir_module_t *mir_module) {} \ No newline at end of file diff --git a/src/config.h b/src/config.h index 1a7d050..7aa56f4 100644 --- a/src/config.h +++ b/src/config.h @@ -17,6 +17,10 @@ typedef struct { cbool emit_hir; cbool emit_lir; cbool emit_mir; + + cbool emit_mir_pass_reg_alloc; + cbool emit_mir_pass_stack_layout; + cbool emit_mir_pass_prolog_epilog; } scc_config_t; static void setup_argparse(scc_argparse_t *argparse, scc_config_t *config, diff --git a/src/main.c b/src/main.c index 99e402d..8a3345a 100644 --- a/src/main.c +++ b/src/main.c @@ -186,13 +186,16 @@ int main(int argc, const char **argv, const char **envp) { scc_parser_t parser; scc_ast_ctx_t ast_ctx; scc_ast_ctx_init(&ast_ctx); - scc_sema_ctx_t sema_callbacks; - scc_sema_init(&sema_callbacks, &ast_ctx); - scc_parser_init(&parser, tok_ring, &ast_ctx, &sema_callbacks); + scc_sema_ctx_t sema_ctx; + scc_sema_init(&sema_ctx, &ast_ctx); + scc_parser_init(&parser, tok_ring, &ast_ctx, &sema_ctx); scc_ast_translation_unit_t *translation_unit = scc_parse_translation_unit(&parser); + if (parser.errcode != 0) { + return parser.errcode; + } - scc_sema_drop(&sema_callbacks); + scc_sema_drop(&sema_ctx); scc_parser_drop(&parser); pproc_drop: scc_pproc_drop(&pproc); @@ -222,7 +225,7 @@ sstream_drop: #include scc_hir_cprog_t cprog; scc_hir_cprog_init(&cprog); - scc_ast2ir_ctx_init(&ast2ir_ctx, &scc_ast_abi_impl, &cprog); + scc_ast2ir_ctx_init(&ast2ir_ctx, &scc_ast_abi_impl, &ast_ctx, &cprog); scc_ast2ir_run(&ast2ir_ctx, translation_unit); scc_ast2ir_ctx_drop(&ast2ir_ctx);