[midend]重构了src目录

This commit is contained in:
Lixuanwang
2025-07-29 21:30:30 +08:00
parent f5922d0178
commit 09ae47924e
84 changed files with 85 additions and 1715 deletions

View File

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