#include "InductionVariableElimination.h" #include "LoopCharacteristics.h" #include "Loop.h" #include "Dom.h" #include "SideEffectAnalysis.h" #include "AliasAnalysis.h" #include "SysYIROptUtils.h" #include #include // 使用全局调试开关 extern int DEBUG; namespace sysy { // 定义 Pass 的唯一 ID void *InductionVariableElimination::ID = (void *)&InductionVariableElimination::ID; bool InductionVariableElimination::runOnFunction(Function* F, AnalysisManager& AM) { if (F->getBasicBlocks().empty()) { return false; // 空函数 } if (DEBUG) { std::cout << "Running InductionVariableElimination on function: " << F->getName() << std::endl; } // 创建优化上下文并运行 InductionVariableEliminationContext context; bool modified = context.run(F, AM); if (DEBUG) { std::cout << "InductionVariableElimination " << (modified ? "modified" : "did not modify") << " function: " << F->getName() << std::endl; } return modified; } void InductionVariableElimination::getAnalysisUsage(std::set& analysisDependencies, std::set& analysisInvalidations) const { // 依赖的分析 analysisDependencies.insert(&LoopAnalysisPass::ID); analysisDependencies.insert(&LoopCharacteristicsPass::ID); analysisDependencies.insert(&DominatorTreeAnalysisPass::ID); analysisDependencies.insert(&SysYSideEffectAnalysisPass::ID); analysisDependencies.insert(&SysYAliasAnalysisPass::ID); // 会使失效的分析(归纳变量消除会修改IR结构) analysisInvalidations.insert(&LoopCharacteristicsPass::ID); // 注意:支配树分析通常不会因为归纳变量消除而失效,因为我们不改变控制流 } // ========== InductionVariableEliminationContext 实现 ========== bool InductionVariableEliminationContext::run(Function* F, AnalysisManager& AM) { if (DEBUG) { std::cout << " Starting induction variable elimination analysis..." << std::endl; } // 获取必要的分析结果 loopAnalysis = AM.getAnalysisResult(F); if (!loopAnalysis || !loopAnalysis->hasLoops()) { if (DEBUG) { std::cout << " No loops found, skipping induction variable elimination" << std::endl; } return false; } loopCharacteristics = AM.getAnalysisResult(F); if (!loopCharacteristics) { if (DEBUG) { std::cout << " LoopCharacteristics analysis not available" << std::endl; } return false; } dominatorTree = AM.getAnalysisResult(F); if (!dominatorTree) { if (DEBUG) { std::cout << " DominatorTree analysis not available" << std::endl; } return false; } sideEffectAnalysis = AM.getAnalysisResult(); if (!sideEffectAnalysis) { if (DEBUG) { std::cout << " SideEffectAnalysis not available, using conservative approach" << std::endl; } // 可以继续执行,但会使用更保守的策略 } else { if (DEBUG) { std::cout << " Using SideEffectAnalysis for safety checks" << std::endl; } } aliasAnalysis = AM.getAnalysisResult(F); if (!aliasAnalysis) { if (DEBUG) { std::cout << " AliasAnalysis not available, using conservative approach" << std::endl; } // 可以继续执行,但会使用更保守的策略 } else { if (DEBUG) { std::cout << " Using AliasAnalysis for memory safety checks" << std::endl; } } // 执行三个阶段的优化 // 阶段1:识别死归纳变量 identifyDeadInductionVariables(F); if (deadIVs.empty()) { if (DEBUG) { std::cout << " No dead induction variables found" << std::endl; } return false; } if (DEBUG) { std::cout << " Found " << deadIVs.size() << " potentially dead induction variables" << std::endl; } // 阶段2:分析安全性 analyzeSafetyForElimination(); // 阶段3:执行消除 bool modified = performInductionVariableElimination(); if (DEBUG) { printDebugInfo(); } return modified; } void InductionVariableEliminationContext::identifyDeadInductionVariables(Function* F) { if (DEBUG) { std::cout << " === Phase 1: Identifying Dead Induction Variables ===" << std::endl; } // 遍历所有循环 for (const auto& loop_ptr : loopAnalysis->getAllLoops()) { Loop* loop = loop_ptr.get(); if (DEBUG) { std::cout << " Analyzing loop: " << loop->getName() << std::endl; } // 获取循环特征 const LoopCharacteristics* characteristics = loopCharacteristics->getCharacteristics(loop); if (!characteristics) { if (DEBUG) { std::cout << " No characteristics available for loop" << std::endl; } continue; } if (characteristics->InductionVars.empty()) { if (DEBUG) { std::cout << " No induction variables found in loop" << std::endl; } continue; } // 检查每个归纳变量是否为死归纳变量 for (const auto& iv : characteristics->InductionVars) { auto deadIV = isDeadInductionVariable(iv.get(), loop); if (deadIV) { if (DEBUG) { std::cout << " Found potential dead IV: %" << deadIV->phiInst->getName() << std::endl; } // 添加到候选项列表 loopToDeadIVs[loop].push_back(deadIV.get()); deadIVs.push_back(std::move(deadIV)); } } } if (DEBUG) { std::cout << " === End Phase 1: Found " << deadIVs.size() << " candidates ===" << std::endl; } } std::unique_ptr InductionVariableEliminationContext::isDeadInductionVariable(const InductionVarInfo* iv, Loop* loop) { // 获取 phi 指令 auto* phiInst = dynamic_cast(iv->div); if (!phiInst) { return nullptr; // 不是 phi 指令 } // 新的逻辑:递归分析整个use-def链,判断是否有真实的使用 if (!isPhiInstructionDeadRecursively(phiInst, loop)) { return nullptr; // 有真实的使用,不能删除 } // 创建死归纳变量信息 auto deadIV = std::make_unique(phiInst, loop); deadIV->relatedInsts = collectRelatedInstructions(phiInst, loop); return deadIV; } // 递归分析phi指令及其使用链是否都是死代码 bool InductionVariableEliminationContext::isPhiInstructionDeadRecursively(PhiInst* phiInst, Loop* loop) { if (DEBUG) { std::cout << " 递归分析归纳变量 " << phiInst->getName() << " 的完整使用链" << std::endl; } // 使用访问集合避免无限递归 std::set visitedInstructions; std::set currentPath; // 用于检测循环依赖 // 核心逻辑:递归分析使用链,寻找任何"逃逸点" return isInstructionUseChainDeadRecursively(phiInst, loop, visitedInstructions, currentPath); } // 递归分析指令的使用链是否都是死代码 bool InductionVariableEliminationContext::isInstructionUseChainDeadRecursively( Instruction* inst, Loop* loop, std::set& visited, std::set& currentPath) { if (DEBUG && visited.size() < 10) { // 限制debug输出 std::cout << " 分析指令 " << inst->getName() << " (" << inst->getKindString() << ")" << std::endl; } // 避免无限递归 if (currentPath.count(inst) > 0) { // 发现循环依赖,这在归纳变量中是正常的,继续分析其他路径 if (DEBUG && visited.size() < 10) { std::cout << " 发现循环依赖,继续分析其他路径" << std::endl; } return true; // 循环依赖本身不是逃逸点 } if (visited.count(inst) > 0) { // 已经分析过这个指令 return true; // 假设之前的分析是正确的 } visited.insert(inst); currentPath.insert(inst); // 1. 检查是否有副作用(逃逸点) if (sideEffectAnalysis && sideEffectAnalysis->hasSideEffect(inst)) { if (DEBUG && visited.size() < 10) { std::cout << " 指令有副作用,是逃逸点" << std::endl; } currentPath.erase(inst); 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. 检查指令的所有使用 bool allUsesAreDead = true; for (auto use : inst->getUses()) { auto user = use->getUser(); auto* userInst = dynamic_cast(user); if (!userInst) { // 被非指令使用(如函数返回值),是逃逸点 if (DEBUG && visited.size() < 10) { std::cout << " 被非指令使用,是逃逸点" << std::endl; } allUsesAreDead = false; break; } // 检查使用是否在循环外(逃逸点) if (!loop->contains(userInst->getParent())) { if (DEBUG && visited.size() < 10) { std::cout << " 在循环外被 " << userInst->getName() << " 使用,是逃逸点" << std::endl; } allUsesAreDead = false; break; } // 特殊检查:如果使用者是循环的退出条件,需要进一步分析 // 对于用于退出条件的归纳变量,需要更谨慎的处理 if (isUsedInLoopExitCondition(userInst, loop)) { // 修复逻辑:用于循环退出条件的归纳变量通常不应该被消除 // 除非整个循环都可以被证明是完全无用的(这需要更复杂的分析) if (DEBUG && visited.size() < 10) { std::cout << " 被用于循环退出条件,是逃逸点(避免破坏循环语义)" << std::endl; } allUsesAreDead = false; break; } // 递归分析使用者的使用链 if (!isInstructionUseChainDeadRecursively(userInst, loop, visited, currentPath)) { allUsesAreDead = false; break; // 找到逃逸点,不需要继续分析 } } currentPath.erase(inst); if (allUsesAreDead && DEBUG && visited.size() < 10) { std::cout << " 指令 " << inst->getName() << " 的所有使用都是死代码" << std::endl; } return allUsesAreDead; } // 检查循环是否有副作用 bool InductionVariableEliminationContext::loopHasSideEffects(Loop* loop) { // 遍历循环中的所有指令,检查是否有副作用 for (BasicBlock* bb : loop->getBlocks()) { for (auto& inst : bb->getInstructions()) { Instruction* instPtr = inst.get(); // 使用副作用分析(如果可用) if (sideEffectAnalysis && sideEffectAnalysis->hasSideEffect(instPtr)) { if (DEBUG) { std::cout << " 循环中发现有副作用的指令: " << instPtr->getName() << std::endl; } return true; } // 如果没有副作用分析,使用保守的判断 if (!sideEffectAnalysis) { auto kind = instPtr->getKind(); // 这些指令通常有副作用 if (kind == Instruction::Kind::kCall || kind == Instruction::Kind::kStore || kind == Instruction::Kind::kReturn) { if (DEBUG) { std::cout << " 循环中发现潜在有副作用的指令: " << instPtr->getName() << std::endl; } return true; } } } } // 重要修复:检查是否为嵌套循环的外层循环 // 如果当前循环包含其他循环,那么它有潜在的副作用 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) { std::cout << " 循环 " << loop->getName() << " 无副作用" << std::endl; } return false; // 循环无副作用 } // 检查指令是否被用于循环退出条件 bool InductionVariableEliminationContext::isUsedInLoopExitCondition(Instruction* inst, Loop* loop) { // 检查指令是否被循环的退出条件使用 for (BasicBlock* exitingBB : loop->getExitingBlocks()) { auto terminatorIt = exitingBB->terminator(); if (terminatorIt != exitingBB->end()) { Instruction* terminator = terminatorIt->get(); if (terminator) { // 检查终结指令的操作数 for (size_t i = 0; i < terminator->getNumOperands(); ++i) { if (terminator->getOperand(i) == inst) { if (DEBUG) { std::cout << " 指令 " << inst->getName() << " 用于循环退出条件" << std::endl; } return true; } } // 对于条件分支,还需要检查条件指令的操作数 if (terminator->getKind() == Instruction::Kind::kCondBr) { auto* condBr = dynamic_cast(terminator); if (condBr) { Value* condition = condBr->getCondition(); if (condition == inst) { if (DEBUG) { std::cout << " 指令 " << inst->getName() << " 是循环条件" << std::endl; } return true; } // 递归检查条件指令的操作数(比如比较指令) auto* condInst = dynamic_cast(condition); if (condInst) { for (size_t i = 0; i < condInst->getNumOperands(); ++i) { if (condInst->getOperand(i) == inst) { if (DEBUG) { std::cout << " 指令 " << inst->getName() << " 用于循环条件的操作数" << std::endl; } return true; } } } } } } } } return false; } // 检查指令的结果是否未被有效使用 bool InductionVariableEliminationContext::isInstructionResultUnused(Instruction* inst, Loop* loop) { // 检查指令的所有使用 if (inst->getUses().empty()) { return true; // 没有使用,肯定是未使用 } for (auto use : inst->getUses()) { auto user = use->getUser(); auto* userInst = dynamic_cast(user); if (!userInst) { return false; // 被非指令使用,认为是有效使用 } // 如果在循环外被使用,认为是有效使用 if (!loop->contains(userInst->getParent())) { return false; } // 递归检查使用这个结果的指令是否也是死代码 // 为了避免无限递归,限制递归深度 if (!isInstructionEffectivelyDead(userInst, loop, 3)) { return false; // 存在有效使用 } } return true; // 所有使用都是无效的 } // 检查store指令是否存储到死地址(利用别名分析) bool InductionVariableEliminationContext::isStoreToDeadLocation(StoreInst* store, Loop* loop) { if (!aliasAnalysis) { return false; // 没有别名分析,保守返回false } Value* storePtr = store->getPointer(); // 检查是否存储到局部临时变量且该变量在循环外不被读取 const MemoryLocation* memLoc = aliasAnalysis->getMemoryLocation(storePtr); if (!memLoc) { return false; // 无法确定内存位置 } // 如果是局部数组且只在循环内被访问 if (memLoc->isLocalArray) { // 检查该内存位置是否在循环外被读取 for (auto* accessInst : memLoc->accessInsts) { if (accessInst->getKind() == Instruction::Kind::kLoad) { if (!loop->contains(accessInst->getParent())) { return false; // 在循环外被读取,不是死存储 } } } if (DEBUG) { std::cout << " 存储到局部数组且仅在循环内访问" << std::endl; } return true; // 存储到仅循环内访问的局部数组 } return false; } // 检查指令是否有效死代码(带递归深度限制) bool InductionVariableEliminationContext::isInstructionEffectivelyDead(Instruction* inst, Loop* loop, int maxDepth) { if (maxDepth <= 0) { return false; // 达到递归深度限制,保守返回false } // 利用副作用分析 if (sideEffectAnalysis && sideEffectAnalysis->hasSideEffect(inst)) { return false; // 有副作用的指令不是死代码 } // 检查特殊指令类型 switch (inst->getKind()) { case Instruction::Kind::kStore: // Store指令可能是死存储 return isStoreToDeadLocation(dynamic_cast(inst), loop); case Instruction::Kind::kCall: // 函数调用通常有副作用 if (sideEffectAnalysis) { return !sideEffectAnalysis->hasSideEffect(inst); } return false; // 保守地认为函数调用有效果 case Instruction::Kind::kReturn: case Instruction::Kind::kBr: case Instruction::Kind::kCondBr: // 控制流指令不是死代码 return false; default: // 其他指令检查其使用是否有效 break; } // 检查指令的使用 if (inst->getUses().empty()) { return true; // 没有使用的纯指令是死代码 } // 递归检查所有使用 for (auto use : inst->getUses()) { auto user = use->getUser(); auto* userInst = dynamic_cast(user); if (!userInst) { return false; // 被非指令使用 } if (!loop->contains(userInst->getParent())) { return false; // 在循环外被使用 } // 递归检查使用者 if (!isInstructionEffectivelyDead(userInst, loop, maxDepth - 1)) { return false; // 存在有效使用 } } return true; // 所有使用都是死代码 } // 原有的函数保持兼容,但现在使用增强的死代码分析 bool InductionVariableEliminationContext::isInstructionDeadOrInternalOnly(Instruction* inst, Loop* loop) { return isInstructionEffectivelyDead(inst, loop, 5); } // 检查store指令是否有后续的load操作 bool InductionVariableEliminationContext::hasSubsequentLoad(StoreInst* store, Loop* loop) { if (!aliasAnalysis) { // 没有别名分析,保守地假设有后续读取 return true; } Value* storePtr = store->getPointer(); const MemoryLocation* storeLoc = aliasAnalysis->getMemoryLocation(storePtr); if (!storeLoc) { // 无法确定内存位置,保守处理 return true; } // 在循环中和循环后查找对同一位置的load操作 std::vector blocksToCheck; // 添加循环内的所有基本块 for (auto* bb : loop->getBlocks()) { blocksToCheck.push_back(bb); } // 添加循环的退出块 auto exitBlocks = loop->getExitBlocks(); for (auto* exitBB : exitBlocks) { blocksToCheck.push_back(exitBB); } // 搜索load操作 for (auto* bb : blocksToCheck) { for (auto& inst : bb->getInstructions()) { if (inst->getKind() == Instruction::Kind::kLoad) { LoadInst* loadInst = static_cast(inst.get()); Value* loadPtr = loadInst->getPointer(); const MemoryLocation* loadLoc = aliasAnalysis->getMemoryLocation(loadPtr); if (loadLoc && aliasAnalysis->queryAlias(storePtr, loadPtr) != AliasType::NO_ALIAS) { // 找到可能读取同一位置的load操作 if (DEBUG) { std::cout << " 找到后续load操作: " << loadInst->getName() << std::endl; } return true; } } } } // 检查是否通过函数调用间接访问 for (auto* bb : blocksToCheck) { for (auto& inst : bb->getInstructions()) { if (inst->getKind() == Instruction::Kind::kCall) { CallInst* callInst = static_cast(inst.get()); if (callInst && sideEffectAnalysis && sideEffectAnalysis->hasSideEffect(callInst)) { // 函数调用可能间接读取内存 if (DEBUG) { std::cout << " 函数调用可能读取内存: " << callInst->getName() << std::endl; } return true; } } } } if (DEBUG) { std::cout << " 未找到后续load操作" << std::endl; } return false; // 没有找到后续读取 } // 检查指令是否在循环外有使用 bool InductionVariableEliminationContext::hasUsageOutsideLoop(Instruction* inst, Loop* loop) { for (auto use : inst->getUses()) { auto user = use->getUser(); auto* userInst = dynamic_cast(user); if (!userInst) { // 被非指令使用,可能在循环外 return true; } if (!loop->contains(userInst->getParent())) { // 在循环外被使用 if (DEBUG) { std::cout << " 指令 " << inst->getName() << " 在循环外被 " << userInst->getName() << " 使用" << std::endl; } return true; } } return false; // 没有循环外使用 } // 检查store指令是否在循环外有后续的load操作 bool InductionVariableEliminationContext::hasSubsequentLoadOutsideLoop(StoreInst* store, Loop* loop) { if (!aliasAnalysis) { // 没有别名分析,保守地假设有后续读取 return true; } Value* storePtr = store->getPointer(); // 检查循环的退出块及其后继 auto exitBlocks = loop->getExitBlocks(); std::set visitedBlocks; for (auto* exitBB : exitBlocks) { if (hasLoadInSubtree(exitBB, storePtr, visitedBlocks)) { if (DEBUG) { std::cout << " 找到循环外的后续load操作" << std::endl; } return true; } } return false; // 没有找到循环外的后续读取 } // 递归检查基本块子树中是否有对指定位置的load操作 bool InductionVariableEliminationContext::hasLoadInSubtree(BasicBlock* bb, Value* ptr, std::set& visited) { if (visited.count(bb) > 0) { return false; // 已经访问过,避免无限循环 } visited.insert(bb); // 检查当前基本块中的指令 for (auto& inst : bb->getInstructions()) { if (inst->getKind() == Instruction::Kind::kLoad) { LoadInst* loadInst = static_cast(inst.get()); if (aliasAnalysis && aliasAnalysis->queryAlias(ptr, loadInst->getPointer()) != AliasType::NO_ALIAS) { return true; // 找到了对相同或别名位置的load } } else if (inst->getKind() == Instruction::Kind::kCall) { // 函数调用可能间接读取内存 CallInst* callInst = static_cast(inst.get()); if (sideEffectAnalysis && sideEffectAnalysis->hasSideEffect(callInst)) { return true; // 保守地认为函数调用可能读取内存 } } } // 递归检查后继基本块(限制深度以避免过度搜索) static int searchDepth = 0; if (searchDepth < 10) { // 限制搜索深度 searchDepth++; for (auto* succ : bb->getSuccessors()) { if (hasLoadInSubtree(succ, ptr, visited)) { searchDepth--; return true; } } searchDepth--; } return false; } std::vector InductionVariableEliminationContext::collectRelatedInstructions( PhiInst* phiInst, Loop* loop) { std::vector relatedInsts; // 收集所有与该归纳变量相关的指令 for (auto use : phiInst->getUses()) { auto user = use->getUser(); auto* userInst = dynamic_cast(user); if (userInst && loop->contains(userInst->getParent())) { relatedInsts.push_back(userInst); } } return relatedInsts; } void InductionVariableEliminationContext::analyzeSafetyForElimination() { if (DEBUG) { std::cout << " === Phase 2: Analyzing Safety for Elimination ===" << std::endl; } // 为每个死归纳变量检查消除的安全性 for (auto& deadIV : deadIVs) { bool isSafe = isSafeToEliminate(deadIV.get()); deadIV->canEliminate = isSafe; if (DEBUG) { std::cout << " Dead IV " << deadIV->phiInst->getName() << ": " << (isSafe ? "SAFE" : "UNSAFE") << " to eliminate" << std::endl; } } if (DEBUG) { size_t safeCount = 0; for (const auto& deadIV : deadIVs) { if (deadIV->canEliminate) safeCount++; } std::cout << " === End Phase 2: " << safeCount << " of " << deadIVs.size() << " variables are safe to eliminate ===" << std::endl; } } bool InductionVariableEliminationContext::isSafeToEliminate(const DeadInductionVariable* deadIV) { // 1. 确保归纳变量在循环头 if (deadIV->phiInst->getParent() != deadIV->containingLoop->getHeader()) { if (DEBUG) { std::cout << " Unsafe: phi not in loop header" << std::endl; } return false; } // 2. 确保相关指令都在循环内 for (auto* inst : deadIV->relatedInsts) { if (!deadIV->containingLoop->contains(inst->getParent())) { if (DEBUG) { std::cout << " Unsafe: related instruction outside loop" << std::endl; } return false; } } // 3. 确保没有副作用 for (auto* inst : deadIV->relatedInsts) { if (sideEffectAnalysis) { // 使用副作用分析进行精确检查 if (sideEffectAnalysis->hasSideEffect(inst)) { if (DEBUG) { std::cout << " Unsafe: related instruction " << inst->getName() << " has side effects" << std::endl; } return false; } } else { // 没有副作用分析时使用保守策略:只允许基本算术运算 auto kind = inst->getKind(); if (kind != Instruction::Kind::kAdd && kind != Instruction::Kind::kSub && kind != Instruction::Kind::kMul) { if (DEBUG) { std::cout << " Unsafe: related instruction may have side effects (conservative)" << std::endl; } return false; } } } // 4. 确保不影响循环的退出条件 for (BasicBlock* exitingBB : deadIV->containingLoop->getExitingBlocks()) { auto terminatorIt = exitingBB->terminator(); if (terminatorIt != exitingBB->end()) { Instruction* terminator = terminatorIt->get(); if (terminator) { for (size_t i = 0; i < terminator->getNumOperands(); ++i) { if (terminator->getOperand(i) == deadIV->phiInst) { if (DEBUG) { std::cout << " Unsafe: phi used in loop exit condition" << std::endl; } return false; } } } } } return true; } bool InductionVariableEliminationContext::performInductionVariableElimination() { if (DEBUG) { std::cout << " === Phase 3: Performing Induction Variable Elimination ===" << std::endl; } bool modified = false; for (auto& deadIV : deadIVs) { if (!deadIV->canEliminate) { continue; } if (DEBUG) { std::cout << " Eliminating dead IV: " << deadIV->phiInst->getName() << std::endl; } if (eliminateDeadInductionVariable(deadIV.get())) { if (DEBUG) { std::cout << " Successfully eliminated: " << deadIV->phiInst->getName() << std::endl; } modified = true; } else { if (DEBUG) { std::cout << " Failed to eliminate: " << deadIV->phiInst->getName() << std::endl; } } } if (DEBUG) { std::cout << " === End Phase 3: " << (modified ? "Eliminations performed" : "No eliminations") << " ===" << std::endl; } return modified; } bool InductionVariableEliminationContext::eliminateDeadInductionVariable(DeadInductionVariable* deadIV) { // 1. 删除所有相关指令 for (auto* inst : deadIV->relatedInsts) { auto* bb = inst->getParent(); auto it = bb->findInstIterator(inst); if (it != bb->end()) { SysYIROptUtils::usedelete(it); // bb->getInstructions().erase(it); if (DEBUG) { std::cout << " Removed related instruction: " << inst->getName() << std::endl; } } } // 2. 删除 phi 指令 auto* bb = deadIV->phiInst->getParent(); auto it = bb->findInstIterator(deadIV->phiInst); if (it != bb->end()) { SysYIROptUtils::usedelete(it); // bb->getInstructions().erase(it); if (DEBUG) { std::cout << " Removed phi instruction: " << deadIV->phiInst->getName() << std::endl; } return true; } return false; } void InductionVariableEliminationContext::printDebugInfo() { if (!DEBUG) return; std::cout << "\n=== Induction Variable Elimination Summary ===" << std::endl; std::cout << "Total dead IVs found: " << deadIVs.size() << std::endl; size_t eliminatedCount = 0; for (auto& [loop, loopDeadIVs] : loopToDeadIVs) { size_t loopEliminatedCount = 0; for (auto* deadIV : loopDeadIVs) { if (deadIV->canEliminate) { loopEliminatedCount++; eliminatedCount++; } } if (loopEliminatedCount > 0) { std::cout << "Loop " << loop->getName() << ": " << loopEliminatedCount << " of " << loopDeadIVs.size() << " IVs eliminated" << std::endl; } } std::cout << "Total eliminated: " << eliminatedCount << " of " << deadIVs.size() << std::endl; std::cout << "=============================================" << std::endl; } } // namespace sysy