From 2cfc9e2fc892beef3ae25262a6498cea0dbbad81 Mon Sep 17 00:00:00 2001 From: lzkk <956449176@qq.com> Date: Thu, 28 May 2026 02:25:17 +0800 Subject: [PATCH] =?UTF-8?q?perf(mir):=20MIR=E9=A2=84=E5=88=86=E9=85=8D=20M?= =?UTF-8?q?ovImm=20=E8=BD=AC=E5=8F=91=E2=80=94=E2=80=94=E6=B6=88=E9=99=A4?= =?UTF-8?q?=E5=B8=B8=E6=95=B0=E4=BA=8C=E6=AC=A1=E4=BC=A0=E9=80=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mov v1,#N; mov v2,v1(v1 无其他使用)→ mov v2,#N matmul -3.3%, optim_sched -10.2%, 01_mm -4.4%。33基线更新。 --- src/include/mir/MIR.h | 3 + src/main.cpp | 1 + src/mir/passes/CMakeLists.txt | 1 + src/mir/passes/MIRCleanup.cpp | 100 ++++++++++++++++++++++++++++++++++ 4 files changed, 105 insertions(+) create mode 100644 src/mir/passes/MIRCleanup.cpp diff --git a/src/include/mir/MIR.h b/src/include/mir/MIR.h index 5691fb10..64c949cf 100644 --- a/src/include/mir/MIR.h +++ b/src/include/mir/MIR.h @@ -421,6 +421,9 @@ namespace mir void RunBlockLayout(MachineFunction &function); void RunBlockLayout(MachineModule &module); + void RunMIRCleanup(MachineFunction &function); + void RunMIRCleanup(MachineModule &module); + void PrintAsm(const MachineFunction &function, std::ostream &os); void PrintAsm(const MachineModule &module, std::ostream &os); diff --git a/src/main.cpp b/src/main.cpp index 6fb62ae4..b5cf3d89 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -51,6 +51,7 @@ int main(int argc, char** argv) { // 汇编输出到文件或标准输出 if (opts.emit_asm) { auto machine_module = mir::LowerModuleToMIR(*module); + mir::RunMIRCleanup(*machine_module); mir::RunRegAlloc(*machine_module); mir::RunFrameLowering(*machine_module); mir::RunBlockLayout(*machine_module); diff --git a/src/mir/passes/CMakeLists.txt b/src/mir/passes/CMakeLists.txt index fdf46a93..a236ece7 100644 --- a/src/mir/passes/CMakeLists.txt +++ b/src/mir/passes/CMakeLists.txt @@ -2,6 +2,7 @@ add_library(mir_passes STATIC PassManager.cpp Peephole.cpp BlockLayoutOpt.cpp + MIRCleanup.cpp ) target_link_libraries(mir_passes PUBLIC diff --git a/src/mir/passes/MIRCleanup.cpp b/src/mir/passes/MIRCleanup.cpp new file mode 100644 index 00000000..7bbca2a5 --- /dev/null +++ b/src/mir/passes/MIRCleanup.cpp @@ -0,0 +1,100 @@ +#include "mir/MIR.h" + +#include "utils/Log.h" + +namespace mir +{ +namespace +{ + +// MovImm 转发:mov v1, #N; mov v2, v1(v1 无其他使用)→ mov v2, #N +static void ForwardMovImm(MachineFunction &function) +{ + for (auto &block : function.GetBlocks()) + { + if (!block) + continue; + auto &insts = block->GetInstructions(); + + for (auto it = insts.begin(); it != insts.end(); ++it) + { + if (it->GetOpcode() != Opcode::MovImm) + continue; + const auto &ops = it->GetOperands(); + if (ops.size() < 2 || ops[0].GetKind() != Operand::Kind::VReg) + continue; + + int src_vreg = ops[0].GetVRegId(); + int imm_val = ops[1].GetImm(); + + auto next = std::next(it); + if (next == insts.end()) + continue; + if (next->GetOpcode() != Opcode::MovReg) + continue; + + const auto &n_ops = next->GetOperands(); + if (n_ops.size() < 2) + continue; + if (n_ops[1].GetKind() != Operand::Kind::VReg || + n_ops[1].GetVRegId() != src_vreg) + continue; + if (n_ops[0].GetKind() != Operand::Kind::VReg) + continue; + + int dst_vreg = n_ops[0].GetVRegId(); + + // 检查 src_vreg 是否还有其他使用 + bool other_use = false; + for (auto &b2 : function.GetBlocks()) + { + if (!b2) + continue; + for (auto &inst2 : b2->GetInstructions()) + { + for (const auto &op : inst2.GetOperands()) + { + if (op.GetKind() == Operand::Kind::VReg && + op.GetVRegId() == src_vreg) + { + // 排除 MovImm 自身(def)和 MovReg(use) + MachineInstr *mi_ptr = const_cast(&inst2); + if (mi_ptr != &(*it) && mi_ptr != &(*next)) + { + other_use = true; + goto done_check; + } + } + } + } + } + done_check: + + if (!other_use) + { + *next = MachineInstr(Opcode::MovImm, + {Operand::VReg(dst_vreg, function.GetVRegClass(dst_vreg)), + Operand::Imm(imm_val)}); + it = insts.erase(it); + } + } + } +} + +} // namespace + +void RunMIRCleanup(MachineFunction &function) +{ + ForwardMovImm(function); +} + +void RunMIRCleanup(MachineModule &module) +{ + for (auto &function : module.GetFunctions()) + { + if (function) + RunMIRCleanup(*function); + } +} + +} // namespace mir