Files
scc/libs/ir/hir/include/scc_hir_builder.h
zzy cec96333e7 feat(ast2ir): 实现C11类型提升系统并重构HIR基本块管理
- 新增 scc_ast2ir_promote.c 实现整数提升(6.3.1.1)和寻常算术转换(6.3.1.8)
- 重构 HIR Builder: bblock → create_bblock + append_bblock,引入BBList链表管理
- AST2IR 全面集成类型提升:二元运算、赋值、函数调用参数、自增/自减操作符
- 变参函数支持:跳过 ... 假参数,实现默认参数提升(float→double等)
- 简化 HIR Dump 实现
- MIR: Win64 ABI改进、x86指令选择优化
- 新增 printf 测试用例
2026-05-24 15:46:22 +08:00

314 lines
12 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.
#ifndef __SCC_HIR_BUILDER_H__
#define __SCC_HIR_BUILDER_H__
#include "scc_hir.h"
#include "scc_hir_prog.h"
typedef struct scc_hir_builder scc_hir_builder_t;
/**
* @brief IR 构建器上下文
*
* 负责管理 IR 构建过程中的所有状态:
* - 类型统一化type uniquing
* - 符号命名分配
* - 内存管理
* - 当前构建位置(函数、基本块)
*/
struct scc_hir_builder {
scc_hir_cprog_t *cprog;
scc_hir_func_ref_t current_func; ///< 当前正在构建的函数
scc_hir_bblock_ref_t current_bblock; ///< 当前基本块
scc_hashtable_t type_uniquing; // 类型哈希表hash -> type_ref
scc_hashtable_t const_pool; // 常量哈希表hash -> node_ref
scc_hashtable_t func_decl_set; // 函数声明集合name -> func_ref
#ifndef SCC_NO_DEBUG
int borrow_depth;
const char *dbg_file;
int dbg_line;
#endif
};
#ifndef SCC_NO_DEBUG
#define SCC_HIR_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_HIR_BUILDER_END_BORROW(builder) \
do { \
(builder)->borrow_depth--; \
} while (0)
#define SCC_HIR_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_HIR_BUILDER_BEGIN_BORROW(builder, ptr_var, ptr_expr) \
ptr_var = (ptr_expr)
#define SCC_HIR_BUILDER_END_BORROW(builder) ((void)0)
#define SCC_HIR_BUILDER_CHECK_NO_BORROW(builder) ((void)0)
#endif
/**
* @brief 初始化 IR 构建器
*/
void scc_hir_builder_init(scc_hir_builder_t *builder, scc_hir_cprog_t *cprog);
/**
* @brief 销毁 IR 构建器及其所有资源
*/
void scc_hir_builder_drop(scc_hir_builder_t *builder);
static inline scc_hir_module_t *
scc_hir_builder_get_module(scc_hir_builder_t *builder) {
return &builder->cprog->module;
}
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_type_ref_t scc_hir_builder_type(scc_hir_builder_t *builder,
const scc_hir_type_t *type_desc);
void scc_hir_builder_add_instr(scc_hir_builder_t *builder,
scc_hir_value_ref_t instr);
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);
/**
* @brief 创建alloca指令在当前基本块中
* @param type 分配的类型
* @param name 变量名可为nullptr
*/
scc_hir_value_ref_t scc_hir_builder_alloca(scc_hir_builder_t *builder,
scc_hir_type_ref_t type,
const char *name);
#define SCC_HIR_BUILDER_TYPE_FUNC(scc_type) \
SCC_MAYBE_UNUSED static inline scc_hir_type_ref_t \
scc_hir_builder_type_##scc_type(scc_hir_builder_t *builder) { \
scc_hir_type_t type_desc; \
scc_hir_type_init(&type_desc, SCC_HIR_TYPE_##scc_type); \
return scc_hir_builder_type(builder, &type_desc); \
}
SCC_HIR_BUILDER_TYPE_FUNC(unknown)
SCC_HIR_BUILDER_TYPE_FUNC(void)
SCC_HIR_BUILDER_TYPE_FUNC(i8)
SCC_HIR_BUILDER_TYPE_FUNC(i16)
SCC_HIR_BUILDER_TYPE_FUNC(i32)
SCC_HIR_BUILDER_TYPE_FUNC(i64)
SCC_HIR_BUILDER_TYPE_FUNC(i128)
SCC_HIR_BUILDER_TYPE_FUNC(u8)
SCC_HIR_BUILDER_TYPE_FUNC(u16)
SCC_HIR_BUILDER_TYPE_FUNC(u32)
SCC_HIR_BUILDER_TYPE_FUNC(u64)
SCC_HIR_BUILDER_TYPE_FUNC(u128)
// SCC_HIR_BUILDER_TYPE_FUNC(f8)
SCC_HIR_BUILDER_TYPE_FUNC(f16)
SCC_HIR_BUILDER_TYPE_FUNC(f32)
SCC_HIR_BUILDER_TYPE_FUNC(f64)
SCC_HIR_BUILDER_TYPE_FUNC(f128)
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);
// TODO
static inline scc_hir_value_ref_t
scc_hir_builder_integer(scc_hir_builder_t *builder, scc_hir_type_ref_t type,
scc_ap_t *val) {
Assert(builder != nullptr && val != nullptr);
scc_hir_value_t value;
scc_hir_value_init(&value, nullptr, SCC_HIR_VALUE_TAG_INTEGER);
// FIXME assign
value.data.integer = *val;
value.type = type;
return scc_hir_module_add_value(&builder->cprog->module, &value);
}
scc_hir_value_ref_t scc_hir_builder_const_string(scc_hir_builder_t *builder,
const char *str, usize len);
/**
* @brief 创建类型转换指令SEXT/ZEXT/TRUNC
* @param operand 被转换的值
* @param target_type 目标类型
* @param conv_kind 转换种类SCC_HIR_CONV_SEXT/ZEXT/TRUNC
*/
scc_hir_value_ref_t scc_hir_builder_conv(scc_hir_builder_t *builder,
scc_hir_value_ref_t operand,
scc_hir_type_ref_t target_type,
int conv_kind);
/**
* @brief 开始构建函数
* @param func_ref 函数引用
* @param param_names 参数名列表可为nullptr
* @return void
*/
void scc_hir_builder_begin_func(scc_hir_builder_t *builder,
scc_hir_func_ref_t func_ref);
/**
* @brief 结束当前函数的构建
*/
void scc_hir_builder_end_func(scc_hir_builder_t *builder);
/**
* @brief 获取当前正在构建的函数
*/
scc_hir_func_ref_t scc_hir_builder_current_func(scc_hir_builder_t *builder);
/**
* @brief 创建一个新的基本块,并自动添加到当前函数中,但不改变当前块。
* @param builder IR构建器
* @param label 基本块标签(可为 nullptr自动生成
* @return 新基本块的引用
*/
scc_hir_bblock_ref_t scc_hir_builder_bblock(scc_hir_builder_t *builder,
const char *label);
/**
* @brief 创建一个新的基本块(仅分配对象,不添加到当前函数的基本块列表)
* @param label 基本块标签(可为 nullptr
* @return 基本块引用(真实 ID
*/
scc_hir_bblock_ref_t scc_hir_builder_create_bblock(scc_hir_builder_t *builder,
const char *label);
/**
* @brief 将指定基本块追加到当前函数的基本块列表末尾
* @param bblock 基本块引用
*/
void scc_hir_builder_append_bblock(scc_hir_builder_t *builder,
scc_hir_bblock_ref_t bblock);
/**
* @brief 开始构建新的基本块
* @param label 基本块标签可为nullptr自动生成
* @return 基本块引用
*/
scc_hir_bblock_ref_t scc_hir_builder_begin_bblock(scc_hir_builder_t *builder,
const char *label);
/**
* @brief 结束当前基本块的构建
*/
void scc_hir_builder_end_bblock(scc_hir_builder_t *builder);
scc_hir_func_ref_t scc_hir_builder_current_bblock(scc_hir_builder_t *builder);
/**
* @brief 设置当前基本块
*/
void scc_hir_builder_set_current_bblock(scc_hir_builder_t *builder,
scc_hir_bblock_ref_t bblock);
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);
/**
* @brief 创建load指令
* @param ptr 指针操作数
*/
scc_hir_value_ref_t scc_hir_builder_load(scc_hir_builder_t *builder,
scc_hir_value_ref_t ptr);
/**
* @brief 创建store指令
* @param ptr 目标指针
* @param value 要存储的值
*/
scc_hir_value_ref_t scc_hir_builder_store(scc_hir_builder_t *builder,
scc_hir_value_ref_t ptr,
scc_hir_value_ref_t value);
/**
* @brief 创建getptr指令指针运算
* @param ptr 基础指针
* @param index 索引值
*/
scc_hir_value_ref_t scc_hir_builder_get_elem_ptr(scc_hir_builder_t *builder,
scc_hir_value_ref_t ptr,
scc_hir_value_ref_t index);
/**
* @brief 创建二元运算指令
* @param op 操作符
* @param lhs 左操作数
* @param rhs 右操作数
*/
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);
/**
* @brief 创建比较指令
* @param op 比较操作符
* @param lhs 左操作数
* @param rhs 右操作数
*/
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);
/**
* @brief 创建跳转指令(无条件)
* @param target 目标基本块
*/
scc_hir_value_ref_t scc_hir_builder_jump(scc_hir_builder_t *builder,
scc_hir_bblock_ref_t target);
/**
* @brief 创建条件分支指令
* @param cond 条件值
* @param true_target 条件为真时的目标
* @param false_target 条件为假时的目标
*/
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);
/**
* @brief 创建函数调用指令
* @param callee 被调用函数
* @param args 参数列表
* @param arg_count 参数数量
*/
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);
/**
* @brief 创建返回指令(带返回值)
* @param value 返回值
*/
scc_hir_value_ref_t scc_hir_builder_ret(scc_hir_builder_t *builder,
scc_hir_value_ref_t value);
/**
* @brief 创建返回指令void返回
*/
scc_hir_value_ref_t scc_hir_builder_ret_void(scc_hir_builder_t *builder);
#endif /* __SCC_HIR_BUILDER_H__ */