diff --git a/src/backend/RISCv64/RISCv64LinearScan.cpp b/src/backend/RISCv64/RISCv64LinearScan.cpp index 1857281..9061cd8 100644 --- a/src/backend/RISCv64/RISCv64LinearScan.cpp +++ b/src/backend/RISCv64/RISCv64LinearScan.cpp @@ -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> 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 first_occurrence, last_occurrence; + std::map 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 use, def; getInstrUseDef(instr_ptr.get(), use, def); - - std::set 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; diff --git a/src/backend/RISCv64/RISCv64RegAlloc.cpp b/src/backend/RISCv64/RISCv64RegAlloc.cpp index f7d364f..c09bd5d 100644 --- a/src/backend/RISCv64/RISCv64RegAlloc.cpp +++ b/src/backend/RISCv64/RISCv64RegAlloc.cpp @@ -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 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;