#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; ///< 当前基本块 #ifndef SCC_NO_DEBUG int borrow_depth; const char *dbg_file; int dbg_line; #endif }; #ifndef SCC_NO_DEBUG #define SCC_IR_BUILDER_BEGIN_BORROW(builder, ptr_var, ptr_expr) \ do { \ (builder)->borrow_depth++; \ (builder)->dbg_file = __FILE__; \ (builder)->dbg_line = __LINE__; \ ptr_var = (ptr_expr); \ } while (0) #define SCC_IR_BUILDER_END_BORROW(builder) \ do { \ (builder)->borrow_depth--; \ } while (0) #define SCC_IR_BUILDER_CHECK_NO_BORROW(builder) \ do { \ if ((builder)->borrow_depth != 0) { \ Panic("IR Builder: attempt to reallocate while borrowed at %s:%d", \ (builder)->dbg_file, (builder)->dbg_line); \ } \ } while (0) #else #define SCC_IR_BUILDER_BEGIN_BORROW(builder, ptr_var, ptr_expr) \ ptr_var = (ptr_expr) #define SCC_IR_BUILDER_END_BORROW(builder) ((void)0) #define SCC_IR_BUILDER_CHECK_NO_BORROW(builder) ((void)0) #endif /** * @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); scc_ir_value_ref_t scc_ir_builder_global_alloca(scc_ir_builder_t *builder, scc_ir_type_ref_t type, scc_ir_value_ref_t value); /** * @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); #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); } scc_ir_value_ref_t scc_ir_builder_const_string(scc_ir_builder_t *builder, const char *str, usize len); /** * @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); 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_elem_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__ */