From a3c4d5a2b83a5f8fe37714322011d69772746431 Mon Sep 17 00:00:00 2001 From: CGH0S7 <776459475@qq.com> Date: Wed, 30 Jul 2025 15:27:23 +0800 Subject: [PATCH] =?UTF-8?q?[Optimize]=E5=AF=B9PreRA=E6=8C=87=E4=BB=A4?= =?UTF-8?q?=E8=B0=83=E5=BA=A6=E8=BF=9B=E8=A1=8C=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RISCv64/Optimize/PreRA_Scheduler.cpp | 164 ++++++++++++------ 1 file changed, 110 insertions(+), 54 deletions(-) diff --git a/src/backend/RISCv64/Optimize/PreRA_Scheduler.cpp b/src/backend/RISCv64/Optimize/PreRA_Scheduler.cpp index 8497429..e26d1b6 100644 --- a/src/backend/RISCv64/Optimize/PreRA_Scheduler.cpp +++ b/src/backend/RISCv64/Optimize/PreRA_Scheduler.cpp @@ -1,8 +1,8 @@ #include "PreRA_Scheduler.h" #include "RISCv64LLIR.h" #include -#include -#include +#include +#include #include #define MAX_SCHEDULING_BLOCK_SIZE 1000 // 严格限制调度块大小 @@ -66,9 +66,44 @@ static bool hasMemoryAccess(MachineInstr *instr) { return isLoadInstr(instr) || isStoreInstr(instr); } -// 获取指令定义的虚拟寄存器 -static std::set getDefinedVirtualRegisters(MachineInstr *instr) { - std::set defined_regs; +// 获取内存访问位置信息 +struct MemoryLocation { + unsigned base_reg; + int64_t offset; + bool is_valid; + + MemoryLocation() : base_reg(0), offset(0), is_valid(false) {} + MemoryLocation(unsigned base, int64_t off) + : base_reg(base), offset(off), is_valid(true) {} + + bool operator==(const MemoryLocation &other) const { + return is_valid && other.is_valid && base_reg == other.base_reg && + offset == other.offset; + } +}; + +// 缓存指令分析信息 +struct InstrInfo { + std::unordered_set defined_regs; + std::unordered_set used_regs; + MemoryLocation mem_location; + bool is_load; + bool is_store; + bool is_terminator; + bool is_call; + bool has_side_effect; + bool has_memory_access; + + InstrInfo() : is_load(false), is_store(false), is_terminator(false), + is_call(false), has_side_effect(false), has_memory_access(false) {} +}; + +// 指令信息缓存 +static std::unordered_map instr_info_cache; + +// 获取指令定义的虚拟寄存器 - 优化版本 +static std::unordered_set getDefinedVirtualRegisters(MachineInstr *instr) { + std::unordered_set defined_regs; RVOpcodes opcode = instr->getOpcode(); // CALL指令可能定义返回值寄存器 @@ -101,9 +136,9 @@ static std::set getDefinedVirtualRegisters(MachineInstr *instr) { return defined_regs; } -// 获取指令使用的虚拟寄存器 -static std::set getUsedVirtualRegisters(MachineInstr *instr) { - std::set used_regs; +// 获取指令使用的虚拟寄存器 - 优化版本 +static std::unordered_set getUsedVirtualRegisters(MachineInstr *instr) { + std::unordered_set used_regs; RVOpcodes opcode = instr->getOpcode(); // CALL指令:跳过第一个操作数(返回值),其余为参数 @@ -164,22 +199,6 @@ static std::set getUsedVirtualRegisters(MachineInstr *instr) { return used_regs; } -// 获取内存访问位置信息 -struct MemoryLocation { - unsigned base_reg; - int64_t offset; - bool is_valid; - - MemoryLocation() : base_reg(0), offset(0), is_valid(false) {} - MemoryLocation(unsigned base, int64_t off) - : base_reg(base), offset(off), is_valid(true) {} - - bool operator==(const MemoryLocation &other) const { - return is_valid && other.is_valid && base_reg == other.base_reg && - offset == other.offset; - } -}; - // 获取内存访问位置 static MemoryLocation getMemoryLocation(MachineInstr *instr) { if (!isLoadInstr(instr) && !isStoreInstr(instr)) { @@ -199,6 +218,27 @@ static MemoryLocation getMemoryLocation(MachineInstr *instr) { return MemoryLocation(); } +// 预计算并缓存指令信息 +static const InstrInfo& getInstrInfo(MachineInstr *instr) { + auto it = instr_info_cache.find(instr); + if (it != instr_info_cache.end()) { + return it->second; + } + + InstrInfo& info = instr_info_cache[instr]; + info.defined_regs = getDefinedVirtualRegisters(instr); + info.used_regs = getUsedVirtualRegisters(instr); + info.mem_location = getMemoryLocation(instr); + info.is_load = isLoadInstr(instr); + info.is_store = isStoreInstr(instr); + info.is_terminator = isTerminatorInstr(instr); + info.is_call = isCallInstr(instr); + info.has_side_effect = hasSideEffect(instr); + info.has_memory_access = hasMemoryAccess(instr); + + return info; +} + // 检查两个内存位置是否可能别名 static bool mayAlias(const MemoryLocation &loc1, const MemoryLocation &loc2) { if (!loc1.is_valid || !loc2.is_valid) { @@ -214,30 +254,28 @@ static bool mayAlias(const MemoryLocation &loc1, const MemoryLocation &loc2) { return loc1.offset == loc2.offset; } -// 检查两个指令之间是否存在数据依赖 +// 检查两个指令之间是否存在数据依赖 - 优化版本 static bool hasDataDependency(MachineInstr *first, MachineInstr *second) { - auto defined_regs_first = getDefinedVirtualRegisters(first); - auto used_regs_first = getUsedVirtualRegisters(first); - auto defined_regs_second = getDefinedVirtualRegisters(second); - auto used_regs_second = getUsedVirtualRegisters(second); + const InstrInfo& info_first = getInstrInfo(first); + const InstrInfo& info_second = getInstrInfo(second); // RAW依赖: second读取first写入的寄存器 - for (const auto ® : defined_regs_first) { - if (used_regs_second.count(reg)) { + for (const auto ® : info_first.defined_regs) { + if (info_second.used_regs.find(reg) != info_second.used_regs.end()) { return true; } } // WAR依赖: second写入first读取的寄存器 - for (const auto ® : used_regs_first) { - if (defined_regs_second.count(reg)) { + for (const auto ® : info_first.used_regs) { + if (info_second.defined_regs.find(reg) != info_second.defined_regs.end()) { return true; } } // WAW依赖: 两个指令写入同一寄存器 - for (const auto ® : defined_regs_first) { - if (defined_regs_second.count(reg)) { + for (const auto ® : info_first.defined_regs) { + if (info_second.defined_regs.find(reg) != info_second.defined_regs.end()) { return true; } } @@ -245,40 +283,41 @@ static bool hasDataDependency(MachineInstr *first, MachineInstr *second) { return false; } -// 检查两个指令之间是否存在内存依赖 +// 检查两个指令之间是否存在内存依赖 - 优化版本 static bool hasMemoryDependency(MachineInstr *first, MachineInstr *second) { - bool first_accesses_memory = isLoadInstr(first) || isStoreInstr(first); - bool second_accesses_memory = isLoadInstr(second) || isStoreInstr(second); + const InstrInfo& info_first = getInstrInfo(first); + const InstrInfo& info_second = getInstrInfo(second); - if (!first_accesses_memory || !second_accesses_memory) { + if (!info_first.has_memory_access || !info_second.has_memory_access) { return false; } // 如果至少有一个是存储指令,需要检查别名 - if (isStoreInstr(first) || isStoreInstr(second)) { - MemoryLocation loc1 = getMemoryLocation(first); - MemoryLocation loc2 = getMemoryLocation(second); - return mayAlias(loc1, loc2); + if (info_first.is_store || info_second.is_store) { + return mayAlias(info_first.mem_location, info_second.mem_location); } return false; // 两个加载指令之间没有依赖 } -// 检查两个指令之间是否存在控制依赖 +// 检查两个指令之间是否存在控制依赖 - 优化版本 static bool hasControlDependency(MachineInstr *first, MachineInstr *second) { + const InstrInfo& info_first = getInstrInfo(first); + const InstrInfo& info_second = getInstrInfo(second); + // 终结指令与任何其他指令都有控制依赖 - if (isTerminatorInstr(first)) { + if (info_first.is_terminator) { return true; // first是终结指令,second不能移动到first之前 } - if (isTerminatorInstr(second)) { + if (info_second.is_terminator) { return false; // second是终结指令,可以保持在后面 } // CALL指令具有控制副作用,但可以参与有限的调度 - if (isCallInstr(first) || isCallInstr(second)) { + if (info_first.is_call || info_second.is_call) { // CALL指令之间保持顺序 - if (isCallInstr(first) && isCallInstr(second)) { + if (info_first.is_call && info_second.is_call) { return true; } // 其他情况允许调度(通过数据依赖控制) @@ -287,7 +326,7 @@ static bool hasControlDependency(MachineInstr *first, MachineInstr *second) { return false; } -// 综合检查两个指令是否可以交换 +// 综合检查两个指令是否可以交换 - 优化版本 static bool canSwapInstructions(MachineInstr *first, MachineInstr *second) { // 检查所有类型的依赖 if (hasDataDependency(first, second) || hasDataDependency(second, first)) { @@ -306,15 +345,17 @@ static bool canSwapInstructions(MachineInstr *first, MachineInstr *second) { return true; } -// 找到基本块中的调度边界 +// 找到基本块中的调度边界 - 优化版本 static std::vector findSchedulingBoundaries(const std::vector &instrs) { std::vector boundaries; + boundaries.reserve(instrs.size() / 10); // 预估边界数量 boundaries.push_back(0); // 起始边界 for (size_t i = 0; i < instrs.size(); i++) { + const InstrInfo& info = getInstrInfo(instrs[i]); // 终结指令前后都是边界 - if (isTerminatorInstr(instrs[i])) { + if (info.is_terminator) { if (i > 0) boundaries.push_back(i); if (i + 1 < instrs.size()) @@ -333,7 +374,7 @@ findSchedulingBoundaries(const std::vector &instrs) { return boundaries; } -// 在单个调度区域内进行指令调度 +// 在单个调度区域内进行指令调度 - 优化版本 static void scheduleRegion(std::vector &instrs, size_t start, size_t end) { if (end - start <= 1) { @@ -347,7 +388,8 @@ static void scheduleRegion(std::vector &instrs, size_t start, // 简单的调度算法:只尝试将加载指令尽可能前移 for (size_t i = start + 1; i < end; i++) { - if (isLoadInstr(instrs[i])) { + const InstrInfo& info = getInstrInfo(instrs[i]); + if (info.is_load) { // 尝试将加载指令向前移动 for (size_t j = i; j > start; j--) { // 检查是否可以与前一条指令交换 @@ -369,12 +411,21 @@ static void scheduleBlock(MachineBasicBlock *mbb) { 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); + } + // 找到调度边界 std::vector boundaries = findSchedulingBoundaries(instr_list); @@ -386,12 +437,14 @@ static void scheduleBlock(MachineBasicBlock *mbb) { } // 重建指令序列 - std::map> instr_map; + 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])); } @@ -405,6 +458,9 @@ void PreRA_Scheduler::runOnMachineFunction(MachineFunction *mfunc) { for (auto &mbb : mfunc->getBlocks()) { scheduleBlock(mbb.get()); } + + // 清理全局缓存 + instr_info_cache.clear(); } } // namespace sysy \ No newline at end of file