[midend-LoopAnalysis]增加维护循环层级的逻辑,修改父子循环关系求解的逻辑。
This commit is contained in:
@@ -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<BasicBlock *> 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; // 结果关联的函数
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// Loop.cpp (完整内容,包含所有修改)
|
||||
#include "Dom.h" // 确保包含 DominatorTreeAnalysisPass 的定义
|
||||
#include "Loop.h"
|
||||
#include "Loop.h" //
|
||||
#include <iostream>
|
||||
#include <queue> // 用于 BFS 遍历设置循环层级
|
||||
|
||||
namespace sysy {
|
||||
|
||||
@@ -33,10 +35,11 @@ bool LoopAnalysisPass::runOnFunction(Function *F, AnalysisManager &AM) {
|
||||
// 回边 (N -> D) 定义:D 支配 N
|
||||
std::vector<std::pair<BasicBlock *, BasicBlock *>> 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<Loop *> 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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user