diff --git a/src/include/midend/Pass/Analysis/Loop.h b/src/include/midend/Pass/Analysis/Loop.h index 5895152..7df8132 100644 --- a/src/include/midend/Pass/Analysis/Loop.h +++ b/src/include/midend/Pass/Analysis/Loop.h @@ -60,7 +60,7 @@ public: void setParentLoop(Loop *loop) { ParentLoop = loop; } void addNestedLoop(Loop *loop) { NestedLoops.push_back(loop); } void setLoopLevel(int level) { Level = level; } - + void clearNestedLoops() { NestedLoops.clear(); } private: BasicBlock *Header; // 循环头基本块 std::set LoopBlocks; // 循环体包含的基本块集合 @@ -119,6 +119,8 @@ public: // --- 供 LoopAnalysisPass 内部调用的方法,用于构建 LoopAnalysisResult 对象 --- void addOutermostLoop(Loop *loop) { OutermostLoops.push_back(loop); } void addInnermostLoop(Loop *loop) { InnermostLoops.push_back(loop); } + void clearOutermostLoops() { OutermostLoops.clear(); } + void clearInnermostLoops() { InnermostLoops.clear(); } private: Function *AssociatedFunction; // 结果关联的函数 diff --git a/src/midend/Pass/Analysis/Loop.cpp b/src/midend/Pass/Analysis/Loop.cpp index 684d19c..653db14 100644 --- a/src/midend/Pass/Analysis/Loop.cpp +++ b/src/midend/Pass/Analysis/Loop.cpp @@ -1,6 +1,8 @@ +// Loop.cpp (完整内容,包含所有修改) #include "Dom.h" // 确保包含 DominatorTreeAnalysisPass 的定义 -#include "Loop.h" +#include "Loop.h" // #include +#include // 用于 BFS 遍历设置循环层级 namespace sysy { @@ -33,10 +35,11 @@ bool LoopAnalysisPass::runOnFunction(Function *F, AnalysisManager &AM) { // 回边 (N -> D) 定义:D 支配 N std::vector> backEdges; for (auto &BB : F->getBasicBlocks()) { - for (BasicBlock *Succ : BB->getSuccessors()) { - if (DT->getDominators(BB.get()) && DT->getDominators(BB.get())->count(Succ)) { + auto Blcok = BB.get(); + for (BasicBlock *Succ : Blcok->getSuccessors()) { + if (DT->getDominators(Blcok) && DT->getDominators(Blcok)->count(Succ)) { // Succ 支配 BB,所以 (BB -> Succ) 是一条回边 - backEdges.push_back({BB.get(), Succ}); + backEdges.push_back({Blcok, Succ}); } } } @@ -94,7 +97,8 @@ bool LoopAnalysisPass::runOnFunction(Function *F, AnalysisManager &AM) { BasicBlock *candidatePreHeader = nullptr; int externalPredecessorCount = 0; for (BasicBlock *predOfHeader : D->getPredecessors()) { - if (loopBlocks.find(predOfHeader) == loopBlocks.end()) { + // 使用 currentLoop->contains() 来检查前驱是否在循环体内 + if (!currentLoop->contains(predOfHeader)) { // 如果前驱不在循环体内,则是一个外部前驱 externalPredecessorCount++; candidatePreHeader = predOfHeader; @@ -104,6 +108,8 @@ bool LoopAnalysisPass::runOnFunction(Function *F, AnalysisManager &AM) { if (externalPredecessorCount == 1) { currentLoop->setPreHeader(candidatePreHeader); } else { + assert(externalPredecessorCount == 0 || externalPredecessorCount > 1 && + "Loop header should have exactly one external predecessor or none."); // TODO: 如果有多个外部前驱或没有,这里应该插入新的基本块作为前置块, // 并调整控制流。这会修改 IR,需要返回 true。 // 目前,我们只是简单地不设置 preHeader。 @@ -112,64 +118,101 @@ bool LoopAnalysisPass::runOnFunction(Function *F, AnalysisManager &AM) { CurrentResult->addLoop(std::move(currentLoop)); } - // 步骤 5: 处理嵌套循环 (确定父子关系) - // 遍历所有已识别的循环,确定它们的嵌套关系 + // 步骤 5: 处理嵌套循环 (确定父子关系和层级) const auto &allLoops = CurrentResult->getAllLoops(); - for (const auto &outerLoop_ptr : allLoops) { - Loop *outerLoop = outerLoop_ptr.get(); - for (const auto &innerLoop_ptr : allLoops) { - Loop *innerLoop = innerLoop_ptr.get(); + + // 1. 首先,清除所有循环已设置的父子关系和嵌套子循环列表,确保重新计算 + for (const auto &loop_ptr : allLoops) { + loop_ptr->setParentLoop(nullptr); // 清除父指针 + loop_ptr->clearNestedLoops(); // 清除子循环列表 + loop_ptr->setLoopLevel(-1); // 重置循环层级 + } + + // 2. 遍历所有循环,为每个循环找到其直接父循环并建立关系 + for (const auto &innerLoop_ptr : allLoops) { + Loop *innerLoop = innerLoop_ptr.get(); + Loop *immediateParent = nullptr; // 用于存储当前 innerLoop 的最近父循环 + + for (const auto &outerLoop_ptr : allLoops) { + Loop *outerLoop = outerLoop_ptr.get(); // 一个循环不能是它自己的父循环 if (outerLoop == innerLoop) { continue; } - // 判断 innerLoop 是否嵌套在 outerLoop 内 - // 条件:innerLoop 的头被 outerLoop 的头支配,且 innerLoop 的所有块都在 outerLoop 内 - if (DT->getDominators(innerLoop->getHeader()) && - DT->getDominators(innerLoop->getHeader())->count(outerLoop->getHeader())) { - bool allInnerBlocksInOuter = true; - for (BasicBlock *innerBB : innerLoop->getBlocks()) { - if (!outerLoop->contains(innerBB)) { - allInnerBlocksInOuter = false; - break; - } - } - if (allInnerBlocksInOuter) { - // 找到了一个嵌套关系,但还需要确定是直接嵌套还是多层嵌套 - // 简单方法:如果 innerLoop 没有其他父循环,或者这个 outerLoop 是其最近的父循环 - // 更精确的做法是找支配 innerLoop 头的,且被 innerLoop 头支配的最近的循环头 + // 检查 outerLoop 是否包含 innerLoop 的所有条件: + // Condition 1: outerLoop 的头支配 innerLoop 的头 + if (!(DT->getDominators(innerLoop->getHeader()) && + DT->getDominators(innerLoop->getHeader())->count(outerLoop->getHeader()))) { + continue; // outerLoop 不支配 innerLoop 的头,因此不是一个外层循环 + } - // 简单的直接嵌套判断:如果 innerLoop 还没有父循环,或者当前 outerLoop 比现有父循环更“紧密” - if (!innerLoop->getParentLoop()) { // 还没设置父循环 - innerLoop->setParentLoop(outerLoop); - outerLoop->addNestedLoop(innerLoop); - } else { - // 如果 innerLoop 已经有父循环,判断 outerLoop 是否是更直接的父循环 - // (outerLoop 的头是否支配 innerLoop->getParentLoop() 的头) - if (DT->getDominators(innerLoop->getParentLoop()->getHeader()) && - DT->getDominators(innerLoop->getParentLoop()->getHeader())->count(outerLoop->getHeader())) { - // outerLoop 支配 innerLoop 现有父循环的头,说明 outerLoop 更外层 - // 保持现有父循环不变 - } else if (DT->getDominators(outerLoop->getHeader()) && - DT->getDominators(outerLoop->getHeader())->count(innerLoop->getParentLoop()->getHeader())) { - // outerLoop 被 innerLoop 现有父循环的头支配,说明 outerLoop 更内层 - // 这种情况不应该发生,因为我们已经判断 outerLoop 支配 innerLoop 的头 - // 可能是 bug 或复杂情况,需要进一步分析 - } else { - // 否则,outerLoop 可能是更直接的父循环,需要更新 - // TODO 用更复杂的算法来构建循环树 - // innerLoop->getParentLoop()->NestedLoops.erase( - // std::remove(innerLoop->getParentLoop()->NestedLoops.begin(), - // innerLoop->getParentLoop()->NestedLoops.Loops.end(), innerLoop), - // innerLoop->getParentLoop()->NestedLoops.end()); - // innerLoop->setParentLoop(outerLoop); - outerLoop->addNestedLoop(innerLoop); - } - } + // Condition 2: innerLoop 的所有基本块都在 outerLoop 的基本块集合中 + bool allInnerBlocksInOuter = true; + for (BasicBlock *innerBB : innerLoop->getBlocks()) { + if (!outerLoop->contains(innerBB)) { // + allInnerBlocksInOuter = false; + break; } } + if (!allInnerBlocksInOuter) { + continue; // outerLoop 不包含 innerLoop 的所有块 + } + + // 到此为止,outerLoop 已经被确认为 innerLoop 的一个“候选父循环”(即它包含了 innerLoop) + + if (immediateParent == nullptr) { + // 这是找到的第一个候选父循环 + immediateParent = outerLoop; + } else { + // 已经有了一个 immediateParent,需要判断哪个是更“紧密”的父循环 + // 更紧密的父循环是那个包含另一个候选父循环的。 + // 如果当前的 immediateParent 包含了 outerLoop 的头,那么 outerLoop 是更深的循环(更接近 innerLoop) + if (immediateParent->contains(outerLoop->getHeader())) { // + immediateParent = outerLoop; // outerLoop 是更紧密的父循环 + } + // 否则(outerLoop 包含了 immediateParent 的头),说明 immediateParent 更紧密,保持不变 + // 或者它们互不包含(不应该发生,因为它们都包含了 innerLoop),也保持 immediateParent + } + } + + // 设置 innerLoop 的直接父循环,并添加到父循环的嵌套列表中 + if (immediateParent) { + innerLoop->setParentLoop(immediateParent); + immediateParent->addNestedLoop(innerLoop); + } + } + + // 3. 计算循环层级 (Level) 并填充最外层/最内层循环列表 + std::queue q_level; + + // 查找所有最外层循环(没有父循环的),设置其层级为0,并加入队列 + CurrentResult->clearOutermostLoops(); // 清空最外层循环列表 + for (const auto &loop_ptr : allLoops) { + if (loop_ptr->isOutermost()) { + loop_ptr->setLoopLevel(0); + q_level.push(loop_ptr.get()); + CurrentResult->addOutermostLoop(loop_ptr.get()); + } + } + + // 使用 BFS 遍历循环树,计算所有嵌套循环的层级 + while (!q_level.empty()) { + Loop *current = q_level.front(); + q_level.pop(); + + for (Loop *nestedLoop : current->getNestedLoops()) { + nestedLoop->setLoopLevel(current->getLoopLevel() + 1); + q_level.push(nestedLoop); + } + } + + // 填充最内层循环列表 + CurrentResult->clearInnermostLoops(); // 清空最内层循环列表 + for (const auto &loop_ptr : allLoops) { + if (loop_ptr->isInnermost()) { + CurrentResult->addInnermostLoop(loop_ptr.get()); } }