[midend-Loop-IVE]修复循环的死IV消除逻辑

This commit is contained in:
rain2133
2025-08-15 01:19:45 +08:00
parent a3435e7c26
commit fa33bf5134
2 changed files with 54 additions and 15 deletions

View File

@ -396,9 +396,25 @@ check_initial_overflow()
智能回退:使用已验证的标准值保证正确性 智能回退:使用已验证的标准值保证正确性
保持通用性:对于没有预设值的除数仍然可以工作 保持通用性:对于没有预设值的除数仍然可以工作
## 死归纳变量消除
整体架构和工作流程
当前的归纳变量消除优化分为三个清晰的阶段:
识别阶段:找出所有潜在的死归纳变量
安全性分析阶段:验证每个变量消除的安全性
消除执行阶段:实际删除安全的死归纳变量
逃逸点检测 (已修复的关键安全机制)
数组索引检测GEP指令被正确识别为逃逸点
循环退出条件:用于比较和条件分支的归纳变量不会被消除
控制流指令condBr、br、return等被特殊处理为逃逸点
内存操作store/load指令经过别名分析检查
# 后续优化可能涉及的改动 # 后续优化可能涉及的改动
## 1将所有的alloca集中到entryblock中 ## 1将所有的alloca集中到entryblock中(已实现)
好处优化友好性方便mem2reg提升 好处优化友好性方便mem2reg提升
目前没有实现这个机制,如果想要实现首先解决同一函数不同域的同名变量命名区分 目前没有实现这个机制,如果想要实现首先解决同一函数不同域的同名变量命名区分

View File

@ -255,6 +255,18 @@ bool InductionVariableEliminationContext::isInstructionUseChainDeadRecursively(
return false; // 有副作用的指令是逃逸点 return false; // 有副作用的指令是逃逸点
} }
// 1.5. 特殊检查:控制流指令永远不是死代码
auto instKind = inst->getKind();
if (instKind == Instruction::Kind::kCondBr ||
instKind == Instruction::Kind::kBr ||
instKind == Instruction::Kind::kReturn) {
if (DEBUG && visited.size() < 10) {
std::cout << " 控制流指令,是逃逸点" << std::endl;
}
currentPath.erase(inst);
return false; // 控制流指令是逃逸点
}
// 2. 检查指令的所有使用 // 2. 检查指令的所有使用
bool allUsesAreDead = true; bool allUsesAreDead = true;
for (auto use : inst->getUses()) { for (auto use : inst->getUses()) {
@ -280,22 +292,15 @@ bool InductionVariableEliminationContext::isInstructionUseChainDeadRecursively(
} }
// 特殊检查:如果使用者是循环的退出条件,需要进一步分析 // 特殊检查:如果使用者是循环的退出条件,需要进一步分析
// 只有当循环有副作用时,才将用于退出条件的归纳变量视为逃逸点 // 对于用于退出条件的归纳变量,需要更谨慎的处理
if (isUsedInLoopExitCondition(userInst, loop)) { if (isUsedInLoopExitCondition(userInst, loop)) {
// 检查循环是否有副作用 // 修复逻辑:用于循环退出条件的归纳变量通常不应该被消除
if (loopHasSideEffects(loop)) { // 除非整个循环都可以被证明是完全无用的(这需要更复杂的分析)
if (DEBUG && visited.size() < 10) { if (DEBUG && visited.size() < 10) {
std::cout << " 被用于循环退出条件且循环有副作用,是逃逸点" << std::endl; std::cout << " 被用于循环退出条件,是逃逸点(避免破坏循环语义)" << std::endl;
}
allUsesAreDead = false;
break;
} else {
if (DEBUG && visited.size() < 10) {
std::cout << " 被用于循环退出条件但循环无副作用,继续分析" << std::endl;
}
// 对于纯循环,即使用于退出条件也不是逃逸点,继续分析其他使用
continue;
} }
allUsesAreDead = false;
break;
} }
// 递归分析使用者的使用链 // 递归分析使用者的使用链
@ -345,6 +350,24 @@ bool InductionVariableEliminationContext::loopHasSideEffects(Loop* loop) {
} }
} }
// 重要修复:检查是否为嵌套循环的外层循环
// 如果当前循环包含其他循环,那么它有潜在的副作用
for (const auto& loop_ptr : loopAnalysis->getAllLoops()) {
Loop* otherLoop = loop_ptr.get();
if(loopAnalysis->getLowestCommonAncestor(otherLoop, loop) == loop) {
if (DEBUG) {
std::cout << " 循环 " << loop->getName() << " 是其他循环的外层循环,视为有副作用" << std::endl;
}
return true; // 外层循环被视为有副作用
}
// if (otherLoop != loop && loop->contains(otherLoop->getHeader())) {
// if (DEBUG) {
// std::cout << " 循环 " << loop->getName() << " 包含子循环 " << otherLoop->getName() << ",视为有副作用" << std::endl;
// }
// return true; // 包含子循环的外层循环被视为有副作用
// }
}
if (DEBUG) { if (DEBUG) {
std::cout << " 循环 " << loop->getName() << " 无副作用" << std::endl; std::cout << " 循环 " << loop->getName() << " 无副作用" << std::endl;
} }