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:
@@ -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";
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user