diff --git a/src/PrologueEpilogueInsertion.cpp b/src/PrologueEpilogueInsertion.cpp index d5ab753..9eec6b5 100644 --- a/src/PrologueEpilogueInsertion.cpp +++ b/src/PrologueEpilogueInsertion.cpp @@ -1,4 +1,4 @@ -#include "include/PrologueEpilogueInsertion.h" +#include "PrologueEpilogueInsertion.h" namespace sysy { @@ -6,114 +6,111 @@ 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字节 - // 保持栈指针16字节对齐 int aligned_stack_size = (total_stack_size + 15) & ~15; 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. 插入序言 --- - MachineBasicBlock* entry_block = mfunc->getBlocks().front().get(); - auto& entry_instrs = entry_block->getInstructions(); + std::vector> prologue_instrs; - // [修复] 创建一个临时 vector 来存放所有序言指令,以避免迭代器失效 - std::vector> prologue_instrs; + // 严格按照 AsmPrinter 的打印顺序来创建和组织指令 + // 1. addi sp, sp, -aligned_stack_size + auto alloc_stack = std::make_unique(RVOpcodes::ADDI); + alloc_stack->addOperand(std::make_unique(PhysicalReg::SP)); + alloc_stack->addOperand(std::make_unique(PhysicalReg::SP)); + alloc_stack->addOperand(std::make_unique(-aligned_stack_size)); + prologue_instrs.push_back(std::move(alloc_stack)); - // a. addi sp, sp, -aligned_stack_size - auto alloc_stack = std::make_unique(RVOpcodes::ADDI); - alloc_stack->addOperand(std::make_unique(PhysicalReg::SP)); - alloc_stack->addOperand(std::make_unique(PhysicalReg::SP)); - alloc_stack->addOperand(std::make_unique(-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(RVOpcodes::SD); + save_ra->addOperand(std::make_unique(PhysicalReg::RA)); + save_ra->addOperand(std::make_unique( + std::make_unique(PhysicalReg::SP), + std::make_unique(aligned_stack_size - 8) + )); + prologue_instrs.push_back(std::move(save_ra)); - // b. sd ra, offset(sp) - auto save_ra = std::make_unique(RVOpcodes::SD); - save_ra->addOperand(std::make_unique(PhysicalReg::RA)); - save_ra->addOperand(std::make_unique( - std::make_unique(PhysicalReg::SP), - std::make_unique(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(RVOpcodes::SD); + save_fp->addOperand(std::make_unique(PhysicalReg::S0)); + save_fp->addOperand(std::make_unique( + std::make_unique(PhysicalReg::SP), + std::make_unique(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(RVOpcodes::ADDI); + set_fp->addOperand(std::make_unique(PhysicalReg::S0)); + set_fp->addOperand(std::make_unique(PhysicalReg::SP)); + set_fp->addOperand(std::make_unique(aligned_stack_size)); + prologue_instrs.push_back(std::move(set_fp)); - // c. sd s0, offset(sp) - auto save_fp = std::make_unique(RVOpcodes::SD); - save_fp->addOperand(std::make_unique(PhysicalReg::S0)); - save_fp->addOperand(std::make_unique( - std::make_unique(PhysicalReg::SP), - std::make_unique(aligned_stack_size - 16) - )); - prologue_instrs.push_back(std::move(save_fp)); - - // d. addi s0, sp, aligned_stack_size - auto set_fp = std::make_unique(RVOpcodes::ADDI); - set_fp->addOperand(std::make_unique(PhysicalReg::S0)); - set_fp->addOperand(std::make_unique(PhysicalReg::SP)); - set_fp->addOperand(std::make_unique(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())); + } - // 确定插入点(在函数名标签之后) - auto insert_pos = entry_instrs.begin(); - if (!entry_instrs.empty() && entry_instrs.front()->getOpcode() == RVOpcodes::LABEL) { - insert_pos++; - } - - // 一次性将所有序言指令插入,安全且高效 - 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> epilogue_instrs; - // --- 2. 插入尾声 --- - for (auto& mbb : mfunc->getBlocks()) { - for (auto it = mbb->getInstructions().begin(); it != mbb->getInstructions().end(); ++it) { - if ((*it)->getOpcode() == RVOpcodes::RET) { - // [修复] 创建一个临时 vector 来存放所有尾声指令 - std::vector> epilogue_instrs; + // 同样严格按照 AsmPrinter 的打印顺序 + // 1. ld ra, (aligned_stack_size - 8)(sp) + auto restore_ra = std::make_unique(RVOpcodes::LD); + restore_ra->addOperand(std::make_unique(PhysicalReg::RA)); + restore_ra->addOperand(std::make_unique( + std::make_unique(PhysicalReg::SP), + std::make_unique(aligned_stack_size - 8) + )); + epilogue_instrs.push_back(std::move(restore_ra)); - // a. ld ra, offset(sp) - auto restore_ra = std::make_unique(RVOpcodes::LD); - restore_ra->addOperand(std::make_unique(PhysicalReg::RA)); - restore_ra->addOperand(std::make_unique( - std::make_unique(PhysicalReg::SP), - std::make_unique(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(RVOpcodes::LD); + restore_fp->addOperand(std::make_unique(PhysicalReg::S0)); + restore_fp->addOperand(std::make_unique( + std::make_unique(PhysicalReg::SP), + std::make_unique(aligned_stack_size - 16) + )); + epilogue_instrs.push_back(std::move(restore_fp)); - // b. ld s0, offset(sp) - auto restore_fp = std::make_unique(RVOpcodes::LD); - restore_fp->addOperand(std::make_unique(PhysicalReg::S0)); - restore_fp->addOperand(std::make_unique( - std::make_unique(PhysicalReg::SP), - std::make_unique(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(RVOpcodes::ADDI); + dealloc_stack->addOperand(std::make_unique(PhysicalReg::SP)); + dealloc_stack->addOperand(std::make_unique(PhysicalReg::SP)); + dealloc_stack->addOperand(std::make_unique(aligned_stack_size)); + epilogue_instrs.push_back(std::move(dealloc_stack)); - // c. addi sp, sp, aligned_stack_size - auto dealloc_stack = std::make_unique(RVOpcodes::ADDI); - dealloc_stack->addOperand(std::make_unique(PhysicalReg::SP)); - dealloc_stack->addOperand(std::make_unique(PhysicalReg::SP)); - dealloc_stack->addOperand(std::make_unique(aligned_stack_size)); - epilogue_instrs.push_back(std::move(dealloc_stack)); - - // 在 RET 指令前一次性插入所有尾声指令 - if (!epilogue_instrs.empty()) { - mbb->getInstructions().insert(it, - std::make_move_iterator(epilogue_instrs.begin()), - std::make_move_iterator(epilogue_instrs.end())); + 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; } - - // 处理完当前基本块的RET后即可跳出内层循环 - break; } + next_block:; } } } diff --git a/src/RISCv64Backend.cpp b/src/RISCv64Backend.cpp index 26e37ac..c32af0c 100644 --- a/src/RISCv64Backend.cpp +++ b/src/RISCv64Backend.cpp @@ -124,14 +124,6 @@ std::string RISCv64CodeGen::function_gen(Function* func) { CalleeSavedHandler callee_handler; 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) PeepholeOptimizer peephole; peephole.runOnMachineFunction(mfunc.get()); @@ -140,6 +132,14 @@ std::string RISCv64CodeGen::function_gen(Function* func) { PostRA_Scheduler local_scheduler; 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) std::stringstream ss; RISCv64AsmPrinter printer(mfunc.get());