refactor(ir): 将IR节点重构为值引用并添加字符串字面量支持

- 将scc_ir_node_ref_t重命名为scc_ir_value_ref_t,并更新所有相关API
- 修改IR定义中的节点标签枚举为值标签枚举(scc_ir_node_tag_t -> scc_ir_value_tag_t)
- 更新AST到IR转换器中所有节点引用的类型声明
- 添加对内置类型(VOID, CHAR, INT等)的完整映射实现
- 实现字符串字面量的常量数组创建功能
- 更新项目名称从"Simple Modual C Compiler"为"Simple C Compiler"
- 在Doxyfile中排除external目录的文档生成
- 移除未使用的strpool字段并重命名decl到IR的映射表

BREAKING CHANGE: IR节点引用类型已更改,所有使用scc_ir_node_ref_t的地方需
替换为scc_ir_value_ref_t。
This commit is contained in:
zzy
2026-03-31 11:42:14 +08:00
parent 4ddad7b456
commit 78e7c800ba
22 changed files with 992 additions and 727 deletions

View File

@@ -6,9 +6,9 @@
#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) {
scc_ir_value_ref_t node_ref) {
Assert(ctx != null && loc != null);
scc_ir_node_t *node = scc_ir_module_get_node(GET_MODULE(ctx), node_ref);
scc_ir_value_t *node = scc_ir_module_get_value(GET_MODULE(ctx), node_ref);
if (node == null) {
LOG_FATAL("invalid node ref");
UNREACHABLE();
@@ -16,7 +16,7 @@ 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:
case SCC_IR_VALUE_TAG_CONST_INT:
scc_ir_type_t *type =
scc_ir_module_get_type(GET_MODULE(ctx), node->type);
Assert(type != 0);
@@ -26,11 +26,14 @@ static void parse_location(scc_ir2mcode_ctx_t *ctx, scc_reg_loc_t *loc,
.idx = (usize)node->data.const_int.int32,
};
return;
case SCC_IR_NODE_CONST_UINT:
case SCC_IR_NODE_CONST_FLOAT:
case SCC_IR_VALUE_TAG_CONST_UINT:
case SCC_IR_VALUE_TAG_CONST_FLOAT:
TODO();
break;
case SCC_IR_NODE_FUNC_ARG_REF: {
case SCC_IR_VALUE_TAG_GLOBAL_ALLOC:
TODO();
break;
case SCC_IR_VALUE_TAG_FUNC_ARG_REF: {
scc_ir_type_t *type =
scc_ir_module_get_type(GET_MODULE(ctx), node->type);
Assert(type != 0);
@@ -97,34 +100,34 @@ static void store_value_from_reg(scc_mcode_t *mcode, scc_reg_loc_t *loc,
}
// 临时存储待修补条目
typedef struct {
typedef struct patch {
usize pos;
usize target_bb_ref;
} patch_t;
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_module_get_node(GET_MODULE(ctx), node_ref);
static void parse_value(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
patch_vec_t *patches) {
scc_ir_value_t *node = scc_ir_module_get_value(GET_MODULE(ctx), node_ref);
if (node == null) {
LOG_ERROR("invalid node ref");
return;
}
switch (node->tag) {
case SCC_IR_NODE_CONV: ///< 类型转换
case SCC_IR_VALUE_TAG_CONV: ///< 类型转换
LOG_FATAL("Unsupported node type: %d", node->tag);
break;
///< 函数参数引用
case SCC_IR_NODE_FUNC_ARG_REF:
case SCC_IR_VALUE_TAG_FUNC_ARG_REF:
///< ABI
break;
case SCC_IR_NODE_BLOCK_ARG_REF: ///< 基本块参数引用
case SCC_IR_NODE_ALLOC: ///< 分配内存(stack)
case SCC_IR_NODE_GLOBAL_ALLOC: ///< 全局分配(bss)
case SCC_IR_VALUE_TAG_BLOCK_ARG_REF: ///< 基本块参数引用
case SCC_IR_VALUE_TAG_ALLOC: ///< 分配内存(stack)
case SCC_IR_VALUE_TAG_GLOBAL_ALLOC: ///< 全局分配(bss)
break;
case SCC_IR_NODE_LOAD: ///< 加载数据
{
///< 加载数据
case SCC_IR_VALUE_TAG_LOAD: {
// node->data.load.target
scc_reg_loc_t from;
scc_reg_loc_t to;
@@ -134,8 +137,8 @@ static void parse_node(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
store_value_from_reg(&ctx->sect_mcode, &to, SCC_AMD64_RAX);
break;
}
case SCC_IR_NODE_STORE: ///< 存储数据
{
///< 存储数据
case SCC_IR_VALUE_TAG_STORE: {
scc_reg_loc_t from;
scc_reg_loc_t to;
parse_location(ctx, &from, node->data.store.value);
@@ -144,11 +147,36 @@ static void parse_node(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
store_value_from_reg(&ctx->sect_mcode, &to, SCC_AMD64_RAX);
break;
}
case SCC_IR_NODE_GET_PTR: ///< 获取指针
case SCC_IR_NODE_GET_ELEM_PTR: ///< 获取元素指针(used by array)
///< 获取指针
case SCC_IR_VALUE_TAG_GET_PTR: {
scc_reg_loc_t loc;
scc_ir_value_t *src_addr = scc_ir_module_get_value(
GET_MODULE(ctx), node->data.get_ptr.src_addr);
Assert(src_addr != null);
if (src_addr->tag != SCC_IR_VALUE_TAG_GLOBAL_ALLOC) {
Panic();
}
scc_mcode_amd64_lea_r64_rip_rel32(&ctx->sect_mcode, SCC_AMD64_RAX, 0);
usize sym_idx =
sccf_builder_get_symbol_idx(ctx->builder, src_addr->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->sect_mcode.mcode) - 4,
.addend = 4,
.sect_type = SCCF_SECT_DATA,
.sym_idx = sym_idx,
});
parse_location(ctx, &loc, node_ref);
store_value_from_reg(&ctx->sect_mcode, &loc, SCC_AMD64_RAX);
break;
}
case SCC_IR_VALUE_TAG_GET_ELEM_PTR: ///< 获取元素指针(used by array)
TODO();
///< 二元运算
case SCC_IR_NODE_OP: {
case SCC_IR_VALUE_TAG_OP: {
scc_reg_loc_t loc_lhs;
parse_location(ctx, &loc_lhs, node->data.op.lhs);
scc_reg_loc_t loc_rhs;
@@ -239,7 +267,7 @@ static void parse_node(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
break;
}
///< 有条件分支
case SCC_IR_NODE_BRANCH: {
case SCC_IR_VALUE_TAG_BRANCH: {
scc_reg_loc_t loc;
parse_location(ctx, &loc, node->data.branch.cond);
// (void)loc;
@@ -259,7 +287,7 @@ static void parse_node(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
break;
}
///< 无条件跳转
case SCC_IR_NODE_JUMP: {
case SCC_IR_VALUE_TAG_JUMP: {
scc_mcode_amd64_jmp_rel32(&ctx->sect_mcode, 0);
usize pos = scc_vec_size(ctx->sect_mcode.mcode);
patch_t patch = {.pos = pos,
@@ -268,7 +296,7 @@ static void parse_node(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
break;
}
///< 调用函数
case SCC_IR_NODE_CALL: {
case SCC_IR_VALUE_TAG_CALL: {
scc_reg_loc_t loc;
/*
ABI
@@ -326,7 +354,7 @@ static void parse_node(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_ref_t node_ref,
break;
}
///< 函数返回
case SCC_IR_NODE_RET: {
case SCC_IR_VALUE_TAG_RET: {
if (node->data.ret.ret_val) {
scc_reg_loc_t loc;
parse_location(ctx, &loc, node->data.ret.ret_val);
@@ -349,8 +377,8 @@ static void parse_bblock(scc_ir2mcode_ctx_t *ctx, scc_ir_bblock_t *bblock,
// 打印基本块中的每条指令
for (usize i = 0; i < scc_vec_size(bblock->instrs); i++) {
scc_ir_node_ref_t node_ref = scc_vec_at(bblock->instrs, i);
parse_node(ctx, node_ref, patches);
scc_ir_value_ref_t node_ref = scc_vec_at(bblock->instrs, i);
parse_value(ctx, node_ref, patches);
}
}
@@ -385,9 +413,9 @@ static void parse_function(scc_ir2mcode_ctx_t *ctx, scc_ir_func_t *func) {
SCC_AMD64_RSP, ctx->stack_size);
scc_reg_loc_t loc;
scc_vec_foreach(func->params, i) {
// scc_ir_node_t *param =
// scc_ir_module_get_node(GET_MODULE(ctx), );
scc_ir_node_ref_t node_ref = scc_vec_at(func->params, i);
// scc_ir_value_t *param =
// scc_ir_module_get_value(GET_MODULE(ctx), );
scc_ir_value_ref_t node_ref = scc_vec_at(func->params, i);
parse_location(ctx, &loc, node_ref);
if (i == 0) {
store_value_from_reg(&ctx->sect_mcode, &loc, SCC_AMD64_RCX);
@@ -438,8 +466,36 @@ void scc_ir2amd64(scc_ir2mcode_ctx_t *ctx) {
scc_reg_alloc_init(&ctx->reg_alloc, scc_reg_alloc_with_stack,
GET_MODULE(ctx));
sccf_sect_data_t data_section;
scc_vec_init(data_section);
scc_vec_foreach(ctx->cprog->global_vals, i) {
scc_ir_value_t *galloc = scc_ir_module_get_value(
GET_MODULE(ctx), scc_vec_at(ctx->cprog->global_vals, i));
Assert(galloc->tag == SCC_IR_VALUE_TAG_GLOBAL_ALLOC);
scc_ir_value_t *value = scc_ir_module_get_value(
GET_MODULE(ctx), galloc->data.global_alloc.value);
Assert(value != null);
sccf_sym_t sym = (sccf_sym_t){
.sccf_sect_offset = scc_vec_size(ctx->sect_data),
.sccf_sect_type = SCCF_SECT_DATA,
.sccf_sym_bind =
galloc->name ? SCCF_SYM_BIND_GLOBAL : SCCF_SYM_BIND_LOCAL,
.sccf_sym_size =
4, // FIXME on windows using rel32, on linux using ?
.sccf_sym_type = SCCF_SYM_TYPE_DATA,
.sccf_sym_vis = SCCF_SYM_VIS_DEFAULT,
};
scc_vec_foreach(value->data.const_array.elements, j) {
scc_vec_push(data_section,
scc_vec_at(value->data.const_array.elements, j));
}
usize sym_idx =
sccf_builder_add_symbol(ctx->builder, galloc->name, &sym);
Assert(sym_idx != 0);
}
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_value_ref_t func_ref = scc_vec_at(ctx->cprog->func_decls, i);
scc_ir_func_t *func = scc_ir_module_get_func(GET_MODULE(ctx), func_ref);
if (!func) {
LOG_ERROR("invalid function reference");
@@ -471,7 +527,7 @@ void scc_ir2amd64(scc_ir2mcode_ctx_t *ctx) {
}
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_value_ref_t func_ref = scc_vec_at(ctx->cprog->func_defs, i);
scc_ir_func_t *func = scc_ir_module_get_func(GET_MODULE(ctx), func_ref);
if (!func) {
LOG_ERROR("invalid function reference");
@@ -494,15 +550,16 @@ void scc_ir2amd64(scc_ir2mcode_ctx_t *ctx) {
if (sym->sccf_sym_type != SCCF_SYM_TYPE_EXTERN) {
Assert(reloc->reloc_type == SCCF_RELOC_TYPE_REL);
Assert(sym->sccf_sect_type == SCCF_SECT_CODE);
Assert(sym->sccf_sym_type == SCCF_SYM_TYPE_FUNC);
i64 target_off = sym->sccf_sect_offset;
i64 next_off = reloc->offset + reloc->addend;
i32 rel = (i32)(target_off - next_off);
// FIXME 写入到指令的偏移字段(小端)
*(i32 *)(&buf[reloc->offset]) = rel;
if (sym->sccf_sect_type == SCCF_SECT_CODE &&
sym->sccf_sym_type == SCCF_SYM_TYPE_FUNC) {
i64 target_off = sym->sccf_sect_offset;
i64 next_off = reloc->offset + reloc->addend;
i32 rel = (i32)(target_off - next_off);
// FIXME 写入到指令的偏移字段(小端)
*(i32 *)(&buf[reloc->offset]) = rel;
reloc->reloc_type = SCCF_RELOC_TYPE_EMPTY;
reloc->reloc_type = SCCF_RELOC_TYPE_EMPTY;
}
}
}
@@ -511,8 +568,7 @@ void scc_ir2amd64(scc_ir2mcode_ctx_t *ctx) {
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";

View File

@@ -26,7 +26,7 @@ scc_hashtable_t *scc_reg_alloc_with_stack(scc_reg_alloc_t *ctx,
scc_reg_loc_t loc;
scc_vec_foreach(func->params, i) {
scc_ir_node_ref_t node_ref = scc_vec_at(func->params, i);
scc_ir_value_ref_t node_ref = scc_vec_at(func->params, i);
loc.kind = SCC_REG_KIND_FUNC_ARG;
loc.idx = i;
ctx->alloc_stack_size += 8;
@@ -40,16 +40,17 @@ scc_hashtable_t *scc_reg_alloc_with_stack(scc_reg_alloc_t *ctx,
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_module_get_node(ctx->ir_module, node_ref);
scc_ir_value_ref_t node_ref = scc_vec_at(bblock->instrs, j);
scc_ir_value_t *node =
scc_ir_module_get_value(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: {
case SCC_IR_VALUE_TAG_LOAD:
case SCC_IR_VALUE_TAG_OP:
case SCC_IR_VALUE_TAG_GET_PTR:
case SCC_IR_VALUE_TAG_GET_ELEM_PTR:
case SCC_IR_VALUE_TAG_ALLOC: {
loc.kind = SCC_REG_KIND_STACK;
loc.idx = ctx->alloc_stack_size;
@@ -60,7 +61,7 @@ scc_hashtable_t *scc_reg_alloc_with_stack(scc_reg_alloc_t *ctx,
(void *)scc_vec_size(ctx->reg_loc_vec));
break;
}
case SCC_IR_NODE_CALL: {
case SCC_IR_VALUE_TAG_CALL: {
// 处理返回值
scc_ir_type_t *func_type =
scc_ir_module_get_type(ctx->ir_module, func->type);