[midend-LoopAnalysis]增加维护循环层级的逻辑,修改父子循环关系求解的逻辑。
This commit is contained in:
@@ -60,7 +60,7 @@ public:
|
|||||||
void setParentLoop(Loop *loop) { ParentLoop = loop; }
|
void setParentLoop(Loop *loop) { ParentLoop = loop; }
|
||||||
void addNestedLoop(Loop *loop) { NestedLoops.push_back(loop); }
|
void addNestedLoop(Loop *loop) { NestedLoops.push_back(loop); }
|
||||||
void setLoopLevel(int level) { Level = level; }
|
void setLoopLevel(int level) { Level = level; }
|
||||||
|
void clearNestedLoops() { NestedLoops.clear(); }
|
||||||
private:
|
private:
|
||||||
BasicBlock *Header; // 循环头基本块
|
BasicBlock *Header; // 循环头基本块
|
||||||
std::set<BasicBlock *> LoopBlocks; // 循环体包含的基本块集合
|
std::set<BasicBlock *> LoopBlocks; // 循环体包含的基本块集合
|
||||||
@@ -119,6 +119,8 @@ public:
|
|||||||
// --- 供 LoopAnalysisPass 内部调用的方法,用于构建 LoopAnalysisResult 对象 ---
|
// --- 供 LoopAnalysisPass 内部调用的方法,用于构建 LoopAnalysisResult 对象 ---
|
||||||
void addOutermostLoop(Loop *loop) { OutermostLoops.push_back(loop); }
|
void addOutermostLoop(Loop *loop) { OutermostLoops.push_back(loop); }
|
||||||
void addInnermostLoop(Loop *loop) { InnermostLoops.push_back(loop); }
|
void addInnermostLoop(Loop *loop) { InnermostLoops.push_back(loop); }
|
||||||
|
void clearOutermostLoops() { OutermostLoops.clear(); }
|
||||||
|
void clearInnermostLoops() { InnermostLoops.clear(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Function *AssociatedFunction; // 结果关联的函数
|
Function *AssociatedFunction; // 结果关联的函数
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
|
// Loop.cpp (完整内容,包含所有修改)
|
||||||
#include "Dom.h" // 确保包含 DominatorTreeAnalysisPass 的定义
|
#include "Dom.h" // 确保包含 DominatorTreeAnalysisPass 的定义
|
||||||
#include "Loop.h"
|
#include "Loop.h" //
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <queue> // 用于 BFS 遍历设置循环层级
|
||||||
|
|
||||||
namespace sysy {
|
namespace sysy {
|
||||||
|
|
||||||
@@ -33,10 +35,11 @@ bool LoopAnalysisPass::runOnFunction(Function *F, AnalysisManager &AM) {
|
|||||||
// 回边 (N -> D) 定义:D 支配 N
|
// 回边 (N -> D) 定义:D 支配 N
|
||||||
std::vector<std::pair<BasicBlock *, BasicBlock *>> backEdges;
|
std::vector<std::pair<BasicBlock *, BasicBlock *>> backEdges;
|
||||||
for (auto &BB : F->getBasicBlocks()) {
|
for (auto &BB : F->getBasicBlocks()) {
|
||||||
for (BasicBlock *Succ : BB->getSuccessors()) {
|
auto Blcok = BB.get();
|
||||||
if (DT->getDominators(BB.get()) && DT->getDominators(BB.get())->count(Succ)) {
|
for (BasicBlock *Succ : Blcok->getSuccessors()) {
|
||||||
|
if (DT->getDominators(Blcok) && DT->getDominators(Blcok)->count(Succ)) {
|
||||||
// Succ 支配 BB,所以 (BB -> 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;
|
BasicBlock *candidatePreHeader = nullptr;
|
||||||
int externalPredecessorCount = 0;
|
int externalPredecessorCount = 0;
|
||||||
for (BasicBlock *predOfHeader : D->getPredecessors()) {
|
for (BasicBlock *predOfHeader : D->getPredecessors()) {
|
||||||
if (loopBlocks.find(predOfHeader) == loopBlocks.end()) {
|
// 使用 currentLoop->contains() 来检查前驱是否在循环体内
|
||||||
|
if (!currentLoop->contains(predOfHeader)) {
|
||||||
// 如果前驱不在循环体内,则是一个外部前驱
|
// 如果前驱不在循环体内,则是一个外部前驱
|
||||||
externalPredecessorCount++;
|
externalPredecessorCount++;
|
||||||
candidatePreHeader = predOfHeader;
|
candidatePreHeader = predOfHeader;
|
||||||
@@ -104,6 +108,8 @@ bool LoopAnalysisPass::runOnFunction(Function *F, AnalysisManager &AM) {
|
|||||||
if (externalPredecessorCount == 1) {
|
if (externalPredecessorCount == 1) {
|
||||||
currentLoop->setPreHeader(candidatePreHeader);
|
currentLoop->setPreHeader(candidatePreHeader);
|
||||||
} else {
|
} else {
|
||||||
|
assert(externalPredecessorCount == 0 || externalPredecessorCount > 1 &&
|
||||||
|
"Loop header should have exactly one external predecessor or none.");
|
||||||
// TODO: 如果有多个外部前驱或没有,这里应该插入新的基本块作为前置块,
|
// TODO: 如果有多个外部前驱或没有,这里应该插入新的基本块作为前置块,
|
||||||
// 并调整控制流。这会修改 IR,需要返回 true。
|
// 并调整控制流。这会修改 IR,需要返回 true。
|
||||||
// 目前,我们只是简单地不设置 preHeader。
|
// 目前,我们只是简单地不设置 preHeader。
|
||||||
@@ -112,64 +118,101 @@ bool LoopAnalysisPass::runOnFunction(Function *F, AnalysisManager &AM) {
|
|||||||
CurrentResult->addLoop(std::move(currentLoop));
|
CurrentResult->addLoop(std::move(currentLoop));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 步骤 5: 处理嵌套循环 (确定父子关系)
|
// 步骤 5: 处理嵌套循环 (确定父子关系和层级)
|
||||||
// 遍历所有已识别的循环,确定它们的嵌套关系
|
|
||||||
const auto &allLoops = CurrentResult->getAllLoops();
|
const auto &allLoops = CurrentResult->getAllLoops();
|
||||||
for (const auto &outerLoop_ptr : allLoops) {
|
|
||||||
Loop *outerLoop = outerLoop_ptr.get();
|
// 1. 首先,清除所有循环已设置的父子关系和嵌套子循环列表,确保重新计算
|
||||||
for (const auto &innerLoop_ptr : allLoops) {
|
for (const auto &loop_ptr : allLoops) {
|
||||||
Loop *innerLoop = innerLoop_ptr.get();
|
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) {
|
if (outerLoop == innerLoop) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 判断 innerLoop 是否嵌套在 outerLoop 内
|
// 检查 outerLoop 是否包含 innerLoop 的所有条件:
|
||||||
// 条件:innerLoop 的头被 outerLoop 的头支配,且 innerLoop 的所有块都在 outerLoop 内
|
// Condition 1: outerLoop 的头支配 innerLoop 的头
|
||||||
if (DT->getDominators(innerLoop->getHeader()) &&
|
if (!(DT->getDominators(innerLoop->getHeader()) &&
|
||||||
DT->getDominators(innerLoop->getHeader())->count(outerLoop->getHeader())) {
|
DT->getDominators(innerLoop->getHeader())->count(outerLoop->getHeader()))) {
|
||||||
bool allInnerBlocksInOuter = true;
|
continue; // outerLoop 不支配 innerLoop 的头,因此不是一个外层循环
|
||||||
for (BasicBlock *innerBB : innerLoop->getBlocks()) {
|
}
|
||||||
if (!outerLoop->contains(innerBB)) {
|
|
||||||
allInnerBlocksInOuter = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (allInnerBlocksInOuter) {
|
|
||||||
// 找到了一个嵌套关系,但还需要确定是直接嵌套还是多层嵌套
|
|
||||||
// 简单方法:如果 innerLoop 没有其他父循环,或者这个 outerLoop 是其最近的父循环
|
|
||||||
// 更精确的做法是找支配 innerLoop 头的,且被 innerLoop 头支配的最近的循环头
|
|
||||||
|
|
||||||
// 简单的直接嵌套判断:如果 innerLoop 还没有父循环,或者当前 outerLoop 比现有父循环更“紧密”
|
// Condition 2: innerLoop 的所有基本块都在 outerLoop 的基本块集合中
|
||||||
if (!innerLoop->getParentLoop()) { // 还没设置父循环
|
bool allInnerBlocksInOuter = true;
|
||||||
innerLoop->setParentLoop(outerLoop);
|
for (BasicBlock *innerBB : innerLoop->getBlocks()) {
|
||||||
outerLoop->addNestedLoop(innerLoop);
|
if (!outerLoop->contains(innerBB)) { //
|
||||||
} else {
|
allInnerBlocksInOuter = false;
|
||||||
// 如果 innerLoop 已经有父循环,判断 outerLoop 是否是更直接的父循环
|
break;
|
||||||
// (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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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