feat(ast2ir): 添加AST上下文支持并修复类型转换逻辑

- 在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): 改进错误处理机制

- 修正语义分析上下文变量命名
- 添加解析错误码检查,及时返回错误状态
This commit is contained in:
zzy
2026-05-01 22:51:31 +08:00
parent 85d698acdf
commit b06c4fe3cc
14 changed files with 89 additions and 39 deletions

View File

@@ -14,10 +14,12 @@ typedef struct {
// scc_strpool_t strpool; ///< string pool // scc_strpool_t strpool; ///< string pool
const scc_abi_type_calc_t *abi; const scc_abi_type_calc_t *abi;
cbool hint_using_value; // 转换时尽可能使用value而不是alloc cbool hint_using_value; // 转换时尽可能使用value而不是alloc
scc_ast_ctx_t *ast_ctx;
} scc_ast2ir_ctx_t; } scc_ast2ir_ctx_t;
void scc_ast2ir_ctx_init(scc_ast2ir_ctx_t *ctx, const scc_abi_type_calc_t *abi, 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_ctx_drop(scc_ast2ir_ctx_t *ctx);
void scc_ast2ir_run(scc_ast2ir_ctx_t *ctx, void scc_ast2ir_run(scc_ast2ir_ctx_t *ctx,

View File

@@ -27,7 +27,7 @@ static scc_hir_type_ref_t parse_base_type(scc_ast2ir_ctx_t *ctx,
return SCC_HIR_REF_nullptr; 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 // 辅助函数计算数组实际长度如果原长度为0
static void resolve_array_length(scc_ast2ir_ctx_t *ctx, 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 // FIXME hack
ir_type.data.array.len = value.data.digit; ir_type.data.array.len = value.data.digit;
} }
break; } break;
}
case SCC_AST_TYPE_FUNCTION: { case SCC_AST_TYPE_FUNCTION: {
scc_hir_type_init(&ir_type, SCC_HIR_TYPE_FUNC); 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); scc_vec_push(params, tmp_type);
} }
ir_type.data.function.params = params; ir_type.data.function.params = params;
break; } break;
}
case SCC_AST_TYPE_STRUCT: case SCC_AST_TYPE_STRUCT:
case SCC_AST_TYPE_UNION: { case SCC_AST_TYPE_UNION: {
scc_hir_type_init(&ir_type, ast_type->base.type == SCC_AST_TYPE_STRUCT 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_ast2ir_type(ctx, decl_field->var.type);
scc_vec_push(ir_type.data.aggregate.fields, field_type); scc_vec_push(ir_type.data.aggregate.fields, field_type);
} }
break; } break;
}
case SCC_AST_TYPE_ENUM: case SCC_AST_TYPE_ENUM:
scc_ast_canon_type_t int_canon_type = { scc_ast_canon_type_t *int_canon_type = scc_ast_ctx_get_builtin_type(
.builtin = SCC_AST_BUILTIN_TYPE_INT, ctx->ast_ctx, SCC_AST_BUILTIN_TYPE_INT);
};
scc_ast_qual_type_t int_type = { scc_ast_qual_type_t int_type = {
.base.type = SCC_AST_TYPE_BUILTIN, .base.type = SCC_AST_TYPE_BUILTIN,
.type = &int_canon_type, .type = int_canon_type,
}; };
return parse_base_type(ctx, &int_type); return parse_base_type(ctx, &int_type);
case SCC_AST_TYPE_TYPEDEF: 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) { if (stmt->for_stmt.incr) {
scc_ast2ir_expr(ctx, stmt->for_stmt.incr, false); 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); scc_hir_builder_set_current_bblock(&ctx->builder, exit_block);
break; 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, 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(ctx != nullptr);
Assert(abi != nullptr);
Assert(ast_ctx != nullptr);
Assert(cprog != nullptr);
ctx->abi = abi; ctx->abi = abi;
ctx->ast_ctx = ast_ctx;
scc_hir_builder_init(&ctx->builder, cprog); scc_hir_builder_init(&ctx->builder, cprog);
scc_hashtable_usize_init(&ctx->ast2ir_cache); scc_hashtable_usize_init(&ctx->ast2ir_cache);
scc_hashtable_usize_init(&ctx->break_cache); scc_hashtable_usize_init(&ctx->break_cache);

View File

@@ -75,15 +75,17 @@ void scc_cfg_module_init(scc_cfg_module_t *module);
void scc_cfg_module_drop(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, scc_cfg_func_id_t scc_cfg_module_add_func(scc_cfg_module_t *module,
const scc_cfg_func_t *func); 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_func_id_t id);
scc_cfg_bblock_id_t scc_cfg_module_add_bblock(scc_cfg_module_t *module, scc_cfg_bblock_id_t scc_cfg_module_add_bblock(scc_cfg_module_t *module,
const scc_cfg_bblock_t *bblock); const scc_cfg_bblock_t *bblock);
scc_cfg_bblock_t *scc_cfg_module_unsafe_get_bblock(scc_cfg_module_t *module, scc_cfg_bblock_t *
scc_cfg_module_unsafe_get_bblock(const scc_cfg_module_t *module,
scc_cfg_bblock_id_t id); scc_cfg_bblock_id_t id);
scc_cfg_symbol_id_t scc_cfg_module_add_symbol(scc_cfg_module_t *module, scc_cfg_symbol_id_t scc_cfg_module_add_symbol(scc_cfg_module_t *module,
const scc_cfg_symbol_t *symbol); const scc_cfg_symbol_t *symbol);
scc_cfg_symbol_t *scc_cfg_module_unsafe_get_symbol(scc_cfg_module_t *module, 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 id);
scc_cfg_symbol_id_t scc_cfg_module_lookup_symbol(const scc_cfg_module_t *module, scc_cfg_symbol_id_t scc_cfg_module_lookup_symbol(const scc_cfg_module_t *module,
const char *name); const char *name);

View File

@@ -27,7 +27,7 @@ scc_cfg_func_id_t scc_cfg_module_add_func(scc_cfg_module_t *module,
return id; 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) { scc_cfg_func_id_t id) {
if (id == SCC_CFG_ID_nullptr) { if (id == SCC_CFG_ID_nullptr) {
Panic("nullptr func id"); Panic("nullptr func id");
@@ -48,7 +48,8 @@ scc_cfg_bblock_id_t scc_cfg_module_add_bblock(scc_cfg_module_t *module,
return id; return id;
} }
scc_cfg_bblock_t *scc_cfg_module_unsafe_get_bblock(scc_cfg_module_t *module, scc_cfg_bblock_t *
scc_cfg_module_unsafe_get_bblock(const scc_cfg_module_t *module,
scc_cfg_bblock_id_t id) { scc_cfg_bblock_id_t id) {
if (id == SCC_CFG_ID_nullptr) { if (id == SCC_CFG_ID_nullptr) {
Panic("nullptr bblocks id"); Panic("nullptr bblocks id");
@@ -68,7 +69,8 @@ scc_cfg_symbol_id_t scc_cfg_module_add_symbol(scc_cfg_module_t *module,
return id; return id;
} }
scc_cfg_symbol_t *scc_cfg_module_unsafe_get_symbol(scc_cfg_module_t *module, 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 id) {
if (id == SCC_CFG_ID_nullptr) { if (id == SCC_CFG_ID_nullptr) {
Panic("nullptr symbol id"); Panic("nullptr symbol id");

View File

@@ -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_NONE() ((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_NONE})
#define SCC_LIR_VREG(n) \ #define SCC_LIR_VREG(n) \
((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_VREG, .data.reg = (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) \ #define SCC_LIR_IMM(v) \
((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_IMM, .data.imm = (v)}) ((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_IMM, .data.imm = (v)})
#define SCC_LIR_FIMM(v) \ #define SCC_LIR_FIMM(v) \

View File

@@ -136,7 +136,10 @@ static scc_lir_val_t ir_value_to_lir_operand(ir2lir_ctx_t *ctx,
return SCC_LIR_VREG(vreg); return SCC_LIR_VREG(vreg);
} }
case SCC_HIR_VALUE_TAG_NULLPTR: { 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: { default: {
// 其他所有产生值的指令:确保其指令已生成,然后返回 vreg // 其他所有产生值的指令:确保其指令已生成,然后返回 vreg

View File

@@ -7,4 +7,7 @@
void scc_lir2mir(scc_mir_module_t *mir_module, void scc_lir2mir(scc_mir_module_t *mir_module,
const scc_lir_module_t *lir_module); const scc_lir_module_t *lir_module);
// TODO
void scc_mir_pass(scc_mir_module_t *mir_module);
#endif /* __SCC_LIR2MIR_H__ */ #endif /* __SCC_LIR2MIR_H__ */

View File

@@ -47,14 +47,27 @@ typedef struct scc_mir_bblock_meta {
#define SCC_MIR_BBLOCK_VALUES(bblock) \ #define SCC_MIR_BBLOCK_VALUES(bblock) \
((scc_mir_instr_vec_t *)&((bblock)->values)) ((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 scc_cfg_func_t scc_mir_func_t;
typedef struct scc_mir_func_meta { typedef struct scc_mir_func_meta {
// 栈帧信息 (由 FrameLayout Pass 填充) // 栈帧信息 (由 FrameLayout Pass 填充)
int frame_size; int frame_size;
int stack_alignment; 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; } scc_mir_func_meta_t;
#define SCC_MIR_FUNC_META(func) ((scc_mir_func_meta_t *)(func)->meta) #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__ */ #endif /* __SCC_MIR_H__ */

View File

@@ -8,7 +8,7 @@
static const char *preg_name(int preg_id) { static const char *preg_name(int preg_id) {
if (preg_id < 1 || preg_id >= SCC_X86_REG_COUNT) if (preg_id < 1 || preg_id >= SCC_X86_REG_COUNT)
return "???"; 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) { 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_FNEG:
// case SCC_LIR_FCVT: // case SCC_LIR_FCVT:
case SCC_LIR_ALLOCA: { 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){ (scc_mir_operand_t){
.kind = SCC_MIR_OP_IMM, .kind = SCC_MIR_OP_IMM,
.imm = instr->size, .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)); 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; } break;
// case SCC_LIR_PARALLEL_COPY: { // case SCC_LIR_PARALLEL_COPY: {
@@ -362,7 +363,8 @@ static void sel_mir(x86_isel_t *isel, const scc_lir_instr_t *instr) {
break; 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; x86_isel_t isel;
scc_vec_foreach(func->bblocks, i) { 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, 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) { scc_vec_foreach(lir_module->cfg_module.funcs, i) {
if (i == 0) if (i == 0)
continue; continue;
scc_lir_func_t *func = &scc_vec_at(lir_module->cfg_module.funcs, i); 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); sel_func(lir_module, func);
} }
} }

View File

@@ -1,7 +1,7 @@
#include <scc_lir2mir.h> #include <scc_lir2mir.h>
extern void scc_isel_x86_64(scc_mir_module_t *mir_module, 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, void scc_lir2mir(scc_mir_module_t *mir_module,
const scc_lir_module_t *lir_module) { const scc_lir_module_t *lir_module) {

View File

@@ -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);
}

View File

@@ -0,0 +1,2 @@
#include <scc_mir_module.h>
void scc_mir_pass(scc_mir_module_t *mir_module) {}

View File

@@ -17,6 +17,10 @@ typedef struct {
cbool emit_hir; cbool emit_hir;
cbool emit_lir; cbool emit_lir;
cbool emit_mir; cbool emit_mir;
cbool emit_mir_pass_reg_alloc;
cbool emit_mir_pass_stack_layout;
cbool emit_mir_pass_prolog_epilog;
} scc_config_t; } scc_config_t;
static void setup_argparse(scc_argparse_t *argparse, scc_config_t *config, static void setup_argparse(scc_argparse_t *argparse, scc_config_t *config,

View File

@@ -186,13 +186,16 @@ int main(int argc, const char **argv, const char **envp) {
scc_parser_t parser; scc_parser_t parser;
scc_ast_ctx_t ast_ctx; scc_ast_ctx_t ast_ctx;
scc_ast_ctx_init(&ast_ctx); scc_ast_ctx_init(&ast_ctx);
scc_sema_ctx_t sema_callbacks; scc_sema_ctx_t sema_ctx;
scc_sema_init(&sema_callbacks, &ast_ctx); scc_sema_init(&sema_ctx, &ast_ctx);
scc_parser_init(&parser, tok_ring, &ast_ctx, &sema_callbacks); scc_parser_init(&parser, tok_ring, &ast_ctx, &sema_ctx);
scc_ast_translation_unit_t *translation_unit = scc_ast_translation_unit_t *translation_unit =
scc_parse_translation_unit(&parser); 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); scc_parser_drop(&parser);
pproc_drop: pproc_drop:
scc_pproc_drop(&pproc); scc_pproc_drop(&pproc);
@@ -222,7 +225,7 @@ sstream_drop:
#include <target/scc_abi_win_x64_pc.h> #include <target/scc_abi_win_x64_pc.h>
scc_hir_cprog_t cprog; scc_hir_cprog_t cprog;
scc_hir_cprog_init(&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_run(&ast2ir_ctx, translation_unit);
scc_ast2ir_ctx_drop(&ast2ir_ctx); scc_ast2ir_ctx_drop(&ast2ir_ctx);