#include "LoopNormalization.h" #include "Dom.h" #include "Loop.h" #include "SysYIROptUtils.h" #include #include #include // 使用全局调试开关 extern int DEBUG; namespace sysy { // 定义 Pass 的唯一 ID void *LoopNormalizationPass::ID = (void *)&LoopNormalizationPass::ID; bool LoopNormalizationPass::runOnFunction(Function *F, AnalysisManager &AM) { if (F->getBasicBlocks().empty()) { return false; // 空函数 } if (DEBUG) std::cout << "Running LoopNormalizationPass on function: " << F->getName() << std::endl; // 获取并缓存所有需要的分析结果 loopAnalysis = AM.getAnalysisResult(F); if (!loopAnalysis || !loopAnalysis->hasLoops()) { if (DEBUG) std::cout << "No loops found in function " << F->getName() << ", skipping normalization" << std::endl; return false; // 没有循环需要规范化 } domTree = AM.getAnalysisResult(F); if (!domTree) { std::cerr << "Error: DominatorTree not available for function " << F->getName() << std::endl; return false; } // 重置统计信息 stats = NormalizationStats(); bool modified = false; const auto& allLoops = loopAnalysis->getAllLoops(); stats.totalLoops = allLoops.size(); if (DEBUG) { std::cout << "Found " << stats.totalLoops << " loops to analyze for normalization" << std::endl; } // 按循环深度从外到内处理,确保外层循环先规范化 std::vector sortedLoops; for (const auto& loop_ptr : allLoops) { sortedLoops.push_back(loop_ptr.get()); } std::sort(sortedLoops.begin(), sortedLoops.end(), [](Loop* a, Loop* b) { return a->getLoopDepth() < b->getLoopDepth(); // 按深度升序排列 }); // 逐个规范化循环 for (Loop* loop : sortedLoops) { if (needsPreheader(loop)) { stats.loopsNeedingPreheader++; if (DEBUG) { std::cout << " Loop " << loop->getName() << " needs preheader (depth=" << loop->getLoopDepth() << ")" << std::endl; } if (normalizeLoop(loop)) { modified = true; stats.loopsNormalized++; // 验证规范化结果 if (!validateNormalization(loop)) { std::cerr << "Warning: Loop normalization validation failed for loop " << loop->getName() << std::endl; } } } else { if (DEBUG) { auto* preheader = getExistingPreheader(loop); if (preheader) { std::cout << " Loop " << loop->getName() << " already has preheader: " << preheader->getName() << std::endl; } } } } if (DEBUG && modified) { printStats(F); } return modified; } bool LoopNormalizationPass::normalizeLoop(Loop* loop) { if (DEBUG) std::cout << " Normalizing loop: " << loop->getName() << std::endl; // 创建前置块 BasicBlock* preheader = createPreheaderForLoop(loop); if (!preheader) { if (DEBUG) std::cout << " Failed to create preheader for loop " << loop->getName() << std::endl; return false; } stats.preheadersCreated++; if (DEBUG) { std::cout << " Successfully created preheader " << preheader->getName() << " for loop " << loop->getName() << std::endl; } return true; } BasicBlock* LoopNormalizationPass::createPreheaderForLoop(Loop* loop) { BasicBlock* header = loop->getHeader(); if (!header) { if (DEBUG) std::cerr << " Error: Loop has no header block" << std::endl; return nullptr; } // 获取循环外的前驱块 std::vector externalPreds = getExternalPredecessors(loop); if (externalPreds.empty()) { if (DEBUG) std::cout << " Loop " << loop->getName() << " has no external predecessors" << std::endl; return nullptr; } if (DEBUG) { std::cout << " Found " << externalPreds.size() << " external predecessors for loop " << loop->getName() << std::endl; for (auto* pred : externalPreds) { std::cout << " External pred: " << pred->getName() << std::endl; } } // 生成前置块名称 std::string preheaderName = generatePreheaderName(loop); // 创建新的前置块 Function* parentFunction = header->getParent(); BasicBlock* preheader = parentFunction->addBasicBlock(preheaderName, header); if (!preheader) { if (DEBUG) std::cerr << " Error: Failed to create basic block " << preheaderName << std::endl; return nullptr; } // 在前置块中创建跳转指令到循环头部 builder->setPosition(preheader, preheader->end()); UncondBrInst* br = builder->createUncondBrInst(header); // 更新preheader的CFG关系 preheader->addSuccessor(header); header->addPredecessor(preheader); if(DEBUG) { std::cout << " Created preheader " << preheader->getName() << " with unconditional branch to " << header->getName() << std::endl; } // 重定向外部前驱到新的前置块 redirectExternalPredecessors(loop, preheader, header, externalPreds); // 更新PHI节点 updatePhiNodesForPreheader(header, preheader, externalPreds); // 更新支配树关系 updateDominatorRelations(preheader, loop); // 重要:更新循环对象的前置块信息 // 这样后续的优化遍可以通过 loop->getPreHeader() 获取到新创建的前置块 loop->setPreHeader(preheader); if (DEBUG) { std::cout << " Updated loop object: preheader set to " << preheader->getName() << std::endl; } return preheader; } bool LoopNormalizationPass::needsPreheader(Loop* loop) { // 检查是否已有合适的前置块 if (getExistingPreheader(loop) != nullptr) { return false; } // 检查是否有外部前驱(如果没有外部前驱,不需要前置块) std::vector externalPreds = getExternalPredecessors(loop); if (externalPreds.empty()) { return false; } // 基于结构性需求判断: // 1. 如果有多个外部前驱,必须创建前置块来合并它们 // 2. 如果单个外部前驱不适合作为前置块,需要创建新的前置块 return (externalPreds.size() > 1) || !isSuitableAsPreheader(externalPreds[0], loop); } BasicBlock* LoopNormalizationPass::getExistingPreheader(Loop* loop) { BasicBlock* header = loop->getHeader(); if (!header) return nullptr; std::vector externalPreds = getExternalPredecessors(loop); // 如果只有一个外部前驱,且适合作为前置块,则返回它 if (externalPreds.size() == 1 && isSuitableAsPreheader(externalPreds[0], loop)) { return externalPreds[0]; } return nullptr; } void LoopNormalizationPass::updateDominatorRelations(BasicBlock* newBlock, Loop* loop) { // 由于在getAnalysisUsage中声明了DominatorTree会失效, // PassManager会在本遍运行后自动将支配树结果标记为失效, // 后续需要支配树的Pass会触发重新计算,所以这里无需手动更新 if (DEBUG) { BasicBlock* header = loop->getHeader(); std::cout << " DominatorTree marked for invalidation - new preheader " << newBlock->getName() << " will dominate " << header->getName() << " after recomputation by PassManager" << std::endl; } } void LoopNormalizationPass::redirectExternalPredecessors(Loop* loop, BasicBlock* preheader, BasicBlock* header, const std::vector& externalPreds) { // std::vector externalPreds = getExternalPredecessors(loop); if (DEBUG) { std::cout << " Redirecting " << externalPreds.size() << " external predecessors" << std::endl; } for (BasicBlock* pred : externalPreds) { // 获取前驱块的终止指令 auto termIt = pred->terminator(); if (termIt == pred->end()) continue; Instruction* terminator = termIt->get(); if (!terminator) continue; // 更新跳转目标 if (auto* br = dynamic_cast(terminator)) { // 无条件跳转 if (br->getBlock() == header) { if(DEBUG){ std::cout << " Updating unconditional branch from " << br->getBlock()->getName() << " to " << preheader->getName() << std::endl; } // 需要更新操作数 br->setOperand(0, preheader); // 更新CFG关系 header->removePredecessor(pred); preheader->addPredecessor(pred); pred->removeSuccessor(header); pred->addSuccessor(preheader); } } else if (auto* condBr = dynamic_cast(terminator)) { // 条件跳转 bool updated = false; if (condBr->getThenBlock() == header) { condBr->setOperand(1, preheader); // 第1个操作数是then分支 updated = true; } if (condBr->getElseBlock() == header) { condBr->setOperand(2, preheader); // 第2个操作数是else分支 updated = true; } if (updated) { // 更新CFG关系 header->removePredecessor(pred); preheader->addPredecessor(pred); pred->removeSuccessor(header); pred->addSuccessor(preheader); if (DEBUG) { std::cout << " Updated conditional branch from " << pred->getName() << " to " << preheader->getName() << std::endl; } } } } } std::string LoopNormalizationPass::generatePreheaderName(Loop* loop) { std::ostringstream oss; oss << loop->getName() << "_preheader"; return oss.str(); } bool LoopNormalizationPass::validateNormalization(Loop* loop) { BasicBlock* header = loop->getHeader(); if (!header) return false; // 检查循环是否现在有唯一的外部前驱 std::vector externalPreds = getExternalPredecessors(loop); if (externalPreds.size() != 1) { if (DEBUG) std::cout << " Validation failed: Loop " << loop->getName() << " has " << externalPreds.size() << " external predecessors (expected 1)" << std::endl; return false; } // 检查外部前驱是否适合作为前置块 BasicBlock* preheader = externalPreds[0]; if (!isSuitableAsPreheader(preheader, loop)) { if (DEBUG) std::cout << " Validation failed: External predecessor " << preheader->getName() << " is not suitable as preheader" << std::endl; return false; } // 额外验证:检查CFG连接性 if (!preheader->hasSuccessor(header)) { if (DEBUG) std::cout << " Validation failed: Preheader " << preheader->getName() << " is not connected to header " << header->getName() << std::endl; return false; } if (!header->hasPredecessor(preheader)) { if (DEBUG) std::cout << " Validation failed: Header " << header->getName() << " does not have preheader " << preheader->getName() << " as predecessor" << std::endl; return false; } if (DEBUG) std::cout << " Validation passed for loop " << loop->getName() << std::endl; return true; } std::vector LoopNormalizationPass::getExternalPredecessors(Loop* loop) { std::vector externalPreds; BasicBlock* header = loop->getHeader(); if (!header) return externalPreds; for (BasicBlock* pred : header->getPredecessors()) { if (!loop->contains(pred)) { externalPreds.push_back(pred); } } return externalPreds; } bool LoopNormalizationPass::isSuitableAsPreheader(BasicBlock* block, Loop* loop) { if (!block) return false; // 检查该块是否只有一个后继,且后继是循环头部 auto successors = block->getSuccessors(); if (successors.size() != 1) { return false; } if (successors[0] != loop->getHeader()) { return false; } // 检查该块是否不包含复杂的控制流 // 理想的前置块应该只包含简单的跳转指令 size_t instCount = 0; for (const auto& inst : block->getInstructions()) { instCount++; // 如果指令过多,可能不适合作为前置块 if (instCount > 10) { // 阈值可调整 return false; } } return true; } void LoopNormalizationPass::updatePhiNodesForPreheader(BasicBlock* header, BasicBlock* preheader, const std::vector& oldPreds) { if (DEBUG) { std::cout << " Updating PHI nodes in header " << header->getName() << " for new preheader " << preheader->getName() << std::endl; } std::vector phisToRemove; // 需要删除的PHI节点 for (auto& inst : header->getInstructions()) { if (auto* phi = dynamic_cast(inst.get())) { if (DEBUG) { std::cout << " Processing PHI node: " << phi->getName() << std::endl; } // 收集来自外部前驱的值 - 需要保持原始的映射关系 std::map externalValues; for (BasicBlock* oldPred : oldPreds) { Value* value = phi->getValfromBlk(oldPred); if (value) { externalValues[oldPred] = value; } } // 处理PHI节点的更新 if (externalValues.size() > 1) { // 多个外部前驱:在前置块中创建新的PHI节点 builder->setPosition(preheader, preheader->getInstructions().begin()); std::vector values; std::vector blocks; for (auto& [block, value] : externalValues) { values.push_back(value); blocks.push_back(block); } PhiInst* newPhi = builder->createPhiInst(phi->getType(), values, blocks); // 移除所有外部前驱的条目 for (BasicBlock* oldPred : oldPreds) { phi->removeIncomingBlock(oldPred); } // 添加来自新前置块的条目 phi->addIncoming(newPhi, preheader); } else if (externalValues.size() == 1) { // 单个外部前驱:直接重新映射 Value* value = externalValues.begin()->second; // 移除旧的外部前驱条目 for (BasicBlock* oldPred : oldPreds) { phi->removeIncomingBlock(oldPred); } // 添加来自新前置块的条目 phi->addIncoming(value, preheader); // 检查PHI节点是否只剩下一个条目(只来自前置块) if (phi->getNumIncomingValues() == 1) { if (DEBUG) { std::cout << " PHI node " << phi->getName() << " now has only one incoming value, scheduling for removal" << std::endl; } // 用单一值替换所有使用 Value* singleValue = phi->getIncomingValue(0u); phi->replaceAllUsesWith(singleValue); phisToRemove.push_back(phi); } } else { // 没有外部值的PHI节点:检查是否需要更新 // 这种PHI节点只有循环内的边,通常不需要修改 // 但我们仍然需要检查是否只有一个条目 if (phi->getNumIncomingValues() == 1) { if (DEBUG) { std::cout << " PHI node " << phi->getName() << " has only one incoming value (no external), scheduling for removal" << std::endl; } // 用单一值替换所有使用 Value* singleValue = phi->getIncomingValue(0u); phi->replaceAllUsesWith(singleValue); phisToRemove.push_back(phi); } } if (DEBUG && std::find(phisToRemove.begin(), phisToRemove.end(), phi) == phisToRemove.end()) { std::cout << " Updated PHI node with " << externalValues.size() << " external values, total incoming: " << phi->getNumIncomingValues() << std::endl; } } } // 删除标记为移除的PHI节点 for (PhiInst* phi : phisToRemove) { if (DEBUG) { std::cout << " Removing redundant PHI node: " << phi->getName() << std::endl; } SysYIROptUtils::usedelete(phi); } // 更新统计信息 stats.redundantPhisRemoved += phisToRemove.size(); if (DEBUG && !phisToRemove.empty()) { std::cout << " Removed " << phisToRemove.size() << " redundant PHI nodes" << std::endl; } } void LoopNormalizationPass::printStats(Function* F) { std::cout << "\n--- Loop Normalization Statistics for Function: " << F->getName() << " ---" << std::endl; std::cout << "Total loops analyzed: " << stats.totalLoops << std::endl; std::cout << "Loops needing preheader: " << stats.loopsNeedingPreheader << std::endl; std::cout << "Preheaders created: " << stats.preheadersCreated << std::endl; std::cout << "Loops successfully normalized: " << stats.loopsNormalized << std::endl; std::cout << "Redundant PHI nodes removed: " << stats.redundantPhisRemoved << std::endl; if (stats.totalLoops > 0) { double normalizationRate = (double)stats.loopsNormalized / stats.totalLoops * 100.0; std::cout << "Normalization rate: " << normalizationRate << "%" << std::endl; } std::cout << "---------------------------------------------------------------" << std::endl; } void LoopNormalizationPass::getAnalysisUsage(std::set &analysisDependencies, std::set &analysisInvalidations) const { // LoopNormalization依赖的分析 analysisDependencies.insert(&LoopAnalysisPass::ID); // 循环结构分析 analysisDependencies.insert(&DominatorTreeAnalysisPass::ID); // 支配树分析 // LoopNormalization会修改CFG结构,因此会使以下分析失效 analysisInvalidations.insert(&DominatorTreeAnalysisPass::ID); // 支配树需要重新计算 // 注意:我们不让循环结构分析失效,原因如下: // 1. 循环规范化只添加前置块,不改变循环的核心结构(头部、体、回边) // 2. 我们会手动更新Loop对象的前置块信息(通过loop->setPreHeader()) // 3. 让循环分析失效并重新计算的成本较高且不必要 // 4. 后续优化遍可以正确获取到更新后的前置块信息 // // 如果未来有更复杂的循环结构修改,可能需要考虑让循环分析失效: // analysisInvalidations.insert(&LoopAnalysisPass::ID); } } // namespace sysy