refactor(ast2ir): 提取模块访问函数并优化类型大小计算

- 添加 scc_ast2ir_mir_module 内联函数统一访问模块
- 替换所有直接访问 ctx->builder.cprog->module 的地方
- 移除重复的 scc_hir_type_size 函数实现
- 添加 scc_hir_module_type_size 函数到模块接口
- 更新所有类型大小计算调用使用新函数

feat(hir): 增强构建器安全性和全局变量处理

- 为 scc_hir_builder_integer 添加空指针检查断言
- 修复 scc_hir_builder_global_alloca 中全局变量类型设置
- 改进 scc_hir_builder_get_elem_ptr 处理空指针索引情况
- 重构字符串常量生成使用 get_elem_ptr 构建器函数

refactor(lir): 简化地址表达式表示并增强内置函数支持

- 移除复杂地址结构体 scc_lir_addr_t
- 简化 scc_lir_instr 结构体中的地址表示
- 移除 STORE_ADDR 操作码
- 添加 memcpy 和 memset 内置函数操作码
- 在符号元数据中使用联合体替代嵌套结构体

feat(hir2lir): 完善 HIR 到 LIR 转换中的内置函数处理

- 添加 ensure_vreg 辅助函数确保虚拟寄存器操作数
- 正确处理全局变量地址符号引用
- 优化 GET_ELEM_PTR 转换使用类型大小计算
- 完整实现所有内置函数(BUILTIN)的 LIR 转换
- 包括 memcpy、memset、va_start、va_arg、va_end、va_copy 等
This commit is contained in:
zzy
2026-05-22 15:15:18 +08:00
parent 41d060d7e7
commit d78b91894e
27 changed files with 1272 additions and 563 deletions

View File

