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