feat(ir): 实现函数调用和参数处理功能

- 在AST定义中移除函数调用结构体中的冗余name字段
- 实现完整的函数声明和定义处理流程,支持符号表查找
- 添加函数参数引用节点类型,支持参数传递和访问
- 实现函数调用的IR生成,包括参数处理和符号解析
- 添加断言确保节点有效性,提升代码健壮性

fix(ast2ir): 优化类型转换处理逻辑

- 移除多余的注释说明
- 简化参数为空检查逻辑,提高代码简洁性
- 修复函数调用时的符号表查找机制

refactor(ir): 改进IR构建器接口设计

- 修改函数构建相关API,使接口更加清晰
- 添加函数声明集合管理
- 重构内置类型缓存机制

feat(ir2mcode): 完善AMD64代码生成

- 实现函数参数到寄存器的映射
- 添加函数调用约定支持(最多4个参数)
- 实现函数符号和重定位处理
- 添加栈帧管理机制
- 修正栈偏移计算

chore(ir): 清理和优化IR dump输出

- 更新节点类型描述信息
- 改进函数声明和定义的输出格式
- 修正格式化输出中的符号显示问题

style: 代码格式化和命名规范化

- 统一重定位类型枚举命名
- 优化函数参数验证和错误处理
This commit is contained in:
zzy
2026-03-23 16:02:23 +08:00
parent 097dbdcc2a
commit 741171dbba
17 changed files with 356 additions and 152 deletions

View File

