[backend]调整了后端pass的顺序

This commit is contained in:
Lixuanwang
2025-07-29 16:15:01 +08:00
parent 8deb4ed076
commit 32bdc17dc3
2 changed files with 94 additions and 97 deletions

View File

@@ -1,4 +1,4 @@
#include "include/PrologueEpilogueInsertion.h" #include "PrologueEpilogueInsertion.h"
namespace sysy { namespace sysy {
@@ -6,114 +6,111 @@ char PrologueEpilogueInsertionPass::ID = 0;
void PrologueEpilogueInsertionPass::runOnMachineFunction(MachineFunction* mfunc) { void PrologueEpilogueInsertionPass::runOnMachineFunction(MachineFunction* mfunc) {
StackFrameInfo& frame_info = mfunc->getFrameInfo(); StackFrameInfo& frame_info = mfunc->getFrameInfo();
// 最终计算总栈帧大小。
// 完全遵循 AsmPrinter 中的计算逻辑
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; // 为 ra 和 s0 固定的16字节
// 保持栈指针16字节对齐
int aligned_stack_size = (total_stack_size + 15) & ~15; 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) { // 只有在需要分配栈空间时才生成指令
return; // 无需插入序言/尾声 if (aligned_stack_size > 0) {
} // --- 1. 插入序言 ---
MachineBasicBlock* entry_block = mfunc->getBlocks().front().get();
auto& entry_instrs = entry_block->getInstructions();
// --- 1. 插入序言 --- std::vector<std::unique_ptr<MachineInstr>> prologue_instrs;
MachineBasicBlock* entry_block = mfunc->getBlocks().front().get();
auto& entry_instrs = entry_block->getInstructions();
// [修复] 创建一个临时 vector 来存放所有序言指令,以避免迭代器失效 // 严格按照 AsmPrinter 的打印顺序来创建和组织指令
std::vector<std::unique_ptr<MachineInstr>> prologue_instrs; // 1. addi sp, sp, -aligned_stack_size
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<ImmOperand>(-aligned_stack_size));
prologue_instrs.push_back(std::move(alloc_stack));
// a. addi sp, sp, -aligned_stack_size // 2. sd ra, (aligned_stack_size - 8)(sp)
auto alloc_stack = std::make_unique<MachineInstr>(RVOpcodes::ADDI); auto save_ra = std::make_unique<MachineInstr>(RVOpcodes::SD);
alloc_stack->addOperand(std::make_unique<RegOperand>(PhysicalReg::SP)); save_ra->addOperand(std::make_unique<RegOperand>(PhysicalReg::RA));
alloc_stack->addOperand(std::make_unique<RegOperand>(PhysicalReg::SP)); save_ra->addOperand(std::make_unique<MemOperand>(
alloc_stack->addOperand(std::make_unique<ImmOperand>(-aligned_stack_size)); std::make_unique<RegOperand>(PhysicalReg::SP),
prologue_instrs.push_back(std::move(alloc_stack)); std::make_unique<ImmOperand>(aligned_stack_size - 8)
));
prologue_instrs.push_back(std::move(save_ra));
// b. sd ra, offset(sp) // 3. sd s0, (aligned_stack_size - 16)(sp)
auto save_ra = std::make_unique<MachineInstr>(RVOpcodes::SD); auto save_fp = std::make_unique<MachineInstr>(RVOpcodes::SD);
save_ra->addOperand(std::make_unique<RegOperand>(PhysicalReg::RA)); save_fp->addOperand(std::make_unique<RegOperand>(PhysicalReg::S0));
save_ra->addOperand(std::make_unique<MemOperand>( save_fp->addOperand(std::make_unique<MemOperand>(
std::make_unique<RegOperand>(PhysicalReg::SP), std::make_unique<RegOperand>(PhysicalReg::SP),
std::make_unique<ImmOperand>(aligned_stack_size - 8) std::make_unique<ImmOperand>(aligned_stack_size - 16)
)); ));
prologue_instrs.push_back(std::move(save_ra)); prologue_instrs.push_back(std::move(save_fp));
// 4. addi s0, sp, aligned_stack_size
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::SP));
set_fp->addOperand(std::make_unique<ImmOperand>(aligned_stack_size));
prologue_instrs.push_back(std::move(set_fp));
// c. sd s0, offset(sp) // 确定插入点(在函数名标签之后)
auto save_fp = std::make_unique<MachineInstr>(RVOpcodes::SD); auto insert_pos = entry_instrs.begin();
save_fp->addOperand(std::make_unique<RegOperand>(PhysicalReg::S0)); // [重要] 这里我们不再需要跳过LABEL因为AsmPrinter将不再打印函数名标签
save_fp->addOperand(std::make_unique<MemOperand>( // 第一个基本块的标签就是函数入口
std::make_unique<RegOperand>(PhysicalReg::SP),
std::make_unique<ImmOperand>(aligned_stack_size - 16) // 一次性将所有序言指令插入
)); if (!prologue_instrs.empty()) {
prologue_instrs.push_back(std::move(save_fp)); entry_instrs.insert(insert_pos,
std::make_move_iterator(prologue_instrs.begin()),
// d. addi s0, sp, aligned_stack_size std::make_move_iterator(prologue_instrs.end()));
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::SP));
set_fp->addOperand(std::make_unique<ImmOperand>(aligned_stack_size));
prologue_instrs.push_back(std::move(set_fp));
// 确定插入点(在函数名标签之后) // --- 2. 插入尾声 ---
auto insert_pos = entry_instrs.begin(); for (auto& mbb : mfunc->getBlocks()) {
if (!entry_instrs.empty() && entry_instrs.front()->getOpcode() == RVOpcodes::LABEL) { for (auto it = mbb->getInstructions().begin(); it != mbb->getInstructions().end(); ++it) {
insert_pos++; if ((*it)->getOpcode() == RVOpcodes::RET) {
} std::vector<std::unique_ptr<MachineInstr>> epilogue_instrs;
// 一次性将所有序言指令插入,安全且高效
if (!prologue_instrs.empty()) {
entry_instrs.insert(insert_pos,
std::make_move_iterator(prologue_instrs.begin()),
std::make_move_iterator(prologue_instrs.end()));
}
// --- 2. 插入尾声 --- // 同样严格按照 AsmPrinter 的打印顺序
for (auto& mbb : mfunc->getBlocks()) { // 1. ld ra, (aligned_stack_size - 8)(sp)
for (auto it = mbb->getInstructions().begin(); it != mbb->getInstructions().end(); ++it) { auto restore_ra = std::make_unique<MachineInstr>(RVOpcodes::LD);
if ((*it)->getOpcode() == RVOpcodes::RET) { restore_ra->addOperand(std::make_unique<RegOperand>(PhysicalReg::RA));
// [修复] 创建一个临时 vector 来存放所有尾声指令 restore_ra->addOperand(std::make_unique<MemOperand>(
std::vector<std::unique_ptr<MachineInstr>> epilogue_instrs; std::make_unique<RegOperand>(PhysicalReg::SP),
std::make_unique<ImmOperand>(aligned_stack_size - 8)
));
epilogue_instrs.push_back(std::move(restore_ra));
// a. ld ra, offset(sp) // 2. ld s0, (aligned_stack_size - 16)(sp)
auto restore_ra = std::make_unique<MachineInstr>(RVOpcodes::LD); auto restore_fp = std::make_unique<MachineInstr>(RVOpcodes::LD);
restore_ra->addOperand(std::make_unique<RegOperand>(PhysicalReg::RA)); restore_fp->addOperand(std::make_unique<RegOperand>(PhysicalReg::S0));
restore_ra->addOperand(std::make_unique<MemOperand>( restore_fp->addOperand(std::make_unique<MemOperand>(
std::make_unique<RegOperand>(PhysicalReg::SP), std::make_unique<RegOperand>(PhysicalReg::SP),
std::make_unique<ImmOperand>(aligned_stack_size - 8) std::make_unique<ImmOperand>(aligned_stack_size - 16)
)); ));
epilogue_instrs.push_back(std::move(restore_ra)); epilogue_instrs.push_back(std::move(restore_fp));
// b. ld s0, offset(sp) // 3. addi sp, sp, aligned_stack_size
auto restore_fp = std::make_unique<MachineInstr>(RVOpcodes::LD); auto dealloc_stack = std::make_unique<MachineInstr>(RVOpcodes::ADDI);
restore_fp->addOperand(std::make_unique<RegOperand>(PhysicalReg::S0)); dealloc_stack->addOperand(std::make_unique<RegOperand>(PhysicalReg::SP));
restore_fp->addOperand(std::make_unique<MemOperand>( dealloc_stack->addOperand(std::make_unique<RegOperand>(PhysicalReg::SP));
std::make_unique<RegOperand>(PhysicalReg::SP), dealloc_stack->addOperand(std::make_unique<ImmOperand>(aligned_stack_size));
std::make_unique<ImmOperand>(aligned_stack_size - 16) epilogue_instrs.push_back(std::move(dealloc_stack));
));
epilogue_instrs.push_back(std::move(restore_fp));
// c. addi sp, sp, aligned_stack_size if (!epilogue_instrs.empty()) {
auto dealloc_stack = std::make_unique<MachineInstr>(RVOpcodes::ADDI); mbb->getInstructions().insert(it,
dealloc_stack->addOperand(std::make_unique<RegOperand>(PhysicalReg::SP)); std::make_move_iterator(epilogue_instrs.begin()),
dealloc_stack->addOperand(std::make_unique<RegOperand>(PhysicalReg::SP)); std::make_move_iterator(epilogue_instrs.end()));
dealloc_stack->addOperand(std::make_unique<ImmOperand>(aligned_stack_size)); }
epilogue_instrs.push_back(std::move(dealloc_stack)); // 处理完一个基本块中的RET后迭代器已失效需跳出
goto next_block;
// 在 RET 指令前一次性插入所有尾声指令
if (!epilogue_instrs.empty()) {
mbb->getInstructions().insert(it,
std::make_move_iterator(epilogue_instrs.begin()),
std::make_move_iterator(epilogue_instrs.end()));
} }
// 处理完当前基本块的RET后即可跳出内层循环
break;
} }
next_block:;
} }
} }
} }

