[backend]完善后端流水线,本地仅剩h/39不通过
This commit is contained in:
@@ -198,10 +198,6 @@ std::string RISCv64CodeGen::module_gen() {
|
||||
}
|
||||
|
||||
std::string RISCv64CodeGen::function_gen(Function* func) {
|
||||
DEBUG = 0;
|
||||
DEEPDEBUG = 0;
|
||||
// === 完整的后端处理流水线 ===
|
||||
|
||||
// 阶段 1: 指令选择 (sysy::IR -> LLIR with virtual registers)
|
||||
RISCv64ISel isel;
|
||||
std::unique_ptr<MachineFunction> mfunc = isel.runOnFunction(func);
|
||||
@@ -214,9 +210,8 @@ std::string RISCv64CodeGen::function_gen(Function* func) {
|
||||
std::cerr << "====== Intermediate Representation after Instruction Selection ======\n"
|
||||
<< ss_after_isel.str();
|
||||
}
|
||||
|
||||
|
||||
// 阶段 2: 消除帧索引 (展开伪指令,计算局部变量偏移)
|
||||
// 这个Pass必须在寄存器分配之前运行
|
||||
EliminateFrameIndicesPass efi_pass;
|
||||
efi_pass.runOnMachineFunction(mfunc.get());
|
||||
|
||||
@@ -229,89 +224,83 @@ std::string RISCv64CodeGen::function_gen(Function* func) {
|
||||
<< ss_after_eli.str();
|
||||
}
|
||||
|
||||
// // 阶段 2: 除法强度削弱优化 (Division Strength Reduction)
|
||||
// DivStrengthReduction div_strength_reduction;
|
||||
// div_strength_reduction.runOnMachineFunction(mfunc.get());
|
||||
// 阶段 2.1: 除法强度削弱优化 (Division Strength Reduction)
|
||||
DivStrengthReduction div_strength_reduction;
|
||||
div_strength_reduction.runOnMachineFunction(mfunc.get());
|
||||
|
||||
// // 阶段 2.1: 指令调度 (Instruction Scheduling)
|
||||
// PreRA_Scheduler scheduler;
|
||||
// scheduler.runOnMachineFunction(mfunc.get());
|
||||
// 阶段 2.2: 指令调度 (Instruction Scheduling)
|
||||
PreRA_Scheduler scheduler;
|
||||
scheduler.runOnMachineFunction(mfunc.get());
|
||||
|
||||
// 阶段 3: 物理寄存器分配 (Register Allocation)
|
||||
|
||||
// 首先尝试图着色分配器
|
||||
// int fooo = 0;
|
||||
int fooo = 1;
|
||||
// DEBUG = 1;
|
||||
// DEEPDEBUG = 1;
|
||||
if (fooo) {
|
||||
RISCv64SimpleRegAlloc simple_alloc(mfunc.get());
|
||||
simple_alloc.run();
|
||||
DEBUG = 0;
|
||||
DEEPDEBUG = 0;
|
||||
} else
|
||||
{if (DEBUG) std::cerr << "Attempting Register Allocation with Graph Coloring...\n";
|
||||
if (!gc_failed) {
|
||||
RISCv64RegAlloc gc_alloc(mfunc.get());
|
||||
|
||||
bool success_gc = gc_alloc.run();
|
||||
|
||||
if (!success_gc) {
|
||||
gc_failed = 1; // 后续不再尝试图着色分配器
|
||||
std::cerr << "Warning: Graph coloring register allocation failed function '"
|
||||
<< func->getName()
|
||||
<< "'. Switching to Linear Scan allocator."
|
||||
<< std::endl;
|
||||
|
||||
RISCv64ISel isel_gc_fallback;
|
||||
mfunc = isel_gc_fallback.runOnFunction(func);
|
||||
EliminateFrameIndicesPass efi_pass_gc_fallback;
|
||||
efi_pass_gc_fallback.runOnMachineFunction(mfunc.get());
|
||||
RISCv64LinearScan ls_alloc(mfunc.get());
|
||||
bool success = ls_alloc.run();
|
||||
if (!success) {
|
||||
// 如果线性扫描最终失败,则调用基本块分配器作为终极后备
|
||||
std::cerr << "Info: Linear Scan failed. Switching to Basic Block Allocator as final fallback.\n";
|
||||
|
||||
// 注意:我们需要在一个“干净”的MachineFunction上运行。
|
||||
// 最安全的方式是重新运行指令选择。
|
||||
RISCv64ISel isel_fallback;
|
||||
mfunc = isel_fallback.runOnFunction(func);
|
||||
EliminateFrameIndicesPass efi_pass_fallback;
|
||||
efi_pass_fallback.runOnMachineFunction(mfunc.get());
|
||||
if (DEBUG) {
|
||||
std::cerr << "====== stack info after reg alloc ======\n";
|
||||
}
|
||||
RISCv64BasicBlockAlloc bb_alloc(mfunc.get());
|
||||
bb_alloc.run();
|
||||
}
|
||||
bool allocation_succeeded = false;
|
||||
// 尝试迭代图着色 (IRC)
|
||||
if (!irc_failed) {
|
||||
if (DEBUG) std::cerr << "Attempting Register Allocation with Iterated Register Coloring (IRC)...\n";
|
||||
RISCv64RegAlloc irc_alloc(mfunc.get());
|
||||
if (irc_alloc.run()) {
|
||||
allocation_succeeded = true;
|
||||
if (DEBUG) std::cerr << "IRC allocation succeeded.\n";
|
||||
} else {
|
||||
// 图着色成功完成
|
||||
if (DEBUG) std::cerr << "Graph Coloring allocation completed successfully.\n";
|
||||
std::cerr << "Warning: IRC failed for function '" << func->getName()
|
||||
<< "'. Blacklisting IRC for subsequent functions and falling back.\n";
|
||||
irc_failed = true; // 拉黑IRC,后续函数不再尝试
|
||||
}
|
||||
} else {
|
||||
std::cerr << "Info: Graph Coloring allocation failed in last function. Switching to Linear Scan allocator...\n";
|
||||
RISCv64LinearScan ls_alloc(mfunc.get());
|
||||
bool success = ls_alloc.run();
|
||||
if (!success) {
|
||||
// 如果线性扫描最终失败,则调用基本块分配器作为终极后备
|
||||
std::cerr << "Info: Linear Scan failed. Switching to Basic Block Allocator as final fallback.\n";
|
||||
|
||||
// 注意:我们需要在一个“干净”的MachineFunction上运行。
|
||||
// 最安全的方式是重新运行指令选择。
|
||||
RISCv64ISel isel_fallback;
|
||||
mfunc = isel_fallback.runOnFunction(func);
|
||||
EliminateFrameIndicesPass efi_pass_fallback;
|
||||
efi_pass_fallback.runOnMachineFunction(mfunc.get());
|
||||
if (DEBUG) {
|
||||
std::cerr << "====== stack info after reg alloc ======\n";
|
||||
}
|
||||
RISCv64BasicBlockAlloc bb_alloc(mfunc.get());
|
||||
bb_alloc.run();
|
||||
}
|
||||
}}
|
||||
|
||||
}
|
||||
|
||||
// 尝试简单图着色 (SGC) 并设置超时
|
||||
if (!allocation_succeeded) {
|
||||
// 如果是从IRC失败回退过来的,需要重新创建干净的mfunc和ISel
|
||||
RISCv64ISel isel_for_sgc;
|
||||
if (irc_failed) {
|
||||
if (DEBUG) std::cerr << "Info: Resetting MachineFunction for SGC attempt.\n";
|
||||
mfunc = isel_for_sgc.runOnFunction(func);
|
||||
EliminateFrameIndicesPass efi_pass_for_sgc;
|
||||
efi_pass_for_sgc.runOnMachineFunction(mfunc.get());
|
||||
}
|
||||
|
||||
if (DEBUG) std::cerr << "Attempting Register Allocation with Simple Graph Coloring (SGC)...\n";
|
||||
|
||||
bool sgc_completed_in_time = false;
|
||||
{
|
||||
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));
|
||||
|
||||
if (status == std::future_status::ready) {
|
||||
try {
|
||||
future.get(); // 检查是否有异常
|
||||
sgc_completed_in_time = true;
|
||||
if (DEBUG) std::cerr << "SGC allocation completed successfully within the time limit.\n";
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "Error: SGC allocation threw an exception: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sgc_completed_in_time) {
|
||||
allocation_succeeded = true;
|
||||
} else {
|
||||
std::cerr << "Warning: SGC allocation timed out or failed for function '" << func->getName()
|
||||
<< "'. Falling back.\n";
|
||||
}
|
||||
}
|
||||
|
||||
// 策略三:如果以上所有策略都失败了,则使用基本块分配器 (BBA)
|
||||
if (!allocation_succeeded) {
|
||||
// 为BBA准备干净的mfunc和ISel
|
||||
std::cerr << "Info: Resetting MachineFunction for BBA fallback.\n";
|
||||
RISCv64ISel isel_for_bba;
|
||||
mfunc = isel_for_bba.runOnFunction(func);
|
||||
EliminateFrameIndicesPass efi_pass_for_bba;
|
||||
efi_pass_for_bba.runOnMachineFunction(mfunc.get());
|
||||
|
||||
std::cerr << "Info: Using Basic Block Allocator as final fallback.\n";
|
||||
RISCv64BasicBlockAlloc bb_alloc(mfunc.get());
|
||||
bb_alloc.run();
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
std::cerr << "====== stack info after reg alloc ======\n";
|
||||
mfunc->dumpStackFrameInfo(std::cerr);
|
||||
@@ -326,9 +315,9 @@ std::string RISCv64CodeGen::function_gen(Function* func) {
|
||||
mfunc->dumpStackFrameInfo(std::cerr);
|
||||
}
|
||||
|
||||
// // 阶段 4: 窥孔优化 (Peephole Optimization)
|
||||
// PeepholeOptimizer peephole;
|
||||
// peephole.runOnMachineFunction(mfunc.get());
|
||||
// 阶段 4: 窥孔优化 (Peephole Optimization)
|
||||
PeepholeOptimizer peephole;
|
||||
peephole.runOnMachineFunction(mfunc.get());
|
||||
|
||||
// 阶段 5: 局部指令调度 (Local Scheduling)
|
||||
PostRA_Scheduler local_scheduler;
|
||||
|
||||
@@ -26,7 +26,7 @@ private:
|
||||
unsigned getTypeSizeInBytes(Type* type);
|
||||
|
||||
Module* module;
|
||||
bool gc_failed = false;
|
||||
bool irc_failed = false;
|
||||
};
|
||||
|
||||
} // namespace sysy
|
||||
|
||||
Reference in New Issue
Block a user