[midend]loop分析构建
This commit is contained in:
155
src/include/midend/Pass/Analysis/Loop.h
Normal file
155
src/include/midend/Pass/Analysis/Loop.h
Normal file
@@ -0,0 +1,155 @@
|
||||
#pragma once
|
||||
|
||||
#include "Dom.h" // 包含 DominatorTreeAnalysisPass 的依赖
|
||||
#include "IR.h" // 包含 IR 定义
|
||||
#include "Pass.h" // 包含 Pass 框架
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <queue> // 用于循环体块的逆向遍历
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
namespace sysy {
|
||||
|
||||
// 前向声明,防止循环引用
|
||||
class LoopAnalysisResult;
|
||||
|
||||
/**
|
||||
* @brief 表示一个识别出的循环。
|
||||
*/
|
||||
class Loop {
|
||||
public:
|
||||
// 构造函数:指定循环头
|
||||
Loop(BasicBlock *header) : Header(header) {}
|
||||
|
||||
// 获取循环头
|
||||
BasicBlock *getHeader() const { return Header; }
|
||||
|
||||
// 获取循环体包含的所有基本块
|
||||
const std::set<BasicBlock *> &getBlocks() const { return LoopBlocks; }
|
||||
|
||||
// 获取循环的出口基本块(即从循环内部跳转到循环外部的基本块)
|
||||
const std::set<BasicBlock *> &getExitBlocks() const { return ExitBlocks; }
|
||||
|
||||
// 获取循环前置块(如果存在),可以为 nullptr
|
||||
BasicBlock *getPreHeader() const { return PreHeader; }
|
||||
|
||||
// 获取直接包含此循环的父循环(如果存在),可以为 nullptr
|
||||
Loop *getParentLoop() const { return ParentLoop; }
|
||||
|
||||
// 获取直接嵌套在此循环内的子循环
|
||||
const std::vector<Loop *> &getNestedLoops() const { return NestedLoops; }
|
||||
|
||||
// 获取循环的层级 (0 表示最外层循环,1 表示嵌套一层,以此类推)
|
||||
int getLoopLevel() const { return Level; }
|
||||
|
||||
// 检查一个基本块是否属于当前循环
|
||||
bool contains(BasicBlock *BB) const { return LoopBlocks.count(BB); }
|
||||
|
||||
// 判断当前循环是否是最内层循环 (没有嵌套子循环)
|
||||
bool isInnermost() const { return NestedLoops.empty(); }
|
||||
|
||||
// 判断当前循环是否是最外层循环 (没有父循环)
|
||||
bool isOutermost() const { return ParentLoop == nullptr; }
|
||||
|
||||
// --- 供 LoopAnalysisPass 内部调用的方法,用于构建 Loop 对象 ---
|
||||
void addBlock(BasicBlock *BB) { LoopBlocks.insert(BB); }
|
||||
void addExitBlock(BasicBlock *BB) { ExitBlocks.insert(BB); }
|
||||
void setPreHeader(BasicBlock *BB) { PreHeader = BB; }
|
||||
void setParentLoop(Loop *loop) { ParentLoop = loop; }
|
||||
void addNestedLoop(Loop *loop) { NestedLoops.push_back(loop); }
|
||||
void setLoopLevel(int level) { Level = level; }
|
||||
|
||||
private:
|
||||
BasicBlock *Header; // 循环头基本块
|
||||
std::set<BasicBlock *> LoopBlocks; // 循环体包含的基本块集合
|
||||
std::set<BasicBlock *> ExitBlocks; // 循环出口基本块集合
|
||||
BasicBlock *PreHeader = nullptr; // 循环前置块 (Optional)
|
||||
Loop *ParentLoop = nullptr; // 父循环 (用于嵌套)
|
||||
std::vector<Loop *> NestedLoops; // 嵌套的子循环
|
||||
int Level = -1; // 循环的层级,-1表示未计算
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 循环分析结果类。
|
||||
* 包含一个函数中所有识别出的循环。
|
||||
*/
|
||||
class LoopAnalysisResult : public AnalysisResultBase {
|
||||
public:
|
||||
LoopAnalysisResult(Function *F) : AssociatedFunction(F) {}
|
||||
~LoopAnalysisResult() override = default;
|
||||
|
||||
// 添加一个识别出的循环到结果中
|
||||
void addLoop(std::unique_ptr<Loop> loop) {
|
||||
AllLoops.push_back(std::move(loop));
|
||||
// 也可以选择将 Loop* 存储到 map 中,方便通过 header 查找
|
||||
LoopMap[AllLoops.back()->getHeader()] = AllLoops.back().get();
|
||||
}
|
||||
|
||||
// 获取所有识别出的循环(unique_ptr 管理内存)
|
||||
const std::vector<std::unique_ptr<Loop>> &getAllLoops() const { return AllLoops; }
|
||||
|
||||
// 获取所有最外层循环
|
||||
const std::vector<Loop *> &getOutermostLoops() const { return OutermostLoops; }
|
||||
|
||||
// 获取所有最内层循环
|
||||
const std::vector<Loop *> &getInnermostLoops() const { return InnermostLoops; }
|
||||
|
||||
// 通过循环头获取 Loop 对象
|
||||
Loop *getLoopForHeader(BasicBlock *header) const {
|
||||
auto it = LoopMap.find(header);
|
||||
return (it != LoopMap.end()) ? it->second : nullptr;
|
||||
}
|
||||
|
||||
// 通过某个基本块获取包含它的最内层循环
|
||||
Loop *getLoopContainingBlock(BasicBlock *BB) const {
|
||||
// 遍历所有循环,找到包含 BB 且层级最深的循环
|
||||
Loop *innermostContainingLoop = nullptr;
|
||||
for (const auto &loop_ptr : AllLoops) {
|
||||
if (loop_ptr->contains(BB)) {
|
||||
if (!innermostContainingLoop || loop_ptr->getLoopLevel() > innermostContainingLoop->getLoopLevel()) {
|
||||
innermostContainingLoop = loop_ptr.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
return innermostContainingLoop;
|
||||
}
|
||||
|
||||
// --- 供 LoopAnalysisPass 内部调用的方法,用于构建 LoopAnalysisResult 对象 ---
|
||||
void addOutermostLoop(Loop *loop) { OutermostLoops.push_back(loop); }
|
||||
void addInnermostLoop(Loop *loop) { InnermostLoops.push_back(loop); }
|
||||
|
||||
private:
|
||||
Function *AssociatedFunction; // 结果关联的函数
|
||||
std::vector<std::unique_ptr<Loop>> AllLoops; // 所有识别出的循环
|
||||
std::map<BasicBlock *, Loop *> LoopMap; // 循环头到 Loop* 的映射,方便查找
|
||||
std::vector<Loop *> OutermostLoops; // 最外层循环的列表
|
||||
std::vector<Loop *> InnermostLoops; // 最内层循环的列表
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 循环分析遍。
|
||||
* 识别函数中的所有循环,并生成 LoopAnalysisResult。
|
||||
*/
|
||||
class LoopAnalysisPass : public AnalysisPass {
|
||||
public:
|
||||
// 唯一的 Pass ID,需要在 .cpp 文件中定义
|
||||
static void *ID;
|
||||
|
||||
LoopAnalysisPass() : AnalysisPass("LoopAnalysis", Pass::Granularity::Function) {}
|
||||
|
||||
// 实现 getPassID
|
||||
void *getPassID() const override { return &ID; }
|
||||
|
||||
// 核心运行方法:在每个函数上执行循环分析
|
||||
bool runOnFunction(Function *F, AnalysisManager &AM) override;
|
||||
|
||||
// 获取分析结果
|
||||
std::unique_ptr<AnalysisResultBase> getResult() override { return std::move(CurrentResult); }
|
||||
|
||||
private:
|
||||
std::unique_ptr<LoopAnalysisResult> CurrentResult; // 当前函数的分析结果
|
||||
};
|
||||
|
||||
} // namespace sysy
|
||||
Reference in New Issue
Block a user