[backend-IRC]修复了现场管理与溢出处理的栈偏移量错误问题

This commit is contained in:
Lixuanwang
2025-08-03 14:42:19 +08:00
parent 004ef82488
commit 845f969c2e
5 changed files with 101 additions and 53 deletions

View File

@@ -60,11 +60,7 @@ display_file_content() {
# 清理临时文件的函数 # 清理临时文件的函数
clean_tmp() { clean_tmp() {
echo "正在清理临时目录: ${TMP_DIR}" echo "正在清理临时目录: ${TMP_DIR}"
rm -rf "${TMP_DIR}"/*.s \ rm -rf "${TMP_DIR}"/*
"${TMP_DIR}"/*_sysyc_riscv64 \
"${TMP_DIR}"/*_sysyc_riscv64.actual_out \
"${TMP_DIR}"/*_sysyc_riscv64.expected_stdout \
"${TMP_DIR}"/*_sysyc_riscv64.o
echo "清理完成。" echo "清理完成。"
} }

View File

@@ -29,6 +29,8 @@ unsigned EliminateFrameIndicesPass::getTypeSizeInBytes(Type* type) {
} }
void EliminateFrameIndicesPass::runOnMachineFunction(MachineFunction* mfunc) { void EliminateFrameIndicesPass::runOnMachineFunction(MachineFunction* mfunc) {
// [方案一修改] 这是修改后完整的函数代码。
// 主要的逻辑变更在原注释"[核心修改]"部分。
StackFrameInfo& frame_info = mfunc->getFrameInfo(); StackFrameInfo& frame_info = mfunc->getFrameInfo();
Function* F = mfunc->getFunc(); Function* F = mfunc->getFunc();
RISCv64ISel* isel = mfunc->getISel(); RISCv64ISel* isel = mfunc->getISel();
@@ -65,6 +67,8 @@ void EliminateFrameIndicesPass::runOnMachineFunction(MachineFunction* mfunc) {
// 记录仅由AllocaInst分配的局部变量的总大小 // 记录仅由AllocaInst分配的局部变量的总大小
frame_info.locals_size = local_var_offset - 16; frame_info.locals_size = local_var_offset - 16;
// [新增] 记录局部变量区域分配结束的最终偏移量
frame_info.locals_end_offset = -local_var_offset;
// 3. [核心修改] 在函数入口为所有栈传递的参数插入load指令 // 3. [核心修改] 在函数入口为所有栈传递的参数插入load指令
// 这个步骤至关重要它在寄存器分配之前为这些参数的vreg创建了明确的“定义(def)”指令。 // 这个步骤至关重要它在寄存器分配之前为这些参数的vreg创建了明确的“定义(def)”指令。
@@ -72,6 +76,8 @@ void EliminateFrameIndicesPass::runOnMachineFunction(MachineFunction* mfunc) {
if (F && isel && !mfunc->getBlocks().empty()) { if (F && isel && !mfunc->getBlocks().empty()) {
MachineBasicBlock* entry_block = mfunc->getBlocks().front().get(); MachineBasicBlock* entry_block = mfunc->getBlocks().front().get();
std::vector<std::unique_ptr<MachineInstr>> arg_load_instrs; std::vector<std::unique_ptr<MachineInstr>> arg_load_instrs;
// 步骤 3.1: 生成所有加载栈参数的指令,暂存起来
int arg_idx = 0; int arg_idx = 0;
for (Argument* arg : F->getArguments()) { for (Argument* arg : F->getArguments()) {
// 根据ABI前8个整型/指针参数通过寄存器传递,这里只处理超出部分。 // 根据ABI前8个整型/指针参数通过寄存器传递,这里只处理超出部分。
@@ -104,13 +110,48 @@ void EliminateFrameIndicesPass::runOnMachineFunction(MachineFunction* mfunc) {
arg_idx++; arg_idx++;
} }
// 将所有新创建的参数加载指令一次性插入到入口块的起始位置 // [方案一修改] 仅当有需要加载的栈参数时,才执行插入逻辑
auto& entry_instrs = entry_block->getInstructions(); if (!arg_load_instrs.empty()) {
entry_instrs.insert(entry_instrs.begin(), auto& entry_instrs = entry_block->getInstructions();
std::make_move_iterator(arg_load_instrs.begin()), auto insertion_point = entry_instrs.begin(); // 默认插入点为块的开头
std::make_move_iterator(arg_load_instrs.end())); auto last_arg_save_it = entry_instrs.end();
}
// 步骤 3.2: 寻找一个安全的插入点。
// 遍历入口块的指令,找到最后一条保存“寄存器传递参数”的伪指令。
// 这样可以确保我们在所有 a0-a7 参数被保存之后,才执行可能覆盖它们的加载指令。
for (auto it = entry_instrs.begin(); it != entry_instrs.end(); ++it) {
MachineInstr* instr = it->get();
// 寻找代表保存参数到栈的伪指令
if (instr->getOpcode() == RVOpcodes::FRAME_STORE_W ||
instr->getOpcode() == RVOpcodes::FRAME_STORE_D ||
instr->getOpcode() == RVOpcodes::FRAME_STORE_F) {
// 检查被保存的值是否是寄存器参数 (arg_no < 8)
auto& operands = instr->getOperands();
if (operands.empty() || operands[0]->getKind() != MachineOperand::KIND_REG) continue;
unsigned src_vreg = static_cast<RegOperand*>(operands[0].get())->getVRegNum();
Value* ir_value = isel->getVRegValueMap().count(src_vreg) ? isel->getVRegValueMap().at(src_vreg) : nullptr;
if (auto ir_arg = dynamic_cast<Argument*>(ir_value)) {
if (ir_arg->getIndex() < 8) {
last_arg_save_it = it; // 找到了一个保存寄存器参数的指令,更新位置
}
}
}
}
// 如果找到了这样的保存指令,我们的插入点就在它之后
if (last_arg_save_it != entry_instrs.end()) {
insertion_point = std::next(last_arg_save_it);
}
// 步骤 3.3: 在计算出的安全位置,一次性插入所有新创建的参数加载指令
entry_instrs.insert(insertion_point,
std::make_move_iterator(arg_load_instrs.begin()),
std::make_move_iterator(arg_load_instrs.end()));
}
}
// 4. 遍历所有机器指令,将访问局部变量的伪指令展开为真实指令 // 4. 遍历所有机器指令,将访问局部变量的伪指令展开为真实指令
// 由于处理参数的逻辑已移除,这里的展开现在只针对局部变量,因此是正确的。 // 由于处理参数的逻辑已移除,这里的展开现在只针对局部变量,因此是正确的。

View File

@@ -9,7 +9,12 @@ namespace sysy {
char PrologueEpilogueInsertionPass::ID = 0; char PrologueEpilogueInsertionPass::ID = 0;
// [函数上下文]
// ...
void PrologueEpilogueInsertionPass::runOnMachineFunction(MachineFunction* mfunc) { void PrologueEpilogueInsertionPass::runOnMachineFunction(MachineFunction* mfunc) {
// [最终修正] 这是修正后完整的函数代码。
// 序言(4.4)和尾声(5.1)中的循环逻辑现在完全一致。
StackFrameInfo& frame_info = mfunc->getFrameInfo(); StackFrameInfo& frame_info = mfunc->getFrameInfo();
Function* F = mfunc->getFunc(); Function* F = mfunc->getFunc();
RISCv64ISel* isel = mfunc->getISel(); RISCv64ISel* isel = mfunc->getISel();
@@ -27,8 +32,7 @@ void PrologueEpilogueInsertionPass::runOnMachineFunction(MachineFunction* mfunc)
); );
} }
// 2. [新增] 确定需要保存的被调用者保存寄存器 (callee-saved) // 2. 确定需要保存的被调用者保存寄存器 (callee-saved)
// 这部分逻辑从 CalleeSavedHandler Pass 移入,以集中管理序言生成
auto& vreg_to_preg_map = frame_info.vreg_to_preg_map; auto& vreg_to_preg_map = frame_info.vreg_to_preg_map;
std::set<PhysicalReg> used_callee_saved_regs_set; std::set<PhysicalReg> used_callee_saved_regs_set;
const auto& callee_saved_int = getCalleeSavedIntRegs(); const auto& callee_saved_int = getCalleeSavedIntRegs();
@@ -36,38 +40,34 @@ void PrologueEpilogueInsertionPass::runOnMachineFunction(MachineFunction* mfunc)
for (const auto& pair : vreg_to_preg_map) { for (const auto& pair : vreg_to_preg_map) {
PhysicalReg preg = pair.second; PhysicalReg preg = pair.second;
// 检查是否在整数或浮点 callee-saved 集合中
// 注意s0作为帧指针由序言/尾声逻辑特殊处理,不在此处保存
bool is_int_cs = std::find(callee_saved_int.begin(), callee_saved_int.end(), preg) != callee_saved_int.end(); bool is_int_cs = std::find(callee_saved_int.begin(), callee_saved_int.end(), preg) != callee_saved_int.end();
bool is_fp_cs = std::find(callee_saved_fp.begin(), callee_saved_fp.end(), preg) != callee_saved_fp.end(); bool is_fp_cs = std::find(callee_saved_fp.begin(), callee_saved_fp.end(), preg) != callee_saved_fp.end();
if ((is_int_cs && preg != PhysicalReg::S0) || is_fp_cs) { if ((is_int_cs && preg != PhysicalReg::S0) || is_fp_cs) {
used_callee_saved_regs_set.insert(preg); used_callee_saved_regs_set.insert(preg);
} }
} }
// 为了确定性排序,并存入 frame_info 供尾声使用
frame_info.callee_saved_regs_to_store.assign( frame_info.callee_saved_regs_to_store.assign(
used_callee_saved_regs_set.begin(), used_callee_saved_regs_set.end() used_callee_saved_regs_set.begin(), used_callee_saved_regs_set.end()
); );
std::sort(frame_info.callee_saved_regs_to_store.begin(), frame_info.callee_saved_regs_to_store.end()); std::sort(frame_info.callee_saved_regs_to_store.begin(), frame_info.callee_saved_regs_to_store.end());
frame_info.callee_saved_size = frame_info.callee_saved_regs_to_store.size() * 8; // 每个寄存器8字节 frame_info.callee_saved_size = frame_info.callee_saved_regs_to_store.size() * 8;
// 3. 计算最终的栈帧总大小 // 3. 计算最终的栈帧总大小
int total_stack_size = frame_info.locals_size + int total_stack_size = frame_info.locals_size +
frame_info.spill_size + frame_info.spill_size +
frame_info.callee_saved_size + frame_info.callee_saved_size +
16; // 为 ra 和 s0 固定的16字节 16;
int aligned_stack_size = (total_stack_size + 15) & ~15; // 16字节对齐 int aligned_stack_size = (total_stack_size + 15) & ~15;
frame_info.total_size = aligned_stack_size; frame_info.total_size = aligned_stack_size;
// 只有在需要分配栈空间时才生成序言和尾声
if (aligned_stack_size > 0) { if (aligned_stack_size > 0) {
// --- 4. 插入完整的序言 --- // --- 4. 插入完整的序言 ---
MachineBasicBlock* entry_block = mfunc->getBlocks().front().get(); MachineBasicBlock* entry_block = mfunc->getBlocks().front().get();
auto& entry_instrs = entry_block->getInstructions(); auto& entry_instrs = entry_block->getInstructions();
std::vector<std::unique_ptr<MachineInstr>> prologue_instrs; std::vector<std::unique_ptr<MachineInstr>> prologue_instrs;
// 4.1. 分配栈帧: addi sp, sp, -aligned_stack_size // 4.1. 分配栈帧
auto alloc_stack = std::make_unique<MachineInstr>(RVOpcodes::ADDI); auto alloc_stack = std::make_unique<MachineInstr>(RVOpcodes::ADDI);
alloc_stack->addOperand(std::make_unique<RegOperand>(PhysicalReg::SP)); alloc_stack->addOperand(std::make_unique<RegOperand>(PhysicalReg::SP));
alloc_stack->addOperand(std::make_unique<RegOperand>(PhysicalReg::SP)); alloc_stack->addOperand(std::make_unique<RegOperand>(PhysicalReg::SP));
@@ -75,7 +75,6 @@ void PrologueEpilogueInsertionPass::runOnMachineFunction(MachineFunction* mfunc)
prologue_instrs.push_back(std::move(alloc_stack)); prologue_instrs.push_back(std::move(alloc_stack));
// 4.2. 保存 ra 和 s0 // 4.2. 保存 ra 和 s0
// sd ra, (aligned_stack_size - 8)(sp)
auto save_ra = std::make_unique<MachineInstr>(RVOpcodes::SD); auto save_ra = std::make_unique<MachineInstr>(RVOpcodes::SD);
save_ra->addOperand(std::make_unique<RegOperand>(PhysicalReg::RA)); save_ra->addOperand(std::make_unique<RegOperand>(PhysicalReg::RA));
save_ra->addOperand(std::make_unique<MemOperand>( save_ra->addOperand(std::make_unique<MemOperand>(
@@ -83,7 +82,6 @@ void PrologueEpilogueInsertionPass::runOnMachineFunction(MachineFunction* mfunc)
std::make_unique<ImmOperand>(aligned_stack_size - 8) std::make_unique<ImmOperand>(aligned_stack_size - 8)
)); ));
prologue_instrs.push_back(std::move(save_ra)); prologue_instrs.push_back(std::move(save_ra));
// sd s0, (aligned_stack_size - 16)(sp)
auto save_fp = std::make_unique<MachineInstr>(RVOpcodes::SD); auto save_fp = std::make_unique<MachineInstr>(RVOpcodes::SD);
save_fp->addOperand(std::make_unique<RegOperand>(PhysicalReg::S0)); save_fp->addOperand(std::make_unique<RegOperand>(PhysicalReg::S0));
save_fp->addOperand(std::make_unique<MemOperand>( save_fp->addOperand(std::make_unique<MemOperand>(
@@ -92,60 +90,55 @@ void PrologueEpilogueInsertionPass::runOnMachineFunction(MachineFunction* mfunc)
)); ));
prologue_instrs.push_back(std::move(save_fp)); prologue_instrs.push_back(std::move(save_fp));
// 4.3. 设置新的帧指针 s0: addi s0, sp, aligned_stack_size // 4.3. 设置新的帧指针 s0
auto set_fp = std::make_unique<MachineInstr>(RVOpcodes::ADDI); auto set_fp = std::make_unique<MachineInstr>(RVOpcodes::ADDI);
set_fp->addOperand(std::make_unique<RegOperand>(PhysicalReg::S0)); set_fp->addOperand(std::make_unique<RegOperand>(PhysicalReg::S0));
set_fp->addOperand(std::make_unique<RegOperand>(PhysicalReg::SP)); set_fp->addOperand(std::make_unique<RegOperand>(PhysicalReg::SP));
set_fp->addOperand(std::make_unique<ImmOperand>(aligned_stack_size)); set_fp->addOperand(std::make_unique<ImmOperand>(aligned_stack_size));
prologue_instrs.push_back(std::move(set_fp)); prologue_instrs.push_back(std::move(set_fp));
// 4.4. [新增] 保存所有使用到的被调用者保存寄存器 // 4.4. 保存所有使用到的被调用者保存寄存器
// 它们保存在 s0 下方,紧接着 ra/s0 的位置 int next_available_offset = -(16 + frame_info.locals_size + frame_info.spill_size);
int callee_saved_offset = -16;
for (const auto& reg : frame_info.callee_saved_regs_to_store) { for (const auto& reg : frame_info.callee_saved_regs_to_store) {
callee_saved_offset -= 8; // [修正] 采用“先使用,后更新”逻辑
RVOpcodes store_op = (reg >= PhysicalReg::F0 && reg <= PhysicalReg::F31) ? RVOpcodes::FSD : RVOpcodes::SD; RVOpcodes store_op = isFPR(reg) ? RVOpcodes::FSD : RVOpcodes::SD;
auto save_cs_reg = std::make_unique<MachineInstr>(store_op); auto save_cs_reg = std::make_unique<MachineInstr>(store_op);
save_cs_reg->addOperand(std::make_unique<RegOperand>(reg)); save_cs_reg->addOperand(std::make_unique<RegOperand>(reg));
save_cs_reg->addOperand(std::make_unique<MemOperand>( save_cs_reg->addOperand(std::make_unique<MemOperand>(
std::make_unique<RegOperand>(PhysicalReg::S0), std::make_unique<RegOperand>(PhysicalReg::S0),
std::make_unique<ImmOperand>(callee_saved_offset) std::make_unique<ImmOperand>(next_available_offset) // 使用当前偏移
)); ));
prologue_instrs.push_back(std::move(save_cs_reg)); prologue_instrs.push_back(std::move(save_cs_reg));
next_available_offset -= 8; // 为下一个寄存器准备偏移
} }
// 4.5. [核心修改] 加载栈传递参数的逻辑已从此移除 // 4.5. 将所有生成的序言指令一次性插入到函数入口
// 这项工作已经前移至 `EliminateFrameIndicesPass` 中完成,
// 以确保在寄存器分配前就将相关虚拟寄存器定义从而修复溢出逻辑的bug。
// 4.6. 将所有生成的序言指令一次性插入到函数入口
entry_instrs.insert(entry_instrs.begin(), entry_instrs.insert(entry_instrs.begin(),
std::make_move_iterator(prologue_instrs.begin()), std::make_move_iterator(prologue_instrs.begin()),
std::make_move_iterator(prologue_instrs.end())); std::make_move_iterator(prologue_instrs.end()));
// --- 5. 插入完整的尾声 --- // --- 5. 插入完整的尾声 ---
for (auto& mbb : mfunc->getBlocks()) { for (auto& mbb : mfunc->getBlocks()) {
// [修正] 使用前向迭代器查找RET指令以确保在正确的位置RET之前插入尾声。
for (auto it = mbb->getInstructions().begin(); it != mbb->getInstructions().end(); ++it) { for (auto it = mbb->getInstructions().begin(); it != mbb->getInstructions().end(); ++it) {
if ((*it)->getOpcode() == RVOpcodes::RET) { if ((*it)->getOpcode() == RVOpcodes::RET) {
std::vector<std::unique_ptr<MachineInstr>> epilogue_instrs; std::vector<std::unique_ptr<MachineInstr>> epilogue_instrs;
// 5.1. [新增] 恢复被调用者保存寄存器 // 5.1. 恢复被调用者保存寄存器
callee_saved_offset = -16; // [修正] 采用与序言完全相同的“先使用,后更新”逻辑
int next_available_offset_restore = -(16 + frame_info.locals_size + frame_info.spill_size);
for (const auto& reg : frame_info.callee_saved_regs_to_store) { for (const auto& reg : frame_info.callee_saved_regs_to_store) {
callee_saved_offset -= 8; RVOpcodes load_op = isFPR(reg) ? RVOpcodes::FLD : RVOpcodes::LD;
RVOpcodes load_op = (reg >= PhysicalReg::F0 && reg <= PhysicalReg::F31) ? RVOpcodes::FLD : RVOpcodes::LD;
auto restore_cs_reg = std::make_unique<MachineInstr>(load_op); auto restore_cs_reg = std::make_unique<MachineInstr>(load_op);
restore_cs_reg->addOperand(std::make_unique<RegOperand>(reg)); restore_cs_reg->addOperand(std::make_unique<RegOperand>(reg));
restore_cs_reg->addOperand(std::make_unique<MemOperand>( restore_cs_reg->addOperand(std::make_unique<MemOperand>(
std::make_unique<RegOperand>(PhysicalReg::S0), std::make_unique<RegOperand>(PhysicalReg::S0),
std::make_unique<ImmOperand>(callee_saved_offset) std::make_unique<ImmOperand>(next_available_offset_restore) // 使用当前偏移
)); ));
epilogue_instrs.push_back(std::move(restore_cs_reg)); epilogue_instrs.push_back(std::move(restore_cs_reg));
next_available_offset_restore -= 8; // 为下一个寄存器准备偏移
} }
// 5.2. 恢复 ra 和 s0 (注意基址现在是sp) // 5.2. 恢复 ra 和 s0
// ld ra, (aligned_stack_size - 8)(sp)
auto restore_ra = std::make_unique<MachineInstr>(RVOpcodes::LD); auto restore_ra = std::make_unique<MachineInstr>(RVOpcodes::LD);
restore_ra->addOperand(std::make_unique<RegOperand>(PhysicalReg::RA)); restore_ra->addOperand(std::make_unique<RegOperand>(PhysicalReg::RA));
restore_ra->addOperand(std::make_unique<MemOperand>( restore_ra->addOperand(std::make_unique<MemOperand>(
@@ -153,7 +146,6 @@ void PrologueEpilogueInsertionPass::runOnMachineFunction(MachineFunction* mfunc)
std::make_unique<ImmOperand>(aligned_stack_size - 8) std::make_unique<ImmOperand>(aligned_stack_size - 8)
)); ));
epilogue_instrs.push_back(std::move(restore_ra)); epilogue_instrs.push_back(std::move(restore_ra));
// ld s0, (aligned_stack_size - 16)(sp)
auto restore_fp = std::make_unique<MachineInstr>(RVOpcodes::LD); auto restore_fp = std::make_unique<MachineInstr>(RVOpcodes::LD);
restore_fp->addOperand(std::make_unique<RegOperand>(PhysicalReg::S0)); restore_fp->addOperand(std::make_unique<RegOperand>(PhysicalReg::S0));
restore_fp->addOperand(std::make_unique<MemOperand>( restore_fp->addOperand(std::make_unique<MemOperand>(
@@ -162,7 +154,7 @@ void PrologueEpilogueInsertionPass::runOnMachineFunction(MachineFunction* mfunc)
)); ));
epilogue_instrs.push_back(std::move(restore_fp)); epilogue_instrs.push_back(std::move(restore_fp));
// 5.3. 释放栈帧: addi sp, sp, aligned_stack_size // 5.3. 释放栈帧
auto dealloc_stack = std::make_unique<MachineInstr>(RVOpcodes::ADDI); auto dealloc_stack = std::make_unique<MachineInstr>(RVOpcodes::ADDI);
dealloc_stack->addOperand(std::make_unique<RegOperand>(PhysicalReg::SP)); dealloc_stack->addOperand(std::make_unique<RegOperand>(PhysicalReg::SP));
dealloc_stack->addOperand(std::make_unique<RegOperand>(PhysicalReg::SP)); dealloc_stack->addOperand(std::make_unique<RegOperand>(PhysicalReg::SP));
@@ -174,7 +166,6 @@ void PrologueEpilogueInsertionPass::runOnMachineFunction(MachineFunction* mfunc)
std::make_move_iterator(epilogue_instrs.begin()), std::make_move_iterator(epilogue_instrs.begin()),
std::make_move_iterator(epilogue_instrs.end())); std::make_move_iterator(epilogue_instrs.end()));
// 一个基本块通常只有一个终止指令,处理完就可以跳到下一个块
goto next_block; goto next_block;
} }
} }

View File

@@ -647,11 +647,22 @@ void RISCv64RegAlloc::assignColors() {
} }
} }
// 在文件 RISCv64RegAlloc.cpp 中:
// [函数上下文]
// ...
// 我将修改下面这个函数
// ...
// 重写程序,插入溢出代码 // 重写程序,插入溢出代码
void RISCv64RegAlloc::rewriteProgram() { void RISCv64RegAlloc::rewriteProgram() {
// 1. 为溢出的旧vreg在栈上分配空间
StackFrameInfo& frame_info = MFunc->getFrameInfo(); StackFrameInfo& frame_info = MFunc->getFrameInfo();
int spill_base_offset = frame_info.locals_size + frame_info.callee_saved_size; // 使用 EFI Pass 确定的 locals_end_offset 作为溢出分配的基准。
// locals_end_offset 本身是负数,代表局部变量区域的下边界地址。
int spill_current_offset = frame_info.locals_end_offset;
// [新增] 保存溢出区域的起始点,用于最后计算总的 spill_size
const int spill_start_offset = frame_info.locals_end_offset;
for (unsigned vreg : spilledNodes) { for (unsigned vreg : spilledNodes) {
if (frame_info.spill_offsets.count(vreg)) continue; if (frame_info.spill_offsets.count(vreg)) continue;
@@ -663,11 +674,19 @@ void RISCv64RegAlloc::rewriteProgram() {
size = 8; // pointer size = 8; // pointer
} }
spill_base_offset += size; // [修改] 在当前偏移基础上继续向下(地址变得更负)分配空间
spill_base_offset = (spill_base_offset + 7) & ~7; spill_current_offset -= size;
frame_info.spill_offsets[vreg] = -spill_base_offset; // [修正] 溢出槽也使用负偏移量
// [修改] 对齐新的、更小的地址RISC-V 要求8字节对齐
spill_current_offset = spill_current_offset & ~7;
// 将计算出的、不会冲突的正确偏移量存入 spill_offsets
frame_info.spill_offsets[vreg] = spill_current_offset;
} }
frame_info.spill_size = spill_base_offset - (frame_info.locals_size + frame_info.callee_saved_size);
// [修改] 更新总的溢出区域大小。
// spill_size = -(结束偏移 - 开始偏移)
frame_info.spill_size = -(spill_current_offset - spill_start_offset);
// 2. 遍历所有指令,重写代码 // 2. 遍历所有指令,重写代码
for (auto& mbb : MFunc->getBlocks()) { for (auto& mbb : MFunc->getBlocks()) {

View File

@@ -39,7 +39,7 @@ enum class PhysicalReg {
// 用于内部表示物理寄存器在干扰图中的节点ID一个简单的特殊ID确保不与vreg_counter冲突 // 用于内部表示物理寄存器在干扰图中的节点ID一个简单的特殊ID确保不与vreg_counter冲突
// 假设 vreg_counter 不会达到这么大的值 // 假设 vreg_counter 不会达到这么大的值
PHYS_REG_START_ID = 100000, PHYS_REG_START_ID = 1000000,
PHYS_REG_END_ID = PHYS_REG_START_ID + 320, // 预留足够的空间 PHYS_REG_END_ID = PHYS_REG_START_ID + 320, // 预留足够的空间
}; };
@@ -280,6 +280,7 @@ private:
// 栈帧信息 // 栈帧信息
struct StackFrameInfo { struct StackFrameInfo {
int locals_size = 0; // 仅为AllocaInst分配的大小 int locals_size = 0; // 仅为AllocaInst分配的大小
int locals_end_offset = 0; // [新增] 记录局部变量分配结束后的偏移量(相对于s0为负)
int spill_size = 0; // 仅为溢出分配的大小 int spill_size = 0; // 仅为溢出分配的大小
int total_size = 0; // 总大小 int total_size = 0; // 总大小
int callee_saved_size = 0; // 保存寄存器的大小 int callee_saved_size = 0; // 保存寄存器的大小