feat(ir): 添加MIR中间表示层并重构LIR相关代码

- 新增mir库模块,包含scc_mir、scc_mir_module、scc_mir_dump等组件
- 添加LIR到MIR的转换接口scc_lir2mir
- 定义MIR操作数类型和指令结构,支持虚拟寄存器、物理寄存器、立即数等
- 实现x86_64指令选择器,将LIR指令转换为MIR指令
- 重构LIR模块中函数参数命名,统一使用lir_module参数名
- 移除LIR中物理寄存器相关的代码和注释
- 更新cbuild.toml依赖配置,添加mir模块依赖
This commit is contained in:
zzy
2026-04-26 17:38:30 +08:00
parent e850b5c981
commit f57ba9bd31
21 changed files with 830 additions and 54 deletions

View File

@@ -31,9 +31,9 @@ typedef enum scc_lir_attr {
} scc_lir_attr_t;
typedef enum {
SCC_LIR_INSTR_KIND_NONE, // 无操作数
SCC_LIR_INSTR_KIND_VREG, // 虚拟寄存器
SCC_LIR_INSTR_KIND_PREG, // 物理寄存器 (后端定义编号)
SCC_LIR_INSTR_KIND_NONE, // 无操作数
SCC_LIR_INSTR_KIND_VREG, // 虚拟寄存器
// SCC_LIR_INSTR_KIND_PREG, // 物理寄存器 (后端定义编号)
SCC_LIR_INSTR_KIND_IMM, // 整数立即数
SCC_LIR_INSTR_KIND_FIMM, // 浮点立即数
SCC_LIR_INSTR_KIND_SYMBOL, // 全局符号 (函数名、全局变量、字符串常量)

View File

@@ -7,7 +7,7 @@
typedef struct {
scc_tree_dump_t *dump_ctx;
scc_lir_module_t *module;
scc_lir_module_t *lir_module;
} scc_lir_dump_ctx_t;
static inline void scc_lir_dump_init(scc_lir_dump_ctx_t *ctx,
@@ -15,7 +15,7 @@ static inline void scc_lir_dump_init(scc_lir_dump_ctx_t *ctx,
scc_lir_module_t *module) {
Assert(ctx != nullptr && dump_ctx != nullptr && module != nullptr);
ctx->dump_ctx = dump_ctx;
ctx->module = module;
ctx->lir_module = module;
}
void scc_lir_dump_ins(scc_lir_dump_ctx_t *ctx, const scc_lir_instr_t *ins);
void scc_lir_dump_bblock(scc_lir_dump_ctx_t *ctx, const scc_lir_bblock_t *bb);

View File

@@ -22,12 +22,12 @@ typedef struct scc_lir_module {
/**
* @brief 初始化 LIR 模块
*/
void scc_lir_module_init(scc_lir_module_t *module);
void scc_lir_module_init(scc_lir_module_t *lir_module);
/**
* @brief 销毁 LIR 模块,释放所有函数和符号资源
*/
void scc_lir_module_drop(scc_lir_module_t *module);
void scc_lir_module_drop(scc_lir_module_t *lir_module);
/**
* @brief 添加一个函数声明(外部或未定义)
@@ -36,7 +36,7 @@ void scc_lir_module_drop(scc_lir_module_t *module);
* @param attr 属性
* @return 符号指针
*/
scc_lir_symbol_id_t scc_lir_module_add_func_decl(scc_lir_module_t *module,
scc_lir_symbol_id_t scc_lir_module_add_func_decl(scc_lir_module_t *lir_module,
const char *name);
/**
@@ -50,7 +50,7 @@ scc_lir_symbol_id_t scc_lir_module_add_func_decl(scc_lir_module_t *module,
* @param attr 属性
* @return 符号指针
*/
scc_lir_symbol_id_t scc_lir_module_add_data(scc_lir_module_t *module,
scc_lir_symbol_id_t scc_lir_module_add_data(scc_lir_module_t *lir_module,
const char *name,
scc_cfg_symbol_kind_t kind,
const u8 *init_data, usize size,

View File

@@ -14,7 +14,6 @@ typedef struct {
scc_lir_func_t *current_func;
scc_lir_instr_vec_t instrs;
scc_hashtable_t bb_map; // ir_bblock_ref_t -> scc_lir_bblock_id_t
scc_hashtable_t value_to_vreg; // ir_value_ref_t -> unsigned int vreg
scc_hashtable_t func_decl_map; // ir_func_ref_t -> const char* (用于调用)
} ir2lir_ctx_t;
@@ -23,13 +22,11 @@ static void ir2lir_ctx_init(ir2lir_ctx_t *ctx, scc_lir_module_t *lir_module,
scc_hir_module_t *hir_module) {
ctx->hir_module = hir_module;
ctx->lir_module = lir_module;
scc_hashtable_usize_init(&ctx->bb_map);
scc_hashtable_usize_init(&ctx->value_to_vreg);
scc_hashtable_usize_init(&ctx->func_decl_map);
}
static void ir2lir_ctx_drop(ir2lir_ctx_t *ctx) {
scc_hashtable_drop(&ctx->bb_map);
scc_hashtable_drop(&ctx->value_to_vreg);
scc_hashtable_drop(&ctx->func_decl_map);
}
@@ -107,7 +104,8 @@ static int get_vreg_for_value(ir2lir_ctx_t *ctx, scc_hir_value_ref_t val_ref) {
if (found)
return (int)(usize)found;
int vreg = SCC_LIR_FUNC_META(ctx->current_func)->vregs_count++;
int vreg = ++(SCC_LIR_FUNC_META(ctx->current_func)->vregs_count);
Assert(vreg != 0);
scc_hashtable_set(&ctx->value_to_vreg, (void *)(usize)val_ref,
(void *)(usize)vreg);
return vreg;
@@ -386,25 +384,18 @@ static void translate_hir_value(ir2lir_ctx_t *ctx, scc_hir_value_t *value,
case SCC_HIR_VALUE_TAG_BRANCH: {
scc_lir_val_t cond =
ir_value_to_lir_operand(ctx, value->data.branch.cond);
scc_lir_bblock_id_t true_bb =
(scc_lir_bblock_id_t)(uintptr_t)scc_hashtable_get(
&ctx->bb_map,
(void *)(uintptr_t)value->data.branch.true_bblock);
scc_lir_bblock_id_t false_bb =
(scc_lir_bblock_id_t)(uintptr_t)scc_hashtable_get(
&ctx->bb_map,
(void *)(uintptr_t)value->data.branch.false_bblock);
scc_lir_instr_t instr = {
.op = SCC_LIR_BR, .arg0 = cond, .metadata.br = {true_bb, false_bb}};
.op = SCC_LIR_BR,
.arg0 = cond,
.metadata.br = {value->data.branch.true_bblock,
value->data.branch.false_bblock}};
scc_lir_builder_add_instr(ctx, &instr);
break;
}
case SCC_HIR_VALUE_TAG_JUMP: {
scc_lir_bblock_id_t target =
(scc_lir_bblock_id_t)(usize)scc_hashtable_get(
&ctx->bb_map, (void *)(usize)value->data.jump.target_bblock);
scc_lir_instr_t instr = {.op = SCC_LIR_JMP,
.metadata.jmp_target = target};
.metadata.jmp_target =
value->data.jump.target_bblock};
scc_lir_builder_add_instr(ctx, &instr);
break;
}
@@ -487,7 +478,6 @@ static void translate_func(ir2lir_ctx_t *ctx, scc_hir_func_t *ir_func) {
}
// 清理本次函数翻译的临时映射
scc_hashtable_drop(&ctx->bb_map);
scc_hashtable_drop(&ctx->value_to_vreg);
}

View File

@@ -144,9 +144,9 @@ static void dump_operand(scc_lir_dump_ctx_t *ctx, const scc_lir_val_t *op) {
case SCC_LIR_INSTR_KIND_VREG:
scc_tree_dump_append_fmt(td, "%%%u", op->data.reg);
break;
case SCC_LIR_INSTR_KIND_PREG:
scc_tree_dump_append_fmt(td, "Phy%u", op->data.reg);
break;
// case SCC_LIR_INSTR_KIND_PREG:
// scc_tree_dump_append_fmt(td, "Phy%u", op->data.reg);
// break;
case SCC_LIR_INSTR_KIND_IMM:
// TODO hack ap
scc_tree_dump_append_fmt(td, "%lld", op->data.imm.data.digit);
@@ -295,7 +295,7 @@ void scc_lir_dump_ins(scc_lir_dump_ctx_t *ctx, const scc_lir_instr_t *ins) {
break;
case SCC_LIR_JMP:
scc_tree_dump_append_fmt(td, "BB#%zu", ins->metadata.jmp_target);
scc_tree_dump_append_fmt(td, "#BB%d", ins->metadata.jmp_target);
break;
case SCC_LIR_JMP_INDIRECT:
@@ -395,7 +395,7 @@ void scc_lir_dump_bblock(scc_lir_dump_ctx_t *ctx, const scc_lir_bblock_t *bb) {
// 基本块头部
scc_tree_dump_begin_line(td);
scc_tree_dump_node(td, "BB%zu", bb->id);
scc_tree_dump_node(td, "#BB%zu", bb->id);
if (bb->name) {
scc_tree_dump_append_fmt(td, " (%s)", bb->name);
}
@@ -430,10 +430,10 @@ void scc_lir_dump_func(scc_lir_dump_ctx_t *ctx, const scc_lir_func_t *func) {
scc_tree_dump_append(td, " {");
// 输出所有基本块
for (usize i = 0; i < scc_vec_size(func->bblocks); ++i) {
scc_vec_foreach(func->bblocks, i) {
scc_cfg_bblock_id_t id = scc_vec_at(func->bblocks, i);
const scc_cfg_bblock_t *bb =
scc_cfg_module_unsafe_get_bblock(&ctx->module->cfg_module, id);
scc_cfg_module_unsafe_get_bblock(&ctx->lir_module->cfg_module, id);
scc_lir_dump_bblock(ctx, bb);
}
@@ -442,18 +442,20 @@ void scc_lir_dump_func(scc_lir_dump_ctx_t *ctx, const scc_lir_func_t *func) {
}
void scc_lir_dump_module(scc_lir_dump_ctx_t *ctx) {
scc_vec_foreach(ctx->module->cfg_module.symbols, i) {
scc_vec_foreach(ctx->lir_module->cfg_module.symbols, i) {
// FIXME 0 is null
if (i == 0)
continue;
scc_lir_symbol_t *sym = &scc_vec_at(ctx->module->cfg_module.symbols, i);
scc_lir_symbol_t *sym =
&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_tree_dump_append_fmt(ctx->dump_ctx, " %s", sym->name);
}
scc_vec_foreach(ctx->module->cfg_module.funcs, i) {
scc_vec_foreach(ctx->lir_module->cfg_module.funcs, i) {
if (i == 0)
continue;
scc_lir_dump_func(ctx, &scc_vec_at(ctx->module->cfg_module.funcs, i));
scc_lir_dump_func(ctx,
&scc_vec_at(ctx->lir_module->cfg_module.funcs, i));
}
}

View File

@@ -1,21 +1,22 @@
#include <scc_lir_module.h>
void scc_lir_module_init(scc_lir_module_t *module) {
void scc_lir_module_init(scc_lir_module_t *lir_module) {
// FIXME
// module->module
// lir_module->lir_module
scc_vec_init(module->func_metas);
scc_vec_init(module->symbol_metas);
scc_vec_init(lir_module->func_metas);
scc_vec_init(lir_module->symbol_metas);
}
void scc_lir_module_drop(scc_lir_module_t *module) {
scc_vec_free(module->func_metas);
scc_vec_free(module->symbol_metas);
void scc_lir_module_drop(scc_lir_module_t *lir_module) {
// FIXME memory leak
scc_vec_free(lir_module->func_metas);
scc_vec_free(lir_module->symbol_metas);
}
scc_lir_symbol_id_t scc_lir_module_add_func_decl(scc_lir_module_t *module,
scc_lir_symbol_id_t scc_lir_module_add_func_decl(scc_lir_module_t *lir_module,
const char *name) {
if (!module || !name)
if (!lir_module || !name)
return SCC_CFG_ID_nullptr;
scc_lir_symbol_meta_t *meta = scc_malloc(sizeof(scc_lir_symbol_meta_t));
@@ -26,21 +27,21 @@ scc_lir_symbol_id_t scc_lir_module_add_func_decl(scc_lir_module_t *module,
.meta = meta};
meta->func.func = nullptr;
scc_vec_push(module->symbol_metas, meta);
scc_vec_push(lir_module->symbol_metas, meta);
scc_cfg_symbol_id_t id =
scc_cfg_module_add_symbol(&module->cfg_module, &sym);
scc_cfg_module_add_symbol(&lir_module->cfg_module, &sym);
if (id == SCC_CFG_ID_nullptr) {
Panic("scc_lir: add func decl '%s' failed", name);
}
return id;
}
scc_lir_symbol_id_t scc_lir_module_add_data(scc_lir_module_t *module,
scc_lir_symbol_id_t scc_lir_module_add_data(scc_lir_module_t *lir_module,
const char *name,
scc_cfg_symbol_kind_t kind,
const u8 *init_data, usize size,
u32 align) {
if (!module || !name)
if (!lir_module || !name)
return SCC_CFG_ID_nullptr;
if (kind != SCC_CFG_SYMBOL_KIND_DATA && kind != SCC_CFG_SYMBOL_KIND_EXTERN)
return SCC_CFG_ID_nullptr;
@@ -67,9 +68,9 @@ scc_lir_symbol_id_t scc_lir_module_add_data(scc_lir_module_t *module,
}
}
scc_vec_push(module->symbol_metas, meta);
scc_vec_push(lir_module->symbol_metas, meta);
scc_cfg_symbol_id_t id =
scc_cfg_module_add_symbol(&module->cfg_module, &sym);
scc_cfg_module_add_symbol(&lir_module->cfg_module, &sym);
if (id = SCC_CFG_ID_nullptr) {
/* 冲突时释放已分配的数据 */
scc_free(meta->data.init_data);