[backend]完善异步执行的超时切断机制

This commit is contained in:
Lixuanwang
2025-08-18 22:50:14 +08:00
parent 0720a622c1
commit babb576317
3 changed files with 44 additions and 12 deletions

View File

@@ -9,6 +9,9 @@
#include <sstream>
#include <future>
#include <chrono>
#include <atomic>
#include <memory>
#include <thread>
#include <iostream>
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<std::atomic<bool>>(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";

View File

@@ -7,6 +7,7 @@
#include <cassert>
#include <chrono>
#include <thread>
#include <atomic>
namespace sysy {
@@ -47,7 +48,7 @@ RISCv64RegAlloc::RISCv64RegAlloc(MachineFunction* mfunc)
}
// 主入口: 迭代运行分配算法直到无溢出
bool RISCv64RegAlloc::run() {
bool RISCv64RegAlloc::run(std::shared_ptr<std::atomic<bool>> 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) {

View File

@@ -20,7 +20,7 @@ public:
RISCv64RegAlloc(MachineFunction* mfunc);
// 模块主入口
bool run();
bool run(std::shared_ptr<std::atomic<bool>> stop_flag);
private:
// 类型定义与Python版本对应