@@ -16,8 +16,8 @@ static const char *op_to_string(scc_lir_op_t op) {
return "load.addr";
case SCC_LIR_STORE:
return "store";
case SCC_LIR_STORE_ADDR:
return "store.addr";
// case SCC_LIR_STORE_ADDR:
// return "store.addr";
case SCC_LIR_ADD:
return "add";
case SCC_LIR_SUB:
@@ -86,6 +86,11 @@ static const char *op_to_string(scc_lir_op_t op) {
return "va_copy";
case SCC_LIR_ALLOCA:
return "alloca";
case SCC_LIR_MEMCPY:
return "memcpy";
case SCC_LIR_MEMSET:
return "memset";
case SCC_LIR_NOP:
return "nop";
default:
@@ -160,29 +165,6 @@ static void dump_operand(scc_lir_dump_ctx_t *ctx, const scc_lir_val_t *op) {
scc_tree_dump_append_fmt(td, "@%s",
op->data.symbol ? op->data.symbol : "<null>");
break;
case SCC_LIR_INSTR_KIND_MEM: {
const scc_lir_addr_t *addr = &op->data.addr;
scc_tree_dump_append(td, "[");
if (addr->base != -1) {
scc_tree_dump_append_fmt(td, "%%%d", addr->base);
}
if (addr->index != -1) {
scc_tree_dump_append_fmt(td, " + %%%d * %d", addr->index,
addr->scale);
}
if (addr->offset != 0) {
if (addr->offset > 0)
scc_tree_dump_append_fmt(td, " + %lld",
(long long)addr->offset);
else
scc_tree_dump_append_fmt(td, " - %lld",
-(long long)addr->offset);
}
if (addr->base == -1 && addr->index == -1 && addr->offset == 0)
scc_tree_dump_append(td, "0");
scc_tree_dump_append(td, "]");
break;
}
default:
scc_tree_dump_append(td, "<?>");
}
@@ -199,6 +181,8 @@ static void dump_size_ext(scc_lir_dump_ctx_t *ctx, u8 size, scc_lir_ext_t ext) {
size_str = "32";
else if (size == SCC_LIR_SIZE_64)
size_str = "64";
else
size_str = "sz(?)";
const char *ext_str = "";
if (ext == SCC_LIR_EXT_SEXT)
@@ -229,31 +213,40 @@ void scc_lir_dump_ins(scc_lir_dump_ctx_t *ctx, const scc_lir_instr_t *ins) {
switch (ins->op) {
case SCC_LIR_MOV:
case SCC_LIR_LOAD:
case SCC_LIR_LOAD_ADDR:
dump_operand(ctx, &ins->to);
scc_tree_dump_append(td, " <- ");
dump_operand(ctx, &ins->arg0);
break;
case SCC_LIR_LOAD_ADDR:
// base + index * scale + offset
dump_operand(ctx, &ins->to);
scc_tree_dump_append(td, " <- (");
dump_operand(ctx, &ins->arg0); // base
scc_tree_dump_append(td, " + ");
dump_operand(ctx, &ins->arg1); // index
scc_tree_dump_append_fmt(td, " * %d + %lld)", ins->metadata.addr.scale,
ins->metadata.addr.offset);
break;
case SCC_LIR_NEG:
case SCC_LIR_NOT:
case SCC_LIR_FNEG:
case SCC_LIR_FCVT:
case SCC_LIR_ALLOCA:
dump_operand(ctx, &ins->to);
if (ins->op != SCC_LIR_ALLOCA) {
scc_tree_dump_append(td, ", ");
dump_operand(ctx, &ins->arg0);
// alloca 额外信息在 metadata 中,但通常只关注 to
}
scc_tree_dump_append(td, ", ");
dump_operand(ctx, &ins->arg0);
break;
case SCC_LIR_ALLOCA:
scc_tree_dump_append_fmt(td, "(sz=%zd,al=%zd) => ",
ins->metadata.alloca.size_bytes,
ins->metadata.alloca.align_bytes);
dump_operand(ctx, &ins->to);
break;
// case SCC_LIR_STORE_ADDR:
case SCC_LIR_STORE:
case SCC_LIR_STORE_ADDR:
dump_operand(ctx, &ins->arg0);
scc_tree_dump_append(td, " -> ");
dump_operand(ctx, &ins->arg1);
break;
case SCC_LIR_ADD:
case SCC_LIR_SUB:
case SCC_LIR_MUL:
@@ -277,7 +270,6 @@ void scc_lir_dump_ins(scc_lir_dump_ctx_t *ctx, const scc_lir_instr_t *ins) {
scc_tree_dump_append(td, ", ");
dump_operand(ctx, &ins->arg1);
break;
case SCC_LIR_CMP:
dump_operand(ctx, &ins->to);
scc_tree_dump_append_fmt(td, ", %s, ",
@@ -286,22 +278,18 @@ void scc_lir_dump_ins(scc_lir_dump_ctx_t *ctx, const scc_lir_instr_t *ins) {
scc_tree_dump_append(td, ", ");
dump_operand(ctx, &ins->arg1);
break;
case SCC_LIR_BR:
dump_operand(ctx, &ins->arg0);
scc_tree_dump_append_fmt(td, ", BB#%zu, BB#%zu",
ins->metadata.br.true_target,
ins->metadata.br.false_target);
break;
case SCC_LIR_JMP:
scc_tree_dump_append_fmt(td, "#BB%d", ins->metadata.jmp_target);
break;
case SCC_LIR_JMP_INDIRECT:
dump_operand(ctx, &ins->arg0);
break;
case SCC_LIR_CALL: {
const struct scc_lir_call *c = &ins->metadata.call;
if (c->ret_vreg.kind != SCC_LIR_INSTR_KIND_NONE) {
@@ -317,9 +305,7 @@ void scc_lir_dump_ins(scc_lir_dump_ctx_t *ctx, const scc_lir_instr_t *ins) {
}
scc_tree_dump_append_fmt(td, ") clobber=0x%llx",
(unsigned long long)c->clobber_mask);
break;
}
} break;
case SCC_LIR_CALL_INDIRECT: {
const struct scc_lir_call_indirect *c = &ins->metadata.call_indirect;
if (c->ret_vreg.kind != SCC_LIR_INSTR_KIND_NONE) {
@@ -336,15 +322,12 @@ void scc_lir_dump_ins(scc_lir_dump_ctx_t *ctx, const scc_lir_instr_t *ins) {
}
scc_tree_dump_append_fmt(td, ") clobber=0x%llx",
(unsigned long long)c->clobber_mask);
break;
}
} break;
case SCC_LIR_RET:
if (ins->metadata.ret_val.kind != SCC_LIR_INSTR_KIND_NONE) {
dump_operand(ctx, &ins->metadata.ret_val);
}
break;
case SCC_LIR_PARALLEL_COPY: {
const struct scc_lir_parallel_copy *pc = &ins->metadata.parallel_copy;
scc_tree_dump_append(td, "[");
@@ -358,13 +341,11 @@ void scc_lir_dump_ins(scc_lir_dump_ctx_t *ctx, const scc_lir_instr_t *ins) {
scc_tree_dump_append(td, "]");
break;
}
case SCC_LIR_VA_START:
dump_operand(ctx, &ins->metadata.va_start.ap);
scc_tree_dump_append(td, ", ");
dump_operand(ctx, &ins->metadata.va_start.last);
break;
case SCC_LIR_VA_ARG:
dump_operand(ctx, &ins->metadata.va_arg.to);
scc_tree_dump_append(td, " = va_arg ");
@@ -373,17 +354,28 @@ void scc_lir_dump_ins(scc_lir_dump_ctx_t *ctx, const scc_lir_instr_t *ins) {
td, ", size=%u, align=%u, float=%d", ins->metadata.va_arg.type_size,
ins->metadata.va_arg.type_align, ins->metadata.va_arg.is_float);
break;
case SCC_LIR_VA_END:
dump_operand(ctx, &ins->metadata.va_end.ap);
break;
case SCC_LIR_VA_COPY:
dump_operand(ctx, &ins->metadata.va_copy.dest);
scc_tree_dump_append(td, ", ");
dump_operand(ctx, &ins->metadata.va_copy.src);
break;
case SCC_LIR_MEMCPY:
dump_operand(ctx, &ins->metadata.memcpy.dest);
scc_tree_dump_append(td, ", ");
dump_operand(ctx, &ins->metadata.memcpy.src);
scc_tree_dump_append(td, ", ");
dump_operand(ctx, &ins->metadata.memcpy.size);
break;
case SCC_LIR_MEMSET:
dump_operand(ctx, &ins->metadata.memset.dest);
scc_tree_dump_append(td, ", ");
dump_operand(ctx, &ins->metadata.memset.value);
scc_tree_dump_append(td, ", ");
dump_operand(ctx, &ins->metadata.memset.size);
break;
case SCC_LIR_NOP:
break;
}
@@ -451,7 +443,12 @@ void scc_lir_dump_module(scc_lir_dump_ctx_t *ctx) {
&scc_vec_at(ctx->lir_module->cfg_module.symbols, i);
scc_tree_dump_begin_line(ctx->dump_ctx);
scc_tree_dump_node(ctx->dump_ctx, "symbol");
scc_lir_symbol_meta_t *meta = SCC_LIR_SYMBOL_META(sym);
scc_tree_dump_append_fmt(ctx->dump_ctx, " %s", sym->name);
if (sym->kind == SCC_CFG_SYMBOL_KIND_DATA) {
scc_tree_dump_append_fmt(ctx->dump_ctx, "(size=%zu)",
meta->data.size);
}
}
scc_vec_foreach(ctx->lir_module->cfg_module.funcs, i) {
if (i == 0)