Files
mysysy/src/include/midend/Pass/Analysis/Loop.h

618 lines
19 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include "Dom.h"
#include "IR.h"
#include "Pass.h"
#include <algorithm>
#include <functional>
#include <map>
#include <memory>
#include <optional>
#include <queue>
#include <set>
#include <vector>
namespace sysy {
// 前向声明
class LoopAnalysisResult;
class AliasAnalysisResult;
class SideEffectAnalysisResult;
/**
* @brief 表示一个识别出的循环。
*/
class Loop {
private:
static int NextLoopID; // 静态变量用于分配唯一ID
int LoopID;
public:
// 构造函数:指定循环头
Loop(BasicBlock *header) : Header(header), LoopID(NextLoopID++) {}
// 获取循环头
BasicBlock *getHeader() const { return Header; }
// 获取循环的名称 基于ID
std::string getName() const { return "loop_" + std::to_string(LoopID); }
// 获取循环体包含的所有基本块
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(); }
// 获取循环的深度(从最外层开始计算)
int getLoopDepth() const { return Level + 1; }
// 获取循环体的大小(基本块数量)
size_t getLoopSize() const { return LoopBlocks.size(); }
// 检查循环是否有唯一的外部前驱(即是否有前置块)
bool hasUniquePreHeader() const { return PreHeader != nullptr; }
// 检查循环是否是最外层循环(没有父循环)
bool isOutermost() const { return getParentLoop() == nullptr; }
// 获取循环的所有出口(从循环内到循环外的基本块)
std::vector<BasicBlock*> getExitingBlocks() const {
std::vector<BasicBlock*> exitingBlocks;
for (BasicBlock* bb : LoopBlocks) {
for (BasicBlock* succ : bb->getSuccessors()) {
if (!contains(succ)) {
exitingBlocks.push_back(bb);
break; // 每个基本块只添加一次
}
}
}
return exitingBlocks;
}
// 判断循环是否是简单循环(只有一个回边)
bool isSimpleLoop() const {
int backEdgeCount = 0;
for (BasicBlock* pred : Header->getPredecessors()) {
if (contains(pred)) {
backEdgeCount++;
}
}
return backEdgeCount == 1;
}
/**
* 获取所有出口目标块 (循环外接收循环出口边的块)
* 使用场景: 循环后置处理、phi节点分析
*/
std::vector<BasicBlock*> getExitTargetBlocks() const {
std::set<BasicBlock*> exitTargetSet;
for (BasicBlock* bb : LoopBlocks) {
for (BasicBlock* succ : bb->getSuccessors()) {
if (!contains(succ)) {
exitTargetSet.insert(succ);
}
}
}
return std::vector<BasicBlock*>(exitTargetSet.begin(), exitTargetSet.end());
}
/**
* 计算循环的"深度"相对于指定的祖先循环
* 使用场景: 相对深度计算、嵌套分析
*/
int getRelativeDepth(Loop* ancestor) const {
if (this == ancestor) return 0;
int depth = 0;
Loop* current = this->ParentLoop;
while (current && current != ancestor) {
depth++;
current = current->ParentLoop;
}
return current == ancestor ? depth : -1; // -1表示不是祖先关系
}
/**
* 检查循环是否包含函数调用
* 使用场景: 内联决策、副作用分析
*/
bool containsFunctionCalls() const {
for (BasicBlock* bb : LoopBlocks) {
for (auto& inst : bb->getInstructions()) {
if (dynamic_cast<CallInst*>(inst.get())) {
return true;
}
}
}
return false;
}
/**
* 检查循环是否可能有副作用(基于副作用分析结果)
* 使用场景: 循环优化决策、并行化分析
*/
bool mayHaveSideEffects(SideEffectAnalysisResult* sideEffectAnalysis) const;
/**
* 检查循环是否访问全局内存(基于别名分析结果)
* 使用场景: 并行化分析、缓存优化
*/
bool accessesGlobalMemory(AliasAnalysisResult* aliasAnalysis) const;
/**
* 检查循环是否有可能的内存别名冲突
* 使用场景: 向量化分析、并行化决策
*/
bool hasMemoryAliasConflicts(AliasAnalysisResult* aliasAnalysis) const;
/**
* 估算循环的"热度" (基于嵌套深度和大小)
* 使用场景: 优化优先级、资源分配
*/
double getLoopHotness() const {
// 简单的热度估算: 深度权重 + 大小惩罚
double hotness = std::pow(2.0, Level); // 深度越深越热
hotness /= std::sqrt(LoopBlocks.size()); // 大小越大相对热度降低
return hotness;
}
// --- 供 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; }
void clearNestedLoops() { NestedLoops.clear(); }
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;
// ========== 缓存统计结构 ==========
struct CacheStats {
size_t innermostLoopsCached;
size_t outermostLoopsCached;
size_t loopsByDepthCached;
size_t containingLoopsCached;
size_t allNestedLoopsCached;
size_t totalCachedQueries;
};
private:
// ========== 高频查询缓存 ==========
mutable std::optional<std::vector<Loop*>> cachedInnermostLoops;
mutable std::optional<std::vector<Loop*>> cachedOutermostLoops;
mutable std::optional<int> cachedMaxDepth;
mutable std::optional<size_t> cachedLoopCount;
mutable std::map<int, std::vector<Loop*>> cachedLoopsByDepth;
// ========== 中频查询缓存 ==========
mutable std::map<BasicBlock*, Loop*> cachedInnermostContainingLoop;
mutable std::map<Loop*, std::set<Loop*>> cachedAllNestedLoops; // 递归嵌套
mutable std::map<BasicBlock*, std::vector<Loop*>> cachedAllContainingLoops;
// ========== 缓存状态管理 ==========
mutable bool cacheValid = true;
// 内部辅助方法
void invalidateCache() const {
cachedInnermostLoops.reset();
cachedOutermostLoops.reset();
cachedMaxDepth.reset();
cachedLoopCount.reset();
cachedLoopsByDepth.clear();
cachedInnermostContainingLoop.clear();
cachedAllNestedLoops.clear();
cachedAllContainingLoops.clear();
cacheValid = false;
}
void ensureCacheValid() const {
if (!cacheValid) {
// 重新计算基础缓存
computeBasicCache();
cacheValid = true;
}
}
void computeBasicCache() const {
// 计算最内层循环
if (!cachedInnermostLoops) {
cachedInnermostLoops = std::vector<Loop*>();
for (const auto& loop : AllLoops) {
if (loop->isInnermost()) {
cachedInnermostLoops->push_back(loop.get());
}
}
}
// 计算最外层循环
if (!cachedOutermostLoops) {
cachedOutermostLoops = std::vector<Loop*>();
for (const auto& loop : AllLoops) {
if (loop->isOutermost()) {
cachedOutermostLoops->push_back(loop.get());
}
}
}
// 计算最大深度
if (!cachedMaxDepth) {
int maxDepth = 0;
for (const auto& loop : AllLoops) {
maxDepth = std::max(maxDepth, loop->getLoopDepth());
}
cachedMaxDepth = maxDepth;
}
// 计算循环总数
if (!cachedLoopCount) {
cachedLoopCount = AllLoops.size();
}
}
public:
// ========== 基础接口 ==========
// 添加一个识别出的循环到结果中
void addLoop(std::unique_ptr<Loop> loop) {
invalidateCache(); // 添加新循环时失效缓存
AllLoops.push_back(std::move(loop));
LoopMap[AllLoops.back()->getHeader()] = AllLoops.back().get();
}
// 获取所有识别出的循环unique_ptr 管理内存)
const std::vector<std::unique_ptr<Loop>> &getAllLoops() const { return AllLoops; }
// ========== 高频查询接口 ==========
/**
* 获取所有最内层循环 - 循环优化的主要目标
* 使用场景: 循环展开、向量化、循环不变量外提
*/
const std::vector<Loop*>& getInnermostLoops() const {
ensureCacheValid();
if (!cachedInnermostLoops) {
cachedInnermostLoops = std::vector<Loop*>();
for (const auto& loop : AllLoops) {
if (loop->isInnermost()) {
cachedInnermostLoops->push_back(loop.get());
}
}
}
return *cachedInnermostLoops;
}
/**
* 获取所有最外层循环
* 使用场景: 循环树遍历、整体优化策略
*/
const std::vector<Loop*>& getOutermostLoops() const {
ensureCacheValid();
if (!cachedOutermostLoops) {
cachedOutermostLoops = std::vector<Loop*>();
for (const auto& loop : AllLoops) {
if (loop->isOutermost()) {
cachedOutermostLoops->push_back(loop.get());
}
}
}
return *cachedOutermostLoops;
}
/**
* 获取指定深度的所有循环
* 使用场景: 分层优化、循环展开决策、并行化分析
*/
const std::vector<Loop*>& getLoopsAtDepth(int depth) const {
ensureCacheValid();
if (cachedLoopsByDepth.find(depth) == cachedLoopsByDepth.end()) {
std::vector<Loop*> result;
for (const auto& loop : AllLoops) {
if (loop->getLoopDepth() == depth) {
result.push_back(loop.get());
}
}
cachedLoopsByDepth[depth] = std::move(result);
}
return cachedLoopsByDepth[depth];
}
/**
* 获取最大循环嵌套深度
* 使用场景: 优化预算分配、编译时间控制
*/
int getMaxLoopDepth() const {
ensureCacheValid();
if (!cachedMaxDepth) {
int maxDepth = 0;
for (const auto& loop : AllLoops) {
maxDepth = std::max(maxDepth, loop->getLoopDepth());
}
cachedMaxDepth = maxDepth;
}
return *cachedMaxDepth;
}
/**
* 获取循环总数
* 使用场景: 统计信息、优化决策
*/
size_t getLoopCount() const {
ensureCacheValid();
if (!cachedLoopCount) {
cachedLoopCount = AllLoops.size();
}
return *cachedLoopCount;
}
// 获取指定深度的循环数量
size_t getLoopCountAtDepth(int depth) const {
return getLoopsAtDepth(depth).size();
}
// 检查函数是否包含循环
bool hasLoops() const { return !AllLoops.empty(); }
// ========== 中频查询接口 ==========
/**
* 获取包含指定基本块的最内层循环
* 使用场景: 活跃性分析、寄存器分配、指令调度
*/
Loop* getInnermostContainingLoop(BasicBlock* BB) const {
ensureCacheValid();
if (cachedInnermostContainingLoop.find(BB) == cachedInnermostContainingLoop.end()) {
Loop* result = nullptr;
int maxDepth = -1;
for (const auto& loop : AllLoops) {
if (loop->contains(BB) && loop->getLoopDepth() > maxDepth) {
result = loop.get();
maxDepth = loop->getLoopDepth();
}
}
cachedInnermostContainingLoop[BB] = result;
}
return cachedInnermostContainingLoop[BB];
}
/**
* 获取包含指定基本块的所有循环 (从外到内排序)
* 使用场景: 循环间优化、依赖分析
*/
const std::vector<Loop*>& getAllContainingLoops(BasicBlock* BB) const {
ensureCacheValid();
if (cachedAllContainingLoops.find(BB) == cachedAllContainingLoops.end()) {
std::vector<Loop*> result;
for (const auto& loop : AllLoops) {
if (loop->contains(BB)) {
result.push_back(loop.get());
}
}
// 按深度排序 (外层到内层)
std::sort(result.begin(), result.end(),
[](Loop* a, Loop* b) { return a->getLoopDepth() < b->getLoopDepth(); });
cachedAllContainingLoops[BB] = std::move(result);
}
return cachedAllContainingLoops[BB];
}
/**
* 获取指定循环的所有嵌套子循环 (递归)
* 使用场景: 循环树分析、嵌套优化
*/
const std::set<Loop*>& getAllNestedLoops(Loop* loop) const {
ensureCacheValid();
if (cachedAllNestedLoops.find(loop) == cachedAllNestedLoops.end()) {
std::set<Loop*> result;
std::function<void(Loop*)> collectNested = [&](Loop* current) {
for (Loop* nested : current->getNestedLoops()) {
result.insert(nested);
collectNested(nested); // 递归收集
}
};
collectNested(loop);
cachedAllNestedLoops[loop] = std::move(result);
}
return cachedAllNestedLoops[loop];
}
// ========== 利用别名和副作用分析的查询接口 ==========
/**
* 获取所有纯循环(无副作用的循环)
* 并行化、循环优化
*/
std::vector<Loop*> getPureLoops(SideEffectAnalysisResult* sideEffectAnalysis) const {
std::vector<Loop*> result;
if (!sideEffectAnalysis) return result;
for (const auto& loop : AllLoops) {
if (!loop->mayHaveSideEffects(sideEffectAnalysis)) {
result.push_back(loop.get());
}
}
return result;
}
/**
* 获取所有只访问局部内存的循环
* 缓存优化、局部性分析
*/
std::vector<Loop*> getLocalMemoryLoops(AliasAnalysisResult* aliasAnalysis) const {
std::vector<Loop*> result;
if (!aliasAnalysis) return result;
for (const auto& loop : AllLoops) {
if (!loop->accessesGlobalMemory(aliasAnalysis)) {
result.push_back(loop.get());
}
}
return result;
}
/**
* 获取所有无内存别名冲突的循环
* 向量化、并行化
*/
std::vector<Loop*> getNoAliasConflictLoops(AliasAnalysisResult* aliasAnalysis) const {
std::vector<Loop*> result;
if (!aliasAnalysis) return result;
for (const auto& loop : AllLoops) {
if (!loop->hasMemoryAliasConflicts(aliasAnalysis)) {
result.push_back(loop.get());
}
}
return result;
}
// ========== 低频查询接口(不缓存) ==========
/**
* 检查两个循环是否有嵌套关系
* 循环间依赖分析
*/
bool isNestedLoop(Loop* inner, Loop* outer) const {
if (inner == outer) return false;
Loop* current = inner->getParentLoop();
while (current) {
if (current == outer) return true;
current = current->getParentLoop();
}
return false;
}
/**
* 获取两个循环的最近公共祖先循环
* 循环融合分析、优化范围确定
*/
Loop* getLowestCommonAncestor(Loop* loop1, Loop* loop2) const {
if (!loop1 || !loop2) return nullptr;
if (loop1 == loop2) return loop1;
// 收集loop1的所有祖先
std::set<Loop*> ancestors1;
Loop* current = loop1;
while (current) {
ancestors1.insert(current);
current = current->getParentLoop();
}
// 查找loop2祖先链中第一个在ancestors1中的循环
current = loop2;
while (current) {
if (ancestors1.count(current)) {
return current;
}
current = current->getParentLoop();
}
return nullptr; // 没有公共祖先
}
// 通过循环头获取 Loop 对象
Loop *getLoopForHeader(BasicBlock *header) const {
auto it = LoopMap.find(header);
return (it != LoopMap.end()) ? it->second : nullptr;
}
// 通过某个基本块获取包含它的最内层循环 (向后兼容接口)
Loop *getLoopContainingBlock(BasicBlock *BB) const {
return getInnermostContainingLoop(BB);
}
// ========== 缓存管理接口 ==========
/**
* 手动失效缓存 (可删除)
*/
void invalidateQueryCache() const {
invalidateCache();
}
/**
* 获取缓存统计信息
*/
CacheStats getCacheStats() const {
CacheStats stats = {};
stats.innermostLoopsCached = cachedInnermostLoops.has_value() ? 1 : 0;
stats.outermostLoopsCached = cachedOutermostLoops.has_value() ? 1 : 0;
stats.loopsByDepthCached = cachedLoopsByDepth.size();
stats.containingLoopsCached = cachedInnermostContainingLoop.size();
stats.allNestedLoopsCached = cachedAllNestedLoops.size();
stats.totalCachedQueries = stats.innermostLoopsCached + stats.outermostLoopsCached +
stats.loopsByDepthCached + stats.containingLoopsCached +
stats.allNestedLoopsCached;
return stats;
}
// 打印分析结果
void print() const;
void printBBSet(const std::string &prefix, const std::set<BasicBlock *> &s) const;
void printLoopVector(const std::string &prefix, const std::vector<Loop *> &loops) const;
private:
Function *AssociatedFunction; // 结果关联的函数
std::vector<std::unique_ptr<Loop>> AllLoops; // 所有识别出的循环
std::map<BasicBlock *, Loop *> LoopMap; // 循环头到 Loop* 的映射,方便查找
};
/**
* @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