diff --git a/src/mir/RegAlloc.cpp b/src/mir/RegAlloc.cpp index a2b04a97..8657c30b 100644 --- a/src/mir/RegAlloc.cpp +++ b/src/mir/RegAlloc.cpp @@ -1,6 +1,7 @@ #include "mir/MIR.h" #include +#include #include #include #include @@ -643,7 +644,8 @@ namespace mir const std::unordered_map &interval_length, const std::unordered_map &ref_count, const std::set &rematerializable_vregs, - const std::unordered_map &move_preferences) + const std::unordered_map &move_preferences, + const std::unordered_map &vreg_loop_depth) { const int K = static_cast(allocatable_regs.size()); GraphColoringResult result; @@ -903,8 +905,13 @@ namespace mir auto rit = ref_count.find(v); if (rit != ref_count.end()) ref = rit->second; int d = degree[v]; - // 可再物化变量(MovImm 常量)大幅降权,优先 spill - int cost = len * 5 + ref * 15 - d * 25; + // 循环深度加权:depth=0 → ×1, depth=1 → ×10, depth=2 → ×100 + int depth = 0; + auto dit = vreg_loop_depth.find(v); + if (dit != vreg_loop_depth.end()) depth = dit->second; + int loop_mult = 1; + for (int i = 0; i < depth; i++) loop_mult *= 10; + int cost = (len * 5 + ref * 15) * loop_mult - d * 25; if (rematerializable_vregs.count(v)) cost -= 100000; return cost; @@ -1301,6 +1308,71 @@ namespace mir auto liveness = ComputeBlockLiveness(function); + // === 回边检测:计算基本块的循环嵌套深度 === + size_t num_blocks = function.GetBlocks().size(); + std::vector loop_depth(num_blocks, 0); + { + std::unordered_map blk_label_to_idx; + for (size_t i = 0; i < liveness.block_liveness.size(); ++i) + blk_label_to_idx[function.GetBlocks()[i]->GetLabelId()] = i; + + std::vector dfs_state(num_blocks, 0); // 0=未访问, 1=栈中, 2=已完成 + + std::function dfs = [&](size_t cur) { + dfs_state[cur] = 1; + const auto &insts = function.GetBlocks()[cur]->GetInstructions(); + for (const auto &inst : insts) + { + size_t succ = static_cast(-1); + if (inst.GetOpcode() == Opcode::Br && inst.GetOperands().size() >= 1 && + inst.GetOperands()[0].GetKind() == Operand::Kind::Label) + { + auto it = blk_label_to_idx.find(inst.GetOperands()[0].GetLabel()); + if (it != blk_label_to_idx.end()) succ = it->second; + } + if (inst.GetOpcode() == Opcode::CondBr && inst.GetOperands().size() >= 2 && + inst.GetOperands()[1].GetKind() == Operand::Kind::Label) + { + auto it = blk_label_to_idx.find(inst.GetOperands()[1].GetLabel()); + if (it != blk_label_to_idx.end()) succ = it->second; + } + if (succ == static_cast(-1)) continue; + if (dfs_state[succ] == 1) + { + // 回边:cur → succ 且 succ 在栈中 + loop_depth[succ]++; + loop_depth[cur]++; + } + else if (dfs_state[succ] == 0) + { + dfs(succ); + if (loop_depth[succ] > 0) + loop_depth[cur] = std::max(loop_depth[cur], loop_depth[succ]); + } + } + dfs_state[cur] = 2; + }; + dfs(0); + } + + // 为每个 vreg 确定其最大循环深度(取定义所在块的 loop_depth) + std::unordered_map vreg_loop_depth; + for (size_t bi = 0; bi < num_blocks; ++bi) + { + const auto &insts = function.GetBlocks()[bi]->GetInstructions(); + for (const auto &inst : insts) + { + auto du = GetInstDefUse(inst, function); + for (int d : du.defs) + { + auto it = vreg_loop_depth.find(d); + int cur_depth = loop_depth[bi]; + if (it == vreg_loop_depth.end() || cur_depth > it->second) + vreg_loop_depth[d] = cur_depth; + } + } + } + // 构建可再物化 vreg 集合(MovImm 常量) std::set rematerializable_vregs; for (const auto &pair : vreg_def_inst) @@ -1368,10 +1440,12 @@ namespace mir auto gp_result = ColorGraph(gp_graph, gp_alloc, function, 19, liveness.interval_length, liveness.ref_count, - rematerializable_vregs, move_preferences); + rematerializable_vregs, move_preferences, + vreg_loop_depth); auto fp_result = ColorGraph(fp_graph, fp_alloc, function, 16, liveness.interval_length, liveness.ref_count, - rematerializable_vregs, move_preferences); + rematerializable_vregs, move_preferences, + vreg_loop_depth); if (gp_result.spilled.empty() && fp_result.spilled.empty()) { @@ -1524,6 +1598,69 @@ namespace mir auto liveness = ComputeBlockLiveness(function); + // === 回边检测:计算基本块的循环嵌套深度 === + size_t num_blocks = function.GetBlocks().size(); + std::vector loop_depth(num_blocks, 0); + { + std::unordered_map blk_label_to_idx; + for (size_t i = 0; i < liveness.block_liveness.size(); ++i) + blk_label_to_idx[function.GetBlocks()[i]->GetLabelId()] = i; + + std::vector dfs_state(num_blocks, 0); + + std::function dfs = [&](size_t cur) { + dfs_state[cur] = 1; + const auto &insts = function.GetBlocks()[cur]->GetInstructions(); + for (const auto &inst : insts) + { + size_t succ = static_cast(-1); + if (inst.GetOpcode() == Opcode::Br && inst.GetOperands().size() >= 1 && + inst.GetOperands()[0].GetKind() == Operand::Kind::Label) + { + auto it = blk_label_to_idx.find(inst.GetOperands()[0].GetLabel()); + if (it != blk_label_to_idx.end()) succ = it->second; + } + if (inst.GetOpcode() == Opcode::CondBr && inst.GetOperands().size() >= 2 && + inst.GetOperands()[1].GetKind() == Operand::Kind::Label) + { + auto it = blk_label_to_idx.find(inst.GetOperands()[1].GetLabel()); + if (it != blk_label_to_idx.end()) succ = it->second; + } + if (succ == static_cast(-1)) continue; + if (dfs_state[succ] == 1) + { + loop_depth[succ]++; + loop_depth[cur]++; + } + else if (dfs_state[succ] == 0) + { + dfs(succ); + if (loop_depth[succ] > 0) + loop_depth[cur] = std::max(loop_depth[cur], loop_depth[succ]); + } + } + dfs_state[cur] = 2; + }; + dfs(0); + } + + std::unordered_map vreg_loop_depth; + for (size_t bi = 0; bi < num_blocks; ++bi) + { + const auto &insts = function.GetBlocks()[bi]->GetInstructions(); + for (const auto &inst : insts) + { + auto du = GetInstDefUse(inst, function); + for (int d : du.defs) + { + auto it = vreg_loop_depth.find(d); + int cur_depth = loop_depth[bi]; + if (it == vreg_loop_depth.end() || cur_depth > it->second) + vreg_loop_depth[d] = cur_depth; + } + } + } + // 构建可再物化 vreg 集合 std::set rematerializable_vregs; for (const auto &pair : vreg_def_inst) @@ -1589,10 +1726,12 @@ namespace mir BuildInterferenceForFP(function, liveness.block_liveness, fp_alloc, fp_graph); auto gp_result = ColorGraph(gp_graph, gp_alloc, function, 19, liveness.interval_length, liveness.ref_count, - rematerializable_vregs, move_preferences); + rematerializable_vregs, move_preferences, + vreg_loop_depth); auto fp_result = ColorGraph(fp_graph, fp_alloc, function, 16, liveness.interval_length, liveness.ref_count, - rematerializable_vregs, move_preferences); + rematerializable_vregs, move_preferences, + vreg_loop_depth); std::set all_spilled = gp_result.spilled; for (int v : fp_result.spilled) all_spilled.insert(v); diff --git a/指令数基线.md b/指令数基线.md index 4a0e482e..3e7ba722 100644 --- a/指令数基线.md +++ b/指令数基线.md @@ -21,66 +21,66 @@ | 测试集标识 | 源基线(行) | 当前(行) | 备注 | |---|---|---|---| -| performance/01_mm1 | 335 | 313 | 比源基线少22行 | 比源基线少8行 | | -| performance/01_mm2 | 335 | 313 | 比源基线少22行 | 比源基线少8行 | | -| performance/01_mm3 | 335 | 313 | 比源基线少22行 | 比源基线少8行 | | -| performance/03_sort1 | 668 | 640 | 比源基线少28行 | 比源基线少14行 | | -| performance/03_sort2 | 668 | 640 | 比源基线少28行 | 比源基线少14行 | | -| performance/03_sort3 | 668 | 640 | 比源基线少28行 | 比源基线少14行 | | -| performance/conv2d-1 | 752 | 657 | 比源基线少95行 | 比源基线少20行 | | -| performance/conv2d-2 | 752 | 657 | 比源基线少95行 | 比源基线少20行 | | -| performance/conv2d-3 | 752 | 657 | 比源基线少95行 | 比源基线少20行 | | -| performance/crc1 | 328 | 290 | 比源基线少38行 | 比源基线少10行 | | -| performance/crc2 | 328 | 290 | 比源基线少38行 | 比源基线少10行 | | -| performance/crc3 | 328 | 290 | 比源基线少38行 | 比源基线少10行 | | -| performance/crypto-1 | 1967 | 1949 | 比源基线少18行 | 比源基线少14行 | | -| performance/crypto-2 | 1967 | 1949 | 比源基线少18行 | 比源基线少14行 | | -| performance/crypto-3 | 1967 | 1949 | 比源基线少18行 | 比源基线少14行 | | -| performance/fft0 | 658 | 619 | 比源基线少39行 | 比源基线少30行 | | -| performance/fft1 | 658 | 619 | 比源基线少39行 | 比源基线少30行 | | -| performance/fft2 | 658 | 619 | 比源基线少39行 | 比源基线少30行 | | -| performance/h-1-01 | 162 | 158 | 比源基线少4行 | 比源基线少2行 | | -| performance/h-1-02 | 162 | 158 | 比源基线少4行 | 比源基线少2行 | | -| performance/h-1-03 | 162 | 158 | 比源基线少4行 | 比源基线少2行 | | -| performance/h-10-01 | 349 | 335 | 比源基线少14行 | 比源基线少6行 | | -| performance/h-10-02 | 349 | 335 | 比源基线少14行 | 比源基线少6行 | | -| performance/h-10-03 | 349 | 335 | 比源基线少14行 | 比源基线少6行 | | -| performance/h-4-01 | 173 | 163 | 比源基线少10行 | 比源基线少6行 | | -| performance/h-4-02 | 173 | 163 | 比源基线少10行 | 比源基线少6行 | | -| performance/h-4-03 | 173 | 163 | 比源基线少10行 | 比源基线少6行 | | -| performance/h-5-01 | 352 | 349 | 比源基线少3行 | 比源基线少10行 | | -| performance/h-5-02 | 352 | 349 | 比源基线少3行 | 比源基线少10行 | | -| performance/h-5-03 | 352 | 349 | 比源基线少3行 | 比源基线少10行 | | -| performance/h-8-01 | 504 | 502 | 比源基线少2行 | 比源基线少2行 | | -| performance/h-8-02 | 504 | 502 | 比源基线少2行 | 比源基线少2行 | | -| performance/h-8-03 | 504 | 502 | 比源基线少2行 | 比源基线少2行 | | -| performance/h-9-01 | 239 | 227 | 比源基线少12行 | 比源基线少2行 | | -| performance/h-9-02 | 239 | 227 | 比源基线少12行 | 比源基线少2行 | | -| performance/h-9-03 | 239 | 227 | 比源基线少12行 | 比源基线少2行 | | -| performance/huffman-01 | 893 | 849 | 比源基线少44行 | 比源基线少14行 | | -| performance/huffman-02 | 893 | 849 | 比源基线少44行 | 比源基线少14行 | | -| performance/huffman-03 | 893 | 849 | 比源基线少44行 | 比源基线少14行 | | -| performance/knapsack_naive-1 | 185 | 175 | 比源基线少10行 | 比源基线少10行 | | -| performance/knapsack_naive-2 | 185 | 175 | 比源基线少10行 | 比源基线少10行 | | -| performance/knapsack_naive-3 | 185 | 175 | 比源基线少10行 | 比源基线少10行 | | +| performance/01_mm1 | 335 | 313 | 比源基线少22行 | 比源基线少22行 | 比源基线少8行 | | +| performance/01_mm2 | 335 | 313 | 比源基线少22行 | 比源基线少22行 | 比源基线少8行 | | +| performance/01_mm3 | 335 | 313 | 比源基线少22行 | 比源基线少22行 | 比源基线少8行 | | +| performance/03_sort1 | 668 | 640 | 比源基线少28行 | 比源基线少28行 | 比源基线少14行 | | +| performance/03_sort2 | 668 | 640 | 比源基线少28行 | 比源基线少28行 | 比源基线少14行 | | +| performance/03_sort3 | 668 | 640 | 比源基线少28行 | 比源基线少28行 | 比源基线少14行 | | +| performance/conv2d-1 | 752 | 657 | 比源基线少95行 | 比源基线少95行 | 比源基线少20行 | | +| performance/conv2d-2 | 752 | 657 | 比源基线少95行 | 比源基线少95行 | 比源基线少20行 | | +| performance/conv2d-3 | 752 | 657 | 比源基线少95行 | 比源基线少95行 | 比源基线少20行 | | +| performance/crc1 | 328 | 290 | 比源基线少38行 | 比源基线少38行 | 比源基线少10行 | | +| performance/crc2 | 328 | 290 | 比源基线少38行 | 比源基线少38行 | 比源基线少10行 | | +| performance/crc3 | 328 | 290 | 比源基线少38行 | 比源基线少38行 | 比源基线少10行 | | +| performance/crypto-1 | 1967 | 1949 | 比源基线少18行 | 比源基线少18行 | 比源基线少14行 | | +| performance/crypto-2 | 1967 | 1949 | 比源基线少18行 | 比源基线少18行 | 比源基线少14行 | | +| performance/crypto-3 | 1967 | 1949 | 比源基线少18行 | 比源基线少18行 | 比源基线少14行 | | +| performance/fft0 | 658 | 619 | 比源基线少39行 | 比源基线少39行 | 比源基线少30行 | | +| performance/fft1 | 658 | 619 | 比源基线少39行 | 比源基线少39行 | 比源基线少30行 | | +| performance/fft2 | 658 | 619 | 比源基线少39行 | 比源基线少39行 | 比源基线少30行 | | +| performance/h-1-01 | 162 | 158 | 比源基线少4行 | 比源基线少4行 | 比源基线少2行 | | +| performance/h-1-02 | 162 | 158 | 比源基线少4行 | 比源基线少4行 | 比源基线少2行 | | +| performance/h-1-03 | 162 | 158 | 比源基线少4行 | 比源基线少4行 | 比源基线少2行 | | +| performance/h-10-01 | 349 | 335 | 比源基线少14行 | 比源基线少14行 | 比源基线少6行 | | +| performance/h-10-02 | 349 | 335 | 比源基线少14行 | 比源基线少14行 | 比源基线少6行 | | +| performance/h-10-03 | 349 | 335 | 比源基线少14行 | 比源基线少14行 | 比源基线少6行 | | +| performance/h-4-01 | 173 | 163 | 比源基线少10行 | 比源基线少10行 | 比源基线少6行 | | +| performance/h-4-02 | 173 | 163 | 比源基线少10行 | 比源基线少10行 | 比源基线少6行 | | +| performance/h-4-03 | 173 | 163 | 比源基线少10行 | 比源基线少10行 | 比源基线少6行 | | +| performance/h-5-01 | 352 | 349 | 比源基线少3行 | 比源基线少3行 | 比源基线少10行 | | +| performance/h-5-02 | 352 | 349 | 比源基线少3行 | 比源基线少3行 | 比源基线少10行 | | +| performance/h-5-03 | 352 | 349 | 比源基线少3行 | 比源基线少3行 | 比源基线少10行 | | +| performance/h-8-01 | 504 | 502 | 比源基线少2行 | 比源基线少2行 | 比源基线少2行 | | +| performance/h-8-02 | 504 | 502 | 比源基线少2行 | 比源基线少2行 | 比源基线少2行 | | +| performance/h-8-03 | 504 | 502 | 比源基线少2行 | 比源基线少2行 | 比源基线少2行 | | +| performance/h-9-01 | 239 | 227 | 比源基线少12行 | 比源基线少12行 | 比源基线少2行 | | +| performance/h-9-02 | 239 | 227 | 比源基线少12行 | 比源基线少12行 | 比源基线少2行 | | +| performance/h-9-03 | 239 | 227 | 比源基线少12行 | 比源基线少12行 | 比源基线少2行 | | +| performance/huffman-01 | 893 | 849 | 比源基线少44行 | 比源基线少44行 | 比源基线少14行 | | +| performance/huffman-02 | 893 | 849 | 比源基线少44行 | 比源基线少44行 | 比源基线少14行 | | +| performance/huffman-03 | 893 | 849 | 比源基线少44行 | 比源基线少44行 | 比源基线少14行 | | +| performance/knapsack_naive-1 | 185 | 175 | 比源基线少10行 | 比源基线少10行 | 比源基线少10行 | | +| performance/knapsack_naive-2 | 185 | 175 | 比源基线少10行 | 比源基线少10行 | 比源基线少10行 | | +| performance/knapsack_naive-3 | 185 | 175 | 比源基线少10行 | 比源基线少10行 | 比源基线少10行 | | | performance/many_mat_cal-1 | 523 | 523 | | | performance/many_mat_cal-2 | 523 | 523 | | | performance/many_mat_cal-3 | 523 | 523 | | | performance/matmul1 | 450 | 450 | | | performance/matmul2 | 450 | 450 | | | performance/matmul3 | 450 | 450 | | -| performance/optimization_scheduling1 | 136 | 122 | 比源基线少14行 | 比源基线少6行 | | -| performance/optimization_scheduling2 | 136 | 122 | 比源基线少14行 | 比源基线少6行 | | -| performance/optimization_scheduling3 | 136 | 122 | 比源基线少14行 | 比源基线少6行 | | -| performance/shuffle0 | 485 | 472 | 比源基线少13行 | 比源基线少6行 | | -| performance/shuffle1 | 485 | 472 | 比源基线少13行 | 比源基线少6行 | | -| performance/shuffle2 | 485 | 472 | 比源基线少13行 | 比源基线少6行 | | -| performance/sl1 | 283 | 280 | 比源基线少3行 | 比源基线少8行 | | -| performance/sl2 | 283 | 280 | 比源基线少3行 | 比源基线少8行 | | -| performance/sl3 | 283 | 280 | 比源基线少3行 | 比源基线少8行 | | -| performance/transpose0 | 225 | 211 | 比源基线少14行 | 比源基线少4行 | | -| performance/transpose1 | 225 | 211 | 比源基线少14行 | 比源基线少4行 | | -| performance/transpose2 | 225 | 211 | 比源基线少14行 | 比源基线少4行 | | +| performance/optimization_scheduling1 | 136 | 122 | 比源基线少14行 | 比源基线少14行 | 比源基线少6行 | | +| performance/optimization_scheduling2 | 136 | 122 | 比源基线少14行 | 比源基线少14行 | 比源基线少6行 | | +| performance/optimization_scheduling3 | 136 | 122 | 比源基线少14行 | 比源基线少14行 | 比源基线少6行 | | +| performance/shuffle0 | 485 | 472 | 比源基线少13行 | 比源基线少13行 | 比源基线少6行 | | +| performance/shuffle1 | 485 | 472 | 比源基线少13行 | 比源基线少13行 | 比源基线少6行 | | +| performance/shuffle2 | 485 | 472 | 比源基线少13行 | 比源基线少13行 | 比源基线少6行 | | +| performance/sl1 | 283 | 280 | 比源基线少3行 | 比源基线少3行 | 比源基线少8行 | | +| performance/sl2 | 283 | 280 | 比源基线少3行 | 比源基线少3行 | 比源基线少8行 | | +| performance/sl3 | 283 | 280 | 比源基线少3行 | 比源基线少3行 | 比源基线少8行 | | +| performance/transpose0 | 225 | 211 | 比源基线少14行 | 比源基线少14行 | 比源基线少4行 | | +| performance/transpose1 | 225 | 211 | 比源基线少14行 | 比源基线少14行 | 比源基线少4行 | | +| performance/transpose2 | 225 | 211 | 比源基线少14行 | 比源基线少14行 | 比源基线少4行 | | ## 统计