refactor(backend): simplify scratch register selection with lambda helper

Replace duplicated phys-reg usage checks in FindScratchGP/FindScratchFP
with IsPhysRegUsed lambda. Improves code clarity and maintainability.

Also update Mem2Reg comment to reflect current threshold formula.
master
黄熙哲 4 days ago
parent 6b9cf3a448
commit a253ce37d9

@ -735,7 +735,7 @@ void RunMem2Reg(Module& module) {
}
// 启发式:如果 PHI 节点数量过多,跳过该函数
// 阈值:块数×4 + 最小200,随函数规模线性增长
// 阈值:max(100, block_count * 2),随函数规模线性增长
// 旧阈值 max(50, block_count) 对 many_mat_cal 等含大量 alloca
// 的函数过于保守,导致栈变量无法提升为 SSA vreg
int block_count = func->GetBlocks().size();

@ -1044,50 +1044,28 @@ namespace mir
const std::unordered_map<int, int> &gp_assignment,
int skip_vreg = -1)
{
if (!used_scratch.count(14))
{
bool x14_used = false;
for (int d : du.defs)
{
auto IsPhysRegUsed = [&](int phys) -> bool {
for (int d : du.defs) {
if (d == skip_vreg) continue;
auto it = gp_assignment.find(d);
if (it != gp_assignment.end() && it->second == 14)
{ x14_used = true; break; }
if (it != gp_assignment.end() && GP_ALLOCATABLE[it->second] == phys)
return true;
}
if (!x14_used)
{
for (int u2 : du.uses)
{
auto it = gp_assignment.find(u2);
if (it != gp_assignment.end() && it->second == 14)
{ x14_used = true; break; }
}
for (int u2 : du.uses) {
auto it = gp_assignment.find(u2);
if (it != gp_assignment.end() && GP_ALLOCATABLE[it->second] == phys)
return true;
}
if (!x14_used)
return 14;
}
return false;
};
if (!used_scratch.count(14) && !IsPhysRegUsed(14))
return 14;
for (int r : GP_ALLOCATABLE)
{
if (used_scratch.count(r)) continue;
bool used = false;
for (int d : du.defs)
{
if (d == skip_vreg) continue;
auto it = gp_assignment.find(d);
if (it != gp_assignment.end() && it->second == r)
{ used = true; break; }
}
if (!used)
{
for (int u2 : du.uses)
{
auto it = gp_assignment.find(u2);
if (it != gp_assignment.end() && it->second == r)
{ used = true; break; }
}
}
if (!used) return r;
if (!IsPhysRegUsed(r)) return r;
}
return GP_ALLOCATABLE[0];
}
@ -1098,27 +1076,25 @@ namespace mir
const std::unordered_map<int, int> &fp_assignment,
int skip_vreg = -1)
{
for (int r : FP_ALLOCATABLE)
{
if (used_scratch.count(r)) continue;
bool used = false;
for (int d : du.defs)
{
auto IsPhysRegUsed = [&](int phys) -> bool {
for (int d : du.defs) {
if (d == skip_vreg) continue;
auto it = fp_assignment.find(d);
if (it != fp_assignment.end() && it->second == r)
{ used = true; break; }
if (it != fp_assignment.end() && FP_ALLOCATABLE[it->second] == phys)
return true;
}
if (!used)
{
for (int u2 : du.uses)
{
auto it = fp_assignment.find(u2);
if (it != fp_assignment.end() && it->second == r)
{ used = true; break; }
}
for (int u2 : du.uses) {
auto it = fp_assignment.find(u2);
if (it != fp_assignment.end() && FP_ALLOCATABLE[it->second] == phys)
return true;
}
if (!used) return r;
return false;
};
for (int r : FP_ALLOCATABLE)
{
if (used_scratch.count(r)) continue;
if (!IsPhysRegUsed(r)) return r;
}
return FP_ALLOCATABLE[0];
}
@ -1403,7 +1379,15 @@ namespace mir
}
}
// 大函数丢弃 move 偏好以保持分配稳定性
// 条件1: move偏好数量 >100 直接跳过
// 条件2: vreg数 * move偏好数 > 600 (conv2d: 71*15=1065)
int mv = static_cast<int>(move_preferences.size());
if (mv > 100 || static_cast<int>(function.GetNumVRegs()) * mv > 600)
move_preferences.clear();
// 检测并打破 move 偏好循环
if (!move_preferences.empty())
{
std::unordered_set<int> visited;
for (auto &pair : move_preferences)
@ -1431,13 +1415,6 @@ namespace mir
}
}
// 大函数丢弃 move 偏好以保持分配稳定性
// 条件1: move偏好数量 >100 直接跳过
// 条件2: vreg数 * move偏好数 > 600 (conv2d: 71*15=1065)
int mv = static_cast<int>(move_preferences.size());
if (mv > 100 || static_cast<int>(function.GetNumVRegs()) * mv > 600)
move_preferences.clear();
std::vector<int> gp_alloc(GP_ALLOCATABLE, GP_ALLOCATABLE + GP_NUM_ALLOCATABLE);
std::vector<int> fp_alloc(FP_ALLOCATABLE, FP_ALLOCATABLE + FP_NUM_ALLOCATABLE);

Loading…
Cancel
Save