Files
scc/libs/lir/include/scc_lir.h
zzy e5bbffe170 feat(cbuild): 添加 lir 库依赖并注释掉未使用的模块
- 添加 { name = "lir", path = "./libs/lir" } 依赖项
- 注释掉 ir2mcode 和 sccf2target 模块以暂时禁用

refactor(ast2ir): 修复类型转换问题并简化哈希表初始化

- 修复 compute_type_layout 函数中的类型转换警告
- 在表达式处理末尾添加 UNREACHABLE() 断言
- 移除 begin_func 中的 param_names 参数
- 使用 scc_hashtable_usize_init 替代自定义比较函数

refactor(ir): 简化函数构建器接口并修复返回值处理

- 移除 scc_ir_builder_begin_func 中的 param_names 参数
- 修改 scc_ir_builder_ret_void 以正确处理 void 返回值
- 初始化返回值节点而不是直接设置为 0

refactor(ir): 简化模块初始化中的哈希表配置

- 移除自定义 hash_key 和 cmp_key 函数
- 使用 scc_hashtable_usize_init 统一初始化哈希表

feat(lir): 添加低层中间表示库基础结构

- 创建 lir 库的包配置文件
- 定义 LIR 的基本数据结构、指令类型和操作枚举
- 实现 LIR 构建器和模块管理功能
- 添加 LIR 转换器头文件和转储功能
2026-04-18 11:35:43 +08:00

