[midend-LoopAnalysis]移除基本循环特征分析中的向量化并行化内容,增加循环向量化并行化特征分析遍,TODO:构建循环优化遍验证分析遍正确性
This commit is contained in:
@@ -4,6 +4,8 @@
|
||||
#include "Loop.h" // 循环分析依赖
|
||||
#include "Liveness.h" // 活跃性分析依赖
|
||||
#include "AliasAnalysis.h" // 别名分析依赖
|
||||
#include "SideEffectAnalysis.h" // 副作用分析依赖
|
||||
#include "CallGraphAnalysis.h" // 调用图分析依赖
|
||||
#include "IR.h" // IR定义
|
||||
#include "Pass.h" // Pass框架
|
||||
#include <algorithm>
|
||||
@@ -19,71 +21,62 @@ namespace sysy {
|
||||
class LoopCharacteristicsResult;
|
||||
|
||||
/**
|
||||
* @brief 循环特征信息结构
|
||||
* 存储单个循环的各种特征信息
|
||||
* @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; // 是否可并行化
|
||||
|
||||
// ========== 内存访问模式 ==========
|
||||
// ========== 基础归纳变量分析 ==========
|
||||
std::vector<Value*> basicInductionVars; // 基本归纳变量
|
||||
std::map<Value*, int> inductionSteps; // 归纳变量的步长(简化)
|
||||
|
||||
// ========== 基础循环不变量分析 ==========
|
||||
std::set<Value*> loopInvariants; // 循环不变量
|
||||
std::set<Instruction*> invariantInsts; // 可提升的不变指令
|
||||
|
||||
// ========== 基础边界分析 ==========
|
||||
std::optional<int> staticTripCount; // 静态循环次数(如果可确定)
|
||||
bool hasKnownBounds; // 是否有已知边界
|
||||
|
||||
// ========== 基础纯度和副作用分析 ==========
|
||||
bool isPure; // 是否为纯循环(无副作用)
|
||||
bool accessesOnlyLocalMemory; // 是否只访问局部内存
|
||||
bool hasNoMemoryAliasConflicts; // 是否无内存别名冲突
|
||||
|
||||
// ========== 基础内存访问模式分析 ==========
|
||||
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),
|
||||
// ========== 基础优化提示 ==========
|
||||
bool benefitsFromUnrolling; // 是否适合循环展开
|
||||
int suggestedUnrollFactor; // 建议的展开因子
|
||||
|
||||
// 构造函数 - 简化的基础分析初始化
|
||||
LoopCharacteristics(Loop* l) : loop(l),
|
||||
isCountingLoop(false), isSimpleForLoop(false), hasComplexControlFlow(false),
|
||||
isInnermost(false), isParallel(false), benefitsFromUnrolling(false),
|
||||
benefitsFromVectorization(false), benefitsFromTiling(false),
|
||||
suggestedUnrollFactor(1), instructionCount(0), memoryOperationCount(0),
|
||||
isInnermost(false), hasKnownBounds(false), isPure(false),
|
||||
accessesOnlyLocalMemory(false), hasNoMemoryAliasConflicts(false),
|
||||
benefitsFromUnrolling(false), suggestedUnrollFactor(1),
|
||||
instructionCount(0), memoryOperationCount(0),
|
||||
arithmeticOperationCount(0), computeToMemoryRatio(0.0) {}
|
||||
};
|
||||
|
||||
@@ -121,7 +114,7 @@ public:
|
||||
return CharacteristicsMap;
|
||||
}
|
||||
|
||||
// ========== 查询接口 ==========
|
||||
// ========== 核心查询接口 ==========
|
||||
|
||||
/**
|
||||
* 获取所有计数循环
|
||||
@@ -137,12 +130,38 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有可向量化循环
|
||||
* 获取所有纯循环(无副作用)
|
||||
*/
|
||||
std::vector<Loop*> getVectorizableLoops() const {
|
||||
std::vector<Loop*> getPureLoops() const {
|
||||
std::vector<Loop*> result;
|
||||
for (const auto& [loop, chars] : CharacteristicsMap) {
|
||||
if (chars->benefitsFromVectorization) {
|
||||
if (chars->isPure) {
|
||||
result.push_back(loop);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有只访问局部内存的循环
|
||||
*/
|
||||
std::vector<Loop*> getLocalMemoryOnlyLoops() const {
|
||||
std::vector<Loop*> result;
|
||||
for (const auto& [loop, chars] : CharacteristicsMap) {
|
||||
if (chars->accessesOnlyLocalMemory) {
|
||||
result.push_back(loop);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有无内存别名冲突的循环
|
||||
*/
|
||||
std::vector<Loop*> getNoAliasConflictLoops() const {
|
||||
std::vector<Loop*> result;
|
||||
for (const auto& [loop, chars] : CharacteristicsMap) {
|
||||
if (chars->hasNoMemoryAliasConflicts) {
|
||||
result.push_back(loop);
|
||||
}
|
||||
}
|
||||
@@ -152,7 +171,7 @@ public:
|
||||
/**
|
||||
* 获取所有适合展开的循环
|
||||
*/
|
||||
std::vector<Loop*> getUnrollCandidateLoops() const {
|
||||
std::vector<Loop*> getUnrollingCandidates() const {
|
||||
std::vector<Loop*> result;
|
||||
for (const auto& [loop, chars] : CharacteristicsMap) {
|
||||
if (chars->benefitsFromUnrolling) {
|
||||
@@ -162,32 +181,6 @@ public:
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据热度排序循环 (用于优化优先级)
|
||||
*/
|
||||
@@ -207,24 +200,24 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
// ========== 统计接口 ==========
|
||||
// ========== 基础统计接口 ==========
|
||||
|
||||
/**
|
||||
* 获取优化候选统计
|
||||
* 获取基础优化统计信息
|
||||
*/
|
||||
struct OptimizationStats {
|
||||
struct BasicOptimizationStats {
|
||||
size_t totalLoops;
|
||||
size_t countingLoops;
|
||||
size_t vectorizableLoops;
|
||||
size_t unrollCandidates;
|
||||
size_t parallelizableLoops;
|
||||
size_t staticBoundLoops;
|
||||
size_t unrollingCandidates;
|
||||
size_t pureLoops;
|
||||
size_t localMemoryOnlyLoops;
|
||||
size_t noAliasConflictLoops;
|
||||
double avgInstructionCount;
|
||||
double avgComputeMemoryRatio;
|
||||
};
|
||||
|
||||
OptimizationStats getOptimizationStats() const {
|
||||
OptimizationStats stats = {};
|
||||
BasicOptimizationStats getOptimizationStats() const {
|
||||
BasicOptimizationStats stats = {};
|
||||
stats.totalLoops = CharacteristicsMap.size();
|
||||
|
||||
size_t totalInstructions = 0;
|
||||
@@ -232,10 +225,10 @@ public:
|
||||
|
||||
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++;
|
||||
if (chars->benefitsFromUnrolling) stats.unrollingCandidates++;
|
||||
if (chars->isPure) stats.pureLoops++;
|
||||
if (chars->accessesOnlyLocalMemory) stats.localMemoryOnlyLoops++;
|
||||
if (chars->hasNoMemoryAliasConflicts) stats.noAliasConflictLoops++;
|
||||
|
||||
totalInstructions += chars->instructionCount;
|
||||
totalComputeMemoryRatio += chars->computeToMemoryRatio;
|
||||
@@ -258,8 +251,8 @@ private:
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 循环特征分析遍
|
||||
* 基于循环分析结果,分析每个循环的特征信息,为优化决策提供依据
|
||||
* @brief 基础循环特征分析遍
|
||||
* 在循环规范化前执行,进行基础的循环特征分析,为后续精确分析提供基础
|
||||
*/
|
||||
class LoopCharacteristicsPass : public AnalysisPass {
|
||||
public:
|
||||
@@ -278,24 +271,42 @@ public:
|
||||
std::unique_ptr<AnalysisResultBase> getResult() override { return std::move(CurrentResult); }
|
||||
|
||||
private:
|
||||
std::unique_ptr<LoopCharacteristicsResult> CurrentResult; // 当前函数的分析结果
|
||||
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 analyzeLoop(Loop* loop, LoopCharacteristics* characteristics, AnalysisManager &AM,
|
||||
AliasAnalysisResult* aliasAnalysis, SideEffectAnalysisResult* sideEffectAnalysis);
|
||||
|
||||
// 基础循环形式分析
|
||||
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);
|
||||
// 基础纯度和副作用分析
|
||||
void analyzePurityAndSideEffects(Loop* loop, LoopCharacteristics* characteristics,
|
||||
SideEffectAnalysisResult* sideEffectAnalysis);
|
||||
|
||||
// 基础归纳变量识别
|
||||
void identifyBasicInductionVariables(Loop* loop, LoopCharacteristics* characteristics);
|
||||
|
||||
// 基础循环不变量识别
|
||||
void identifyBasicLoopInvariants(Loop* loop, LoopCharacteristics* characteristics);
|
||||
|
||||
// 基础边界分析
|
||||
void analyzeBasicLoopBounds(Loop* loop, LoopCharacteristics* characteristics);
|
||||
|
||||
// 基础内存访问模式分析
|
||||
void analyzeBasicMemoryAccessPatterns(Loop* loop, LoopCharacteristics* characteristics,
|
||||
AliasAnalysisResult* aliasAnalysis);
|
||||
|
||||
// 基础优化评估
|
||||
void evaluateBasicOptimizationOpportunities(Loop* loop, LoopCharacteristics* characteristics);
|
||||
|
||||
// ========== 辅助方法 ==========
|
||||
bool isBasicInductionVariable(Value* val, Loop* loop);
|
||||
bool isBasicLoopInvariant(Value* val, Loop* loop);
|
||||
bool hasSimpleMemoryPattern(Loop* loop); // 简单的内存模式检查
|
||||
};
|
||||
|
||||
} // namespace sysy
|
||||
|
||||
Reference in New Issue
Block a user