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

302 lines
10 KiB
C++

#pragma once
#include "Dom.h" // 支配树分析依赖
#include "Loop.h" // 循环分析依赖
#include "Liveness.h" // 活跃性分析依赖
#include "AliasAnalysis.h" // 别名分析依赖
#include "IR.h" // IR定义
#include "Pass.h" // Pass框架
#include <algorithm>
#include <map>
#include <memory>
#include <optional>
#include <set>
#include <vector>
namespace sysy {
// 前向声明
class LoopCharacteristicsResult;
/**
* @brief 循环特征信息结构
* 存储单个循环的各种特征信息
*/
struct LoopCharacteristics {
Loop* loop; // 关联的循环对象
// ========== 归纳变量分析 ==========
std::vector<Value*> basicInductionVars; // 基本归纳变量 (i = phi(init, i+step))
std::vector<Value*> derivedInductionVars; // 派生归纳变量 (j = i * scale + offset)
std::map<Value*, int> inductionSteps; // 归纳变量的步长
std::map<Value*, Value*> inductionInits; // 归纳变量的初始值
// ========== 循环不变量分析 ==========
std::set<Value*> loopInvariants; // 循环不变量 (循环内定义但值不变)
std::set<Instruction*> invariantInsts; // 不变指令 (可以外提的指令)
// ========== 循环边界分析 ==========
std::optional<int> staticTripCount; // 静态可确定的循环次数
Value* dynamicTripCountExpr; // 动态循环次数表达式
bool hasKnownBounds; // 是否有已知边界
Value* lowerBound; // 循环下界
Value* upperBound; // 循环上界
// ========== 循环形式分析 ==========
bool isCountingLoop; // 是否为计数循环 (for i=0; i<n; i++)
bool isSimpleForLoop; // 是否为简单for循环
bool hasComplexControlFlow; // 是否有复杂控制流 (break, continue)
bool isInnermost; // 是否为最内层循环
bool isParallel; // 是否可并行化
// ========== 内存访问模式 ==========
struct MemoryAccessPattern {
bool isSequential; // 是否顺序访问 (a[i], a[i+1], ...)
bool isStrided; // 是否跨步访问 (a[2*i], a[3*i], ...)
int stride; // 访问步长
std::vector<Instruction*> loadInsts; // load指令列表
std::vector<Instruction*> storeInsts; // store指令列表
// 使用外部别名分析结果
AliasType aliasType; // 别名类型(来自别名分析)
bool isArrayParameter; // 是否为数组参数访问
bool isGlobalArray; // 是否为全局数组访问
bool hasConstantIndices; // 是否使用常量索引
};
std::map<Value*, MemoryAccessPattern> memoryPatterns; // 内存访问模式
// ========== 循环优化提示 ==========
bool benefitsFromUnrolling; // 是否适合循环展开
bool benefitsFromVectorization; // 是否适合向量化
bool benefitsFromTiling; // 是否适合分块
int suggestedUnrollFactor; // 建议的展开因子
// ========== 性能特征 ==========
size_t instructionCount; // 循环体指令数
size_t memoryOperationCount; // 内存操作数
size_t arithmeticOperationCount; // 算术操作数
double computeToMemoryRatio; // 计算与内存操作比率
// 构造函数
LoopCharacteristics(Loop* l) : loop(l), dynamicTripCountExpr(nullptr),
hasKnownBounds(false), lowerBound(nullptr), upperBound(nullptr),
isCountingLoop(false), isSimpleForLoop(false), hasComplexControlFlow(false),
isInnermost(false), isParallel(false), benefitsFromUnrolling(false),
benefitsFromVectorization(false), benefitsFromTiling(false),
suggestedUnrollFactor(1), instructionCount(0), memoryOperationCount(0),
arithmeticOperationCount(0), computeToMemoryRatio(0.0) {}
};
/**
* @brief 循环特征分析结果类
* 包含函数中所有循环的特征信息,并提供查询接口
*/
class LoopCharacteristicsResult : public AnalysisResultBase {
public:
LoopCharacteristicsResult(Function *F) : AssociatedFunction(F) {}
~LoopCharacteristicsResult() override = default;
// ========== 基础接口 ==========
/**
* 添加循环特征信息
*/
void addLoopCharacteristics(std::unique_ptr<LoopCharacteristics> characteristics) {
auto* loop = characteristics->loop;
CharacteristicsMap[loop] = std::move(characteristics);
}
/**
* 获取指定循环的特征信息
*/
const LoopCharacteristics* getCharacteristics(Loop* loop) const {
auto it = CharacteristicsMap.find(loop);
return (it != CharacteristicsMap.end()) ? it->second.get() : nullptr;
}
/**
* 获取所有循环特征信息
*/
const std::map<Loop*, std::unique_ptr<LoopCharacteristics>>& getAllCharacteristics() const {
return CharacteristicsMap;
}
// ========== 查询接口 ==========
/**
* 获取所有计数循环
*/
std::vector<Loop*> getCountingLoops() const {
std::vector<Loop*> result;
for (const auto& [loop, chars] : CharacteristicsMap) {
if (chars->isCountingLoop) {
result.push_back(loop);
}
}
return result;
}
/**
* 获取所有可向量化循环
*/
std::vector<Loop*> getVectorizableLoops() const {
std::vector<Loop*> result;
for (const auto& [loop, chars] : CharacteristicsMap) {
if (chars->benefitsFromVectorization) {
result.push_back(loop);
}
}
return result;
}
/**
* 获取所有适合展开的循环
*/
std::vector<Loop*> getUnrollCandidateLoops() const {
std::vector<Loop*> result;
for (const auto& [loop, chars] : CharacteristicsMap) {
if (chars->benefitsFromUnrolling) {
result.push_back(loop);
}
}
return result;
}
/**
* 获取所有可并行化循环
*/
std::vector<Loop*> getParallelizableLoops() const {
std::vector<Loop*> result;
for (const auto& [loop, chars] : CharacteristicsMap) {
if (chars->isParallel) {
result.push_back(loop);
}
}
return result;
}
/**
* 获取所有有静态已知循环次数的循环
*/
std::vector<Loop*> getStaticBoundLoops() const {
std::vector<Loop*> result;
for (const auto& [loop, chars] : CharacteristicsMap) {
if (chars->staticTripCount.has_value()) {
result.push_back(loop);
}
}
return result;
}
/**
* 根据热度排序循环 (用于优化优先级)
*/
std::vector<Loop*> getLoopsByHotness() const {
std::vector<Loop*> result;
for (const auto& [loop, chars] : CharacteristicsMap) {
result.push_back(loop);
}
// 按循环热度排序 (嵌套深度 + 循环次数 + 指令数)
std::sort(result.begin(), result.end(), [](Loop* a, Loop* b) {
double hotnessA = a->getLoopHotness();
double hotnessB = b->getLoopHotness();
return hotnessA > hotnessB; // 降序排列
});
return result;
}
// ========== 统计接口 ==========
/**
* 获取优化候选统计
*/
struct OptimizationStats {
size_t totalLoops;
size_t countingLoops;
size_t vectorizableLoops;
size_t unrollCandidates;
size_t parallelizableLoops;
size_t staticBoundLoops;
double avgInstructionCount;
double avgComputeMemoryRatio;
};
OptimizationStats getOptimizationStats() const {
OptimizationStats stats = {};
stats.totalLoops = CharacteristicsMap.size();
size_t totalInstructions = 0;
double totalComputeMemoryRatio = 0.0;
for (const auto& [loop, chars] : CharacteristicsMap) {
if (chars->isCountingLoop) stats.countingLoops++;
if (chars->benefitsFromVectorization) stats.vectorizableLoops++;
if (chars->benefitsFromUnrolling) stats.unrollCandidates++;
if (chars->isParallel) stats.parallelizableLoops++;
if (chars->staticTripCount.has_value()) stats.staticBoundLoops++;
totalInstructions += chars->instructionCount;
totalComputeMemoryRatio += chars->computeToMemoryRatio;
}
if (stats.totalLoops > 0) {
stats.avgInstructionCount = static_cast<double>(totalInstructions) / stats.totalLoops;
stats.avgComputeMemoryRatio = totalComputeMemoryRatio / stats.totalLoops;
}
return stats;
}
// 打印分析结果
void print() const;
private:
Function *AssociatedFunction; // 关联的函数
std::map<Loop*, std::unique_ptr<LoopCharacteristics>> CharacteristicsMap; // 循环特征映射
};
/**
* @brief 循环特征分析遍
* 基于循环分析结果,分析每个循环的特征信息,为优化决策提供依据
*/
class LoopCharacteristicsPass : public AnalysisPass {
public:
// 唯一的 Pass ID
static void *ID;
LoopCharacteristicsPass() : AnalysisPass("LoopCharacteristics", 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<LoopCharacteristicsResult> CurrentResult; // 当前函数的分析结果
// 内部分析方法
void analyzeLoop(Loop* loop, LoopCharacteristics* characteristics, AnalysisManager &AM);
void identifyInductionVariables(Loop* loop, LoopCharacteristics* characteristics);
void identifyLoopInvariants(Loop* loop, LoopCharacteristics* characteristics);
void analyzeLoopBounds(Loop* loop, LoopCharacteristics* characteristics);
void analyzeLoopForm(Loop* loop, LoopCharacteristics* characteristics);
void analyzeMemoryAccessPatterns(Loop* loop, LoopCharacteristics* characteristics);
void evaluateOptimizationOpportunities(Loop* loop, LoopCharacteristics* characteristics);
void computePerformanceMetrics(Loop* loop, LoopCharacteristics* characteristics);
// 辅助方法
bool isInductionVariable(Value* val, Loop* loop);
bool isLoopInvariant(Value* val, Loop* loop);
bool hasLoopCarriedDependence(Loop* loop);
int estimateUnrollFactor(Loop* loop);
bool benefitsFromVectorization(Loop* loop);
};
} // namespace sysy