@@ -14,33 +14,44 @@ void scc_ir_builder_drop(scc_ir_builder_t *builder) {
scc_ir_ctx_drop(&builder->ctx);
}
scc_ir_func_ref_t scc_ir_builder_begin_func(scc_ir_builder_t *builder,
const char *name,
scc_ir_type_ref_t type,
const char **param_names) {
scc_ir_func_t func = {0};
// 初始化参数和基本块向量
func.name = name;
func.type = type;
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);
return func_ref;
}
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;
// 如果提供了参数名称,则创建参数节点
if (param_names == null) {
return func_ref;
}
scc_ir_func_t *func_ptr = scc_ir_ctx_get_func(&builder->ctx, func_ref);
scc_ir_type_t *func_type = scc_ir_ctx_get_type(&builder->ctx, type);
scc_ir_type_t *func_type =
scc_ir_ctx_get_type(&builder->ctx, func_ptr->type);
if (func_type == null || func_type->tag != SCC_IR_TYPE_FUNC) {
LOG_ERROR("Invalid function type");
return func_ref;
return;
}
if (func_ptr == null) {
LOG_ERROR("Invalid function reference");
return;
}
if (scc_vec_size(func_ptr->bblocks) != 0 ||
scc_vec_size(func_ptr->params) != 0) {
LOG_FATAL("Multiple function definitions");
return;
}
scc_vec_foreach(func_type->data.function.params, i) {
@@ -48,9 +59,10 @@ scc_ir_func_ref_t scc_ir_builder_begin_func(scc_ir_builder_t *builder,
scc_vec_at(func_type->data.function.params, i);
scc_ir_node_t param_node = {0};
param_node.tag = SCC_IR_NODE_NULL; // 参数节点标记
param_node.tag = SCC_IR_NODE_FUNC_ARG_REF; // 参数节点标记
param_node.type = param_type;
param_node.name = param_names[i];
param_node.name = param_names ? param_names[i] : null;
param_node.data.arg_ref.idx = i;
scc_vec_init(param_node.used_by);
scc_ir_node_ref_t param_ref =
@@ -58,7 +70,7 @@ scc_ir_func_ref_t scc_ir_builder_begin_func(scc_ir_builder_t *builder,
scc_vec_push(func_ptr->params, param_ref);
}
return func_ref;
return;
}
void scc_ir_builder_end_func(scc_ir_builder_t *builder) {
@@ -144,6 +156,21 @@ scc_ir_node_ref_t scc_ir_builder_alloca(scc_ir_builder_t *builder,
return node_ref;
}
scc_ir_node_ref_t scc_ir_builder_func_arg_ref(scc_ir_builder_t *builder,
scc_ir_type_ref_t type,
const char *name, usize arg_idx) {
scc_ir_node_t node = {0};
node.tag = SCC_IR_NODE_FUNC_ARG_REF;
node.type = type;
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_builder_add_instr(builder, node_ref);
return node_ref;
}
scc_ir_node_ref_t scc_ir_builder_load(scc_ir_builder_t *builder,
scc_ir_node_ref_t target) {
scc_ir_node_t load_node = {0};

View File

@@ -213,20 +213,7 @@ scc_ir_type_ref_t scc_ir_ctx_new_type(scc_ir_cprog_ctx_t *ctx,
return (scc_ir_type_ref_t)(uintptr_t)existing;
}
// 创建新类型
unsigned new_uid = ctx->type_uid++;
scc_vec_push(ctx->types, *type);
// 添加到UID映射
usize idx = ctx->types.size - 1;
scc_hashtable_set(&ctx->uid2types, &new_uid, (void *)idx);
// 添加到去重表
scc_hashtable_set(&ctx->type_uniquing,
&ctx->types.data[idx], // 使用向量中的地址作为键
(void *)(uintptr_t)new_uid);
return new_uid;
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,
@@ -292,11 +279,12 @@ scc_ir_func_t *scc_ir_ctx_get_func(scc_ir_cprog_ctx_t *ctx,
#undef GET_ENTITY_INDEX
// 内置类型和常量缓存
static scc_ir_type_ref_t cached_i32_type = 0;
static scc_ir_node_ref_t cached_zero_const = 0;
// // 内置类型和常量缓存
// 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);
@@ -305,6 +293,7 @@ scc_ir_type_ref_t scc_ir_ctx_get_builtin_i32(scc_ir_cprog_ctx_t *ctx) {
}
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),
@@ -333,7 +322,7 @@ scc_ir_node_ref_t scc_ir_ctx_get_i32_const(scc_ir_cprog_ctx_t *ctx, i32 value) {
.type = scc_ir_ctx_get_builtin_i32(ctx),
.data.const_int.int32 = value};
const_node.name = "";
const_node.name = null;
return scc_ir_ctx_new_node(ctx, &const_node);
}

View File

@@ -13,12 +13,25 @@
// 获取IR节点类型的字符串表示
static const char *get_node_type_str(scc_ir_node_tag_t tag) {
static const char *node_types[] = {
[SCC_IR_NODE_NULL] = "Null", [SCC_IR_NODE_CONST_INT] = "ConstInt",
[SCC_IR_NODE_ALLOC] = "Alloc", [SCC_IR_NODE_LOAD] = "Load",
[SCC_IR_NODE_STORE] = "Store", [SCC_IR_NODE_GET_PTR] = "GetElementPtr",
[SCC_IR_NODE_OP] = "Op", [SCC_IR_NODE_BRANCH] = "Branch",
[SCC_IR_NODE_JUMP] = "Jump", [SCC_IR_NODE_CALL] = "Call",
[SCC_IR_NODE_RET] = "Return",
[SCC_IR_NODE_NULL] = "Null",
[SCC_IR_NODE_CONST_INT] = "ConstInt",
[SCC_IR_NODE_CONST_UINT] = "ConstUint",
[SCC_IR_NODE_CONST_FLOAT] = "ConstFloat",
[SCC_IR_NODE_CONV] = "Convert", ///< 类型转换
[SCC_IR_NODE_FUNC_ARG_REF] = "FuncArgRef", ///< 函数参数引用
[SCC_IR_NODE_BLOCK_ARG_REF] = "BlockArgRef", ///< 基本块参数引用
[SCC_IR_NODE_ALLOC] = "Alloc", ///< 分配内存(stack)
[SCC_IR_NODE_GLOBAL_ALLOC] = "GlobalAlloc", ///< 全局分配(bss)
[SCC_IR_NODE_LOAD] = "Load", ///< 加载数据
[SCC_IR_NODE_STORE] = "Store", ///< 存储数据
[SCC_IR_NODE_GET_PTR] = "GetPtr", ///< 获取指针
[SCC_IR_NODE_GET_ELEM_PTR] =
"GetElemPtr", ///< 获取元素指针(used by array)
[SCC_IR_NODE_OP] = "Op", ///< 二元运算
[SCC_IR_NODE_BRANCH] = "Branch", ///< 有条件分支
[SCC_IR_NODE_JUMP] = "Jump", ///< 无条件跳转
[SCC_IR_NODE_CALL] = "Call", ///< 调用函数
[SCC_IR_NODE_RET] = "Ret", ///< 函数返回
};
if (tag >= 0 && (usize)tag < sizeof(node_types) / sizeof(node_types[0]) &&
@@ -713,10 +726,10 @@ void scc_ir_dump_node_linear(scc_ir_dump_ctx_t *ctx,
args_remaining = sizeof(args_buf) - (args_p - args_buf);
}
format_node_ref_or_value(ctx, node_name, sizeof(node_name),
node->data.call.callee);
p += scc_snprintf(p, remaining, "call @%s(%s)", node_name, args_buf);
scc_ir_func_t *func =
scc_ir_ctx_get_func(ctx->ir_ctx, node->data.call.callee);
p += scc_snprintf(p, remaining, "call @%s(%s)",
func ? func->name : null, args_buf);
break;
}
@@ -731,6 +744,11 @@ void scc_ir_dump_node_linear(scc_ir_dump_ctx_t *ctx,
}
break;
case SCC_IR_NODE_FUNC_ARG_REF: {
p += scc_snprintf(p, remaining, "arg[%zu]", node->data.arg_ref.idx);
break;
}
default:
p += scc_snprintf(p, remaining, "<%s node %u>",
get_node_type_str(node->tag), node_ref);
@@ -796,7 +814,7 @@ void scc_ir_dump_func_linear(scc_ir_dump_ctx_t *ctx,
if (i > 0)
PRINT_NODE(ctx->dump_ctx, ", ");
scc_ir_node_ref_t param_ref = scc_vec_at(func->params, i);
PRINT_NODE(ctx->dump_ctx, "%%");
PRINT_NODE(ctx->dump_ctx, "%");
scc_ir_node_t *param_node =
scc_ir_ctx_get_node(ctx->ir_ctx, param_ref);
if (param_node && param_node->name && param_node->name[0] != '\0') {
@@ -813,11 +831,8 @@ void scc_ir_dump_func_linear(scc_ir_dump_ctx_t *ctx,
PRINT_NODE(ctx->dump_ctx, "()");
}
// 如果有返回类型
if (func->type != 0) {
PRINT_NODE(ctx->dump_ctx, " -> ");
scc_ir_dump_type_linear(ctx, func->type);
}
PRINT_NODE(ctx->dump_ctx, ": ");
scc_ir_dump_type_linear(ctx, func->type);
PRINT_NODE(ctx->dump_ctx, " {\n");
@@ -833,6 +848,13 @@ 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);
Assert(func != null);
if (scc_vec_size(func->bblocks) == 0)
scc_ir_dump_func_linear(ctx, func_decl);
}
scc_vec_foreach(ctx->cprog->func_defs, i) {
scc_ir_dump_func_linear(ctx, scc_vec_at(ctx->cprog->func_defs, i));
}