[backend]完善异步执行的超时切断机制
This commit is contained in:
@@ -9,6 +9,9 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <future>
|
#include <future>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <atomic>
|
||||||
|
#include <memory>
|
||||||
|
#include <thread>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
namespace sysy {
|
namespace sysy {
|
||||||
|
|
||||||
@@ -233,23 +236,46 @@ std::string RISCv64CodeGen::function_gen(Function* func) {
|
|||||||
scheduler.runOnMachineFunction(mfunc.get());
|
scheduler.runOnMachineFunction(mfunc.get());
|
||||||
|
|
||||||
// 阶段 3: 物理寄存器分配 (Register Allocation)
|
// 阶段 3: 物理寄存器分配 (Register Allocation)
|
||||||
|
|
||||||
bool allocation_succeeded = false;
|
bool allocation_succeeded = false;
|
||||||
|
|
||||||
// 尝试迭代图着色 (IRC)
|
// 尝试迭代图着色 (IRC)
|
||||||
if (!irc_failed) {
|
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());
|
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;
|
allocation_succeeded = true;
|
||||||
if (DEBUG) std::cerr << "IRC allocation succeeded.\n";
|
if (DEBUG) std::cerr << "IRC allocation succeeded.\n";
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "Warning: IRC failed for function '" << func->getName()
|
std::cerr << "Info: Blacklisting IRC for subsequent functions and falling back.\n";
|
||||||
<< "'. Blacklisting IRC for subsequent functions and falling back.\n";
|
irc_failed = true;
|
||||||
irc_failed = true; // 拉黑IRC,后续函数不再尝试
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 尝试简单图着色 (SGC) 并设置超时
|
// 尝试简单图着色 (SGC)
|
||||||
if (!allocation_succeeded) {
|
if (!allocation_succeeded) {
|
||||||
// 如果是从IRC失败回退过来的,需要重新创建干净的mfunc和ISel
|
// 如果是从IRC失败回退过来的,需要重新创建干净的mfunc和ISel
|
||||||
RISCv64ISel isel_for_sgc;
|
RISCv64ISel isel_for_sgc;
|
||||||
@@ -266,7 +292,7 @@ std::string RISCv64CodeGen::function_gen(Function* func) {
|
|||||||
{
|
{
|
||||||
RISCv64SimpleRegAlloc sgc_alloc(mfunc.get());
|
RISCv64SimpleRegAlloc sgc_alloc(mfunc.get());
|
||||||
auto future = std::async(std::launch::async, &RISCv64SimpleRegAlloc::run, &sgc_alloc);
|
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) {
|
if (status == std::future_status::ready) {
|
||||||
try {
|
try {
|
||||||
@@ -287,7 +313,7 @@ std::string RISCv64CodeGen::function_gen(Function* func) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 策略三:如果以上所有策略都失败了,则使用基本块分配器 (BBA)
|
// 如果都失败了,则使用基本块分配器 (BBA)
|
||||||
if (!allocation_succeeded) {
|
if (!allocation_succeeded) {
|
||||||
// 为BBA准备干净的mfunc和ISel
|
// 为BBA准备干净的mfunc和ISel
|
||||||
std::cerr << "Info: Resetting MachineFunction for BBA fallback.\n";
|
std::cerr << "Info: Resetting MachineFunction for BBA fallback.\n";
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
namespace sysy {
|
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";
|
if (DEBUG) std::cerr << "===== LLIR Before Running Graph Coloring Register Allocation " << MFunc->getName() << " =====\n";
|
||||||
std::stringstream ss_before_reg_alloc;
|
std::stringstream ss_before_reg_alloc;
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
@@ -68,6 +69,11 @@ bool RISCv64RegAlloc::run() {
|
|||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
rewriteProgram();
|
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 (DEBUG) std::cerr << "--- Spilling detected, re-running allocation (iteration " << iteration << ") ---\n";
|
||||||
|
|
||||||
if (iteration >= MAX_ITERATIONS) {
|
if (iteration >= MAX_ITERATIONS) {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public:
|
|||||||
RISCv64RegAlloc(MachineFunction* mfunc);
|
RISCv64RegAlloc(MachineFunction* mfunc);
|
||||||
|
|
||||||
// 模块主入口
|
// 模块主入口
|
||||||
bool run();
|
bool run(std::shared_ptr<std::atomic<bool>> stop_flag);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// 类型定义,与Python版本对应
|
// 类型定义,与Python版本对应
|
||||||
|
|||||||
Reference in New Issue
Block a user