feat(mir): 实现x86-64架构寄存器分配和指令选择优化
- 修改x86_64_isel.h接口,将func_meta替换为func指针,并添加新的isel函数原型 - 添加x86_64_reg_alloc.h头文件,提供架构特定的寄存器分配操作填充函数 - 更新frame_layout.h定义frame_layout上下文结构 - 重构reg_alloc.h中的寄存器分配操作结构体,将ops从指针改为值类型, 并将mark_reg_unused重命名为clean_mark_regs - 扩展scc_mir.h中的函数元数据,添加vregs_count字段和虚拟寄存器管理函数 - 重新定义MIR pass阶段枚举,添加FRAME_LAYOUT和PROLOGUE_EPILOGUE阶段 - 添加win64目标相关头文件和实现,提供Windows x64 ABI降低和寄存器分配填充 - 更新虚拟寄存器表示格式从$到%,修复alloca指令处理 - 重构寄存器分配算法,改进虚拟寄存器到物理寄存器/栈槽的映射机制 - 完善MIR pass调度,支持多阶段处理流程
This commit is contained in:
@@ -1,9 +1,64 @@
|
||||
#include "scc_mir.h"
|
||||
#include <scc_mir.h>
|
||||
|
||||
void scc_mir_func_meta_init(scc_mir_func_meta_t *func_meta) {
|
||||
func_meta->frame_size = 0;
|
||||
func_meta->stack_alignment = 0;
|
||||
func_meta->vregs_count = 0;
|
||||
scc_vec_init(func_meta->stack_slots);
|
||||
scc_hashtable_usize_init(&func_meta->vreg2preg);
|
||||
scc_hashtable_usize_init(&func_meta->vreg2slot);
|
||||
|
||||
// For null stack slot
|
||||
scc_vec_push(func_meta->stack_slots, (scc_mir_stack_slot_t){0});
|
||||
scc_hashtable_usize_init(&func_meta->vreg2physic);
|
||||
}
|
||||
|
||||
int scc_mir_alloc_vreg(scc_mir_func_t *func) {
|
||||
scc_mir_func_meta_t *meta = SCC_MIR_FUNC_META(func);
|
||||
return meta->vregs_count++;
|
||||
}
|
||||
|
||||
void scc_mir_vreg_op(const scc_mir_func_t *func, int vreg,
|
||||
scc_mir_operand_t *out) {
|
||||
scc_mir_func_meta_t *meta = SCC_MIR_FUNC_META(func);
|
||||
isize idx =
|
||||
(isize)scc_hashtable_get(&meta->vreg2physic, (void *)(usize)vreg);
|
||||
if (idx == 0) {
|
||||
out->kind = SCC_MIR_OP_VREG;
|
||||
out->vreg = vreg;
|
||||
} else if (idx < 0) {
|
||||
out->kind = SCC_MIR_OP_PREG;
|
||||
out->preg = (int)-idx;
|
||||
} else {
|
||||
out->kind = SCC_MIR_OP_MEM;
|
||||
Assert(idx < scc_vec_size(meta->stack_slots));
|
||||
out->stack_slot = (int)(usize)idx;
|
||||
}
|
||||
}
|
||||
|
||||
void scc_mir_vreg_map2preg(scc_mir_func_t *func, int vreg, int preg) {
|
||||
scc_mir_func_meta_t *meta = SCC_MIR_FUNC_META(func);
|
||||
isize val =
|
||||
(isize)scc_hashtable_get(&meta->vreg2physic, (void *)(usize)vreg);
|
||||
if (val != 0) {
|
||||
Panic("vreg %d already mapped", vreg);
|
||||
return;
|
||||
}
|
||||
scc_hashtable_set(&meta->vreg2physic, (void *)(usize)vreg,
|
||||
(void *)(usize)(isize)-preg);
|
||||
}
|
||||
|
||||
int scc_mir_vreg_map2slot(scc_mir_func_t *func, int vreg, int size, int align) {
|
||||
scc_mir_func_meta_t *meta = SCC_MIR_FUNC_META(func);
|
||||
isize val =
|
||||
(isize)scc_hashtable_get(&meta->vreg2physic, (void *)(usize)vreg);
|
||||
if (val != 0) {
|
||||
Panic("vreg %d already mapped", vreg);
|
||||
return 0;
|
||||
}
|
||||
int new_slot = scc_vec_size(meta->stack_slots);
|
||||
scc_mir_stack_slot_t s = {
|
||||
.slot_id = new_slot, .size = size, .alignment = align, .offset = 0};
|
||||
scc_vec_push(meta->stack_slots, s);
|
||||
scc_hashtable_set(&meta->vreg2physic, (void *)(usize)vreg,
|
||||
(void *)(usize)new_slot);
|
||||
return new_slot;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user