[backend]调整了后端pass的顺序
This commit is contained in:
@@ -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:;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|||||||
Reference in New Issue
Block a user