feat(ir): 启用LIR模块并重构HIR组件结构
- 在cbuild.toml中启用lir依赖项,取消注释相关配置 - 重构libs/README.md文档,添加详细的库说明和层级结构 - 重命名头文件以统一命名规范:ast_def.h → scc_ast_def.h, ast_dump.h → scc_ast_dump.h, hir相关文件添加scc前缀 - 更新include路径以匹配新的文件命名 - 在cfg模块中添加symbol ID类型和linkage枚举,完善符号表功能 - 实现cfg模块中的符号添加、查找和获取功能 - 修改HIR中meta字段替换原有的attribute字段,更新相关访问宏 - 修复HIR构建器中的函数元数据访问错误 - 为LIR模块创建完整的头文件结构,包括指令定义、转换器等组件
This commit is contained in:
1 parent
0fbfb36262
commit
e850b5c981
30 files changed
+1588
-2627
No files matched your search
@@ -0,0 +1,691 @@
|
||||
#include <scc_hir_builder.h>
|
||||
#include <scc_hir_def.h>
|
||||
#include <scc_hir_prog.h>
|
||||
|
||||
#define GET_MODULE(builder) (&(builder->cprog->module))
|
||||
|
||||
/**
|
||||
* @brief 哈希混合函数(类似Rust的hash combine)
|
||||
*
|
||||
* Rust的默认哈希实现(SipHash 1-3)使用旋转和异或,
|
||||
* 这里使用简单的FNV-1a变体,类似于Rust的`#[derive(Hash)]`
|
||||
*/
|
||||
static inline u32 scc_hash_mix(u32 seed, u32 value) {
|
||||
// FNV-1a风格混合
|
||||
return (seed ^ value) * 16777619u;
|
||||
}
|
||||
|
||||
static u32 hash_type(const void *_key, void *userdata) {
|
||||
scc_hir_module_t *module = userdata;
|
||||
const scc_hir_type_t *key =
|
||||
_key == SCC_HIR_REF_nullptr
|
||||
? &scc_vec_at(module->types, 0)
|
||||
: scc_hir_module_get_type(module, (usize)_key);
|
||||
// 初始哈希:tag
|
||||
u32 hash = (u32)key->tag;
|
||||
|
||||
switch (key->tag) {
|
||||
case SCC_HIR_TYPE_void:
|
||||
case SCC_HIR_TYPE_u8:
|
||||
case SCC_HIR_TYPE_u16:
|
||||
case SCC_HIR_TYPE_u32:
|
||||
case SCC_HIR_TYPE_u64:
|
||||
case SCC_HIR_TYPE_u128:
|
||||
case SCC_HIR_TYPE_i8:
|
||||
case SCC_HIR_TYPE_i16:
|
||||
case SCC_HIR_TYPE_i32:
|
||||
case SCC_HIR_TYPE_i64:
|
||||
case SCC_HIR_TYPE_i128:
|
||||
case SCC_HIR_TYPE_f16:
|
||||
case SCC_HIR_TYPE_f32:
|
||||
case SCC_HIR_TYPE_f64:
|
||||
case SCC_HIR_TYPE_f128:
|
||||
// 基本类型,只有tag
|
||||
break;
|
||||
|
||||
case SCC_HIR_TYPE_PTR:
|
||||
hash = scc_hash_mix(hash, (u32)key->data.array.base);
|
||||
break;
|
||||
|
||||
case SCC_HIR_TYPE_ARRAY:
|
||||
hash = scc_hash_mix(hash, (u32)key->data.array.base);
|
||||
hash = scc_hash_mix(hash, (u32)key->data.array.len);
|
||||
break;
|
||||
|
||||
case SCC_HIR_TYPE_FUNC:
|
||||
// 注意:这里需要递归哈希参数类型
|
||||
hash = scc_hash_mix(hash, (u32)key->data.function.ret_type);
|
||||
for (usize i = 0; i < key->data.function.params.size; i++) {
|
||||
hash = scc_hash_mix(hash, (u32)key->data.function.params.data[i]);
|
||||
}
|
||||
hash = scc_hash_mix(hash, (u32)key->data.function.params.size);
|
||||
break;
|
||||
|
||||
case SCC_HIR_TYPE_STRUCT:
|
||||
case SCC_HIR_TYPE_UNION:
|
||||
return 0;
|
||||
case SCC_HIR_TYPE_VECTOR:
|
||||
default:
|
||||
Panic("Invalid type tag %d", key->tag);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
static int cmp_type(const void *_key1, const void *_key2, void *userdata) {
|
||||
scc_hir_module_t *module = userdata;
|
||||
const scc_hir_type_t *key1 = _key1 == SCC_HIR_REF_nullptr
|
||||
? &scc_vec_at(module->types, 0)
|
||||
: scc_hir_module_get_type(module,
|
||||
(usize)_key1),
|
||||
*key2 = _key2 == SCC_HIR_REF_nullptr
|
||||
? &scc_vec_at(module->types, 0)
|
||||
: scc_hir_module_get_type(module,
|
||||
(usize)_key2);
|
||||
Assert(key1 != nullptr && key2 != nullptr);
|
||||
if (key1->tag == SCC_HIR_TYPE_unknown ||
|
||||
key2->tag == SCC_HIR_TYPE_unknown) {
|
||||
return 1;
|
||||
}
|
||||
// tag不同
|
||||
if (key1->tag != key2->tag) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (key1->tag) {
|
||||
case SCC_HIR_TYPE_void:
|
||||
case SCC_HIR_TYPE_u8:
|
||||
case SCC_HIR_TYPE_u16:
|
||||
case SCC_HIR_TYPE_u32:
|
||||
case SCC_HIR_TYPE_u64:
|
||||
case SCC_HIR_TYPE_u128:
|
||||
case SCC_HIR_TYPE_i8:
|
||||
case SCC_HIR_TYPE_i16:
|
||||
case SCC_HIR_TYPE_i32:
|
||||
case SCC_HIR_TYPE_i64:
|
||||
case SCC_HIR_TYPE_i128:
|
||||
case SCC_HIR_TYPE_f16:
|
||||
case SCC_HIR_TYPE_f32:
|
||||
case SCC_HIR_TYPE_f64:
|
||||
case SCC_HIR_TYPE_f128:
|
||||
return 0; // 基本类型,tag相同即可
|
||||
case SCC_HIR_TYPE_PTR:
|
||||
return key1->data.pointer.base != key2->data.pointer.base;
|
||||
case SCC_HIR_TYPE_ARRAY:
|
||||
return (key1->data.array.base != key2->data.array.base) ||
|
||||
(key1->data.array.len != key2->data.array.len);
|
||||
case SCC_HIR_TYPE_FUNC: {
|
||||
if (key1->data.function.ret_type != key2->data.function.ret_type) {
|
||||
return 1;
|
||||
}
|
||||
if (key1->data.function.params.size !=
|
||||
key2->data.function.params.size) {
|
||||
return 1;
|
||||
}
|
||||
for (usize i = 0; i < key1->data.function.params.size; i++) {
|
||||
if (key1->data.function.params.data[i] !=
|
||||
key2->data.function.params.data[i]) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
Panic("Unknown key type %d", key1->tag);
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void scc_hir_builder_init(scc_hir_builder_t *builder, scc_hir_cprog_t *cprog) {
|
||||
builder->current_bblock = SCC_HIR_REF_nullptr;
|
||||
builder->current_func = SCC_HIR_REF_nullptr;
|
||||
builder->cprog = cprog;
|
||||
|
||||
scc_hashtable_init(&builder->type_uniquing, hash_type, cmp_type,
|
||||
GET_MODULE(builder));
|
||||
// scc_hashtable_init(&builder->const_pool, /* 常量哈希函数 */,
|
||||
// /* 常量比较函数 */);
|
||||
scc_hashtable_cstr_init(&builder->func_decl_set);
|
||||
#ifndef SCC_NO_DEBUG
|
||||
builder->borrow_depth = 0;
|
||||
builder->dbg_file = nullptr;
|
||||
builder->dbg_line = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void scc_hir_builder_drop(scc_hir_builder_t *builder) {
|
||||
scc_hashtable_drop(&builder->type_uniquing);
|
||||
// scc_hashtable_drop(&builder->const_pool);
|
||||
scc_hashtable_drop(&builder->func_decl_set);
|
||||
}
|
||||
|
||||
scc_hir_func_ref_t scc_hir_builder_func(scc_hir_builder_t *builder,
|
||||
scc_hir_type_ref_t type_ref,
|
||||
const char *name) {
|
||||
SCC_HIR_BUILDER_CHECK_NO_BORROW(builder);
|
||||
// 检查是否已声明
|
||||
void *found = scc_hashtable_get(&builder->func_decl_set, (void *)name);
|
||||
if (found) {
|
||||
return (scc_hir_func_ref_t)(usize)found;
|
||||
}
|
||||
|
||||
// 创建新函数
|
||||
scc_hir_func_t func;
|
||||
scc_hir_func_meta_t *meta = scc_malloc(sizeof(scc_hir_func_meta_t));
|
||||
Assert(meta != nullptr);
|
||||
func.meta = meta;
|
||||
scc_hir_func_init(&func, name);
|
||||
meta->type = type_ref;
|
||||
|
||||
scc_hir_func_ref_t func_ref =
|
||||
scc_hir_module_add_func(GET_MODULE(builder), &func);
|
||||
scc_hashtable_set(&builder->func_decl_set, (void *)name,
|
||||
(void *)(usize)func_ref);
|
||||
|
||||
scc_vec_push(builder->cprog->func_decls, func_ref);
|
||||
return func_ref;
|
||||
}
|
||||
|
||||
scc_hir_bblock_ref_t scc_hir_builder_bblock(scc_hir_builder_t *builder,
|
||||
const char *label) {
|
||||
SCC_HIR_BUILDER_CHECK_NO_BORROW(builder);
|
||||
scc_hir_bblock_t bblock = {0};
|
||||
if (label) {
|
||||
bblock.name = label;
|
||||
}
|
||||
// scc_hir_bblock_meta_t bblock_meta = {0};
|
||||
// FIXME 当前没有bblock meta
|
||||
bblock.meta = nullptr;
|
||||
scc_vec_init(*SCC_HIR_BBLOCK_VALUES(&bblock));
|
||||
|
||||
scc_hir_bblock_ref_t bblock_ref =
|
||||
scc_hir_module_add_bblock(GET_MODULE(builder), &bblock);
|
||||
|
||||
// 将基本块添加到当前函数
|
||||
scc_hir_func_t *current_func = nullptr;
|
||||
SCC_HIR_BUILDER_BEGIN_BORROW(
|
||||
builder, current_func,
|
||||
scc_hir_module_get_func(GET_MODULE(builder), builder->current_func));
|
||||
if (current_func) {
|
||||
// FIXME hack cfg
|
||||
scc_vec_push(current_func->bblocks, bblock_ref);
|
||||
}
|
||||
SCC_HIR_BUILDER_END_BORROW(builder);
|
||||
return bblock_ref;
|
||||
}
|
||||
|
||||
scc_hir_type_ref_t scc_hir_builder_type(scc_hir_builder_t *builder,
|
||||
const scc_hir_type_t *type_desc) {
|
||||
SCC_HIR_BUILDER_CHECK_NO_BORROW(builder);
|
||||
|
||||
Assert(type_desc->tag != SCC_HIR_TYPE_unknown);
|
||||
|
||||
scc_vec_at(GET_MODULE(builder)->types, 0) = *type_desc;
|
||||
// 先查哈希表
|
||||
void *found = scc_hashtable_get(&builder->type_uniquing, (void *)(usize)0);
|
||||
if (found) {
|
||||
return (scc_hir_type_ref_t)(usize)found;
|
||||
}
|
||||
|
||||
// 不存在,添加新类型
|
||||
scc_hir_type_ref_t new_ref =
|
||||
scc_hir_module_add_type(GET_MODULE(builder), type_desc);
|
||||
scc_hashtable_set(&builder->type_uniquing, (void *)(usize)new_ref,
|
||||
(void *)(usize)new_ref);
|
||||
return new_ref;
|
||||
}
|
||||
|
||||
scc_hir_value_ref_t scc_hir_builder_const_string(scc_hir_builder_t *builder,
|
||||
const char *str, usize len) {
|
||||
SCC_HIR_BUILDER_CHECK_NO_BORROW(builder);
|
||||
scc_hir_type_ref_t u8_type = scc_hir_builder_type_u8(builder);
|
||||
scc_hir_type_t array_type = {
|
||||
.tag = SCC_HIR_TYPE_ARRAY,
|
||||
.data.array.base = u8_type,
|
||||
.data.array.len = len - 1, // 包含 nullptr 结尾
|
||||
};
|
||||
scc_hir_type_ref_t array_type_ref =
|
||||
scc_hir_builder_type(builder, &array_type);
|
||||
|
||||
// 5. 创建聚合节点
|
||||
scc_hir_value_t const_array_value = {
|
||||
.tag = SCC_HIR_VALUE_TAG_ARRAY,
|
||||
.type = array_type_ref,
|
||||
.data.const_array.base_type = u8_type,
|
||||
};
|
||||
char *buff = scc_malloc(len - 1);
|
||||
Assert(buff);
|
||||
// FIXME content to real string
|
||||
for (usize i = 1; i < len - 1; i++) {
|
||||
buff[i - 1] = str[i];
|
||||
}
|
||||
buff[len - 2] = '\0';
|
||||
scc_vec_unsafe_from_buffer(const_array_value.data.const_array.fields,
|
||||
(u8 *)buff, len - 1);
|
||||
scc_hir_value_ref_t const_array_ref =
|
||||
scc_hir_module_add_value(GET_MODULE(builder), &const_array_value);
|
||||
Assert(const_array_ref != SCC_HIR_REF_nullptr);
|
||||
|
||||
// 3. 创建全局变量节点,类型为指针,初始值指向常量数组
|
||||
scc_hir_value_ref_t global_value_ref =
|
||||
scc_hir_builder_global_alloca(builder, array_type_ref, const_array_ref);
|
||||
// scc_hashtable_insert(builder);
|
||||
|
||||
scc_hir_value_ref_t pointer_to_global_value = scc_hir_module_add_value(
|
||||
GET_MODULE(builder),
|
||||
&(scc_hir_value_t){
|
||||
.tag = SCC_HIR_VALUE_TAG_GET_ELEM_PTR,
|
||||
.data.get_elem_ptr.src_addr = global_value_ref,
|
||||
.data.get_elem_ptr.index = SCC_HIR_VALUE_TAG_NULLPTR,
|
||||
});
|
||||
scc_hir_builder_add_instr(builder, pointer_to_global_value);
|
||||
return pointer_to_global_value;
|
||||
}
|
||||
|
||||
void scc_hir_builder_begin_func(scc_hir_builder_t *builder,
|
||||
scc_hir_func_ref_t func_ref) {
|
||||
SCC_HIR_BUILDER_CHECK_NO_BORROW(builder);
|
||||
builder->current_func = func_ref;
|
||||
|
||||
// 借用 func_ptr 和 func_type 以获取参数类型列表
|
||||
scc_hir_func_t *func_ptr = nullptr;
|
||||
scc_hir_type_t *func_type = nullptr;
|
||||
SCC_HIR_BUILDER_BEGIN_BORROW(
|
||||
builder, func_ptr,
|
||||
scc_hir_module_get_func(GET_MODULE(builder), func_ref));
|
||||
SCC_HIR_BUILDER_BEGIN_BORROW(
|
||||
builder, func_type,
|
||||
scc_hir_module_get_type(GET_MODULE(builder),
|
||||
SCC_HIR_FUNC_META(func_ptr)->type));
|
||||
|
||||
if (func_type == nullptr || func_type->tag != SCC_HIR_TYPE_FUNC) {
|
||||
LOG_ERROR("Invalid function type");
|
||||
SCC_HIR_BUILDER_END_BORROW(builder); // func_type
|
||||
SCC_HIR_BUILDER_END_BORROW(builder); // func_ptr
|
||||
return;
|
||||
}
|
||||
if (func_ptr == nullptr) {
|
||||
LOG_ERROR("Invalid function reference");
|
||||
SCC_HIR_BUILDER_END_BORROW(builder); // func_type
|
||||
SCC_HIR_BUILDER_END_BORROW(builder); // func_ptr
|
||||
return;
|
||||
}
|
||||
if (scc_vec_size(func_ptr->bblocks) != 0 ||
|
||||
scc_vec_size(SCC_HIR_FUNC_META(func_ptr)->params) != 0) {
|
||||
LOG_FATAL("Multiple function definitions");
|
||||
SCC_HIR_BUILDER_END_BORROW(builder); // func_type
|
||||
SCC_HIR_BUILDER_END_BORROW(builder); // func_ptr
|
||||
return;
|
||||
}
|
||||
|
||||
// 释放借用,因为下面要调用 add_value(可能 realloc)
|
||||
SCC_HIR_BUILDER_END_BORROW(builder); // func_type
|
||||
SCC_HIR_BUILDER_END_BORROW(builder); // func_ptr
|
||||
}
|
||||
|
||||
void scc_hir_builder_end_func(scc_hir_builder_t *builder) {
|
||||
SCC_HIR_BUILDER_CHECK_NO_BORROW(builder);
|
||||
scc_hir_func_t *func_ptr = nullptr;
|
||||
SCC_HIR_BUILDER_BEGIN_BORROW(
|
||||
builder, func_ptr,
|
||||
scc_hir_module_get_func(GET_MODULE(builder), builder->current_func));
|
||||
if (func_ptr == nullptr) {
|
||||
LOG_FATAL("Invalid function reference");
|
||||
SCC_HIR_BUILDER_END_BORROW(builder);
|
||||
return;
|
||||
}
|
||||
if (scc_vec_size(func_ptr->bblocks) == 0) {
|
||||
scc_vec_push(builder->cprog->func_decls, builder->current_func);
|
||||
} else {
|
||||
scc_vec_push(builder->cprog->func_defs, builder->current_func);
|
||||
}
|
||||
SCC_HIR_BUILDER_END_BORROW(builder);
|
||||
builder->current_func = 0;
|
||||
}
|
||||
|
||||
scc_hir_func_ref_t scc_hir_builder_current_func(scc_hir_builder_t *builder) {
|
||||
// 只读操作,无需检查借用
|
||||
return builder->current_func;
|
||||
}
|
||||
|
||||
scc_hir_bblock_ref_t scc_hir_builder_begin_bblock(scc_hir_builder_t *builder,
|
||||
const char *label) {
|
||||
SCC_HIR_BUILDER_CHECK_NO_BORROW(builder);
|
||||
builder->current_bblock = scc_hir_builder_bblock(builder, label);
|
||||
return builder->current_bblock;
|
||||
}
|
||||
|
||||
void scc_hir_builder_end_bblock(scc_hir_builder_t *builder) {
|
||||
SCC_HIR_BUILDER_CHECK_NO_BORROW(builder);
|
||||
builder->current_bblock = 0;
|
||||
}
|
||||
|
||||
void scc_hir_builder_set_current_bblock(scc_hir_builder_t *builder,
|
||||
scc_hir_bblock_ref_t bblock) {
|
||||
SCC_HIR_BUILDER_CHECK_NO_BORROW(builder);
|
||||
builder->current_bblock = bblock;
|
||||
}
|
||||
|
||||
scc_hir_func_ref_t scc_hir_builder_current_bblock(scc_hir_builder_t *builder) {
|
||||
return builder->current_bblock;
|
||||
}
|
||||
|
||||
void scc_hir_builder_add_instr(scc_hir_builder_t *builder,
|
||||
scc_hir_value_ref_t instr) {
|
||||
SCC_HIR_BUILDER_CHECK_NO_BORROW(builder);
|
||||
scc_hir_bblock_t *current_bblock = nullptr;
|
||||
SCC_HIR_BUILDER_BEGIN_BORROW(
|
||||
builder, current_bblock,
|
||||
scc_hir_module_get_bblock(GET_MODULE(builder),
|
||||
builder->current_bblock));
|
||||
if (current_bblock) {
|
||||
scc_vec_push(*SCC_HIR_BBLOCK_VALUES(current_bblock), instr);
|
||||
} else {
|
||||
LOG_ERROR("Current basic block is not set");
|
||||
}
|
||||
SCC_HIR_BUILDER_END_BORROW(builder);
|
||||
}
|
||||
|
||||
scc_hir_value_ref_t scc_hir_builder_global_alloca(scc_hir_builder_t *builder,
|
||||
scc_hir_type_ref_t type,
|
||||
scc_hir_value_ref_t value) {
|
||||
SCC_HIR_BUILDER_CHECK_NO_BORROW(builder);
|
||||
char *name = scc_malloc(32);
|
||||
scc_hir_value_ref_t global_value_ref = scc_hir_module_add_value(
|
||||
GET_MODULE(builder), &(scc_hir_value_t){
|
||||
.name = name,
|
||||
.tag = SCC_HIR_VALUE_TAG_GLOBAL_ALLOC,
|
||||
.type = type,
|
||||
.data.global_alloc.value = value,
|
||||
});
|
||||
scc_snprintf(name, 32, "$G%u", global_value_ref);
|
||||
scc_vec_push(builder->cprog->global_vals, global_value_ref);
|
||||
return global_value_ref;
|
||||
}
|
||||
|
||||
scc_hir_value_ref_t scc_hir_builder_alloca(scc_hir_builder_t *builder,
|
||||
scc_hir_type_ref_t type,
|
||||
const char *name) {
|
||||
SCC_HIR_BUILDER_CHECK_NO_BORROW(builder);
|
||||
scc_hir_value_t alloc_node = {0};
|
||||
alloc_node.tag = SCC_HIR_VALUE_TAG_ALLOC;
|
||||
alloc_node.type = scc_hir_module_add_type(
|
||||
GET_MODULE(builder),
|
||||
&(scc_hir_type_t){.tag = SCC_HIR_TYPE_PTR, .data.pointer.base = type});
|
||||
alloc_node.name = name;
|
||||
|
||||
scc_hir_value_ref_t value_ref =
|
||||
scc_hir_module_add_value(GET_MODULE(builder), &alloc_node);
|
||||
scc_hir_builder_add_instr(builder, value_ref);
|
||||
return value_ref;
|
||||
}
|
||||
|
||||
scc_hir_value_ref_t scc_hir_builder_func_arg_ref(scc_hir_builder_t *builder,
|
||||
scc_hir_type_ref_t type,
|
||||
const char *name,
|
||||
usize arg_idx) {
|
||||
SCC_HIR_BUILDER_CHECK_NO_BORROW(builder);
|
||||
scc_hir_value_t value = {0};
|
||||
value.tag = SCC_HIR_VALUE_TAG_FUNC_ARG_REF;
|
||||
value.type = type;
|
||||
value.name = name;
|
||||
value.data.arg_ref.idx = arg_idx;
|
||||
|
||||
scc_hir_value_ref_t value_ref =
|
||||
scc_hir_module_add_value(GET_MODULE(builder), &value);
|
||||
scc_hir_builder_add_instr(builder, value_ref);
|
||||
return value_ref;
|
||||
}
|
||||
|
||||
scc_hir_value_ref_t scc_hir_builder_load(scc_hir_builder_t *builder,
|
||||
scc_hir_value_ref_t target) {
|
||||
SCC_HIR_BUILDER_CHECK_NO_BORROW(builder);
|
||||
scc_hir_value_t load_node = {0};
|
||||
load_node.tag = SCC_HIR_VALUE_TAG_LOAD;
|
||||
load_node.data.load.target = target;
|
||||
|
||||
// 借用 ptr_node 和 ptr_type 获取类型信息
|
||||
scc_hir_value_t *ptr_node = nullptr;
|
||||
SCC_HIR_BUILDER_BEGIN_BORROW(
|
||||
builder, ptr_node,
|
||||
scc_hir_module_get_value(GET_MODULE(builder), target));
|
||||
if (ptr_node) {
|
||||
scc_hir_type_t *ptr_type = nullptr;
|
||||
SCC_HIR_BUILDER_BEGIN_BORROW(
|
||||
builder, ptr_type,
|
||||
scc_hir_module_get_type(GET_MODULE(builder), ptr_node->type));
|
||||
if (ptr_type && ptr_type->tag == SCC_HIR_TYPE_PTR) {
|
||||
load_node.type = ptr_type->data.pointer.base;
|
||||
}
|
||||
SCC_HIR_BUILDER_END_BORROW(builder); // ptr_type
|
||||
}
|
||||
SCC_HIR_BUILDER_END_BORROW(builder); // ptr_node
|
||||
|
||||
scc_hir_value_ref_t value_ref =
|
||||
scc_hir_module_add_value(GET_MODULE(builder), &load_node);
|
||||
scc_hir_builder_add_instr(builder, value_ref);
|
||||
return value_ref;
|
||||
}
|
||||
|
||||
scc_hir_value_ref_t scc_hir_builder_store(scc_hir_builder_t *builder,
|
||||
scc_hir_value_ref_t target,
|
||||
scc_hir_value_ref_t value) {
|
||||
SCC_HIR_BUILDER_CHECK_NO_BORROW(builder);
|
||||
Assert(target != SCC_HIR_REF_nullptr && value != SCC_HIR_REF_nullptr);
|
||||
scc_hir_value_t store_node = {0};
|
||||
store_node.tag = SCC_HIR_VALUE_TAG_STORE;
|
||||
store_node.data.store.target = target;
|
||||
store_node.data.store.value = value;
|
||||
|
||||
scc_hir_value_ref_t value_ref =
|
||||
scc_hir_module_add_value(GET_MODULE(builder), &store_node);
|
||||
scc_hir_builder_add_instr(builder, value_ref);
|
||||
return value_ref;
|
||||
}
|
||||
|
||||
scc_hir_value_ref_t scc_hir_builder_get_elem_ptr(scc_hir_builder_t *builder,
|
||||
scc_hir_value_ref_t target,
|
||||
scc_hir_value_ref_t index) {
|
||||
SCC_HIR_BUILDER_CHECK_NO_BORROW(builder);
|
||||
scc_hir_value_t get_ptr_node = {0};
|
||||
get_ptr_node.tag = SCC_HIR_VALUE_TAG_GET_ELEM_PTR;
|
||||
get_ptr_node.data.get_elem_ptr.src_addr = target;
|
||||
get_ptr_node.data.get_elem_ptr.index = index;
|
||||
|
||||
// 借用类型信息
|
||||
scc_hir_type_t *type_ref = nullptr;
|
||||
SCC_HIR_BUILDER_BEGIN_BORROW(
|
||||
builder, type_ref,
|
||||
scc_hir_module_get_type_by_value(GET_MODULE(builder), target));
|
||||
Assert(type_ref != nullptr);
|
||||
scc_hir_type_t type = *type_ref; // 拷贝一份,避免后续借用
|
||||
SCC_HIR_BUILDER_END_BORROW(builder); // type_ref
|
||||
|
||||
if (type.tag == SCC_HIR_TYPE_PTR) {
|
||||
scc_hir_type_t *base_type = nullptr;
|
||||
SCC_HIR_BUILDER_BEGIN_BORROW(
|
||||
builder, base_type,
|
||||
scc_hir_module_get_type(GET_MODULE(builder),
|
||||
type_ref->data.pointer.base));
|
||||
if (base_type->tag == SCC_HIR_TYPE_ARRAY) {
|
||||
scc_hir_type_t type = (scc_hir_type_t){
|
||||
.tag = SCC_HIR_TYPE_PTR,
|
||||
.data.pointer.base = base_type->data.array.base,
|
||||
};
|
||||
SCC_HIR_BUILDER_END_BORROW(builder); // base_type
|
||||
get_ptr_node.type = scc_hir_builder_type(builder, &type);
|
||||
} else {
|
||||
SCC_HIR_BUILDER_END_BORROW(builder); // base_type
|
||||
get_ptr_node.type = scc_hir_builder_type(builder, &type);
|
||||
}
|
||||
} else {
|
||||
get_ptr_node.type = scc_hir_builder_type(builder, &type);
|
||||
}
|
||||
|
||||
scc_hir_value_ref_t value_ref =
|
||||
scc_hir_module_add_value(GET_MODULE(builder), &get_ptr_node);
|
||||
scc_hir_builder_add_instr(builder, value_ref);
|
||||
return value_ref;
|
||||
}
|
||||
|
||||
scc_hir_value_ref_t scc_hir_builder_binop(scc_hir_builder_t *builder,
|
||||
scc_hir_op_type_t op,
|
||||
scc_hir_value_ref_t lhs,
|
||||
scc_hir_value_ref_t rhs) {
|
||||
SCC_HIR_BUILDER_CHECK_NO_BORROW(builder);
|
||||
scc_hir_value_t binop_node = {0};
|
||||
binop_node.tag = SCC_HIR_VALUE_TAG_OP;
|
||||
binop_node.data.op.op = op;
|
||||
binop_node.data.op.lhs = lhs;
|
||||
binop_node.data.op.rhs = rhs;
|
||||
|
||||
// 借用 lhs_node 获取类型
|
||||
scc_hir_value_t *lhs_node = nullptr;
|
||||
SCC_HIR_BUILDER_BEGIN_BORROW(
|
||||
builder, lhs_node, scc_hir_module_get_value(GET_MODULE(builder), lhs));
|
||||
if (lhs_node) {
|
||||
binop_node.type = lhs_node->type;
|
||||
}
|
||||
SCC_HIR_BUILDER_END_BORROW(builder); // lhs_node
|
||||
|
||||
scc_hir_value_ref_t value_ref =
|
||||
scc_hir_module_add_value(GET_MODULE(builder), &binop_node);
|
||||
scc_hir_builder_add_instr(builder, value_ref);
|
||||
return value_ref;
|
||||
}
|
||||
|
||||
scc_hir_value_ref_t scc_hir_builder_cmp(scc_hir_builder_t *builder,
|
||||
scc_hir_op_type_t op,
|
||||
scc_hir_value_ref_t lhs,
|
||||
scc_hir_value_ref_t rhs) {
|
||||
SCC_HIR_BUILDER_CHECK_NO_BORROW(builder);
|
||||
scc_hir_value_t cmp_node = {0};
|
||||
cmp_node.tag = SCC_HIR_VALUE_TAG_OP;
|
||||
cmp_node.data.op.op = op;
|
||||
cmp_node.data.op.lhs = lhs;
|
||||
cmp_node.data.op.rhs = rhs;
|
||||
cmp_node.type = 0; // FIXME
|
||||
|
||||
scc_hir_value_ref_t value_ref =
|
||||
scc_hir_module_add_value(GET_MODULE(builder), &cmp_node);
|
||||
scc_hir_builder_add_instr(builder, value_ref);
|
||||
return value_ref;
|
||||
}
|
||||
|
||||
scc_hir_value_ref_t scc_hir_builder_jump(scc_hir_builder_t *builder,
|
||||
scc_hir_bblock_ref_t target) {
|
||||
SCC_HIR_BUILDER_CHECK_NO_BORROW(builder);
|
||||
scc_hir_value_t jump_node = {0};
|
||||
jump_node.tag = SCC_HIR_VALUE_TAG_JUMP;
|
||||
jump_node.data.jump.target_bblock = target;
|
||||
|
||||
scc_hir_value_ref_t value_ref =
|
||||
scc_hir_module_add_value(GET_MODULE(builder), &jump_node);
|
||||
scc_hir_builder_add_instr(builder, value_ref);
|
||||
return value_ref;
|
||||
}
|
||||
|
||||
scc_hir_value_ref_t scc_hir_builder_branch(scc_hir_builder_t *builder,
|
||||
scc_hir_value_ref_t cond,
|
||||
scc_hir_bblock_ref_t true_target,
|
||||
scc_hir_bblock_ref_t false_target) {
|
||||
SCC_HIR_BUILDER_CHECK_NO_BORROW(builder);
|
||||
scc_hir_value_t branch_node = {0};
|
||||
branch_node.tag = SCC_HIR_VALUE_TAG_BRANCH;
|
||||
branch_node.data.branch.cond = cond;
|
||||
branch_node.data.branch.true_bblock = true_target;
|
||||
branch_node.data.branch.false_bblock = false_target;
|
||||
|
||||
scc_hir_value_ref_t value_ref =
|
||||
scc_hir_module_add_value(GET_MODULE(builder), &branch_node);
|
||||
scc_hir_builder_add_instr(builder, value_ref);
|
||||
return value_ref;
|
||||
}
|
||||
|
||||
scc_hir_value_ref_t scc_hir_builder_call(scc_hir_builder_t *builder,
|
||||
scc_hir_func_ref_t callee,
|
||||
const scc_hir_value_ref_t *args,
|
||||
usize arg_count) {
|
||||
SCC_HIR_BUILDER_CHECK_NO_BORROW(builder);
|
||||
scc_hir_value_t call_node = {0};
|
||||
call_node.tag = SCC_HIR_VALUE_TAG_CALL;
|
||||
call_node.data.call.callee = callee;
|
||||
|
||||
scc_vec_init(call_node.data.call.args);
|
||||
for (usize i = 0; i < arg_count; i++) {
|
||||
scc_vec_push(call_node.data.call.args, args[i]);
|
||||
}
|
||||
|
||||
// 借用 callee_func 和 func_type 获取返回类型
|
||||
scc_hir_func_t *callee_func = nullptr;
|
||||
SCC_HIR_BUILDER_BEGIN_BORROW(
|
||||
builder, callee_func,
|
||||
scc_hir_module_get_func(GET_MODULE(builder), callee));
|
||||
if (callee_func) {
|
||||
scc_hir_type_t *func_type = nullptr;
|
||||
SCC_HIR_BUILDER_BEGIN_BORROW(
|
||||
builder, func_type,
|
||||
scc_hir_module_get_type(GET_MODULE(builder),
|
||||
SCC_HIR_FUNC_META(callee_func)->type));
|
||||
if (func_type && func_type->tag == SCC_HIR_TYPE_FUNC) {
|
||||
call_node.type = func_type->data.function.ret_type;
|
||||
}
|
||||
SCC_HIR_BUILDER_END_BORROW(builder); // func_type
|
||||
}
|
||||
SCC_HIR_BUILDER_END_BORROW(builder); // callee_func
|
||||
|
||||
scc_hir_value_ref_t value_ref =
|
||||
scc_hir_module_add_value(GET_MODULE(builder), &call_node);
|
||||
scc_hir_builder_add_instr(builder, value_ref);
|
||||
return value_ref;
|
||||
}
|
||||
|
||||
scc_hir_value_ref_t scc_hir_builder_ret(scc_hir_builder_t *builder,
|
||||
scc_hir_value_ref_t value) {
|
||||
SCC_HIR_BUILDER_CHECK_NO_BORROW(builder);
|
||||
scc_hir_value_t ret_node = {0};
|
||||
ret_node.tag = SCC_HIR_VALUE_TAG_RET;
|
||||
ret_node.data.ret.ret_val = value;
|
||||
|
||||
scc_hir_value_ref_t value_ref =
|
||||
scc_hir_module_add_value(GET_MODULE(builder), &ret_node);
|
||||
scc_hir_builder_add_instr(builder, value_ref);
|
||||
return value_ref;
|
||||
}
|
||||
|
||||
scc_hir_value_ref_t scc_hir_builder_ret_void(scc_hir_builder_t *builder) {
|
||||
SCC_HIR_BUILDER_CHECK_NO_BORROW(builder);
|
||||
scc_hir_value_t ret_node = {0};
|
||||
ret_node.tag = SCC_HIR_VALUE_TAG_RET;
|
||||
|
||||
scc_hir_value_t ret_val_node;
|
||||
scc_hir_value_init(&ret_val_node, nullptr, SCC_HIR_VALUE_TAG_NULLPTR);
|
||||
ret_val_node.type = scc_hir_builder_type_void(builder);
|
||||
ret_node.data.ret.ret_val =
|
||||
scc_hir_module_add_value(GET_MODULE(builder), &ret_val_node);
|
||||
|
||||
scc_hir_value_ref_t value_ref =
|
||||
scc_hir_module_add_value(GET_MODULE(builder), &ret_node);
|
||||
scc_hir_builder_add_instr(builder, value_ref);
|
||||
return value_ref;
|
||||
}
|
||||
|
||||
scc_hir_value_ref_t scc_hir_builder_builtin_memcpy(scc_hir_builder_t *builder,
|
||||
scc_hir_value_ref_t dest,
|
||||
scc_hir_value_ref_t src,
|
||||
scc_hir_value_ref_t len) {
|
||||
Assert(builder && src && dest && len);
|
||||
scc_hir_value_t value;
|
||||
scc_hir_value_init(&value, nullptr, SCC_HIR_VALUE_TAG_BUILTIN);
|
||||
value.type = scc_hir_builder_type_void(builder); // memcpy 返回 void*
|
||||
value.data.builtin.tag = SCC_HIR_BUILTIN_TAG_MEMCPY;
|
||||
value.data.builtin.func.memcpy.dest = dest;
|
||||
value.data.builtin.func.memcpy.src = src;
|
||||
value.data.builtin.func.memcpy.size = len;
|
||||
scc_hir_value_ref_t ref =
|
||||
scc_hir_module_add_value(GET_MODULE(builder), &value);
|
||||
scc_hir_builder_add_instr(builder, ref);
|
||||
return ref;
|
||||
}
|
||||
Reference in new issue
Block a user