stage1 实现部分ast2ir内容

This commit is contained in:
zzy committed 2026-08-26 14:55:47 +08:00
1 parent f1d86b6e34
commit 3d57260f3f
6 files changed
+298 -148

No files matched your search

+151 -82
View File
@@ -14,8 +14,8 @@ const char *spl_ir_kind_name(spl_ir_kind_t kind) {
void spl_ir_init(spl_ir_t *ir) {
vec_init(ir->funcs);
vec_push(ir->funcs, (spl_ir_func_t){0});
vec_init(ir->gdata);
vec_push(ir->gdata, (spl_ir_node_t){0});
// vec_init(ir->gdata);
// vec_push(ir->gdata, (spl_ir_node_t){0});
}
static void node_drop_vecs(spl_ir_node_t *n) {
@@ -38,43 +38,52 @@ void spl_ir_drop(spl_ir_t *ir) {
spl_ir_func_t *f = &vec_at(ir->funcs, i);
vec_for(f->nodes, j) { node_drop_vecs(&vec_at(f->nodes, j)); }
vec_free(f->nodes);
vec_free(f->labels);
}
vec_free(ir->funcs);
vec_for(ir->gdata, i) { node_drop_vecs(&vec_at(ir->gdata, i)); }
vec_free(ir->gdata);
// vec_for(ir->gdata, i) { node_drop_vecs(&vec_at(ir->gdata, i)); }
// vec_free(ir->gdata);
}
// 申请空的 ir_func 返回 id
spl_ir_func_ref_t spl_ir_alloc_fn(spl_ir_t *ir) {
if (ir == NULL) {
return 0;
}
spl_ir_func_t f = {0};
vec_init(f.nodes);
vec_init(f.labels);
vec_push(f.nodes, (spl_ir_node_t){0}); /* 0 = error 哨兵 */
vec_push(f.nodes, (spl_ir_node_t){0});
vec_push(ir->funcs, f);
return vec_size(ir->funcs) - 1;
}
// 从 fn_id 申请空的 ir_node 返回 id
spl_ir_node_ref_t spl_ir_alloc_node(spl_ir_t *ir, spl_ir_func_ref_t fn_id) {
if (!fn_id || fn_id >= vec_size(ir->funcs))
if (!fn_id || fn_id >= vec_size(ir->funcs)) {
return 0;
}
spl_ir_func_t *f = &vec_at(ir->funcs, fn_id);
spl_ir_node_t n = {0};
vec_push(f->nodes, n);
return vec_size(f->nodes) - 1;
}
// 从 fn_id 里通过 node_id 获取 ir_node
spl_ir_node_t *spl_ir_node(spl_ir_t *ir, spl_ir_func_ref_t fn_id, spl_ir_node_ref_t node_id) {
if (!fn_id || fn_id >= vec_size(ir->funcs))
if (!fn_id || fn_id >= vec_size(ir->funcs)) {
return NULL;
}
spl_ir_func_t *f = &vec_at(ir->funcs, fn_id);
if (!node_id || node_id >= vec_size(f->nodes))
if (!node_id || node_id >= vec_size(f->nodes)) {
return NULL;
}
return &vec_at(f->nodes, node_id);
}
// 从 fn_id 获取 ir_func
spl_ir_func_t *spl_ir_func(spl_ir_t *ir, spl_ir_func_ref_t fn_id) {
if (!fn_id || fn_id >= vec_size(ir->funcs))
if (!fn_id || fn_id >= vec_size(ir->funcs)) {
return NULL;
}
return &vec_at(ir->funcs, fn_id);
}
@@ -279,102 +288,126 @@ void spl_ir_dump(spl_ir_t *ir, const spl_type_t *ty) {
if (vec_size(func->nodes) == 0)
printf(" (extern)\n");
}
if (vec_size(ir->gdata) > 1) {
printf("gdata:\n");
vec_for(ir->gdata, i) {
if (i == 0)
continue;
spl_ir_node_t *node = &vec_at(ir->gdata, i);
printf(" #%zu ", i);
printf("%s", spl_ir_kind_name(node->kind));
ir_dump_node(ty, node);
printf("\n");
}
}
// if (vec_size(ir->gdata) > 1) {
// printf("gdata:\n");
// vec_for(ir->gdata, i) {
// if (i == 0)
// continue;
// spl_ir_node_t *node = &vec_at(ir->gdata, i);
// printf(" #%zu ", i);
// printf("%s", spl_ir_kind_name(node->kind));
// ir_dump_node(ty, node);
// printf("\n");
// }
// }
}
// IR Builder
// 从当前 fn 申请新的 node 并注入到当前基本块
static spl_ir_node_ref_t builder_alloc_node(spl_ir_builder_t *b, spl_ir_kind_t kind) {
Assert(!b->terminated && "emit into a terminated block");
spl_ir_node_ref_t ref = spl_ir_alloc_node(&b->ir, b->current_fn);
Assert(ref != 0);
spl_ir_node_t *n = spl_ir_node(&b->ir, b->current_fn, ref);
n->kind = kind;
n->dbg = b->dbg;
b->current_node = ref;
if (b->current_block < vec_size(b->blocks)) {
vec_at(b->blocks, b->current_block) = ref;
} else {
Panic("unknown bblock");
return 0;
}
return ref;
}
static spl_ir_func_t *builder_cur_func(spl_ir_builder_t *b) {
return spl_ir_func(&b->ir, b->current_fn);
}
static void builder_reloc_add(spl_ir_builder_t *b, spl_ir_node_ref_t label) {
if (label == 0) {
LOG_WARN("reloc null lable");
return;
}
spl_ir_func_t *f = builder_cur_func(b);
if (f && label < vec_size(f->nodes)) {
// resolved
return;
}
vec_for(b->reloc_label, i) {
if (vec_at(b->reloc_label, i) == label) {
return;
}
}
vec_push(b->reloc_label, label);
}
static void builder_reloc_check(spl_ir_builder_t *b) {
spl_ir_func_t *f = builder_cur_func(b);
if (!f)
return;
vec_for(b->reloc_label, i) {
spl_ir_node_ref_t label = vec_at(b->reloc_label, i);
if (label >= vec_size(f->nodes)) {
LOG_ERROR("fn `%s`: forward label %%%zu unresolved", f->name ? f->name : "?", label);
}
}
b->reloc_label.size = 0;
}
void spl_ir_builder_init(spl_ir_builder_t *b) {
spl_ir_init(&b->ir);
b->current_fn = 0;
b->current_node = 0;
b->dbg = (spl_dbg_node_t){0};
vec_init(b->reloc_label);
vec_init(b->blocks);
b->current_block = 0;
vec_init(b->fixups);
b->terminated = false;
}
void spl_ir_builder_drop(spl_ir_builder_t *b) {
spl_ir_drop(&b->ir);
vec_free(b->reloc_label);
vec_free(b->blocks);
vec_free(b->fixups);
}
spl_ir_func_ref_t spl_ir_builder_fn_new(spl_ir_builder_t *b, const char *name,
spl_type_id_t fn_tid) {
spl_ir_func_ref_t spl_ir_builder_fn_begin(spl_ir_builder_t *b, const char *name,
spl_type_id_t fn_tid, spl_ir_attr_t attr) {
if (b->current_fn) {
builder_reloc_check(b);
spl_ir_builder_fn_end(b);
}
spl_ir_func_ref_t fid = spl_ir_alloc_fn(&b->ir);
spl_ir_func_t *f = spl_ir_func(&b->ir, fid);
f->name = name;
f->attr = attr;
f->fn_tid = fn_tid;
b->current_fn = fid;
b->current_node = 0;
b->current_block = 0;
b->blocks.size = 0;
b->fixups.size = 0;
b->terminated = false;
return fid;
}
spl_ir_func_ref_t spl_ir_builder_cur_fn(const spl_ir_builder_t *b) { return b->current_fn; }
void spl_ir_builder_fn_end(spl_ir_builder_t *b) {
spl_ir_func_t *f = spl_ir_func(&b->ir, b->current_fn);
if (!f) {
Panic("ir func not found");
return;
}
void spl_ir_builder_set_dbg(spl_ir_builder_t *b, spl_dbg_node_t dbg) { b->dbg = dbg; }
vec_for(b->fixups, i) {
spl_ir_fix_t *fx = &vec_at(b->fixups, i);
spl_ir_node_t *n = spl_ir_node(&b->ir, b->current_fn, fx->node);
if (!n) {
SPL_ERROR(&n->dbg, "unknown node in func");
continue;
}
spl_ir_node_ref_t target = 0;
if (fx->block < vec_size(b->blocks)) {
target = vec_at(b->blocks, fx->block);
}
if (target == 0) {
Panic("unknown reloc target bblock");
}
switch (fx->slot) {
case SPL_IR_FIX_BR_TRUE:
n->control_br.true_label = target;
break;
case SPL_IR_FIX_BR_FALSE:
n->control_br.false_label = target;
break;
case SPL_IR_FIX_JMP:
n->control_jmp.label = target;
break;
}
}
spl_ir_node_ref_t spl_ir_builder_block_new(spl_ir_builder_t *b) {
spl_ir_func_t *f = builder_cur_func(b);
Assert(f != NULL);
return vec_size(f->nodes);
b->current_block = 0;
b->blocks.size = 0;
b->fixups.size = 0;
b->terminated = false;
}
usize spl_ir_builder_block_begin(spl_ir_builder_t *b) {
vec_push(b->blocks, (spl_ir_block_t){0});
usize block = vec_size(b->blocks) - 1;
b->current_block = block;
b->terminated = false;
return block;
}
void spl_ir_builder_block_end(spl_ir_builder_t *b) {
if (!b->terminated) {
Panic("bblock must be end of terminated");
}
}
#define X(name, kind) \
@@ -510,6 +543,22 @@ spl_ir_node_ref_t spl_ir_builder_mem_set(spl_ir_builder_t *b, spl_type_id_t tid,
return ref;
}
spl_ir_node_ref_t spl_ir_builder_type_const_bool(spl_ir_builder_t *b, spl_type_id_t tid, bool val) {
spl_ir_node_ref_t ref = builder_alloc_node(b, SPL_IR_TYPE_CONST);
spl_ir_node_t *n = spl_ir_node(&b->ir, b->current_fn, ref);
n->type_const.tid = tid;
n->type_const.bool_lit = val;
return ref;
}
spl_ir_node_ref_t spl_ir_builder_type_const_ptr(spl_ir_builder_t *b, spl_type_id_t tid, void *val) {
spl_ir_node_ref_t ref = builder_alloc_node(b, SPL_IR_TYPE_CONST);
spl_ir_node_t *n = spl_ir_node(&b->ir, b->current_fn, ref);
n->type_const.tid = tid;
n->type_const.ptr_lit = val;
return ref;
}
spl_ir_node_ref_t spl_ir_builder_type_const_int(spl_ir_builder_t *b, spl_type_id_t tid, usize val) {
spl_ir_node_ref_t ref = builder_alloc_node(b, SPL_IR_TYPE_CONST);
spl_ir_node_t *n = spl_ir_node(&b->ir, b->current_fn, ref);
@@ -640,27 +689,46 @@ spl_ir_node_ref_t spl_ir_builder_control_select(spl_ir_builder_t *b, spl_type_id
return ref;
}
spl_ir_node_ref_t spl_ir_builder_control_br(spl_ir_builder_t *b, spl_ir_node_ref_t cond,
spl_ir_node_ref_t true_label,
spl_ir_node_ref_t false_label) {
builder_reloc_add(b, true_label);
builder_reloc_add(b, false_label);
spl_ir_node_ref_t spl_ir_builder_control_br(spl_ir_builder_t *b, spl_ir_node_ref_t cond) {
spl_ir_node_ref_t ref = builder_alloc_node(b, SPL_IR_CONTROL_BR);
spl_ir_node_t *n = spl_ir_node(&b->ir, b->current_fn, ref);
n->control_br.cond = cond;
n->control_br.true_label = true_label;
n->control_br.false_label = false_label;
n->control_br.true_label = 0;
n->control_br.false_label = 0;
b->terminated = true;
return ref;
}
spl_ir_node_ref_t spl_ir_builder_control_jmp(spl_ir_builder_t *b, spl_ir_node_ref_t label) {
builder_reloc_add(b, label);
void spl_ir_builder_control_br_fixup(spl_ir_builder_t *b, spl_ir_node_ref_t ref, usize true_block,
usize false_block) {
spl_ir_node_t *node = spl_ir_node(&b->ir, b->current_fn, ref);
if (!(node && node->kind == SPL_IR_CONTROL_BR)) {
Panic("fixup must be valid jmp ir node");
}
spl_ir_fix_t f1 = {.node = ref, .slot = SPL_IR_FIX_BR_TRUE, .block = true_block};
vec_push(b->fixups, f1);
spl_ir_fix_t f2 = {.node = ref, .slot = SPL_IR_FIX_BR_FALSE, .block = false_block};
vec_push(b->fixups, f2);
}
spl_ir_node_ref_t spl_ir_builder_control_jmp(spl_ir_builder_t *b) {
spl_ir_node_ref_t ref = builder_alloc_node(b, SPL_IR_CONTROL_JMP);
spl_ir_node_t *n = spl_ir_node(&b->ir, b->current_fn, ref);
n->control_jmp.label = label;
n->control_jmp.label = 0;
b->terminated = true;
return ref;
}
void spl_ir_builder_control_jmp_fixup(spl_ir_builder_t *b, spl_ir_node_ref_t ref,
usize target_block) {
spl_ir_node_t *node = spl_ir_node(&b->ir, b->current_fn, ref);
if (!(node && node->kind == SPL_IR_CONTROL_JMP)) {
Panic("fixup must be valid jmp ir node");
}
spl_ir_fix_t fx = {.node = ref, .slot = SPL_IR_FIX_JMP, .block = target_block};
vec_push(b->fixups, fx);
}
spl_ir_node_ref_t spl_ir_builder_control_call(spl_ir_builder_t *b, spl_type_id_t tid,
spl_ir_node_ref_t func) {
spl_ir_node_ref_t ref = builder_alloc_node(b, SPL_IR_CONTROL_CALL);
@@ -693,6 +761,7 @@ spl_ir_node_ref_t spl_ir_builder_control_ret(spl_ir_builder_t *b, spl_type_id_t
spl_ir_node_t *n = spl_ir_node(&b->ir, b->current_fn, ref);
n->control_ret.tid = tid;
n->control_ret.val = val;
b->terminated = true;
return ref;
}