[midend-LoopAnalysis]移除基本循环特征分析中的向量化并行化内容,增加循环向量化并行化特征分析遍,TODO:构建循环优化遍验证分析遍正确性
This commit is contained in:
@ -1,21 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "Dom.h" // 包含 DominatorTreeAnalysisPass 的依赖
|
||||
#include "IR.h" // 包含 IR 定义
|
||||
#include "Pass.h" // 包含 Pass 框架
|
||||
#include "Dom.h"
|
||||
#include "IR.h"
|
||||
#include "Pass.h"
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <queue> // 用于循环体块的逆向遍历
|
||||
#include <queue>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
namespace sysy {
|
||||
|
||||
// 前向声明,防止循环引用
|
||||
// 前向声明
|
||||
class LoopAnalysisResult;
|
||||
class AliasAnalysisResult;
|
||||
class SideEffectAnalysisResult;
|
||||
|
||||
/**
|
||||
* @brief 表示一个识别出的循环。
|
||||
@ -142,6 +144,24 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查循环是否可能有副作用(基于副作用分析结果)
|
||||
* 使用场景: 循环优化决策、并行化分析
|
||||
*/
|
||||
bool mayHaveSideEffects(SideEffectAnalysisResult* sideEffectAnalysis) const;
|
||||
|
||||
/**
|
||||
* 检查循环是否访问全局内存(基于别名分析结果)
|
||||
* 使用场景: 并行化分析、缓存优化
|
||||
*/
|
||||
bool accessesGlobalMemory(AliasAnalysisResult* aliasAnalysis) const;
|
||||
|
||||
/**
|
||||
* 检查循环是否有可能的内存别名冲突
|
||||
* 使用场景: 向量化分析、并行化决策
|
||||
*/
|
||||
bool hasMemoryAliasConflicts(AliasAnalysisResult* aliasAnalysis) const;
|
||||
|
||||
/**
|
||||
* 估算循环的"热度" (基于嵌套深度和大小)
|
||||
* 使用场景: 优化优先级、资源分配
|
||||
@ -191,14 +211,14 @@ public:
|
||||
};
|
||||
|
||||
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;
|
||||
@ -264,7 +284,7 @@ private:
|
||||
}
|
||||
|
||||
public:
|
||||
// ========== 基础接口 (保持向后兼容,但增加缓存失效) ==========
|
||||
// ========== 基础接口 ==========
|
||||
|
||||
// 添加一个识别出的循环到结果中
|
||||
void addLoop(std::unique_ptr<Loop> loop) {
|
||||
@ -276,7 +296,7 @@ public:
|
||||
// 获取所有识别出的循环(unique_ptr 管理内存)
|
||||
const std::vector<std::unique_ptr<Loop>> &getAllLoops() const { return AllLoops; }
|
||||
|
||||
// ========== 高频查询接口 (缓存优化) ==========
|
||||
// ========== 高频查询接口 ==========
|
||||
|
||||
/**
|
||||
* 获取所有最内层循环 - 循环优化的主要目标
|
||||
@ -366,7 +386,7 @@ public:
|
||||
// 检查函数是否包含循环
|
||||
bool hasLoops() const { return !AllLoops.empty(); }
|
||||
|
||||
// ========== 中频查询接口 (选择性缓存) ==========
|
||||
// ========== 中频查询接口 ==========
|
||||
|
||||
/**
|
||||
* 获取包含指定基本块的最内层循环
|
||||
@ -429,11 +449,61 @@ public:
|
||||
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;
|
||||
@ -448,7 +518,7 @@ public:
|
||||
|
||||
/**
|
||||
* 获取两个循环的最近公共祖先循环
|
||||
* 使用场景: 循环融合分析、优化范围确定
|
||||
* 循环融合分析、优化范围确定
|
||||
*/
|
||||
Loop* getLowestCommonAncestor(Loop* loop1, Loop* loop2) const {
|
||||
if (!loop1 || !loop2) return nullptr;
|
||||
@ -488,14 +558,14 @@ public:
|
||||
// ========== 缓存管理接口 ==========
|
||||
|
||||
/**
|
||||
* 手动失效缓存 (当IR结构改变时调用)
|
||||
* 手动失效缓存 (可删除)
|
||||
*/
|
||||
void invalidateQueryCache() const {
|
||||
invalidateCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存统计信息 (用于性能调试)
|
||||
* 获取缓存统计信息
|
||||
*/
|
||||
CacheStats getCacheStats() const {
|
||||
CacheStats stats = {};
|
||||
@ -510,9 +580,6 @@ public:
|
||||
return stats;
|
||||
}
|
||||
|
||||
// --- 保留的内部接口 ---
|
||||
// 注意:由于使用了缓存机制,不再需要手动维护最外层和最内层循环列表
|
||||
|
||||
// 打印分析结果
|
||||
void print() const;
|
||||
void printBBSet(const std::string &prefix, const std::set<BasicBlock *> &s) const;
|
||||
@ -522,7 +589,6 @@ private:
|
||||
Function *AssociatedFunction; // 结果关联的函数
|
||||
std::vector<std::unique_ptr<Loop>> AllLoops; // 所有识别出的循环
|
||||
std::map<BasicBlock *, Loop *> LoopMap; // 循环头到 Loop* 的映射,方便查找
|
||||
// 注意: 最外层和最内层循环列表已移除,现在通过缓存机制动态计算
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -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
|
||||
|
||||
250
src/include/midend/Pass/Analysis/LoopVectorization.h
Normal file
250
src/include/midend/Pass/Analysis/LoopVectorization.h
Normal file
@ -0,0 +1,250 @@
|
||||
#pragma once
|
||||
|
||||
#include "Pass.h"
|
||||
#include "Loop.h"
|
||||
#include "LoopCharacteristics.h"
|
||||
#include "AliasAnalysis.h"
|
||||
#include "SideEffectAnalysis.h"
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
namespace sysy {
|
||||
|
||||
/**
|
||||
* @brief 依赖类型枚举 - 只考虑真正影响并行性的依赖
|
||||
*
|
||||
* 依赖类型分析说明:
|
||||
* - TRUE_DEPENDENCE (RAW): 真依赖,必须保持原始执行顺序,是最关键的依赖
|
||||
* - ANTI_DEPENDENCE (WAR): 反依赖,影响指令重排序,可通过寄存器重命名等技术缓解
|
||||
* - OUTPUT_DEPENDENCE (WAW): 输出依赖,相对较少但需要考虑,可通过变量私有化解决
|
||||
*
|
||||
*/
|
||||
enum class DependenceType {
|
||||
TRUE_DEPENDENCE, // 真依赖 (RAW) - 读后写流依赖,最重要的依赖类型
|
||||
ANTI_DEPENDENCE, // 反依赖 (WAR) - 写后读反向依赖,影响指令重排序
|
||||
OUTPUT_DEPENDENCE // 输出依赖 (WAW) - 写后写,相对较少但需要考虑
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 依赖向量 - 表示两个内存访问之间的迭代距离
|
||||
* 例如:a[i] 和 a[i+1] 之间的依赖向量是 [1]
|
||||
* a[i][j] 和 a[i+1][j-2] 之间的依赖向量是 [1,-2]
|
||||
*/
|
||||
struct DependenceVector {
|
||||
std::vector<int> distances; // 每个循环层次的依赖距离
|
||||
bool isConstant; // 是否为常量距离
|
||||
bool isKnown; // 是否已知距离
|
||||
|
||||
DependenceVector(size_t loopDepth) : distances(loopDepth, 0), isConstant(false), isKnown(false) {}
|
||||
|
||||
// 检查是否为循环无关依赖
|
||||
bool isLoopIndependent() const {
|
||||
for (int dist : distances) {
|
||||
if (dist != 0) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// 获取词典序方向向量
|
||||
std::vector<int> getDirectionVector() const;
|
||||
|
||||
// 检查是否可以通过向量化处理
|
||||
bool isVectorizationSafe() const;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 精确依赖关系 - 包含依赖向量的详细依赖信息
|
||||
*/
|
||||
struct PreciseDependence {
|
||||
Instruction* source;
|
||||
Instruction* sink;
|
||||
DependenceType type;
|
||||
DependenceVector dependenceVector;
|
||||
Value* memoryLocation;
|
||||
|
||||
// 并行化相关
|
||||
bool allowsParallelization; // 是否允许并行化
|
||||
bool requiresSynchronization; // 是否需要同步
|
||||
bool isReductionDependence; // 是否为归约依赖
|
||||
|
||||
PreciseDependence(size_t loopDepth) : dependenceVector(loopDepth),
|
||||
allowsParallelization(true), requiresSynchronization(false), isReductionDependence(false) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 向量化分析信息 - 暂时搁置,保留接口
|
||||
*/
|
||||
struct VectorizationAnalysis {
|
||||
bool isVectorizable; // 固定为false,暂不支持
|
||||
int suggestedVectorWidth; // 固定为1
|
||||
std::vector<std::string> preventingFactors; // 阻止向量化的因素
|
||||
|
||||
VectorizationAnalysis() : isVectorizable(false), suggestedVectorWidth(1) {
|
||||
preventingFactors.push_back("Vectorization temporarily disabled");
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 并行化分析信息
|
||||
*/
|
||||
struct ParallelizationAnalysis {
|
||||
bool isParallelizable; // 是否可并行化
|
||||
int suggestedThreadCount; // 建议的线程数
|
||||
std::vector<std::string> preventingFactors; // 阻止并行化的因素
|
||||
|
||||
// 并行化模式
|
||||
enum ParallelizationType {
|
||||
NONE, // 不可并行化
|
||||
EMBARRASSINGLY_PARALLEL, // 完全并行
|
||||
REDUCTION_PARALLEL, // 归约并行
|
||||
PIPELINE_PARALLEL, // 流水线并行
|
||||
CONDITIONAL_PARALLEL // 条件并行
|
||||
} parallelType;
|
||||
|
||||
// 负载均衡
|
||||
bool hasLoadBalance; // 是否有良好的负载均衡
|
||||
bool isDynamicLoadBalanced; // 是否需要动态负载均衡
|
||||
double workComplexity; // 工作复杂度估计
|
||||
|
||||
// 同步需求
|
||||
bool requiresReduction; // 是否需要归约操作
|
||||
bool requiresBarrier; // 是否需要屏障同步
|
||||
std::set<Value*> sharedVariables; // 共享变量
|
||||
std::set<Value*> reductionVariables; // 归约变量
|
||||
std::set<Value*> privatizableVariables; // 可私有化变量
|
||||
|
||||
// 内存访问模式
|
||||
bool hasMemoryConflicts; // 是否有内存冲突
|
||||
bool hasReadOnlyAccess; // 是否只有只读访问
|
||||
bool hasIndependentAccess; // 是否有独立的内存访问
|
||||
|
||||
// 并行化收益评估
|
||||
double parallelizationBenefit; // 并行化收益估计 (0-1)
|
||||
size_t communicationCost; // 通信开销估计
|
||||
size_t synchronizationCost; // 同步开销估计
|
||||
|
||||
ParallelizationAnalysis() : isParallelizable(false), suggestedThreadCount(1), parallelType(NONE),
|
||||
hasLoadBalance(true), isDynamicLoadBalanced(false), workComplexity(0.0), requiresReduction(false),
|
||||
requiresBarrier(false), hasMemoryConflicts(false), hasReadOnlyAccess(false), hasIndependentAccess(false),
|
||||
parallelizationBenefit(0.0), communicationCost(0), synchronizationCost(0) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 循环向量化/并行化分析结果
|
||||
*/
|
||||
class LoopVectorizationResult : public AnalysisResultBase {
|
||||
private:
|
||||
Function* AssociatedFunction;
|
||||
std::map<Loop*, VectorizationAnalysis> VectorizationMap;
|
||||
std::map<Loop*, ParallelizationAnalysis> ParallelizationMap;
|
||||
std::map<Loop*, std::vector<PreciseDependence>> DependenceMap;
|
||||
|
||||
public:
|
||||
LoopVectorizationResult(Function* F) : AssociatedFunction(F) {}
|
||||
~LoopVectorizationResult() override = default;
|
||||
|
||||
// 基础接口
|
||||
void addVectorizationAnalysis(Loop* loop, VectorizationAnalysis analysis) {
|
||||
VectorizationMap[loop] = std::move(analysis);
|
||||
}
|
||||
|
||||
void addParallelizationAnalysis(Loop* loop, ParallelizationAnalysis analysis) {
|
||||
ParallelizationMap[loop] = std::move(analysis);
|
||||
}
|
||||
|
||||
void addDependenceAnalysis(Loop* loop, std::vector<PreciseDependence> dependences) {
|
||||
DependenceMap[loop] = std::move(dependences);
|
||||
}
|
||||
|
||||
// 查询接口
|
||||
const VectorizationAnalysis* getVectorizationAnalysis(Loop* loop) const {
|
||||
auto it = VectorizationMap.find(loop);
|
||||
return it != VectorizationMap.end() ? &it->second : nullptr;
|
||||
}
|
||||
|
||||
const ParallelizationAnalysis* getParallelizationAnalysis(Loop* loop) const {
|
||||
auto it = ParallelizationMap.find(loop);
|
||||
return it != ParallelizationMap.end() ? &it->second : nullptr;
|
||||
}
|
||||
|
||||
const std::vector<PreciseDependence>* getPreciseDependences(Loop* loop) const {
|
||||
auto it = DependenceMap.find(loop);
|
||||
return it != DependenceMap.end() ? &it->second : nullptr;
|
||||
}
|
||||
|
||||
// 统计接口
|
||||
size_t getVectorizableLoopCount() const;
|
||||
size_t getParallelizableLoopCount() const;
|
||||
|
||||
// 优化建议
|
||||
std::vector<Loop*> getVectorizationCandidates() const;
|
||||
std::vector<Loop*> getParallelizationCandidates() const;
|
||||
|
||||
// 打印分析结果
|
||||
void print() const;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 循环向量化/并行化分析遍
|
||||
* 在循环规范化后执行,进行精确的依赖向量分析和向量化/并行化可行性评估
|
||||
* 专注于并行化分析,向量化功能暂时搁置
|
||||
*/
|
||||
class LoopVectorizationPass : public AnalysisPass {
|
||||
public:
|
||||
// 唯一的 Pass ID
|
||||
static void *ID;
|
||||
|
||||
LoopVectorizationPass() : AnalysisPass("LoopVectorization", 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<LoopVectorizationResult> CurrentResult;
|
||||
|
||||
// ========== 主要分析方法 ==========
|
||||
void analyzeLoop(Loop* loop, LoopCharacteristics* characteristics,
|
||||
AliasAnalysisResult* aliasAnalysis, SideEffectAnalysisResult* sideEffectAnalysis);
|
||||
|
||||
// ========== 依赖向量分析 ==========
|
||||
std::vector<PreciseDependence> computeDependenceVectors(Loop* loop, AliasAnalysisResult* aliasAnalysis);
|
||||
DependenceVector computeAccessDependence(Instruction* inst1, Instruction* inst2, Loop* loop);
|
||||
bool areAccessesAffinelyRelated(Value* ptr1, Value* ptr2, Loop* loop);
|
||||
|
||||
// ========== 向量化分析 (暂时搁置) ==========
|
||||
VectorizationAnalysis analyzeVectorizability(Loop* loop, const std::vector<PreciseDependence>& dependences,
|
||||
LoopCharacteristics* characteristics);
|
||||
|
||||
// ========== 并行化分析 ==========
|
||||
ParallelizationAnalysis analyzeParallelizability(Loop* loop, const std::vector<PreciseDependence>& dependences,
|
||||
LoopCharacteristics* characteristics);
|
||||
bool checkParallelizationLegality(Loop* loop, const std::vector<PreciseDependence>& dependences);
|
||||
int estimateOptimalThreadCount(Loop* loop, LoopCharacteristics* characteristics);
|
||||
ParallelizationAnalysis::ParallelizationType determineParallelizationType(Loop* loop,
|
||||
const std::vector<PreciseDependence>& dependences);
|
||||
|
||||
// ========== 并行化专用分析方法 ==========
|
||||
void analyzeReductionPatterns(Loop* loop, ParallelizationAnalysis* analysis);
|
||||
void analyzeMemoryAccessPatterns(Loop* loop, ParallelizationAnalysis* analysis, AliasAnalysisResult* aliasAnalysis);
|
||||
void estimateParallelizationBenefit(Loop* loop, ParallelizationAnalysis* analysis, LoopCharacteristics* characteristics);
|
||||
void identifyPrivatizableVariables(Loop* loop, ParallelizationAnalysis* analysis);
|
||||
void analyzeSynchronizationNeeds(Loop* loop, ParallelizationAnalysis* analysis, const std::vector<PreciseDependence>& dependences);
|
||||
|
||||
// ========== 辅助方法 ==========
|
||||
std::vector<int> extractInductionCoefficients(Value* ptr, Loop* loop);
|
||||
bool isConstantStride(Value* ptr, Loop* loop, int& stride);
|
||||
bool isIndependentMemoryAccess(Value* ptr1, Value* ptr2, Loop* loop);
|
||||
double estimateWorkComplexity(Loop* loop);
|
||||
bool hasReductionPattern(Value* var, Loop* loop);
|
||||
};
|
||||
|
||||
} // namespace sysy
|
||||
Reference in New Issue
Block a user