From 860ebcd44756f7ee27a6496ef4c5f6483a2b1ca0 Mon Sep 17 00:00:00 2001 From: CGH0S7 <776459475@qq.com> Date: Wed, 30 Jul 2025 10:28:06 +0800 Subject: [PATCH] =?UTF-8?q?[Optimize]=E5=AF=B9PostRA=E6=8C=87=E4=BB=A4?= =?UTF-8?q?=E8=B0=83=E5=BA=A6=E8=BF=9B=E8=A1=8C=E5=AE=B9=E5=99=A8/?= =?UTF-8?q?=E7=AE=97=E6=B3=95/=E7=BC=93=E5=AD=98=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RISCv64/Optimize/PostRA_Scheduler.cpp | 689 +++++++++--------- .../RISCv64/Optimize/PostRA_Scheduler.h | 20 + 2 files changed, 381 insertions(+), 328 deletions(-) diff --git a/src/backend/RISCv64/Optimize/PostRA_Scheduler.cpp b/src/backend/RISCv64/Optimize/PostRA_Scheduler.cpp index efc18dc..b0ca9b6 100644 --- a/src/backend/RISCv64/Optimize/PostRA_Scheduler.cpp +++ b/src/backend/RISCv64/Optimize/PostRA_Scheduler.cpp @@ -1,8 +1,8 @@ #include "PostRA_Scheduler.h" -#include -#include -#include #include +#include +#include +#include #define MAX_SCHEDULING_BLOCK_SIZE 10000 // 限制调度块大小,避免过大导致性能问题 namespace sysy { @@ -10,374 +10,407 @@ namespace sysy { char PostRA_Scheduler::ID = 0; // 检查指令是否是加载指令 (LW, LD) -bool isLoadInstr(MachineInstr* instr) { - RVOpcodes opcode = instr->getOpcode(); - return opcode == RVOpcodes::LW || opcode == RVOpcodes::LD || - opcode == RVOpcodes::LH || opcode == RVOpcodes::LB || - opcode == RVOpcodes::LHU || opcode == RVOpcodes::LBU || - opcode == RVOpcodes::LWU; +bool isLoadInstr(MachineInstr *instr) { + RVOpcodes opcode = instr->getOpcode(); + return opcode == RVOpcodes::LW || opcode == RVOpcodes::LD || + opcode == RVOpcodes::LH || opcode == RVOpcodes::LB || + opcode == RVOpcodes::LHU || opcode == RVOpcodes::LBU || + opcode == RVOpcodes::LWU; } // 检查指令是否是存储指令 (SW, SD) -bool isStoreInstr(MachineInstr* instr) { - RVOpcodes opcode = instr->getOpcode(); - return opcode == RVOpcodes::SW || opcode == RVOpcodes::SD || - opcode == RVOpcodes::SH || opcode == RVOpcodes::SB; +bool isStoreInstr(MachineInstr *instr) { + RVOpcodes opcode = instr->getOpcode(); + return opcode == RVOpcodes::SW || opcode == RVOpcodes::SD || + opcode == RVOpcodes::SH || opcode == RVOpcodes::SB; } // 检查指令是否为控制流指令 -bool isControlFlowInstr(MachineInstr* instr) { - RVOpcodes opcode = instr->getOpcode(); - return opcode == RVOpcodes::RET || opcode == RVOpcodes::J || - opcode == RVOpcodes::BEQ || opcode == RVOpcodes::BNE || - opcode == RVOpcodes::BLT || opcode == RVOpcodes::BGE || - opcode == RVOpcodes::BLTU || opcode == RVOpcodes::BGEU || - opcode == RVOpcodes::CALL; +bool isControlFlowInstr(MachineInstr *instr) { + RVOpcodes opcode = instr->getOpcode(); + return opcode == RVOpcodes::RET || opcode == RVOpcodes::J || + opcode == RVOpcodes::BEQ || opcode == RVOpcodes::BNE || + opcode == RVOpcodes::BLT || opcode == RVOpcodes::BGE || + opcode == RVOpcodes::BLTU || opcode == RVOpcodes::BGEU || + opcode == RVOpcodes::CALL; } -// 获取指令定义的寄存器 - 修复版本 -std::set getDefinedRegisters(MachineInstr* instr) { - std::set defined_regs; - RVOpcodes opcode = instr->getOpcode(); - - // 特殊处理CALL指令 - if (opcode == RVOpcodes::CALL) { - // CALL指令可能定义返回值寄存器 - if (!instr->getOperands().empty() && - instr->getOperands().front()->getKind() == MachineOperand::KIND_REG) { - auto reg_op = static_cast(instr->getOperands().front().get()); - if (!reg_op->isVirtual()) { - defined_regs.insert(reg_op->getPReg()); - } - } - return defined_regs; - } - - // 存储指令不定义寄存器 - if (isStoreInstr(instr)) { - return defined_regs; - } - - // 分支指令不定义寄存器 - if (opcode == RVOpcodes::BEQ || opcode == RVOpcodes::BNE || - opcode == RVOpcodes::BLT || opcode == RVOpcodes::BGE || - opcode == RVOpcodes::BLTU || opcode == RVOpcodes::BGEU || - opcode == RVOpcodes::J || opcode == RVOpcodes::RET) { - return defined_regs; - } - - // 对于其他指令,第一个寄存器操作数通常是定义的 - if (!instr->getOperands().empty() && +// 预计算指令信息的缓存 +static std::unordered_map instr_info_cache; + +// 获取指令定义的寄存器 - 优化版本 +std::unordered_set getDefinedRegisters(MachineInstr *instr) { + std::unordered_set defined_regs; + RVOpcodes opcode = instr->getOpcode(); + + // 特殊处理CALL指令 + if (opcode == RVOpcodes::CALL) { + // CALL指令可能定义返回值寄存器 + if (!instr->getOperands().empty() && instr->getOperands().front()->getKind() == MachineOperand::KIND_REG) { - auto reg_op = static_cast(instr->getOperands().front().get()); - if (!reg_op->isVirtual()) { - defined_regs.insert(reg_op->getPReg()); - } + auto reg_op = + static_cast(instr->getOperands().front().get()); + if (!reg_op->isVirtual()) { + defined_regs.insert(reg_op->getPReg()); + } } - return defined_regs; + } + + // 存储指令不定义寄存器 + if (isStoreInstr(instr)) { + return defined_regs; + } + + // 分支指令不定义寄存器 + if (opcode == RVOpcodes::BEQ || opcode == RVOpcodes::BNE || + opcode == RVOpcodes::BLT || opcode == RVOpcodes::BGE || + opcode == RVOpcodes::BLTU || opcode == RVOpcodes::BGEU || + opcode == RVOpcodes::J || opcode == RVOpcodes::RET) { + return defined_regs; + } + + // 对于其他指令,第一个寄存器操作数通常是定义的 + if (!instr->getOperands().empty() && + instr->getOperands().front()->getKind() == MachineOperand::KIND_REG) { + auto reg_op = static_cast(instr->getOperands().front().get()); + if (!reg_op->isVirtual()) { + defined_regs.insert(reg_op->getPReg()); + } + } + + return defined_regs; } -// 获取指令使用的寄存器 - 修复版本 -std::set getUsedRegisters(MachineInstr* instr) { - std::set used_regs; - RVOpcodes opcode = instr->getOpcode(); - - // 特殊处理CALL指令 - if (opcode == RVOpcodes::CALL) { - bool first_reg_skipped = false; - for (const auto& op : instr->getOperands()) { - if (op->getKind() == MachineOperand::KIND_REG) { - if (!first_reg_skipped) { - first_reg_skipped = true; - continue; // 跳过返回值寄存器 - } - auto reg_op = static_cast(op.get()); - if (!reg_op->isVirtual()) { - used_regs.insert(reg_op->getPReg()); - } - } +// 获取指令使用的寄存器 - 优化版本 +std::unordered_set getUsedRegisters(MachineInstr *instr) { + std::unordered_set used_regs; + RVOpcodes opcode = instr->getOpcode(); + + // 特殊处理CALL指令 + if (opcode == RVOpcodes::CALL) { + bool first_reg_skipped = false; + for (const auto &op : instr->getOperands()) { + if (op->getKind() == MachineOperand::KIND_REG) { + if (!first_reg_skipped) { + first_reg_skipped = true; + continue; // 跳过返回值寄存器 } - return used_regs; - } - - // 对于存储指令,所有寄存器操作数都是使用的 - if (isStoreInstr(instr)) { - for (const auto& op : instr->getOperands()) { - if (op->getKind() == MachineOperand::KIND_REG) { - auto reg_op = static_cast(op.get()); - if (!reg_op->isVirtual()) { - used_regs.insert(reg_op->getPReg()); - } - } else if (op->getKind() == MachineOperand::KIND_MEM) { - auto mem_op = static_cast(op.get()); - if (!mem_op->getBase()->isVirtual()) { - used_regs.insert(mem_op->getBase()->getPReg()); - } - } - } - return used_regs; - } - - // 对于分支指令,所有寄存器操作数都是使用的 - if (opcode == RVOpcodes::BEQ || opcode == RVOpcodes::BNE || - opcode == RVOpcodes::BLT || opcode == RVOpcodes::BGE || - opcode == RVOpcodes::BLTU || opcode == RVOpcodes::BGEU) { - for (const auto& op : instr->getOperands()) { - if (op->getKind() == MachineOperand::KIND_REG) { - auto reg_op = static_cast(op.get()); - if (!reg_op->isVirtual()) { - used_regs.insert(reg_op->getPReg()); - } - } - } - return used_regs; - } - - // 对于其他指令,除了第一个寄存器操作数(通常是定义),其余都是使用的 - bool first_reg = true; - for (const auto& op : instr->getOperands()) { - if (op->getKind() == MachineOperand::KIND_REG) { - if (first_reg) { - first_reg = false; - continue; // 跳过第一个寄存器(定义) - } - auto reg_op = static_cast(op.get()); - if (!reg_op->isVirtual()) { - used_regs.insert(reg_op->getPReg()); - } - } else if (op->getKind() == MachineOperand::KIND_MEM) { - auto mem_op = static_cast(op.get()); - if (!mem_op->getBase()->isVirtual()) { - used_regs.insert(mem_op->getBase()->getPReg()); - } + auto reg_op = static_cast(op.get()); + if (!reg_op->isVirtual()) { + used_regs.insert(reg_op->getPReg()); } + } } return used_regs; + } + + // 对于存储指令,所有寄存器操作数都是使用的 + if (isStoreInstr(instr)) { + for (const auto &op : instr->getOperands()) { + if (op->getKind() == MachineOperand::KIND_REG) { + auto reg_op = static_cast(op.get()); + if (!reg_op->isVirtual()) { + used_regs.insert(reg_op->getPReg()); + } + } else if (op->getKind() == MachineOperand::KIND_MEM) { + auto mem_op = static_cast(op.get()); + if (!mem_op->getBase()->isVirtual()) { + used_regs.insert(mem_op->getBase()->getPReg()); + } + } + } + return used_regs; + } + + // 对于分支指令,所有寄存器操作数都是使用的 + if (opcode == RVOpcodes::BEQ || opcode == RVOpcodes::BNE || + opcode == RVOpcodes::BLT || opcode == RVOpcodes::BGE || + opcode == RVOpcodes::BLTU || opcode == RVOpcodes::BGEU) { + for (const auto &op : instr->getOperands()) { + if (op->getKind() == MachineOperand::KIND_REG) { + auto reg_op = static_cast(op.get()); + if (!reg_op->isVirtual()) { + used_regs.insert(reg_op->getPReg()); + } + } + } + return used_regs; + } + + // 对于其他指令,除了第一个寄存器操作数(通常是定义),其余都是使用的 + bool first_reg = true; + for (const auto &op : instr->getOperands()) { + if (op->getKind() == MachineOperand::KIND_REG) { + if (first_reg) { + first_reg = false; + continue; // 跳过第一个寄存器(定义) + } + auto reg_op = static_cast(op.get()); + if (!reg_op->isVirtual()) { + used_regs.insert(reg_op->getPReg()); + } + } else if (op->getKind() == MachineOperand::KIND_MEM) { + auto mem_op = static_cast(op.get()); + if (!mem_op->getBase()->isVirtual()) { + used_regs.insert(mem_op->getBase()->getPReg()); + } + } + } + return used_regs; } // 获取内存访问的基址和偏移 -struct MemoryAccess { - PhysicalReg base_reg; - int64_t offset; - bool valid; - - MemoryAccess() : valid(false) {} - MemoryAccess(PhysicalReg base, int64_t off) : base_reg(base), offset(off), valid(true) {} -}; -MemoryAccess getMemoryAccess(MachineInstr* instr) { - if (!isLoadInstr(instr) && !isStoreInstr(instr)) { - return MemoryAccess(); - } - - // 查找内存操作数 - for (const auto& op : instr->getOperands()) { - if (op->getKind() == MachineOperand::KIND_MEM) { - auto mem_op = static_cast(op.get()); - if (!mem_op->getBase()->isVirtual()) { - return MemoryAccess(mem_op->getBase()->getPReg(), mem_op->getOffset()->getValue()); - } - } - } - +MemoryAccess getMemoryAccess(MachineInstr *instr) { + if (!isLoadInstr(instr) && !isStoreInstr(instr)) { return MemoryAccess(); + } + + // 查找内存操作数 + for (const auto &op : instr->getOperands()) { + if (op->getKind() == MachineOperand::KIND_MEM) { + auto mem_op = static_cast(op.get()); + if (!mem_op->getBase()->isVirtual()) { + return MemoryAccess(mem_op->getBase()->getPReg(), + mem_op->getOffset()->getValue()); + } + } + } + + return MemoryAccess(); } -// 检查内存依赖 - 加强版本 -bool hasMemoryDependency(MachineInstr* instr1, MachineInstr* instr2) { - // 如果都不是内存指令,没有内存依赖 - if (!isLoadInstr(instr1) && !isStoreInstr(instr1) && - !isLoadInstr(instr2) && !isStoreInstr(instr2)) { - return false; - } - - MemoryAccess mem1 = getMemoryAccess(instr1); - MemoryAccess mem2 = getMemoryAccess(instr2); - - if (!mem1.valid || !mem2.valid) { - // 如果无法确定内存访问模式,保守地认为存在依赖 - return true; - } - - // 如果访问相同的内存位置 - if (mem1.base_reg == mem2.base_reg && mem1.offset == mem2.offset) { - // Store->Load: RAW依赖 - // Load->Store: WAR依赖 - // Store->Store: WAW依赖 - return isStoreInstr(instr1) || isStoreInstr(instr2); - } - - // 不同内存位置通常没有依赖,但为了安全起见, - // 如果涉及store指令,我们需要更保守 - if (isStoreInstr(instr1) && isLoadInstr(instr2)) { - // 保守处理:不同store和load之间可能有别名 - return false; // 这里可以根据需要调整策略 - } - +// 预计算指令信息 +InstrRegInfo &getInstrInfo(MachineInstr *instr) { + auto it = instr_info_cache.find(instr); + if (it != instr_info_cache.end()) { + return it->second; + } + + InstrRegInfo &info = instr_info_cache[instr]; + info.defined_regs = getDefinedRegisters(instr); + info.used_regs = getUsedRegisters(instr); + info.is_load = isLoadInstr(instr); + info.is_store = isStoreInstr(instr); + info.is_control_flow = isControlFlowInstr(instr); + info.mem_access = getMemoryAccess(instr); + + return info; +} + +// 检查内存依赖 - 优化版本 +bool hasMemoryDependency(const InstrRegInfo &info1, const InstrRegInfo &info2) { + // 如果都不是内存指令,没有内存依赖 + if (!info1.is_load && !info1.is_store && !info2.is_load && !info2.is_store) { return false; + } + + const MemoryAccess &mem1 = info1.mem_access; + const MemoryAccess &mem2 = info2.mem_access; + + if (!mem1.valid || !mem2.valid) { + // 如果无法确定内存访问模式,保守地认为存在依赖 + return true; + } + + // 如果访问相同的内存位置 + if (mem1.base_reg == mem2.base_reg && mem1.offset == mem2.offset) { + // Store->Load: RAW依赖 + // Load->Store: WAR依赖 + // Store->Store: WAW依赖 + return info1.is_store || info2.is_store; + } + + // 不同内存位置通常没有依赖,但为了安全起见, + // 如果涉及store指令,我们需要更保守 + if (info1.is_store && info2.is_load) { + // 保守处理:不同store和load之间可能有别名 + return false; // 这里可以根据需要调整策略 + } + + return false; } -// 检查两个指令之间是否存在依赖关系 - 修复版本 -bool hasDependency(MachineInstr* instr1, MachineInstr* instr2) { - // 检查RAW依赖:instr1定义的寄存器是否被instr2使用 - auto defined_regs1 = getDefinedRegisters(instr1); - auto used_regs2 = getUsedRegisters(instr2); - - for (const auto& reg : defined_regs1) { - if (used_regs2.find(reg) != used_regs2.end()) { - return true; // RAW依赖 - instr2读取instr1写入的值 - } +// 检查两个指令之间是否存在依赖关系 - 优化版本 +bool hasDependency(MachineInstr *instr1, MachineInstr *instr2) { + const InstrRegInfo &info1 = getInstrInfo(instr1); + const InstrRegInfo &info2 = getInstrInfo(instr2); + + // 检查RAW依赖:instr1定义的寄存器是否被instr2使用 + for (const auto ® : info1.defined_regs) { + if (info2.used_regs.find(reg) != info2.used_regs.end()) { + return true; // RAW依赖 - instr2读取instr1写入的值 } - - // 检查WAR依赖:instr1使用的寄存器是否被instr2定义 - auto used_regs1 = getUsedRegisters(instr1); - auto defined_regs2 = getDefinedRegisters(instr2); - - for (const auto& reg : used_regs1) { - if (defined_regs2.find(reg) != defined_regs2.end()) { - return true; // WAR依赖 - instr2覆盖instr1需要的值 - } + } + + // 检查WAR依赖:instr1使用的寄存器是否被instr2定义 + for (const auto ® : info1.used_regs) { + if (info2.defined_regs.find(reg) != info2.defined_regs.end()) { + return true; // WAR依赖 - instr2覆盖instr1需要的值 } - - // 检查WAW依赖:两个指令定义相同寄存器 - for (const auto& reg : defined_regs1) { - if (defined_regs2.find(reg) != defined_regs2.end()) { - return true; // WAW依赖 - 两条指令写入同一寄存器 - } + } + + // 检查WAW依赖:两个指令定义相同寄存器 + for (const auto ® : info1.defined_regs) { + if (info2.defined_regs.find(reg) != info2.defined_regs.end()) { + return true; // WAW依赖 - 两条指令写入同一寄存器 } - - // 检查内存依赖 - if (hasMemoryDependency(instr1, instr2)) { - return true; - } - + } + + // 检查内存依赖 + if (hasMemoryDependency(info1, info2)) { + return true; + } + + return false; +} + +// 检查是否可以安全地将instr1和instr2交换位置 - 优化版本 +bool canSwapInstructions(MachineInstr *instr1, MachineInstr *instr2) { + const InstrRegInfo &info1 = getInstrInfo(instr1); + const InstrRegInfo &info2 = getInstrInfo(instr2); + + // 不能移动控制流指令 + if (info1.is_control_flow || info2.is_control_flow) { return false; + } + + // 检查双向依赖关系 + return !hasDependency(instr1, instr2) && !hasDependency(instr2, instr1); } -// 检查是否可以安全地将instr1和instr2交换位置 -bool canSwapInstructions(MachineInstr* instr1, MachineInstr* instr2) { - // 不能移动控制流指令 - if (isControlFlowInstr(instr1) || isControlFlowInstr(instr2)) { - return false; - } - - // 检查双向依赖关系 - return !hasDependency(instr1, instr2) && !hasDependency(instr2, instr1); -} +// 新增:验证调度结果的正确性 - 优化版本 +void validateSchedule(const std::vector &instr_list) { + for (int i = 0; i < (int)instr_list.size(); i++) { + for (int j = i + 1; j < (int)instr_list.size(); j++) { + MachineInstr *earlier = instr_list[i]; + MachineInstr *later = instr_list[j]; -// 新增:验证调度结果的正确性 -void validateSchedule(const std::vector& instr_list) { - for (int i = 0; i < (int)instr_list.size(); i++) { - for (int j = i + 1; j < (int)instr_list.size(); j++) { - MachineInstr* earlier = instr_list[i]; - MachineInstr* later = instr_list[j]; - - // 检查是否存在被违反的依赖关系 - auto defined_regs = getDefinedRegisters(earlier); - auto used_regs = getUsedRegisters(later); - - // 检查RAW依赖 - for (const auto& reg : defined_regs) { - if (used_regs.find(reg) != used_regs.end()) { - // 这是正常的依赖关系,earlier应该在later之前 - continue; - } - } - - // 检查内存依赖 - if (hasMemoryDependency(earlier, later)) { - MemoryAccess mem1 = getMemoryAccess(earlier); - MemoryAccess mem2 = getMemoryAccess(later); - - if (mem1.valid && mem2.valid && - mem1.base_reg == mem2.base_reg && mem1.offset == mem2.offset) { - if (isStoreInstr(earlier) && isLoadInstr(later)) { - // Store->Load依赖,顺序正确 - continue; - } - } - } + const InstrRegInfo &info_earlier = getInstrInfo(earlier); + const InstrRegInfo &info_later = getInstrInfo(later); + + // 检查是否存在被违反的依赖关系 + // 检查RAW依赖 + for (const auto ® : info_earlier.defined_regs) { + if (info_later.used_regs.find(reg) != info_later.used_regs.end()) { + // 这是正常的依赖关系,earlier应该在later之前 + continue; } - } -} + } -// 在基本块内对指令进行调度优化 - 完全重写版本 -void scheduleBlock(MachineBasicBlock* mbb) { - auto& instructions = mbb->getInstructions(); - if (instructions.size() <= 1) return; - if (instructions.size() > MAX_SCHEDULING_BLOCK_SIZE) { - return; // 跳过超大块,防止卡住 - } - - std::vector instr_list; - for (auto& instr : instructions) { - instr_list.push_back(instr.get()); - } - - // 使用更严格的调度策略,避免破坏依赖关系 - bool changed = true; - int max_iterations = 10; // 限制迭代次数避免死循环 - int iteration = 0; - - while (changed && iteration < max_iterations) { - changed = false; - iteration++; - - for (int i = 0; i < (int)instr_list.size() - 1; i++) { - MachineInstr* instr1 = instr_list[i]; - MachineInstr* instr2 = instr_list[i + 1]; - - // 只进行非常保守的优化 - bool should_swap = false; - - // 策略1: 将load指令提前,减少load-use延迟 - if (isLoadInstr(instr2) && !isLoadInstr(instr1) && !isStoreInstr(instr1)) { - should_swap = canSwapInstructions(instr1, instr2); - } - // 策略2: 将非关键store指令延后,为其他指令让路 - else if (isStoreInstr(instr1) && !isLoadInstr(instr2) && !isStoreInstr(instr2)) { - should_swap = canSwapInstructions(instr1, instr2); - } - - if (should_swap) { - std::swap(instr_list[i], instr_list[i + 1]); - changed = true; - - // 调试输出 - // std::cout << "Swapped instructions at positions " << i << " and " << (i+1) << std::endl; - } + // 检查内存依赖 + if (hasMemoryDependency(info_earlier, info_later)) { + const MemoryAccess &mem1 = info_earlier.mem_access; + const MemoryAccess &mem2 = info_later.mem_access; + + if (mem1.valid && mem2.valid && mem1.base_reg == mem2.base_reg && + mem1.offset == mem2.offset) { + if (info_earlier.is_store && info_later.is_load) { + // Store->Load依赖,顺序正确 + continue; + } } + } } - - // 验证调度结果的正确性 - validateSchedule(instr_list); - - // 将调度后的指令顺序写回 - std::map> instr_map; - for (auto& instr : instructions) { - instr_map[instr.get()] = std::move(instr); - } - - instructions.clear(); - for (auto instr : instr_list) { - instructions.push_back(std::move(instr_map[instr])); - } + } } -bool PostRA_Scheduler::runOnFunction(Function *F, AnalysisManager& AM) { - // 这个函数在IR级别运行,但我们需要在机器指令级别运行 - // 所以我们返回false,表示没有对IR进行修改 - return false; +// 在基本块内对指令进行调度优化 - 优化版本 +void scheduleBlock(MachineBasicBlock *mbb) { + auto &instructions = mbb->getInstructions(); + if (instructions.size() <= 1) + return; + if (instructions.size() > MAX_SCHEDULING_BLOCK_SIZE) { + return; // 跳过超大块,防止卡住 + } + + // 清理缓存,避免无效指针 + instr_info_cache.clear(); + + std::vector instr_list; + instr_list.reserve(instructions.size()); // 预分配容量 + for (auto &instr : instructions) { + instr_list.push_back(instr.get()); + } + + // 预计算所有指令的信息 + for (auto *instr : instr_list) { + getInstrInfo(instr); + } + + // 使用更严格的调度策略,避免破坏依赖关系 + bool changed = true; + int max_iterations = 10; // 限制迭代次数避免死循环 + int iteration = 0; + + while (changed && iteration < max_iterations) { + changed = false; + iteration++; + + for (int i = 0; i < (int)instr_list.size() - 1; i++) { + MachineInstr *instr1 = instr_list[i]; + MachineInstr *instr2 = instr_list[i + 1]; + + const InstrRegInfo &info1 = getInstrInfo(instr1); + const InstrRegInfo &info2 = getInstrInfo(instr2); + + // 只进行非常保守的优化 + bool should_swap = false; + + // 策略1: 将load指令提前,减少load-use延迟 + if (info2.is_load && !info1.is_load && !info1.is_store) { + should_swap = canSwapInstructions(instr1, instr2); + } + // 策略2: 将非关键store指令延后,为其他指令让路 + else if (info1.is_store && !info2.is_load && !info2.is_store) { + should_swap = canSwapInstructions(instr1, instr2); + } + + if (should_swap) { + std::swap(instr_list[i], instr_list[i + 1]); + changed = true; + + // 调试输出 + // std::cout << "Swapped instructions at positions " << i << " and " << + // (i+1) << std::endl; + } + } + } + + // 验证调度结果的正确性 + validateSchedule(instr_list); + + // 将调度后的指令顺序写回 + std::unordered_map> instr_map; + instr_map.reserve(instructions.size()); // 预分配容量 + for (auto &instr : instructions) { + instr_map[instr.get()] = std::move(instr); + } + + instructions.clear(); + instructions.reserve(instr_list.size()); // 预分配容量 + for (auto instr : instr_list) { + instructions.push_back(std::move(instr_map[instr])); + } +} + +bool PostRA_Scheduler::runOnFunction(Function *F, AnalysisManager &AM) { + // 这个函数在IR级别运行,但我们需要在机器指令级别运行 + // 所以我们返回false,表示没有对IR进行修改 + return false; } void PostRA_Scheduler::runOnMachineFunction(MachineFunction *mfunc) { - // std::cout << "Running Post-RA Local Scheduler... " << std::endl; - - // 遍历每个机器基本块 - for (auto& mbb : mfunc->getBlocks()) { - scheduleBlock(mbb.get()); - } + // std::cout << "Running Post-RA Local Scheduler... " << std::endl; + + // 遍历每个机器基本块 + for (auto &mbb : mfunc->getBlocks()) { + scheduleBlock(mbb.get()); + } + + // 清理全局缓存 + instr_info_cache.clear(); } } // namespace sysy \ No newline at end of file diff --git a/src/include/backend/RISCv64/Optimize/PostRA_Scheduler.h b/src/include/backend/RISCv64/Optimize/PostRA_Scheduler.h index c0f656c..6f3fd68 100644 --- a/src/include/backend/RISCv64/Optimize/PostRA_Scheduler.h +++ b/src/include/backend/RISCv64/Optimize/PostRA_Scheduler.h @@ -12,6 +12,26 @@ namespace sysy { * * 主要目标是优化寄存器分配器插入的spill/fill代码(lw/sw), * 尝试将加载指令提前,以隐藏其访存延迟。 */ +struct MemoryAccess { + PhysicalReg base_reg; + int64_t offset; + bool valid; + + MemoryAccess() : valid(false) {} + MemoryAccess(PhysicalReg base, int64_t off) : base_reg(base), offset(off), valid(true) {} +}; + +struct InstrRegInfo { + std::unordered_set defined_regs; + std::unordered_set used_regs; + bool is_load; + bool is_store; + bool is_control_flow; + MemoryAccess mem_access; + + InstrRegInfo() : is_load(false), is_store(false), is_control_flow(false) {} +}; + class PostRA_Scheduler : public Pass { public: static char ID;