Files
scc/libs/ir/src/ir_ctx.c
zzy 8c7af571c2 refactor(ast2ir): 更新IR构建器接口并重构类型映射
- 将IR构建器初始化函数修改为接受cprog参数
- 添加scc_ast2ir_ctx_drop函数用于资源清理
- 更新类型标识符命名规范,从大写改为小写形式
- 替换scc_ir_ctx_get_*函数调用为scc_ir_module_get_*函数
- 移除对ir_builtin.h的依赖,改用ir_builder.h中的构建器函数
- 为整数常量创建添加专门的构建器辅助函数

fix(ir): 重构IR上下文和模块管理结构

- 将原有的scc_ir_cprog_ctx_t拆分为scc_ir_module_t和scc_ir_ctx_t
- 添加scc_ir_module_t结构用于统一管理IR对象存储
- 更新IR类型枚举名称格式,从SCC_IR_TYPE_XXX改为SCC_IR_TYPE_xxx
- 添加整数、无符号整数和浮点数常量联合体定义
- 移除ir_base.h和ir_builtin.h头文件,整合到scc_ir.h中

feat(ir_builder): 添加类型构建器函数和常量创建功能

- 为各种基础类型添加scc_ir_builder_type_*内联函数
- 实现scc_ir_builder_const_int函数用于创建整数常量
- 修改构建器初始化函数签名以接受cprog参数
- 更新构建器内部结构,使用指向cprog的指针而非嵌入式结构
2026-03-25 11:59:27 +08:00

179 lines
5.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <ir_ctx.h>
/**
* @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) {
const scc_ir_type_t *key = _key;
// 初始哈希tag
u32 hash = (u32)key->tag;
switch (key->tag) {
case SCC_IR_TYPE_void:
case SCC_IR_TYPE_u8:
case SCC_IR_TYPE_u16:
case SCC_IR_TYPE_u32:
case SCC_IR_TYPE_u64:
case SCC_IR_TYPE_u128:
case SCC_IR_TYPE_i8:
case SCC_IR_TYPE_i16:
case SCC_IR_TYPE_i32:
case SCC_IR_TYPE_i64:
case SCC_IR_TYPE_i128:
case SCC_IR_TYPE_f16:
case SCC_IR_TYPE_f32:
case SCC_IR_TYPE_f64:
case SCC_IR_TYPE_f128:
// 基本类型只有tag
break;
case SCC_IR_TYPE_PTR:
hash = scc_hash_mix(hash, (u32)key->data.array.base);
break;
case SCC_IR_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_IR_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_IR_TYPE_STRUCT:
case SCC_IR_TYPE_VECTOR:
default:
UNREACHABLE();
return 0;
}
return hash;
}
static int cmp_type(const void *_key1, const void *_key2) {
const scc_ir_type_t *key1 = _key1, *key2 = _key2;
// tag不同
if (key1->tag != key2->tag) {
return 1;
}
switch (key1->tag) {
case SCC_IR_TYPE_void:
case SCC_IR_TYPE_u8:
case SCC_IR_TYPE_u16:
case SCC_IR_TYPE_u32:
case SCC_IR_TYPE_u64:
case SCC_IR_TYPE_u128:
case SCC_IR_TYPE_i8:
case SCC_IR_TYPE_i16:
case SCC_IR_TYPE_i32:
case SCC_IR_TYPE_i64:
case SCC_IR_TYPE_i128:
case SCC_IR_TYPE_f16:
case SCC_IR_TYPE_f32:
case SCC_IR_TYPE_f64:
case SCC_IR_TYPE_f128:
return 0; // 基本类型tag相同即可
case SCC_IR_TYPE_PTR:
return key1->data.pointer.base != key2->data.pointer.base;
case SCC_IR_TYPE_ARRAY:
return (key1->data.array.base != key2->data.array.base) ||
(key1->data.array.len != key2->data.array.len);
case SCC_IR_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:
UNREACHABLE();
return 1;
}
return 1;
}
void scc_ir_ctx_init(scc_ir_ctx_t *ctx, scc_ir_module_t *module) {
ctx->module = module;
scc_hashtable_init(&ctx->type_uniquing, hash_type, cmp_type);
// scc_hashtable_init(&ctx->const_pool, /* 常量哈希函数 */,
// /* 常量比较函数 */);
scc_hashtable_init(&ctx->func_decl_set,
(scc_hashtable_hash_func_t)scc_strhash32,
(scc_hashtable_equal_func_t)scc_strcmp);
}
void scc_ir_ctx_drop(scc_ir_ctx_t *ctx) {
scc_hashtable_drop(&ctx->type_uniquing);
// scc_hashtable_drop(&ctx->const_pool);
scc_hashtable_drop(&ctx->func_decl_set);
}
scc_ir_type_ref_t scc_ir_ctx_get_type(scc_ir_ctx_t *ctx,
const scc_ir_type_t *type_desc) {
// 先查哈希表
void *found = scc_hashtable_get(&ctx->type_uniquing, (void *)type_desc);
if (found) {
return (scc_ir_type_ref_t)(usize)found;
}
// 不存在,添加新类型
scc_ir_type_ref_t new_ref = scc_ir_module_add_type(ctx->module, type_desc);
scc_hashtable_set(&ctx->type_uniquing, (void *)type_desc,
(void *)(usize)new_ref);
return new_ref;
}
// scc_ir_node_ref_t scc_ir_ctx_get_const_int(scc_ir_ctx_t *ctx,
// scc_ir_type_ref_t type, i64 value)
// {
// return scc_ir_node_ref_t();
// }
scc_ir_func_ref_t scc_ir_ctx_declare_func(scc_ir_ctx_t *ctx,
scc_ir_type_ref_t type,
const char *name) {
// 检查是否已声明
void *found = scc_hashtable_get(&ctx->func_decl_set, (void *)name);
if (found) {
return (scc_ir_func_ref_t)(usize)found;
}
// 创建新函数
scc_ir_func_t func = {
.name = name,
.type = type,
};
scc_vec_init(func.params);
scc_vec_init(func.bblocks);
scc_ir_func_ref_t new_ref = scc_ir_module_add_func(ctx->module, &func);
scc_hashtable_set(&ctx->func_decl_set, (void *)name,
(void *)(usize)new_ref);
return new_ref;
}