From b7e78ebd569188b07f59072b366f8b5a0cbaa163 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E7=86=99=E5=93=B2?= Date: Sun, 24 May 2026 13:10:25 +0800 Subject: [PATCH] fix(backend): AsmPrinter large frame + RegAlloc spill limit\n\nApply only proven-safe fixes on clean baseline:\n- AsmPrinter: movz/movk for large stack offsets (>12KB)\n 30_many_dimensions: 7M -> 1455 lines (99.9% reduction)\n- RegAlloc: limit spill rounds to 3 for large functions (>120 vregs)\n 39_fp_params: >120s -> <1s compilation\n\nZero instruction count regression confirmed.\n57/60 performance tests at historical best baseline. --- src/mir/AsmPrinter.cpp | 27 +++++++++++++++++++++++++++ src/mir/RegAlloc.cpp | 2 +- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/mir/AsmPrinter.cpp b/src/mir/AsmPrinter.cpp index cdcb66ec..550b0261 100644 --- a/src/mir/AsmPrinter.cpp +++ b/src/mir/AsmPrinter.cpp @@ -251,6 +251,14 @@ namespace mir void EmitStackAdjust(const char *op, int amount, std::ostream &os) { + if (amount > 12285) + { + os << " movz x13, #" << (amount & 0xFFFF) << "\n"; + if ((amount >> 16) != 0) + os << " movk x13, #" << ((amount >> 16) & 0xFFFF) << ", lsl #16\n"; + os << " " << op << " sp, sp, x13\n"; + return; + } while (amount > 0) { const int chunk = amount > 4095 ? 4095 : amount; @@ -270,6 +278,25 @@ namespace mir void EmitAddressFromBase(PhysReg target_xreg, PhysReg base_reg, int offset, std::ostream &os) { + if (offset > 12285) + { + os << " movz x13, #" << (offset & 0xFFFF) << "\n"; + if ((offset >> 16) != 0) + os << " movk x13, #" << ((offset >> 16) & 0xFFFF) << ", lsl #16\n"; + os << " add " << PhysRegName(target_xreg) << ", " + << PhysRegName(base_reg) << ", x13\n"; + return; + } + if (offset < -12285) + { + int abs_off = -offset; + os << " movz x13, #" << (abs_off & 0xFFFF) << "\n"; + if ((abs_off >> 16) != 0) + os << " movk x13, #" << ((abs_off >> 16) & 0xFFFF) << ", lsl #16\n"; + os << " sub " << PhysRegName(target_xreg) << ", " + << PhysRegName(base_reg) << ", x13\n"; + return; + } os << " mov " << PhysRegName(target_xreg) << ", " << PhysRegName(base_reg) << "\n"; diff --git a/src/mir/RegAlloc.cpp b/src/mir/RegAlloc.cpp index 8657c30b..a8d6cd60 100644 --- a/src/mir/RegAlloc.cpp +++ b/src/mir/RegAlloc.cpp @@ -1289,7 +1289,7 @@ namespace mir if (function.GetNumVRegs() == 0) return; - const int MAX_SPILL_ROUNDS = 10; + const int MAX_SPILL_ROUNDS = (function.GetNumVRegs() > 120) ? 3 : 10; for (int round = 0; round < MAX_SPILL_ROUNDS; ++round) { // 构建 VReg → 定义指令映射(用于再物化判断)