fix(mir): 分配顺序改为FirstUsePos + 别名无条件冲突 + per-round reserve

三处改进:
1. 新vreg按FirstUsePos升序分配(指令顺序),确保重叠vreg在干涉检查时可见
   替代之前的Length()排序(弦图最优序近似)
2. GPR32/GPR64别名无条件冲突(移除segments.empty()条件)
3. 每轮EnhancerIntervals后reserve *16 防止push_back指针失效

Mem2Reg问题已精确诊断:高寄存器压力下,多个Ptr vreg的重叠段未被子涉检
测捕获,导致地址计算base和index共享同一物理寄存器。
当前正确率:94% (94/100),剩余2个Mem2Reg交互失败+4个预存缺陷。
lzk
lzkk 3 days ago
parent 83228a8123
commit 0f1b545568

@ -52,8 +52,10 @@ struct SpillWeightCmp
const auto& lb = intervals[b];
if (la.generation != lb.generation)
return la.generation > lb.generation;
// 新 vreg 按 FirstUsePos 升序:确保处理顺序与指令顺序一致,
// 这样当 vreg B 被分配时,更早的 vreg A 已在 reg_assignments_ 中
if (la.deferred_count == 0 && lb.deferred_count == 0)
return la.Length() > lb.Length();
return la.FirstUsePos() > lb.FirstUsePos();
return la.spill_weight < lb.spill_weight;
}
};
@ -532,6 +534,7 @@ static void AllocateRegistersForFunction(MachineFunction &function)
// ---- 阶段 0活跃分析 + 预处理 ----
auto raw = ComputeInstLiveness(function);
auto intervals = EnhanceIntervals(raw, function);
intervals.reserve(function.GetNumVRegs() * 16);
auto &blocks = function.GetBlocks();
std::vector<int> pos_to_block;
@ -549,7 +552,7 @@ static void AllocateRegistersForFunction(MachineFunction &function)
auto block_depth = AnalyzeLoopDepth(function);
ComputeSpillWeights(intervals, block_depth, pos_to_block);
PropagateCopyHints(intervals, function);
intervals.reserve(function.GetNumVRegs() * 4);
intervals.reserve(function.GetNumVRegs() * 16);
// LLVM 风格:全局 cascade 计数器
int global_cascade = 1;
@ -661,6 +664,7 @@ static void AllocateRegistersForFunction(MachineFunction &function)
// ---- 重新分析活跃 ----
raw = ComputeInstLiveness(function);
intervals = EnhanceIntervals(raw, function);
intervals.reserve(function.GetNumVRegs() * 16);
// ---- 重建位置映射 ----
pos_to_block.clear();

Loading…
Cancel
Save