[backend]完善异步执行的超时切断机制
This commit is contained in:
@@ -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";
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -20,7 +20,7 @@ public:
|
||||
RISCv64RegAlloc(MachineFunction* mfunc);
|
||||
|
||||
// 模块主入口
|
||||
bool run();
|
||||
bool run(std::shared_ptr<std::atomic<bool>> stop_flag);
|
||||
|
||||
private:
|
||||
// 类型定义,与Python版本对应
|
||||
|
||||
Reference in New Issue
Block a user