#ifndef __SCC_IR_BUILDER_H__ #define __SCC_IR_BUILDER_H__ #include "ir_ctx.h" #include "scc_ir.h" typedef struct scc_ir_builder scc_ir_builder_t; /** * @brief IR 构建器上下文 * * 负责管理 IR 构建过程中的所有状态: * - 类型统一化(type uniquing) * - 符号命名分配 * - 内存管理 * - 当前构建位置(函数、基本块) */ struct scc_ir_builder { scc_ir_cprog_t *cprog; scc_ir_ctx_t ctx; ///< 核心上下文 scc_ir_func_ref_t current_func; ///< 当前正在构建的函数 scc_ir_bblock_ref_t current_bblock; ///< 当前基本块 }; /** * @brief 初始化 IR 构建器 */ void scc_ir_builder_init(scc_ir_builder_t *builder, scc_ir_cprog_t *cprog); /** * @brief 销毁 IR 构建器及其所有资源 */ void scc_ir_builder_drop(scc_ir_builder_t *builder); scc_ir_func_ref_t scc_ir_builder_func(scc_ir_builder_t *builder, scc_ir_type_ref_t type_ref, const char *name); scc_ir_type_ref_t scc_ir_builder_type(scc_ir_builder_t *builder, const scc_ir_type_t *type_desc); void scc_ir_builder_add_instr(scc_ir_builder_t *builder, scc_ir_value_ref_t instr); #define SCC_IR_BUILDER_TYPE_FUNC(scc_type) \ [[maybe_unused]] static inline scc_ir_type_ref_t \ scc_ir_builder_type_##scc_type(scc_ir_builder_t *builder) { \ scc_ir_type_t type_desc; \ scc_ir_type_init(&type_desc, SCC_IR_TYPE_##scc_type); \ return scc_ir_ctx_get_type(&builder->ctx, &type_desc); \ } SCC_IR_BUILDER_TYPE_FUNC(unknown) SCC_IR_BUILDER_TYPE_FUNC(void) SCC_IR_BUILDER_TYPE_FUNC(i8) SCC_IR_BUILDER_TYPE_FUNC(i16) SCC_IR_BUILDER_TYPE_FUNC(i32) SCC_IR_BUILDER_TYPE_FUNC(i64) SCC_IR_BUILDER_TYPE_FUNC(i128) SCC_IR_BUILDER_TYPE_FUNC(u8) SCC_IR_BUILDER_TYPE_FUNC(u16) SCC_IR_BUILDER_TYPE_FUNC(u32) SCC_IR_BUILDER_TYPE_FUNC(u64) SCC_IR_BUILDER_TYPE_FUNC(u128) // SCC_IR_BUILDER_TYPE_FUNC(f8) SCC_IR_BUILDER_TYPE_FUNC(f16) SCC_IR_BUILDER_TYPE_FUNC(f32) SCC_IR_BUILDER_TYPE_FUNC(f64) SCC_IR_BUILDER_TYPE_FUNC(f128) static inline scc_ir_value_ref_t scc_ir_builder_builtin_memcpy(scc_ir_builder_t *builder, scc_ir_value_ref_t dest, scc_ir_value_ref_t src, scc_ir_value_ref_t len) { Assert(builder && src && dest && len); scc_ir_value_t value; scc_ir_value_init(&value, nullptr, SCC_IR_VALUE_TAG_BUILTIN); value.type = scc_ir_builder_type_void(builder); // memcpy 返回 void* value.data.builtin.tag = SCC_IR_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_ir_value_ref_t ref = scc_ir_module_add_value(builder->ctx.module, &value); scc_ir_builder_add_instr(builder, ref); return ref; } // TODO static inline scc_ir_value_ref_t scc_ir_builder_const_int(scc_ir_builder_t *builder, scc_ir_type_ref_t type, scc_ir_const_int_t val) { scc_ir_value_t value; scc_ir_value_init(&value, nullptr, SCC_IR_VALUE_TAG_CONST_INT); value.data.const_int = val; value.type = type; return scc_ir_module_add_value(&builder->cprog->module, &value); } static inline scc_ir_value_ref_t scc_ir_builder_const_string(scc_ir_builder_t *builder, const char *str, usize len) { scc_ir_type_ref_t u8_type = scc_ir_builder_type_u8(builder); scc_ir_type_t array_type = { .tag = SCC_IR_TYPE_ARRAY, .data.array.base = u8_type, .data.array.len = len - 1, // 包含 nullptr 结尾 }; scc_ir_type_ref_t array_type_ref = scc_ir_ctx_get_type(&builder->ctx, &array_type); // 5. 创建聚合节点 scc_ir_value_t const_array_value = { .tag = SCC_IR_VALUE_TAG_CONST_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.elements, (u8 *)buff, len - 1); scc_ir_value_ref_t const_array_ref = scc_ir_module_add_value(builder->ctx.module, &const_array_value); Assert(const_array_ref != SCC_IR_REF_nullptr); // 3. 创建全局变量节点,类型为指针,初始值指向常量数组 char *name = scc_malloc(32); // FIXME MAYBE MEMORY LEAK scc_ir_value_ref_t global_value_ref = scc_ir_module_add_value( builder->ctx.module, &(scc_ir_value_t){ .name = name, .tag = SCC_IR_VALUE_TAG_GLOBAL_ALLOC, .type = array_type_ref, .data.global_alloc.value = const_array_ref, }); scc_snprintf(name, 32, "$G%u", global_value_ref); scc_vec_push(builder->cprog->global_vals, global_value_ref); // scc_hashtable_insert(builder); scc_ir_value_ref_t pointer_to_global_value = scc_ir_module_add_value( builder->ctx.module, &(scc_ir_value_t){ .tag = SCC_IR_VALUE_TAG_GET_PTR, .data.get_ptr.src_addr = global_value_ref, .data.get_ptr.index = SCC_IR_VALUE_TAG_NULLPTR, }); scc_ir_builder_add_instr(builder, pointer_to_global_value); return pointer_to_global_value; } /** * @brief 开始构建函数 * @param func_ref 函数引用 * @param param_names 参数名列表(可为nullptr) * @return void */ void scc_ir_builder_begin_func(scc_ir_builder_t *builder, scc_ir_func_ref_t func_ref, const char **param_names); /** * @brief 结束当前函数的构建 */ void scc_ir_builder_end_func(scc_ir_builder_t *builder); /** * @brief 获取当前正在构建的函数 */ scc_ir_func_ref_t scc_ir_builder_current_func(scc_ir_builder_t *builder); /** * @brief 创建一个新的基本块,并自动添加到当前函数中,但不改变当前块。 * @param builder IR构建器 * @param label 基本块标签(可为 nullptr,自动生成) * @return 新基本块的引用 */ scc_ir_bblock_ref_t scc_ir_builder_bblock(scc_ir_builder_t *builder, const char *label); /** * @brief 开始构建新的基本块 * @param label 基本块标签(可为nullptr,自动生成) * @return 基本块引用 */ scc_ir_bblock_ref_t scc_ir_builder_begin_bblock(scc_ir_builder_t *builder, const char *label); /** * @brief 结束当前基本块的构建 */ void scc_ir_builder_end_bblock(scc_ir_builder_t *builder); scc_ir_func_ref_t scc_ir_builder_current_bblock(scc_ir_builder_t *builder); /** * @brief 设置当前基本块 */ void scc_ir_builder_set_current_bblock(scc_ir_builder_t *builder, scc_ir_bblock_ref_t bblock); /** * @brief 创建alloca指令(在当前基本块中) * @param type 分配的类型 * @param name 变量名(可为nullptr) */ scc_ir_value_ref_t scc_ir_builder_alloca(scc_ir_builder_t *builder, scc_ir_type_ref_t type, const char *name); scc_ir_value_ref_t scc_ir_builder_func_arg_ref(scc_ir_builder_t *builder, scc_ir_type_ref_t type, const char *name, usize arg_idx); /** * @brief 创建load指令 * @param ptr 指针操作数 */ scc_ir_value_ref_t scc_ir_builder_load(scc_ir_builder_t *builder, scc_ir_value_ref_t ptr); /** * @brief 创建store指令 * @param ptr 目标指针 * @param value 要存储的值 */ scc_ir_value_ref_t scc_ir_builder_store(scc_ir_builder_t *builder, scc_ir_value_ref_t ptr, scc_ir_value_ref_t value); /** * @brief 创建getptr指令(指针运算) * @param ptr 基础指针 * @param index 索引值 */ scc_ir_value_ref_t scc_ir_builder_get_ptr(scc_ir_builder_t *builder, scc_ir_value_ref_t ptr, scc_ir_value_ref_t index); /** * @brief 创建二元运算指令 * @param op 操作符 * @param lhs 左操作数 * @param rhs 右操作数 */ scc_ir_value_ref_t scc_ir_builder_binop(scc_ir_builder_t *builder, scc_ir_op_type_t op, scc_ir_value_ref_t lhs, scc_ir_value_ref_t rhs); /** * @brief 创建比较指令 * @param op 比较操作符 * @param lhs 左操作数 * @param rhs 右操作数 */ scc_ir_value_ref_t scc_ir_builder_cmp(scc_ir_builder_t *builder, scc_ir_op_type_t op, scc_ir_value_ref_t lhs, scc_ir_value_ref_t rhs); /** * @brief 创建跳转指令(无条件) * @param target 目标基本块 */ scc_ir_value_ref_t scc_ir_builder_jump(scc_ir_builder_t *builder, scc_ir_bblock_ref_t target); /** * @brief 创建条件分支指令 * @param cond 条件值 * @param true_target 条件为真时的目标 * @param false_target 条件为假时的目标 */ scc_ir_value_ref_t scc_ir_builder_branch(scc_ir_builder_t *builder, scc_ir_value_ref_t cond, scc_ir_bblock_ref_t true_target, scc_ir_bblock_ref_t false_target); /** * @brief 创建函数调用指令 * @param callee 被调用函数 * @param args 参数列表 * @param arg_count 参数数量 */ scc_ir_value_ref_t scc_ir_builder_call(scc_ir_builder_t *builder, scc_ir_func_ref_t callee, const scc_ir_value_ref_t *args, usize arg_count); /** * @brief 创建返回指令(带返回值) * @param value 返回值 */ scc_ir_value_ref_t scc_ir_builder_ret(scc_ir_builder_t *builder, scc_ir_value_ref_t value); /** * @brief 创建返回指令(void返回) */ scc_ir_value_ref_t scc_ir_builder_ret_void(scc_ir_builder_t *builder); #endif /* __SCC_IR_BUILDER_H__ */