|
|
|
|
@ -214,10 +214,21 @@ namespace mir
|
|
|
|
|
{
|
|
|
|
|
LiveInterval &cur = queue[qi];
|
|
|
|
|
|
|
|
|
|
// 同一 vreg 可能有多个 LiveInterval(分割产生),跳过已处理(已有范围)的
|
|
|
|
|
if (cur.vreg >= 0 && cur.vreg < num_vregs &&
|
|
|
|
|
vreg_has_range[cur.vreg])
|
|
|
|
|
continue;
|
|
|
|
|
// 检查当前区间是否已被覆盖(split 产生的溢出区间已有 vreg_ranges 条目)
|
|
|
|
|
if (cur.vreg >= 0 && cur.vreg < num_vregs)
|
|
|
|
|
{
|
|
|
|
|
bool already_covered = false;
|
|
|
|
|
for (const auto &rng : vreg_ranges[cur.vreg])
|
|
|
|
|
{
|
|
|
|
|
if (rng.start <= cur.start && cur.end <= rng.end)
|
|
|
|
|
{
|
|
|
|
|
already_covered = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (already_covered)
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 选择对应寄存器池
|
|
|
|
|
const int K = (cur.vreg_class == VRegClass::Float) ? K_FP : K_GP;
|
|
|
|
|
@ -269,10 +280,10 @@ namespace mir
|
|
|
|
|
VRegRange &last = ranges.back();
|
|
|
|
|
if (last.reg_idx == stolen_reg)
|
|
|
|
|
{
|
|
|
|
|
// 把 last.end 截断到 cur.end,后半段新建溢出范围
|
|
|
|
|
// 截断范围:寄存器在 cur.start 通过 save point 保存后即被 cur 覆写
|
|
|
|
|
int orig_end = last.end;
|
|
|
|
|
last.end = cur.end;
|
|
|
|
|
vreg_ranges[evicted_vreg].push_back({cur.end + 1, orig_end, -1});
|
|
|
|
|
last.end = cur.start;
|
|
|
|
|
vreg_ranges[evicted_vreg].push_back({cur.start + 1, orig_end, -1});
|
|
|
|
|
|
|
|
|
|
// 在此位置需要保存被驱逐的值到栈
|
|
|
|
|
int slot = GetOrCreateSpillSlot(func, evicted_vreg, vreg_to_slot);
|
|
|
|
|
@ -281,7 +292,7 @@ namespace mir
|
|
|
|
|
// 把分割后的溢出部分送回队列(它以 evicted 的 vreg 标识,但 vreg_has_range 已为真)
|
|
|
|
|
LiveInterval split_li;
|
|
|
|
|
split_li.vreg = evicted_vreg;
|
|
|
|
|
split_li.start = cur.end + 1;
|
|
|
|
|
split_li.start = cur.start + 1;
|
|
|
|
|
split_li.end = orig_end;
|
|
|
|
|
split_li.vreg_class = spill_cand.interval->vreg_class;
|
|
|
|
|
split_li.spilled = true;
|
|
|
|
|
|