From babb576317b5d0a7e64b4c706e320484ba938e4f Mon Sep 17 00:00:00 2001 From: Lixuanwang Date: Mon, 18 Aug 2025 22:50:14 +0800 Subject: [PATCH] =?UTF-8?q?[backend]=E5=AE=8C=E5=96=84=E5=BC=82=E6=AD=A5?= =?UTF-8?q?=E6=89=A7=E8=A1=8C=E7=9A=84=E8=B6=85=E6=97=B6=E5=88=87=E6=96=AD?= =?UTF-8?q?=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/RISCv64/RISCv64Backend.cpp | 46 +++++++++++++++---- src/backend/RISCv64/RISCv64RegAlloc.cpp | 8 +++- src/include/backend/RISCv64/RISCv64RegAlloc.h | 2 +- 3 files changed, 44 insertions(+), 12 deletions(-) diff --git a/src/backend/RISCv64/RISCv64Backend.cpp b/src/backend/RISCv64/RISCv64Backend.cpp index 8dc2d92..f2b6562 100644 --- a/src/backend/RISCv64/RISCv64Backend.cpp +++ b/src/backend/RISCv64/RISCv64Backend.cpp @@ -9,6 +9,9 @@ #include #include #include +#include +#include +#include #include namespace sysy { @@ -233,23 +236,46 @@ std::string RISCv64CodeGen::function_gen(Function* func) { scheduler.runOnMachineFunction(mfunc.get()); // 阶段 3: 物理寄存器分配 (Register Allocation) - bool allocation_succeeded = false; + // 尝试迭代图着色 (IRC) if (!irc_failed) { - if (DEBUG) std::cerr << "Attempting Register Allocation with Iterated Register Coloring (IRC)...\n"; + if (DEBUG) std::cerr << "Attempting Register Allocation with Iterated Register Coloring (IRC)...\n"; RISCv64RegAlloc irc_alloc(mfunc.get()); - if (irc_alloc.run()) { + auto stop_flag = std::make_shared>(false); + auto future = std::async(std::launch::async, &RISCv64RegAlloc::run, &irc_alloc, stop_flag); + std::future_status status = future.wait_for(std::chrono::seconds(25)); + bool success_irc = false; + if (status == std::future_status::ready) { + try { + if (future.get()) { + success_irc = true; + } else { + std::cerr << "Warning: IRC explicitly returned failure for function '" << func->getName() << "'.\n"; + } + } catch (const std::exception& e) { + std::cerr << "Error: IRC allocation threw an exception: " << e.what() << std::endl; + } + } else if (status == std::future_status::timeout) { + std::cerr << "Warning: IRC allocation timed out after 25 seconds. Requesting cancellation...\n"; + stop_flag->store(true); + try { + future.get(); + } catch (const std::exception& e) { + std::cerr << "Exception occurred during IRC thread shutdown after timeout: " << e.what() << std::endl; + } + } + + if (success_irc) { allocation_succeeded = true; if (DEBUG) std::cerr << "IRC allocation succeeded.\n"; } else { - std::cerr << "Warning: IRC failed for function '" << func->getName() - << "'. Blacklisting IRC for subsequent functions and falling back.\n"; - irc_failed = true; // 拉黑IRC,后续函数不再尝试 + std::cerr << "Info: Blacklisting IRC for subsequent functions and falling back.\n"; + irc_failed = true; } } - - // 尝试简单图着色 (SGC) 并设置超时 + + // 尝试简单图着色 (SGC) if (!allocation_succeeded) { // 如果是从IRC失败回退过来的,需要重新创建干净的mfunc和ISel RISCv64ISel isel_for_sgc; @@ -266,7 +292,7 @@ std::string RISCv64CodeGen::function_gen(Function* func) { { RISCv64SimpleRegAlloc sgc_alloc(mfunc.get()); auto future = std::async(std::launch::async, &RISCv64SimpleRegAlloc::run, &sgc_alloc); - std::future_status status = future.wait_for(std::chrono::seconds(20)); + std::future_status status = future.wait_for(std::chrono::seconds(25)); if (status == std::future_status::ready) { try { @@ -287,7 +313,7 @@ std::string RISCv64CodeGen::function_gen(Function* func) { } } - // 策略三:如果以上所有策略都失败了,则使用基本块分配器 (BBA) + // 如果都失败了,则使用基本块分配器 (BBA) if (!allocation_succeeded) { // 为BBA准备干净的mfunc和ISel std::cerr << "Info: Resetting MachineFunction for BBA fallback.\n"; diff --git a/src/backend/RISCv64/RISCv64RegAlloc.cpp b/src/backend/RISCv64/RISCv64RegAlloc.cpp index a0bde8d..84d397e 100644 --- a/src/backend/RISCv64/RISCv64RegAlloc.cpp +++ b/src/backend/RISCv64/RISCv64RegAlloc.cpp @@ -7,6 +7,7 @@ #include #include #include +#include namespace sysy { @@ -47,7 +48,7 @@ RISCv64RegAlloc::RISCv64RegAlloc(MachineFunction* mfunc) } // 主入口: 迭代运行分配算法直到无溢出 -bool RISCv64RegAlloc::run() { +bool RISCv64RegAlloc::run(std::shared_ptr> stop_flag) { if (DEBUG) std::cerr << "===== LLIR Before Running Graph Coloring Register Allocation " << MFunc->getName() << " =====\n"; std::stringstream ss_before_reg_alloc; if (DEBUG) { @@ -68,6 +69,11 @@ bool RISCv64RegAlloc::run() { break; } else { rewriteProgram(); + if (stop_flag && stop_flag->load()) { + // 如果从外部接收到停止信号 + std::cerr << "Info: IRC allocation cancelled due to timeout.\n"; + return false; // 提前退出,并返回失败 + } if (DEBUG) std::cerr << "--- Spilling detected, re-running allocation (iteration " << iteration << ") ---\n"; if (iteration >= MAX_ITERATIONS) { diff --git a/src/include/backend/RISCv64/RISCv64RegAlloc.h b/src/include/backend/RISCv64/RISCv64RegAlloc.h index 420623a..1d76fac 100644 --- a/src/include/backend/RISCv64/RISCv64RegAlloc.h +++ b/src/include/backend/RISCv64/RISCv64RegAlloc.h @@ -20,7 +20,7 @@ public: RISCv64RegAlloc(MachineFunction* mfunc); // 模块主入口 - bool run(); + bool run(std::shared_ptr> stop_flag); private: // 类型定义,与Python版本对应