[backend]消除了线性扫描分配器对参数寄存器的引用

This commit is contained in:
Lixuanwang
2025-08-05 02:21:42 +08:00
parent df50eedaeb
commit 676880ca05
2 changed files with 63 additions and 20 deletions

View File

@ -73,7 +73,7 @@ RISCv64LinearScan::RISCv64LinearScan(MachineFunction* mfunc)
allocable_int_regs = {
PhysicalReg::T0, PhysicalReg::T1, PhysicalReg::T2, PhysicalReg::T3, PhysicalReg::T4, PhysicalReg::T6,
PhysicalReg::A0, PhysicalReg::A1, PhysicalReg::A2, PhysicalReg::A3, PhysicalReg::A4, PhysicalReg::A5, PhysicalReg::A6, PhysicalReg::A7,
// PhysicalReg::A0, PhysicalReg::A1, PhysicalReg::A2, PhysicalReg::A3, PhysicalReg::A4, PhysicalReg::A5, PhysicalReg::A6, PhysicalReg::A7,
PhysicalReg::S1, PhysicalReg::S2, PhysicalReg::S3, PhysicalReg::S4, PhysicalReg::S5, PhysicalReg::S6, PhysicalReg::S7,
PhysicalReg::S8, PhysicalReg::S9, PhysicalReg::S10, PhysicalReg::S11,
};
@ -159,7 +159,7 @@ void RISCv64LinearScan::computeLiveIntervals() {
}
}
// b. 活跃变量分析(数据流分析部分)
// b. 活跃变量分析(数据流分析部分,这部分是正确的,保持不变
if (DEEPDEBUG) std::cerr << " [Live] Starting live variable dataflow analysis...\n";
std::map<const MachineBasicBlock*, std::set<unsigned>> live_in, live_out;
bool changed = true;
@ -198,44 +198,49 @@ void RISCv64LinearScan::computeLiveIntervals() {
// c. 根据指令遍历和活跃出口信息,精确构建区间
if (DEEPDEBUG) std::cerr << " [Live] Building precise intervals...\n";
std::map<unsigned, int> first_occurrence, last_occurrence;
std::map<unsigned, int> first_def, last_use;
// 步骤 c.1: 遍历所有指令找到每个vreg的首次定义和最后一次使用
for (auto* mbb : linear_order_blocks) {
for (auto& instr_ptr : mbb->getInstructions()) {
int instr_num = instr_numbering.at(instr_ptr.get());
std::set<unsigned> use, def;
getInstrUseDef(instr_ptr.get(), use, def);
std::set<unsigned> all_vregs = use;
all_vregs.insert(def.begin(), def.end());
for (unsigned vreg : all_vregs) {
if (first_occurrence.find(vreg) == first_occurrence.end()) {
first_occurrence[vreg] = instr_num;
for (unsigned vreg : def) {
if (first_def.find(vreg) == first_def.end()) {
first_def[vreg] = instr_num;
}
last_occurrence[vreg] = instr_num;
}
for (unsigned vreg : use) {
last_use[vreg] = instr_num;
}
}
}
// 使用 live_out 信息修正区间的结束点
// 步骤 c.2: 创建 LiveInterval 对象,并使用 live_out 信息修正区间的结束点
for (auto const& [vreg, start] : first_def) {
live_intervals.emplace(vreg, LiveInterval(vreg));
auto& interval = live_intervals.at(vreg);
interval.start = start;
// 初始结束点是最后一次使用。如果从未被使用,则结束点就是定义点。
interval.end = last_use.count(vreg) ? last_use.at(vreg) : start;
}
for (auto const& [mbb, live_set] : live_out) {
if (mbb->getInstructions().empty()) continue;
int block_end_num = instr_numbering.at(mbb->getInstructions().back().get());
for (unsigned vreg : live_set) {
if (last_occurrence.count(vreg)) {
last_occurrence[vreg] = std::max(last_occurrence[vreg], block_end_num);
if (live_intervals.count(vreg)) {
live_intervals.at(vreg).end = std::max(live_intervals.at(vreg).end, block_end_num);
}
}
}
// 创建最终的 LiveInterval 对象
for (auto const& [vreg, start] : first_occurrence) {
live_intervals.emplace(vreg, LiveInterval(vreg));
auto& interval = live_intervals.at(vreg);
interval.start = start;
interval.end = last_occurrence.at(vreg);
// 步骤 c.3: 检查是否跨越函数调用
for (auto& pair : live_intervals) {
auto& interval = pair.second;
auto it = call_locations.lower_bound(interval.start);
if (it != call_locations.end() && *it < interval.end) {
interval.crosses_call = true;

View File

@ -65,6 +65,44 @@ void RISCv64RegAlloc::run() {
}
}
// const int MAX_ITERATIONS = 50;
// int iteration = 0;
// while (iteration++ < MAX_ITERATIONS) {
// if (doAllocation()) {
// break;
// } else {
// rewriteProgram();
// if (DEBUG) std::cerr << "--- Spilling detected, re-running allocation (iteration " << iteration << ") ---\n";
// if (iteration >= MAX_ITERATIONS) {
// std::cerr << "ERROR: Register allocation failed to converge after " << MAX_ITERATIONS << " iterations\n";
// std::cerr << " Spill worklist size: " << spillWorklist.size() << "\n";
// std::cerr << " Total nodes: " << (initial.size() + coloredNodes.size()) << "\n";
// // Emergency spill remaining nodes to break the loop
// std::cerr << " Emergency spilling remaining spill worklist nodes...\n";
// for (unsigned node : spillWorklist) {
// spilledNodes.insert(node);
// }
// // Also spill any nodes that didn't get colors
// std::set<unsigned> uncolored;
// for (unsigned node : initial) {
// if (color_map.find(node) == color_map.end()) {
// uncolored.insert(node);
// }
// }
// for (unsigned node : uncolored) {
// spilledNodes.insert(node);
// }
// // Force completion
// break;
// }
// }
// }
applyColoring();
MFunc->getFrameInfo().vreg_to_preg_map = this->color_map;