View File

@@ -124,14 +124,6 @@ std::string RISCv64CodeGen::function_gen(Function* func) {
CalleeSavedHandler callee_handler; CalleeSavedHandler callee_handler;
callee_handler.runOnMachineFunction(mfunc.get()); callee_handler.runOnMachineFunction(mfunc.get());
// 阶段 3.2: 插入序言和尾声
PrologueEpilogueInsertionPass pei_pass;
pei_pass.runOnMachineFunction(mfunc.get());
// 阶段 3.3: 清理产生的大立即数
LegalizeImmediatesPass legalizer;
legalizer.runOnMachineFunction(mfunc.get());
// 阶段 4: 窥孔优化 (Peephole Optimization) // 阶段 4: 窥孔优化 (Peephole Optimization)
PeepholeOptimizer peephole; PeepholeOptimizer peephole;
peephole.runOnMachineFunction(mfunc.get()); peephole.runOnMachineFunction(mfunc.get());
@@ -140,6 +132,14 @@ std::string RISCv64CodeGen::function_gen(Function* func) {
PostRA_Scheduler local_scheduler; PostRA_Scheduler local_scheduler;
local_scheduler.runOnMachineFunction(mfunc.get()); local_scheduler.runOnMachineFunction(mfunc.get());
// 阶段 3.2: 插入序言和尾声
PrologueEpilogueInsertionPass pei_pass;
pei_pass.runOnMachineFunction(mfunc.get());
// 阶段 3.3: 清理产生的大立即数
LegalizeImmediatesPass legalizer;
legalizer.runOnMachineFunction(mfunc.get());
// 阶段 6: 代码发射 (Code Emission) // 阶段 6: 代码发射 (Code Emission)
std::stringstream ss; std::stringstream ss;
RISCv64AsmPrinter printer(mfunc.get()); RISCv64AsmPrinter printer(mfunc.get());