264 lines
7.0 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.
/**
* @file scc_lir.h
* @brief 低层中间表示 (Low-Level IR) - 实用精简版
*
* 设计原则:
* - 依赖 scc_core.h 和 scc_utils.h (仅使用哈希表)
* - 保留所有核心功能复杂地址、并行复制、VA 支持、符号引用
* - 基本块使用稳定 ID通过哈希表快速查找
* - 预留属性位掩码 (attr),未来可扩展 align、packed、weak 等
* - 无字符串池、无类型缓存,保持简单
*/
#ifndef __SCC_LIR_H__
#define __SCC_LIR_H__
#include <scc_core.h>
#include <scc_hashtable.h>
#include <scc_pos.h>
typedef enum scc_lir_attr {
SCC_LIR_ATTR_NONE = 0,
SCC_LIR_ATTR_STATIC = 1 << 0, // 内部链接
SCC_LIR_ATTR_WEAK = 1 << 1, // 弱符号
SCC_LIR_ATTR_VIS_HIDDEN = 1 << 2, // 符号可见性 hidden
SCC_LIR_ATTR_NOINLINE = 1 << 3,
SCC_LIR_ATTR_ALWAYSINLINE = 1 << 4,
// 对齐值可编码在 attr 的高位,例如:
// #define SCC_LIR_ATTR_ALIGN(n) (((n) << 8) | SCC_LIR_ATTR_ALIGN_FLAG)
} scc_lir_attr_t;
typedef enum {
SCC_LIR_INSTR_KIND_NONE, // 无操作数
SCC_LIR_INSTR_KIND_VREG, // 虚拟寄存器
SCC_LIR_INSTR_KIND_PREG, // 物理寄存器 (后端定义编号)
SCC_LIR_INSTR_KIND_IMM, // 整数立即数
SCC_LIR_INSTR_KIND_FIMM, // 浮点立即数
SCC_LIR_INSTR_KIND_SYMBOL, // 全局符号 (函数名、全局变量、字符串常量)
SCC_LIR_INSTR_KIND_ADDR // 复杂地址表达式 (base + index*scale + offset)
} scc_lir_instr_kind_t;
/**
* @brief 复杂地址表达式
* base + index * scale + offset
*/
typedef struct scc_lir_addr {
int base; // 基址寄存器,-1 表示无
int index; // 索引寄存器,-1 表示无
int scale; // 比例因子 (1, 2, 4, 8)
i64 offset; // 常量偏移
} scc_lir_addr_t;
typedef struct scc_lir_instr {
scc_lir_instr_kind_t kind;
union {
unsigned int reg; // VREG 或 PREG 索引
i64 imm; // 整型立即数
f64 fimm; // 浮点立即数
const char *symbol; // 符号名 (生命周期由前端管理)
scc_lir_addr_t addr; // 复杂地址
} data;
} scc_lir_val_t;
/* 构造宏 */
#define SCC_LIR_NONE() ((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_NONE})
#define SCC_LIR_VREG(n) \
((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_VREG, .data.reg = (n)})
#define SCC_LIR_PREG(r) \
((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_PREG, .data.reg = (r)})
#define SCC_LIR_IMM(v) \
((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_IMM, .data.imm = (v)})
#define SCC_LIR_FIMM(v) \
((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_FIMM, .data.fimm = (v)})
#define SCC_LIR_SYMBOL(s) \
((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_SYMBOL, .data.symbol = (s)})
#define SCC_LIR_ADDR(b, i, s, o) \
((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_ADDR, \
.data.addr = {b, i, s, o}})
#define SCC_LIR_SIZE_8 1
#define SCC_LIR_SIZE_16 2
#define SCC_LIR_SIZE_32 4
#define SCC_LIR_SIZE_64 8
typedef enum {
SCC_LIR_EXT_NONE,
SCC_LIR_EXT_SEXT,
SCC_LIR_EXT_ZEXT,
SCC_LIR_EXT_FLOAT
} scc_lir_ext_t;
typedef enum {
/* 数据移动 */
SCC_LIR_MOV,
SCC_LIR_LOAD,
SCC_LIR_LOAD_ADDR,
SCC_LIR_STORE,
SCC_LIR_STORE_ADDR,
SCC_LIR_LEA,
/* 整数算术 */
SCC_LIR_ADD,
SCC_LIR_SUB,
SCC_LIR_MUL,
SCC_LIR_DIV_S,
SCC_LIR_DIV_U,
SCC_LIR_REM_S,
SCC_LIR_REM_U,
SCC_LIR_AND,
SCC_LIR_OR,
SCC_LIR_XOR,
SCC_LIR_SHL,
SCC_LIR_SHR,
SCC_LIR_SAR,
SCC_LIR_NEG,
SCC_LIR_NOT,
/* 浮点算术 */
SCC_LIR_FADD,
SCC_LIR_FSUB,
SCC_LIR_FMUL,
SCC_LIR_FDIV,
SCC_LIR_FNEG,
SCC_LIR_FCVT,
/* 比较 */
SCC_LIR_CMP,
/* 控制流 */
SCC_LIR_BR,
SCC_LIR_JMP,
SCC_LIR_JMP_INDIRECT,
SCC_LIR_CALL,
SCC_LIR_CALL_INDIRECT,
SCC_LIR_RET,
/* 并行复制 */
SCC_LIR_PARALLEL_COPY,
/* 可变参数 */
SCC_LIR_VA_START,
SCC_LIR_VA_ARG,
SCC_LIR_VA_END,
SCC_LIR_VA_COPY,
/* 栈管理 */
SCC_LIR_ALLOCA,
SCC_LIR_NOP
} scc_lir_op_t;
typedef enum {
SCC_LIR_COND_EQ,
SCC_LIR_COND_NE,
SCC_LIR_COND_SLT,
SCC_LIR_COND_SLE,
SCC_LIR_COND_SGT,
SCC_LIR_COND_SGE,
SCC_LIR_COND_ULT,
SCC_LIR_COND_ULE,
SCC_LIR_COND_UGT,
SCC_LIR_COND_UGE,
SCC_LIR_COND_FEQ,
SCC_LIR_COND_FNE,
SCC_LIR_COND_FLT,
SCC_LIR_COND_FLE,
SCC_LIR_COND_FGT,
SCC_LIR_COND_FGE
} scc_lir_cond_t;
typedef usize scc_lir_bblock_uid_t;
typedef struct scc_lir_ins {
scc_lir_op_t op;
u8 size;
scc_lir_ext_t ext;
scc_lir_val_t to;
scc_lir_val_t arg0;
scc_lir_val_t arg1;
/// @brief debug 信息
scc_pos_t src_loc;
union {
scc_lir_cond_t cond;
struct scc_lir_br {
scc_lir_bblock_uid_t true_target;
scc_lir_bblock_uid_t false_target;
} br;
scc_lir_bblock_uid_t jmp_target;
struct scc_lir_call {
const char *callee;
scc_lir_val_t *args;
int arg_count;
scc_lir_val_t ret_vreg;
u64 clobber_mask;
} call;
struct scc_lir_call_indirect {
scc_lir_val_t target;
scc_lir_val_t *args;
int arg_count;
scc_lir_val_t ret_vreg;
u64 clobber_mask;
} call_indirect;
scc_lir_val_t ret_val;
struct scc_lir_parallel_copy {
scc_lir_val_t *dests;
scc_lir_val_t *srcs;
int num_copies;
} parallel_copy;
struct scc_lir_alloca {
int size_bytes;
int align_bytes;
} alloca;
struct {
scc_lir_val_t ap;
scc_lir_val_t last;
} va_start;
struct {
scc_lir_val_t ap;
int type_size;
int type_align;
char is_float;
scc_lir_val_t to;
} va_arg;
struct {
scc_lir_val_t ap;
} va_end;
struct {
scc_lir_val_t dest;
scc_lir_val_t src;
} va_copy;
} metadata;
} scc_lir_instr_t;
typedef SCC_VEC(scc_lir_instr_t) scc_lir_instr_vec_t;
typedef struct scc_lir_bblock {
scc_lir_bblock_uid_t id; // 稳定唯一 ID
const char *label; // 可读标签
scc_lir_instr_vec_t ins; // 指令序列
} scc_lir_bblock_t;
typedef SCC_VEC(scc_lir_bblock_t) scc_lir_bblock_vec_t;
typedef struct scc_lir_func {
const char *name;
scc_lir_bblock_vec_t bblocks;
scc_hashtable_t bb_map; // ID -> 基本块索引 (usize)
scc_lir_bblock_uid_t next_bb_uid;
unsigned int vregs_count;
int frame_size;
scc_lir_attr_t attr;
} scc_lir_func_t;
#endif /* __SCC_LIR_H__ */