[midend-LoopAnalysis]移除基本循环特征分析中的向量化并行化内容,增加循环向量化并行化特征分析遍,TODO:构建循环优化遍验证分析遍正确性

This commit is contained in:
rain2133
2025-08-09 13:53:00 +08:00
parent bd23f6154d
commit ac3358d7e3
7 changed files with 1473 additions and 303 deletions

View File

@@ -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* 的映射,方便查找
// 注意: 最外层和最内层循环列表已移除,现在通过缓存机制动态计算
};
/**

View File

@@ -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

View 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

View File

@@ -8,6 +8,7 @@ add_library(midend_lib STATIC
Pass/Analysis/Liveness.cpp
Pass/Analysis/Loop.cpp
Pass/Analysis/LoopCharacteristics.cpp
Pass/Analysis/LoopVectorization.cpp
Pass/Analysis/AliasAnalysis.cpp
Pass/Analysis/SideEffectAnalysis.cpp
Pass/Analysis/CallGraphAnalysis.cpp

View File

@@ -1,5 +1,7 @@
#include "Dom.h" // 确保包含 DominatorTreeAnalysisPass 的定义
#include "Loop.h" //
#include "AliasAnalysis.h" // 添加别名分析依赖
#include "SideEffectAnalysis.h" // 添加副作用分析依赖
#include <iostream>
#include <queue> // 用于 BFS 遍历设置循环层级
@@ -124,6 +126,18 @@ bool LoopAnalysisPass::runOnFunction(Function *F, AnalysisManager &AM) {
return false;
}
// 获取别名分析结果 - 用于循环内存访问分析
AliasAnalysisResult *aliasAnalysis = AM.getAnalysisResult<AliasAnalysisResult, SysYAliasAnalysisPass>(F);
if (DEBUG && aliasAnalysis) {
std::cout << "Loop Analysis: Using alias analysis results for enhanced memory pattern detection" << std::endl;
}
// 获取副作用分析结果 - 用于循环纯度分析
SideEffectAnalysisResult *sideEffectAnalysis = AM.getAnalysisResult<SideEffectAnalysisResult, SysYSideEffectAnalysisPass>();
if (DEBUG && sideEffectAnalysis) {
std::cout << "Loop Analysis: Using side effect analysis results for loop purity detection" << std::endl;
}
CurrentResult = std::make_unique<LoopAnalysisResult>(F);
bool changed = false; // 循环分析本身不修改IR所以通常返回false
@@ -335,4 +349,67 @@ bool LoopAnalysisPass::runOnFunction(Function *F, AnalysisManager &AM) {
return changed;
}
// ========== Loop 类的新增方法实现 ==========
bool Loop::mayHaveSideEffects(SideEffectAnalysisResult* sideEffectAnalysis) const {
if (!sideEffectAnalysis) return true; // 保守假设
for (BasicBlock* bb : LoopBlocks) {
for (auto& inst : bb->getInstructions()) {
if (sideEffectAnalysis->hasSideEffect(inst.get())) {
return true;
}
}
}
return false;
}
bool Loop::accessesGlobalMemory(AliasAnalysisResult* aliasAnalysis) const {
if (!aliasAnalysis) return true; // 保守假设
for (BasicBlock* bb : LoopBlocks) {
for (auto& inst : bb->getInstructions()) {
if (auto* loadInst = dynamic_cast<LoadInst*>(inst.get())) {
if (!aliasAnalysis->isLocalArray(loadInst->getPointer())) {
return true;
}
} else if (auto* storeInst = dynamic_cast<StoreInst*>(inst.get())) {
if (!aliasAnalysis->isLocalArray(storeInst->getPointer())) {
return true;
}
}
}
}
return false;
}
bool Loop::hasMemoryAliasConflicts(AliasAnalysisResult* aliasAnalysis) const {
if (!aliasAnalysis) return true; // 保守假设
std::vector<Value*> memoryAccesses;
// 收集所有内存访问
for (BasicBlock* bb : LoopBlocks) {
for (auto& inst : bb->getInstructions()) {
if (auto* loadInst = dynamic_cast<LoadInst*>(inst.get())) {
memoryAccesses.push_back(loadInst->getPointer());
} else if (auto* storeInst = dynamic_cast<StoreInst*>(inst.get())) {
memoryAccesses.push_back(storeInst->getPointer());
}
}
}
// 检查两两之间是否有别名
for (size_t i = 0; i < memoryAccesses.size(); ++i) {
for (size_t j = i + 1; j < memoryAccesses.size(); ++j) {
auto aliasType = aliasAnalysis->queryAlias(memoryAccesses[i], memoryAccesses[j]);
if (aliasType == AliasType::SELF_ALIAS || aliasType == AliasType::POSSIBLE_ALIAS) {
return true;
}
}
}
return false;
}
} // namespace sysy

View File

@@ -2,6 +2,8 @@
#include "Dom.h"
#include "Loop.h"
#include "Liveness.h"
#include "AliasAnalysis.h"
#include "SideEffectAnalysis.h"
#include <iostream>
#include <cmath>
@@ -14,7 +16,7 @@ namespace sysy {
void *LoopCharacteristicsPass::ID = (void *)&LoopCharacteristicsPass::ID;
void LoopCharacteristicsResult::print() const {
if (!DEBUG) return; // 只有在 DEBUG 模式下才打印
if (!DEBUG) return;
std::cout << "\n--- Loop Characteristics Analysis Results for Function: "
<< AssociatedFunction->getName() << " ---" << std::endl;
@@ -26,13 +28,13 @@ void LoopCharacteristicsResult::print() const {
// 打印统计信息
auto stats = getOptimizationStats();
std::cout << "\n=== Optimization Statistics ===" << std::endl;
std::cout << "\n=== Basic Loop Characteristics Statistics ===" << std::endl;
std::cout << "Total Loops: " << stats.totalLoops << std::endl;
std::cout << "Counting Loops: " << stats.countingLoops << std::endl;
std::cout << "Vectorizable Loops: " << stats.vectorizableLoops << std::endl;
std::cout << "Unroll Candidates: " << stats.unrollCandidates << std::endl;
std::cout << "Parallelizable Loops: " << stats.parallelizableLoops << std::endl;
std::cout << "Static Bound Loops: " << stats.staticBoundLoops << std::endl;
std::cout << "Unrolling Candidates: " << stats.unrollingCandidates << std::endl;
std::cout << "Pure Loops: " << stats.pureLoops << std::endl;
std::cout << "Local Memory Only Loops: " << stats.localMemoryOnlyLoops << std::endl;
std::cout << "No Alias Conflict Loops: " << stats.noAliasConflictLoops << std::endl;
std::cout << "Avg Instructions per Loop: " << stats.avgInstructionCount << std::endl;
std::cout << "Avg Compute/Memory Ratio: " << stats.avgComputeMemoryRatio << std::endl;
@@ -58,6 +60,9 @@ void LoopCharacteristicsResult::print() const {
if (chars->isSimpleForLoop) std::cout << "SimpleFor ";
if (chars->isInnermost) std::cout << "Innermost ";
if (chars->hasComplexControlFlow) std::cout << "Complex ";
if (chars->isPure) std::cout << "Pure ";
if (chars->accessesOnlyLocalMemory) std::cout << "LocalMemOnly ";
if (chars->hasNoMemoryAliasConflicts) std::cout << "NoAliasConflicts ";
std::cout << std::endl;
// 边界信息
@@ -72,18 +77,12 @@ void LoopCharacteristicsResult::print() const {
std::cout << " Optimization Opportunities: ";
if (chars->benefitsFromUnrolling)
std::cout << "Unroll(factor=" << chars->suggestedUnrollFactor << ") ";
if (chars->benefitsFromVectorization) std::cout << "Vectorize ";
if (chars->benefitsFromTiling) std::cout << "Tile ";
if (chars->isParallel) std::cout << "Parallelize ";
std::cout << std::endl;
// 归纳变量
if (!chars->basicInductionVars.empty()) {
std::cout << " Basic Induction Vars: " << chars->basicInductionVars.size() << std::endl;
}
if (!chars->derivedInductionVars.empty()) {
std::cout << " Derived Induction Vars: " << chars->derivedInductionVars.size() << std::endl;
}
// 循环不变量
if (!chars->loopInvariants.empty()) {
@@ -106,7 +105,7 @@ bool LoopCharacteristicsPass::runOnFunction(Function *F, AnalysisManager &AM) {
if (DEBUG)
std::cout << "Running LoopCharacteristicsPass on function: " << F->getName() << std::endl;
// 获取循环分析结果 - 这是我们的核心依赖
// 获取循环分析结果
auto* loopAnalysisResult = AM.getAnalysisResult<LoopAnalysisResult, LoopAnalysisPass>(F);
if (!loopAnalysisResult) {
std::cerr << "Error: LoopAnalysisResult not available for function " << F->getName() << std::endl;
@@ -120,6 +119,15 @@ bool LoopCharacteristicsPass::runOnFunction(Function *F, AnalysisManager &AM) {
return false;
}
// 获取别名分析和副作用分析结果
auto* aliasAnalysis = AM.getAnalysisResult<AliasAnalysisResult, SysYAliasAnalysisPass>(F);
auto* sideEffectAnalysis = AM.getAnalysisResult<SideEffectAnalysisResult, SysYSideEffectAnalysisPass>();
if (DEBUG) {
if (aliasAnalysis) std::cout << "LoopCharacteristics: Using alias analysis results" << std::endl;
if (sideEffectAnalysis) std::cout << "LoopCharacteristics: Using side effect analysis results" << std::endl;
}
CurrentResult = std::make_unique<LoopCharacteristicsResult>(F);
// 分析每个循环的特征
@@ -127,8 +135,8 @@ bool LoopCharacteristicsPass::runOnFunction(Function *F, AnalysisManager &AM) {
Loop* loop = loop_ptr.get();
auto characteristics = std::make_unique<LoopCharacteristics>(loop);
// 执行各种特征分析
analyzeLoop(loop, characteristics.get(), AM);
// 执行各种特征分析,传递分析结果
analyzeLoop(loop, characteristics.get(), AM, aliasAnalysis, sideEffectAnalysis);
// 添加到结果中
CurrentResult->addLoopCharacteristics(std::move(characteristics));
@@ -138,25 +146,28 @@ bool LoopCharacteristicsPass::runOnFunction(Function *F, AnalysisManager &AM) {
std::cout << "LoopCharacteristicsPass completed for function: " << F->getName() << std::endl;
auto stats = CurrentResult->getOptimizationStats();
std::cout << "Analyzed " << stats.totalLoops << " loops, found "
<< stats.vectorizableLoops << " vectorizable, "
<< stats.unrollCandidates << " unrollable" << std::endl;
<< stats.countingLoops << " counting loops, "
<< stats.unrollingCandidates << " unroll candidates" << std::endl;
}
return false; // 特征分析不修改IR
}
void LoopCharacteristicsPass::analyzeLoop(Loop* loop, LoopCharacteristics* characteristics, AnalysisManager &AM) {
void LoopCharacteristicsPass::analyzeLoop(Loop* loop, LoopCharacteristics* characteristics,
AnalysisManager &AM, AliasAnalysisResult* aliasAnalysis,
SideEffectAnalysisResult* sideEffectAnalysis) {
if (DEBUG)
std::cout << " Analyzing characteristics of loop: " << loop->getName() << std::endl;
std::cout << " Analyzing basic characteristics of loop: " << loop->getName() << std::endl;
// 按顺序执行各种分析
// 按顺序执行基础分析
computePerformanceMetrics(loop, characteristics);
analyzeLoopForm(loop, characteristics);
identifyInductionVariables(loop, characteristics);
identifyLoopInvariants(loop, characteristics);
analyzeLoopBounds(loop, characteristics);
analyzeMemoryAccessPatterns(loop, characteristics);
evaluateOptimizationOpportunities(loop, characteristics);
analyzePurityAndSideEffects(loop, characteristics, sideEffectAnalysis);
identifyBasicInductionVariables(loop, characteristics);
identifyBasicLoopInvariants(loop, characteristics);
analyzeBasicLoopBounds(loop, characteristics);
analyzeBasicMemoryAccessPatterns(loop, characteristics, aliasAnalysis);
evaluateBasicOptimizationOpportunities(loop, characteristics);
}
void LoopCharacteristicsPass::computePerformanceMetrics(Loop* loop, LoopCharacteristics* characteristics) {
@@ -210,140 +221,132 @@ void LoopCharacteristicsPass::analyzeLoopForm(Loop* loop, LoopCharacteristics* c
characteristics->isCountingLoop = isSimple && loop->isInnermost() && exitingBlocks.size() == 1;
}
void LoopCharacteristicsPass::identifyInductionVariables(Loop* loop, LoopCharacteristics* characteristics) {
// 寻找基本归纳变量
void LoopCharacteristicsPass::analyzePurityAndSideEffects(Loop* loop, LoopCharacteristics* characteristics,
SideEffectAnalysisResult* sideEffectAnalysis) {
if (!sideEffectAnalysis) {
// 没有副作用分析结果,保守处理
characteristics->isPure = false;
return;
}
// 检查循环是否有副作用
characteristics->isPure = !loop->mayHaveSideEffects(sideEffectAnalysis);
if (DEBUG && characteristics->isPure) {
std::cout << " Loop " << loop->getName() << " is identified as PURE (no side effects)" << std::endl;
}
}
void LoopCharacteristicsPass::analyzeBasicMemoryAccessPatterns(Loop* loop, LoopCharacteristics* characteristics,
AliasAnalysisResult* aliasAnalysis) {
if (!aliasAnalysis) {
// 没有别名分析结果,保守处理
characteristics->accessesOnlyLocalMemory = false;
characteristics->hasNoMemoryAliasConflicts = false;
return;
}
// 检查是否只访问局部内存
characteristics->accessesOnlyLocalMemory = !loop->accessesGlobalMemory(aliasAnalysis);
// 检查是否有内存别名冲突
characteristics->hasNoMemoryAliasConflicts = !loop->hasMemoryAliasConflicts(aliasAnalysis);
if (DEBUG) {
if (characteristics->accessesOnlyLocalMemory) {
std::cout << " Loop " << loop->getName() << " accesses ONLY LOCAL MEMORY" << std::endl;
}
if (characteristics->hasNoMemoryAliasConflicts) {
std::cout << " Loop " << loop->getName() << " has NO MEMORY ALIAS CONFLICTS" << std::endl;
}
}
// 分析基础的内存访问模式
for (BasicBlock* bb : loop->getBlocks()) {
for (auto& inst : bb->getInstructions()) {
if (auto* loadInst = dynamic_cast<LoadInst*>(inst.get())) {
Value* ptr = loadInst->getPointer();
auto& pattern = characteristics->memoryPatterns[ptr];
pattern.loadInsts.push_back(loadInst);
pattern.isArrayParameter = aliasAnalysis->isFunctionParameter(ptr);
pattern.isGlobalArray = aliasAnalysis->isGlobalArray(ptr);
pattern.hasConstantIndices = aliasAnalysis->hasConstantAccess(ptr);
} else if (auto* storeInst = dynamic_cast<StoreInst*>(inst.get())) {
Value* ptr = storeInst->getPointer();
auto& pattern = characteristics->memoryPatterns[ptr];
pattern.storeInsts.push_back(storeInst);
pattern.isArrayParameter = aliasAnalysis->isFunctionParameter(ptr);
pattern.isGlobalArray = aliasAnalysis->isGlobalArray(ptr);
pattern.hasConstantIndices = aliasAnalysis->hasConstantAccess(ptr);
}
}
}
}
void LoopCharacteristicsPass::identifyBasicInductionVariables(Loop* loop, LoopCharacteristics* characteristics) {
// 寻找基本归纳变量(简化版本)
BasicBlock* header = loop->getHeader();
// 遍历循环头的phi指令寻找归纳变量模式
// 遍历循环头的phi指令寻找基本归纳变量模式
for (auto& inst : header->getInstructions()) {
auto* phiInst = dynamic_cast<PhiInst*>(inst.get());
if (!phiInst) continue;
// 检查phi指令是否符合归纳变量模式
if (isInductionVariable(phiInst, loop)) {
// 检查phi指令是否符合基本归纳变量模式
if (isBasicInductionVariable(phiInst, loop)) {
characteristics->basicInductionVars.push_back(phiInst);
// 分析步长 (简化版本)
characteristics->inductionSteps[phiInst] = 1; // 默认步长为1
characteristics->inductionSteps[phiInst] = 1; // 简化默认步长为1
if (DEBUG)
std::cout << " Found basic induction variable: " << phiInst->getName() << std::endl;
}
}
// 寻找派生归纳变量 (基于基本归纳变量的线性表达式)
for (BasicBlock* bb : loop->getBlocks()) {
for (auto& inst : bb->getInstructions()) {
// 检查是否为基于归纳变量的计算
if (auto* binInst = dynamic_cast<BinaryInst*>(inst.get())) {
// 简化:检查操作数是否包含基本归纳变量
for (Value* basicIV : characteristics->basicInductionVars) {
// 这里需要更复杂的分析来确定派生关系
// 暂时简化处理
}
}
}
}
}
void LoopCharacteristicsPass::identifyLoopInvariants(Loop* loop, LoopCharacteristics* characteristics) {
// 收集循环不变量
void LoopCharacteristicsPass::identifyBasicLoopInvariants(Loop* loop, LoopCharacteristics* characteristics) {
// 收集基础循环不变量(简化版本)
for (BasicBlock* bb : loop->getBlocks()) {
for (auto& inst : bb->getInstructions()) {
Value* val = inst.get();
// 跳过phi指令和终结指令
if (dynamic_cast<PhiInst*>(val)) {
continue;
}
// 检查是否为终结指令
if (dynamic_cast<PhiInst*>(val)) continue;
if (auto* instPtr = dynamic_cast<Instruction*>(val)) {
if (instPtr->isTerminator()) {
continue;
}
if (instPtr->isTerminator()) continue;
}
if (isLoopInvariant(val, loop)) {
if (isBasicLoopInvariant(val, loop)) {
characteristics->loopInvariants.insert(val);
characteristics->invariantInsts.insert(static_cast<Instruction*>(val));
if (DEBUG)
std::cout << " Found loop invariant: " << val->getName() << std::endl;
std::cout << " Found basic loop invariant: " << val->getName() << std::endl;
}
}
}
}
void LoopCharacteristicsPass::analyzeLoopBounds(Loop* loop, LoopCharacteristics* characteristics) {
// 简化的边界分析
// 在实际实现中,需要分析循环的条件表达式来确定边界
// 检查是否有静态可确定的循环次数
void LoopCharacteristicsPass::analyzeBasicLoopBounds(Loop* loop, LoopCharacteristics* characteristics) {
// 简化的基础边界分析
// 检查是否有静态可确定的循环次数(简化版本)
if (characteristics->isCountingLoop && !characteristics->basicInductionVars.empty()) {
// 简化:如果是计数循环且有基本归纳变量,尝试确定循环次数
// 这里需要更复杂的符号执行或约束求解
// 暂时设置一个保守估计
if (characteristics->instructionCount < 10) {
characteristics->staticTripCount = 100; // 假设小循环执行100次
characteristics->staticTripCount = 100; // 简化估计
characteristics->hasKnownBounds = true;
if (DEBUG) {
std::cout << " Estimated static trip count: " << *characteristics->staticTripCount << std::endl;
}
}
}
}
void LoopCharacteristicsPass::analyzeMemoryAccessPatterns(Loop* loop, LoopCharacteristics* characteristics) {
// 使用外部别名分析结果 - 大幅简化版本
std::map<Value*, std::vector<Instruction*>> accessMap;
// 收集所有内存访问
for (BasicBlock* bb : loop->getBlocks()) {
for (auto& inst : bb->getInstructions()) {
if (auto* loadInst = dynamic_cast<LoadInst*>(inst.get())) {
Value* ptr = loadInst->getPointer();
accessMap[ptr].push_back(loadInst);
} else if (auto* storeInst = dynamic_cast<StoreInst*>(inst.get())) {
Value* ptr = storeInst->getPointer();
accessMap[ptr].push_back(storeInst);
}
}
}
// 分析每个内存位置的访问模式
for (auto& [ptr, accesses] : accessMap) {
LoopCharacteristics::MemoryAccessPattern pattern;
// 初始化基本字段
pattern.isSequential = true; // 简化:假设大部分访问是顺序的
pattern.isStrided = false;
pattern.stride = 1;
// 使用别名分析结果 (简化:设置默认值,实际应该查询别名分析)
pattern.aliasType = AliasType::UNKNOWN_ALIAS; // 保守默认值
pattern.isArrayParameter = false;
pattern.isGlobalArray = false;
pattern.hasConstantIndices = true;
// 分类load和store
for (Instruction* inst : accesses) {
if (dynamic_cast<LoadInst*>(inst)) {
pattern.loadInsts.push_back(inst);
} else {
pattern.storeInsts.push_back(inst);
}
}
characteristics->memoryPatterns[ptr] = pattern;
if (DEBUG && (static_cast<int>(pattern.aliasType) >= 2)) { // POSSIBLE_ALIAS及以上
std::cout << " Found potential aliasing for memory access, type: "
<< static_cast<int>(pattern.aliasType) << std::endl;
}
}
}
void LoopCharacteristicsPass::evaluateOptimizationOpportunities(Loop* loop, LoopCharacteristics* characteristics) {
// 评估循环展开机会
void LoopCharacteristicsPass::evaluateBasicOptimizationOpportunities(Loop* loop, LoopCharacteristics* characteristics) {
// 评估基础循环展开机会
characteristics->benefitsFromUnrolling =
characteristics->isInnermost &&
characteristics->instructionCount > 3 &&
@@ -351,27 +354,25 @@ void LoopCharacteristicsPass::evaluateOptimizationOpportunities(Loop* loop, Loop
!characteristics->hasComplexControlFlow;
if (characteristics->benefitsFromUnrolling) {
characteristics->suggestedUnrollFactor = estimateUnrollFactor(loop);
// 基于循环体大小估算展开因子
if (characteristics->instructionCount <= 5) characteristics->suggestedUnrollFactor = 8;
else if (characteristics->instructionCount <= 10) characteristics->suggestedUnrollFactor = 4;
else if (characteristics->instructionCount <= 20) characteristics->suggestedUnrollFactor = 2;
else characteristics->suggestedUnrollFactor = 1;
}
// 评估向量化机会
characteristics->benefitsFromVectorization = benefitsFromVectorization(loop);
// 评估并行化机会
characteristics->isParallel =
!hasLoopCarriedDependence(loop) &&
characteristics->isCountingLoop;
// 评估分块机会 (主要针对嵌套循环)
characteristics->benefitsFromTiling =
!loop->isInnermost() &&
characteristics->memoryOperationCount > characteristics->arithmeticOperationCount;
if (DEBUG) {
if (characteristics->benefitsFromUnrolling) {
std::cout << " Loop " << loop->getName() << " benefits from UNROLLING (factor="
<< characteristics->suggestedUnrollFactor << ")" << std::endl;
}
}
}
// ========== 辅助方法实现 ==========
bool LoopCharacteristicsPass::isInductionVariable(Value* val, Loop* loop) {
// 简化的归纳变量检测
bool LoopCharacteristicsPass::isBasicInductionVariable(Value* val, Loop* loop) {
// 简化的基础归纳变量检测
auto* phiInst = dynamic_cast<PhiInst*>(val);
if (!phiInst) return false;
@@ -381,15 +382,14 @@ bool LoopCharacteristicsPass::isInductionVariable(Value* val, Loop* loop) {
// 检查是否有来自循环内的更新
for (auto& [incomingBB, incomingVal] : phiInst->getIncomingValues()) {
if (loop->contains(incomingBB)) {
// 简化:如果有来自循环内的值认为可能是归纳变量
return true;
return true; // 简化:有来自循环内的值认为是基础归纳变量
}
}
return false;
}
bool LoopCharacteristicsPass::isLoopInvariant(Value* val, Loop* loop) {
bool LoopCharacteristicsPass::isBasicLoopInvariant(Value* val, Loop* loop) {
auto* inst = dynamic_cast<Instruction*>(val);
if (!inst) return true; // 非指令(如常量)认为是不变的
@@ -398,57 +398,19 @@ bool LoopCharacteristicsPass::isLoopInvariant(Value* val, Loop* loop) {
return true;
}
// 检查操作数是否都是循环不变
// 简化版本如果是load指令且指针是不变的认为可能是不变的
// 简化的基础不变量检测load指令且指针是循环
if (auto* loadInst = dynamic_cast<LoadInst*>(inst)) {
Value* ptr = loadInst->getPointer();
return isLoopInvariant(ptr, loop);
return isBasicLoopInvariant(ptr, loop);
}
// 简化:对于其他指令,保守地认为是变化的
// 保守:对于其他指令,认为是变化的
return false;
}
bool LoopCharacteristicsPass::hasLoopCarriedDependence(Loop* loop) {
// 简化的依赖分析
// 检查是否有写后读或写后写依赖跨越循环迭代
std::set<Value*> writtenVars;
std::set<Value*> readVars;
for (BasicBlock* bb : loop->getBlocks()) {
for (auto& inst : bb->getInstructions()) {
if (auto* storeInst = dynamic_cast<StoreInst*>(inst.get())) {
writtenVars.insert(storeInst->getPointer());
} else if (auto* loadInst = dynamic_cast<LoadInst*>(inst.get())) {
readVars.insert(loadInst->getPointer());
}
}
}
// 简化:如果有写后读到同一变量,假设存在依赖
for (Value* written : writtenVars) {
if (readVars.count(written)) {
return true; // 可能存在依赖
}
}
return false; // 保守估计:没有明显依赖
}
int LoopCharacteristicsPass::estimateUnrollFactor(Loop* loop) {
// 基于循环体大小估算展开因子
if (loop->getLoopSize() <= 2) return 8; // 很小的循环
if (loop->getLoopSize() <= 5) return 4; // 小循环
if (loop->getLoopSize() <= 10) return 2; // 中等循环
return 1; // 大循环不建议展开
}
bool LoopCharacteristicsPass::benefitsFromVectorization(Loop* loop) {
// 简化的向量化收益评估
return loop->isInnermost() && // 最内层循环
loop->isSimpleLoop() && // 简单循环结构
!hasLoopCarriedDependence(loop); // 没有明显的依赖
bool LoopCharacteristicsPass::hasSimpleMemoryPattern(Loop* loop) {
// 检查是否有简单的内存访问模式
return true; // 暂时简化处理
}
} // namespace sysy

View File

@@ -0,0 +1,803 @@
#include "LoopVectorization.h"
#include "Dom.h"
#include "Loop.h"
#include "Liveness.h"
#include "AliasAnalysis.h"
#include "SideEffectAnalysis.h"
#include <iostream>
#include <algorithm>
#include <cmath>
#include <set>
extern int DEBUG;
namespace sysy {
// 定义 Pass 的唯一 ID
void *LoopVectorizationPass::ID = (void *)&LoopVectorizationPass::ID;
std::vector<int> DependenceVector::getDirectionVector() const {
std::vector<int> direction;
direction.reserve(distances.size());
for (int dist : distances) {
if (dist > 0) direction.push_back(1); // 前向依赖
else if (dist < 0) direction.push_back(-1); // 后向依赖
else direction.push_back(0); // 无依赖
}
return direction;
}
bool DependenceVector::isVectorizationSafe() const {
if (!isKnown) return false; // 未知依赖,不安全
// 对于向量化,我们主要关心最内层循环的依赖
if (distances.empty()) return true;
int innermostDistance = distances.back(); // 最内层循环的距离
// 前向依赖 (距离 > 0) 通常是安全的,可以通过调整向量化顺序处理
// 后向依赖 (距离 < 0) 通常不安全,会阻止向量化
// 距离 = 0 表示同一迭代内的依赖,通常安全
return innermostDistance >= 0;
}
size_t LoopVectorizationResult::getVectorizableLoopCount() const {
size_t count = 0;
for (const auto& [loop, analysis] : VectorizationMap) {
if (analysis.isVectorizable) count++;
}
return count;
}
size_t LoopVectorizationResult::getParallelizableLoopCount() const {
size_t count = 0;
for (const auto& [loop, analysis] : ParallelizationMap) {
if (analysis.isParallelizable) count++;
}
return count;
}
std::vector<Loop*> LoopVectorizationResult::getVectorizationCandidates() const {
std::vector<Loop*> candidates;
for (const auto& [loop, analysis] : VectorizationMap) {
if (analysis.isVectorizable) {
candidates.push_back(loop);
}
}
// 按建议的向量宽度排序,优先处理收益更大的循环
std::sort(candidates.begin(), candidates.end(),
[this](Loop* a, Loop* b) {
const auto& analysisA = VectorizationMap.at(a);
const auto& analysisB = VectorizationMap.at(b);
return analysisA.suggestedVectorWidth > analysisB.suggestedVectorWidth;
});
return candidates;
}
std::vector<Loop*> LoopVectorizationResult::getParallelizationCandidates() const {
std::vector<Loop*> candidates;
for (const auto& [loop, analysis] : ParallelizationMap) {
if (analysis.isParallelizable) {
candidates.push_back(loop);
}
}
// 按建议的线程数排序
std::sort(candidates.begin(), candidates.end(),
[this](Loop* a, Loop* b) {
const auto& analysisA = ParallelizationMap.at(a);
const auto& analysisB = ParallelizationMap.at(b);
return analysisA.suggestedThreadCount > analysisB.suggestedThreadCount;
});
return candidates;
}
void LoopVectorizationResult::print() const {
if (!DEBUG) return;
std::cout << "\n--- Loop Vectorization/Parallelization Analysis Results for Function: "
<< AssociatedFunction->getName() << " ---" << std::endl;
if (VectorizationMap.empty() && ParallelizationMap.empty()) {
std::cout << " No vectorization/parallelization analysis results." << std::endl;
return;
}
// 统计信息
std::cout << "\n=== Summary ===" << std::endl;
std::cout << "Total Loops Analyzed: " << VectorizationMap.size() << std::endl;
std::cout << "Vectorizable Loops: " << getVectorizableLoopCount() << std::endl;
std::cout << "Parallelizable Loops: " << getParallelizableLoopCount() << std::endl;
// 详细分析结果
for (const auto& [loop, vecAnalysis] : VectorizationMap) {
std::cout << "\n--- Loop: " << loop->getName() << " ---" << std::endl;
// 向量化分析 (暂时搁置)
std::cout << " Vectorization: " << (vecAnalysis.isVectorizable ? "YES" : "NO") << std::endl;
if (!vecAnalysis.preventingFactors.empty()) {
std::cout << " Preventing Factors: ";
for (const auto& factor : vecAnalysis.preventingFactors) {
std::cout << factor << " ";
}
std::cout << std::endl;
}
// 并行化分析
auto parallelIt = ParallelizationMap.find(loop);
if (parallelIt != ParallelizationMap.end()) {
const auto& parAnalysis = parallelIt->second;
std::cout << " Parallelization: " << (parAnalysis.isParallelizable ? "YES" : "NO") << std::endl;
if (parAnalysis.isParallelizable) {
std::cout << " Suggested Thread Count: " << parAnalysis.suggestedThreadCount << std::endl;
if (parAnalysis.requiresReduction) {
std::cout << " Requires Reduction: Yes" << std::endl;
}
if (parAnalysis.requiresBarrier) {
std::cout << " Requires Barrier: Yes" << std::endl;
}
} else if (!parAnalysis.preventingFactors.empty()) {
std::cout << " Preventing Factors: ";
for (const auto& factor : parAnalysis.preventingFactors) {
std::cout << factor << " ";
}
std::cout << std::endl;
}
}
// 依赖关系
auto depIt = DependenceMap.find(loop);
if (depIt != DependenceMap.end()) {
const auto& dependences = depIt->second;
std::cout << " Dependences: " << dependences.size() << " found" << std::endl;
for (const auto& dep : dependences) {
if (dep.dependenceVector.isKnown) {
std::cout << " " << dep.source->getName() << " -> " << dep.sink->getName();
std::cout << " [";
for (size_t i = 0; i < dep.dependenceVector.distances.size(); ++i) {
if (i > 0) std::cout << ",";
std::cout << dep.dependenceVector.distances[i];
}
std::cout << "]" << std::endl;
}
}
}
}
std::cout << "-----------------------------------------------" << std::endl;
}
bool LoopVectorizationPass::runOnFunction(Function *F, AnalysisManager &AM) {
if (F->getBasicBlocks().empty()) {
CurrentResult = std::make_unique<LoopVectorizationResult>(F);
return false;
}
if (DEBUG) {
std::cout << "Running LoopVectorizationPass on function: " << F->getName() << std::endl;
}
// 获取循环分析结果
auto* loopAnalysisResult = AM.getAnalysisResult<LoopAnalysisResult, LoopAnalysisPass>(F);
if (!loopAnalysisResult || !loopAnalysisResult->hasLoops()) {
CurrentResult = std::make_unique<LoopVectorizationResult>(F);
return false;
}
// 获取循环特征分析结果
auto* loopCharacteristics = AM.getAnalysisResult<LoopCharacteristicsResult, LoopCharacteristicsPass>(F);
if (!loopCharacteristics) {
if (DEBUG) {
std::cout << "Warning: LoopCharacteristics analysis not available" << std::endl;
}
}
// 获取别名分析结果
auto* aliasAnalysis = AM.getAnalysisResult<AliasAnalysisResult, SysYAliasAnalysisPass>(F);
// 获取副作用分析结果
auto* sideEffectAnalysis = AM.getAnalysisResult<SideEffectAnalysisResult, SysYSideEffectAnalysisPass>();
CurrentResult = std::make_unique<LoopVectorizationResult>(F);
// 分析每个循环的向量化/并行化可行性
for (const auto& loop_ptr : loopAnalysisResult->getAllLoops()) {
Loop* loop = loop_ptr.get();
// 获取该循环的特征信息
LoopCharacteristics* characteristics = nullptr;
if (loopCharacteristics) {
characteristics = const_cast<LoopCharacteristics*>(loopCharacteristics->getCharacteristics(loop));
}
analyzeLoop(loop, characteristics, aliasAnalysis, sideEffectAnalysis);
}
if (DEBUG) {
std::cout << "LoopVectorizationPass completed. Found "
<< CurrentResult->getVectorizableLoopCount() << " vectorizable loops, "
<< CurrentResult->getParallelizableLoopCount() << " parallelizable loops" << std::endl;
}
return false; // 分析遍不修改IR
}
void LoopVectorizationPass::analyzeLoop(Loop* loop, LoopCharacteristics* characteristics,
AliasAnalysisResult* aliasAnalysis, SideEffectAnalysisResult* sideEffectAnalysis) {
if (DEBUG) {
std::cout << " Analyzing advanced features for loop: " << loop->getName() << std::endl;
}
// 1. 计算精确依赖向量
auto dependences = computeDependenceVectors(loop, aliasAnalysis);
CurrentResult->addDependenceAnalysis(loop, dependences);
// 2. 分析向量化可行性 (暂时搁置,总是返回不可向量化)
auto vecAnalysis = analyzeVectorizability(loop, dependences, characteristics);
CurrentResult->addVectorizationAnalysis(loop, vecAnalysis);
// 3. 分析并行化可行性
auto parAnalysis = analyzeParallelizability(loop, dependences, characteristics);
CurrentResult->addParallelizationAnalysis(loop, parAnalysis);
}
// ========== 依赖向量分析实现 ==========
std::vector<PreciseDependence> LoopVectorizationPass::computeDependenceVectors(Loop* loop,
AliasAnalysisResult* aliasAnalysis) {
std::vector<PreciseDependence> dependences;
std::vector<Instruction*> memoryInsts;
// 收集所有内存操作指令
for (BasicBlock* bb : loop->getBlocks()) {
for (auto& inst : bb->getInstructions()) {
if (dynamic_cast<LoadInst*>(inst.get()) || dynamic_cast<StoreInst*>(inst.get())) {
memoryInsts.push_back(inst.get());
}
}
}
// 分析每对内存操作之间的依赖关系
for (size_t i = 0; i < memoryInsts.size(); ++i) {
for (size_t j = i + 1; j < memoryInsts.size(); ++j) {
Instruction* inst1 = memoryInsts[i];
Instruction* inst2 = memoryInsts[j];
Value* ptr1 = nullptr;
Value* ptr2 = nullptr;
if (auto* load = dynamic_cast<LoadInst*>(inst1)) {
ptr1 = load->getPointer();
} else if (auto* store = dynamic_cast<StoreInst*>(inst1)) {
ptr1 = store->getPointer();
}
if (auto* load = dynamic_cast<LoadInst*>(inst2)) {
ptr2 = load->getPointer();
} else if (auto* store = dynamic_cast<StoreInst*>(inst2)) {
ptr2 = store->getPointer();
}
if (!ptr1 || !ptr2) continue;
// 检查是否可能存在别名关系
bool mayAlias = false;
if (aliasAnalysis) {
mayAlias = aliasAnalysis->queryAlias(ptr1, ptr2) != AliasType::NO_ALIAS;
} else {
mayAlias = (ptr1 != ptr2); // 保守估计
}
if (mayAlias) {
// 创建依赖关系
PreciseDependence dep(loop->getLoopDepth());
dep.source = inst1;
dep.sink = inst2;
dep.memoryLocation = ptr1;
// 确定依赖类型
bool isStore1 = dynamic_cast<StoreInst*>(inst1) != nullptr;
bool isStore2 = dynamic_cast<StoreInst*>(inst2) != nullptr;
if (isStore1 && !isStore2) {
dep.type = DependenceType::TRUE_DEPENDENCE; // Write -> Read (RAW)
} else if (!isStore1 && isStore2) {
dep.type = DependenceType::ANTI_DEPENDENCE; // Read -> Write (WAR)
} else if (isStore1 && isStore2) {
dep.type = DependenceType::OUTPUT_DEPENDENCE; // Write -> Write (WAW)
} else {
continue; // Read -> Read (RAR) - 跳过,不是真正的依赖
}
// 计算依赖向量
dep.dependenceVector = computeAccessDependence(inst1, inst2, loop);
// 判断是否允许并行化
dep.allowsParallelization = dep.dependenceVector.isLoopIndependent() ||
(dep.dependenceVector.isKnown &&
std::all_of(dep.dependenceVector.distances.begin(),
dep.dependenceVector.distances.end(),
[](int d) { return d >= 0; }));
dependences.push_back(dep);
if (DEBUG && dep.dependenceVector.isKnown) {
std::cout << " Found dependence: " << inst1->getName()
<< " -> " << inst2->getName() << " [";
for (size_t k = 0; k < dep.dependenceVector.distances.size(); ++k) {
if (k > 0) std::cout << ",";
std::cout << dep.dependenceVector.distances[k];
}
std::cout << "]" << std::endl;
}
}
}
}
return dependences;
}
DependenceVector LoopVectorizationPass::computeAccessDependence(Instruction* inst1, Instruction* inst2, Loop* loop) {
DependenceVector depVec(loop->getLoopDepth());
Value* ptr1 = nullptr;
Value* ptr2 = nullptr;
if (auto* load = dynamic_cast<LoadInst*>(inst1)) {
ptr1 = load->getPointer();
} else if (auto* store = dynamic_cast<StoreInst*>(inst1)) {
ptr1 = store->getPointer();
}
if (auto* load = dynamic_cast<LoadInst*>(inst2)) {
ptr2 = load->getPointer();
} else if (auto* store = dynamic_cast<StoreInst*>(inst2)) {
ptr2 = store->getPointer();
}
if (!ptr1 || !ptr2) return depVec;
// 尝试分析仿射关系
if (areAccessesAffinelyRelated(ptr1, ptr2, loop)) {
auto coeff1 = extractInductionCoefficients(ptr1, loop);
auto coeff2 = extractInductionCoefficients(ptr2, loop);
if (coeff1.size() == coeff2.size()) {
depVec.isKnown = true;
depVec.isConstant = true;
for (size_t i = 0; i < coeff1.size(); ++i) {
depVec.distances[i] = coeff2[i] - coeff1[i];
}
}
}
return depVec;
}
bool LoopVectorizationPass::areAccessesAffinelyRelated(Value* ptr1, Value* ptr2, Loop* loop) {
// 简化实现:检查是否都是基于归纳变量的数组访问
// 真正的实现需要复杂的仿射关系分析
// 检查是否为 GEP 指令
auto* gep1 = dynamic_cast<GetElementPtrInst*>(ptr1);
auto* gep2 = dynamic_cast<GetElementPtrInst*>(ptr2);
if (!gep1 || !gep2) return false;
// 检查是否访问同一个数组基址
if (gep1->getBasePointer() != gep2->getBasePointer()) return false;
// 简化:假设都是仿射的
return true;
}
// ========== 向量化分析实现 (暂时搁置) ==========
VectorizationAnalysis LoopVectorizationPass::analyzeVectorizability(Loop* loop,
const std::vector<PreciseDependence>& dependences,
LoopCharacteristics* characteristics) {
VectorizationAnalysis analysis; // 构造函数已设置为不可向量化
if (DEBUG) {
std::cout << " Vectorization analysis: DISABLED (temporarily)" << std::endl;
}
// 向量化功能暂时搁置,总是返回不可向量化
// 这里可以添加一些基本的诊断信息用于日志
if (!loop->isInnermost()) {
analysis.preventingFactors.push_back("Not innermost loop");
}
if (loop->getBlocks().size() > 1) {
analysis.preventingFactors.push_back("Complex control flow");
}
if (!dependences.empty()) {
analysis.preventingFactors.push_back("Has dependences (not analyzed in detail)");
}
return analysis;
}
// ========== 并行化分析实现 ==========
ParallelizationAnalysis LoopVectorizationPass::analyzeParallelizability(Loop* loop,
const std::vector<PreciseDependence>& dependences,
LoopCharacteristics* characteristics) {
ParallelizationAnalysis analysis;
if (DEBUG) {
std::cout << " Analyzing parallelizability for loop: " << loop->getName() << std::endl;
std::cout << " Found " << dependences.size() << " dependences" << std::endl;
}
// 按依赖类型分类分析
bool hasTrueDependences = false;
bool hasAntiDependences = false;
bool hasOutputDependences = false;
for (const auto& dep : dependences) {
switch (dep.type) {
case DependenceType::TRUE_DEPENDENCE:
hasTrueDependences = true;
// 真依赖通常是最难处理的,需要检查是否为归约模式
if (dep.isReductionDependence) {
analysis.requiresReduction = true;
analysis.reductionVariables.insert(dep.memoryLocation);
} else {
analysis.preventingFactors.push_back("Non-reduction true dependence");
}
break;
case DependenceType::ANTI_DEPENDENCE:
hasAntiDependences = true;
// 反依赖可以通过变量私有化解决
analysis.privatizableVariables.insert(dep.memoryLocation);
break;
case DependenceType::OUTPUT_DEPENDENCE:
hasOutputDependences = true;
// 输出依赖可以通过变量私有化或原子操作解决
analysis.sharedVariables.insert(dep.memoryLocation);
break;
}
}
// 确定并行化类型
analysis.parallelType = determineParallelizationType(loop, dependences);
// 基于依赖类型评估可并行性
if (!hasTrueDependences && !hasOutputDependences) {
// 只有反依赖或无依赖,完全可并行
analysis.parallelType = ParallelizationAnalysis::EMBARRASSINGLY_PARALLEL;
analysis.isParallelizable = true;
} else if (analysis.requiresReduction) {
// 有归约模式,可以并行但需要特殊处理
analysis.parallelType = ParallelizationAnalysis::REDUCTION_PARALLEL;
analysis.isParallelizable = true;
} else if (hasTrueDependences) {
// 有非归约的真依赖,通常不能并行化
analysis.isParallelizable = false;
analysis.preventingFactors.push_back("Non-reduction loop-carried true dependences");
}
if (analysis.isParallelizable) {
// 进一步分析并行化收益和成本
estimateParallelizationBenefit(loop, &analysis, characteristics);
analyzeSynchronizationNeeds(loop, &analysis, dependences);
analysis.suggestedThreadCount = estimateOptimalThreadCount(loop, characteristics);
}
if (DEBUG) {
std::cout << " Parallelizable: " << (analysis.isParallelizable ? "YES" : "NO") << std::endl;
if (analysis.isParallelizable) {
std::cout << " Type: " << (int)analysis.parallelType << ", Threads: " << analysis.suggestedThreadCount << std::endl;
}
}
return analysis;
}
bool LoopVectorizationPass::checkParallelizationLegality(Loop* loop, const std::vector<PreciseDependence>& dependences) {
// 检查所有依赖是否允许并行化
for (const auto& dep : dependences) {
if (!dep.allowsParallelization) {
return false;
}
}
// 检查是否有无法并行化的操作
for (BasicBlock* bb : loop->getBlocks()) {
for (auto& inst : bb->getInstructions()) {
// 检查原子操作、同步操作等
if (auto* call = dynamic_cast<CallInst*>(inst.get())) {
// 简化:假设函数调用需要特殊处理
// 在实际实现中,需要分析函数的副作用
return false;
}
}
}
return true;
}
int LoopVectorizationPass::estimateOptimalThreadCount(Loop* loop, LoopCharacteristics* characteristics) {
// 基于循环特征估计最优线程数
if (!characteristics) return 2;
// 基于循环体大小和计算密度
int baseThreads = 2;
if (characteristics->instructionCount > 50) baseThreads = 4;
if (characteristics->instructionCount > 200) baseThreads = 8;
// 基于计算与内存比率调整
if (characteristics->computeToMemoryRatio > 2.0) {
baseThreads *= 2; // 计算密集型,可以使用更多线程
}
return std::min(baseThreads, 16); // 限制最大线程数
}
// ========== 辅助方法实现 ==========
bool LoopVectorizationPass::isConstantStride(Value* ptr, Loop* loop, int& stride) {
// 简化实现:检查是否为常量步长访问
stride = 1; // 默认步长
auto* gep = dynamic_cast<GetElementPtrInst*>(ptr);
if (!gep) return false;
// 检查最后一个索引是否为归纳变量 + 常量
if (gep->getNumIndices() > 0) {
Value* lastIndex = gep->getIndex(gep->getNumIndices() - 1);
// 简化:假设是 i 或 i+c 的形式
if (auto* binInst = dynamic_cast<BinaryInst*>(lastIndex)) {
if (binInst->getKind() == Instruction::kAdd) {
// 检查是否为 i + constant
if (auto* constInt = dynamic_cast<ConstantInteger*>(binInst->getRhs())) {
stride = constInt->getInt();
return true;
}
}
}
// 默认为步长1的连续访问
stride = 1;
return true;
}
return false;
}
std::vector<int> LoopVectorizationPass::extractInductionCoefficients(Value* ptr, Loop* loop) {
// 简化实现:返回默认的仿射系数
std::vector<int> coefficients;
// 假设是简单的 a[i] 形式,系数为 [0, 1]
coefficients.push_back(0); // 常数项
coefficients.push_back(1); // 归纳变量系数
return coefficients;
}
// ========== 缺失的方法实现 ==========
ParallelizationAnalysis::ParallelizationType LoopVectorizationPass::determineParallelizationType(
Loop* loop, const std::vector<PreciseDependence>& dependences) {
// 检查是否有任何依赖
if (dependences.empty()) {
return ParallelizationAnalysis::EMBARRASSINGLY_PARALLEL;
}
// 检查是否只有归约模式
bool hasReduction = false;
bool hasOtherDependences = false;
for (const auto& dep : dependences) {
if (dep.isReductionDependence) {
hasReduction = true;
} else if (dep.type == DependenceType::TRUE_DEPENDENCE) {
hasOtherDependences = true;
}
}
if (hasReduction && !hasOtherDependences) {
return ParallelizationAnalysis::REDUCTION_PARALLEL;
} else if (!hasOtherDependences) {
return ParallelizationAnalysis::EMBARRASSINGLY_PARALLEL;
}
return ParallelizationAnalysis::NONE;
}
void LoopVectorizationPass::analyzeReductionPatterns(Loop* loop, ParallelizationAnalysis* analysis) {
// 简化实现:查找常见的归约模式
for (BasicBlock* bb : loop->getBlocks()) {
for (auto& inst : bb->getInstructions()) {
if (auto* binInst = dynamic_cast<BinaryInst*>(inst.get())) {
if (binInst->getKind() == Instruction::kAdd || binInst->getKind() == Instruction::kMul) {
// 检查是否为累加/累乘模式
Value* lhs = binInst->getLhs();
if (hasReductionPattern(lhs, loop)) {
analysis->requiresReduction = true;
analysis->reductionVariables.insert(lhs);
}
}
}
}
}
}
void LoopVectorizationPass::analyzeMemoryAccessPatterns(Loop* loop, ParallelizationAnalysis* analysis,
AliasAnalysisResult* aliasAnalysis) {
std::vector<Value*> memoryAccesses;
// 收集所有内存访问
for (BasicBlock* bb : loop->getBlocks()) {
for (auto& inst : bb->getInstructions()) {
if (auto* load = dynamic_cast<LoadInst*>(inst.get())) {
memoryAccesses.push_back(load->getPointer());
} else if (auto* store = dynamic_cast<StoreInst*>(inst.get())) {
memoryAccesses.push_back(store->getPointer());
}
}
}
// 分析内存访问独立性
bool hasIndependentAccess = true;
for (size_t i = 0; i < memoryAccesses.size(); ++i) {
for (size_t j = i + 1; j < memoryAccesses.size(); ++j) {
if (!isIndependentMemoryAccess(memoryAccesses[i], memoryAccesses[j], loop)) {
hasIndependentAccess = false;
analysis->hasMemoryConflicts = true;
}
}
}
analysis->hasIndependentAccess = hasIndependentAccess;
}
void LoopVectorizationPass::estimateParallelizationBenefit(Loop* loop, ParallelizationAnalysis* analysis,
LoopCharacteristics* characteristics) {
if (!analysis->isParallelizable) {
analysis->parallelizationBenefit = 0.0;
return;
}
// 基于计算复杂度和并行度计算收益
double workComplexity = estimateWorkComplexity(loop);
double parallelFraction = 1.0; // 假设完全可并行
// 根据依赖调整并行度
if (analysis->requiresReduction) {
parallelFraction *= 0.8; // 归约降低并行效率
}
if (analysis->hasMemoryConflicts) {
parallelFraction *= 0.6; // 内存冲突降低效率
}
// Amdahl定律估算
double serialFraction = 1.0 - parallelFraction;
int threadCount = analysis->suggestedThreadCount;
double speedup = 1.0 / (serialFraction + parallelFraction / threadCount);
analysis->parallelizationBenefit = std::min((speedup - 1.0) / threadCount, 1.0);
// 估算同步和通信开销
analysis->synchronizationCost = analysis->requiresBarrier ? 100 : 0;
analysis->communicationCost = analysis->sharedVariables.size() * 50;
}
void LoopVectorizationPass::identifyPrivatizableVariables(Loop* loop, ParallelizationAnalysis* analysis) {
// 简化实现:标识循环内定义的变量为可私有化
for (BasicBlock* bb : loop->getBlocks()) {
for (auto& inst : bb->getInstructions()) {
if (!inst->getType()->isVoid()) {
// 如果变量只在循环内使用,可能可以私有化
bool onlyUsedInLoop = true;
for (auto& use : inst->getUses()) {
if (auto* userInst = dynamic_cast<Instruction*>(use->getUser())) {
if (!loop->contains(userInst->getParent())) {
onlyUsedInLoop = false;
break;
}
}
}
if (onlyUsedInLoop) {
analysis->privatizableVariables.insert(inst.get());
}
}
}
}
}
void LoopVectorizationPass::analyzeSynchronizationNeeds(Loop* loop, ParallelizationAnalysis* analysis,
const std::vector<PreciseDependence>& dependences) {
// 根据依赖类型确定同步需求
for (const auto& dep : dependences) {
if (dep.type == DependenceType::OUTPUT_DEPENDENCE) {
analysis->requiresBarrier = true;
analysis->sharedVariables.insert(dep.memoryLocation);
}
}
// 如果有归约,需要特殊的归约同步
if (analysis->requiresReduction) {
analysis->requiresBarrier = true;
}
}
bool LoopVectorizationPass::isIndependentMemoryAccess(Value* ptr1, Value* ptr2, Loop* loop) {
// 简化实现:基本的独立性检查
if (ptr1 == ptr2) return false;
// 如果是不同的基址,认为是独立的
auto* gep1 = dynamic_cast<GetElementPtrInst*>(ptr1);
auto* gep2 = dynamic_cast<GetElementPtrInst*>(ptr2);
if (gep1 && gep2) {
if (gep1->getBasePointer() != gep2->getBasePointer()) {
return true; // 不同的基址
}
// 相同基址,需要更精细的分析(这里简化为不独立)
return false;
}
return true; // 默认认为独立
}
double LoopVectorizationPass::estimateWorkComplexity(Loop* loop) {
double complexity = 0.0;
for (BasicBlock* bb : loop->getBlocks()) {
for (auto& inst : bb->getInstructions()) {
// 基于指令类型分配复杂度权重
if (auto* binInst = dynamic_cast<BinaryInst*>(inst.get())) {
switch (binInst->getKind()) {
case Instruction::kAdd:
case Instruction::kSub:
complexity += 1.0;
break;
case Instruction::kMul:
complexity += 3.0;
break;
case Instruction::kDiv:
complexity += 10.0;
break;
default:
complexity += 2.0;
}
} else if (dynamic_cast<LoadInst*>(inst.get()) || dynamic_cast<StoreInst*>(inst.get())) {
complexity += 2.0; // 内存访问
} else {
complexity += 1.0; // 其他指令
}
}
}
return complexity;
}
bool LoopVectorizationPass::hasReductionPattern(Value* var, Loop* loop) {
// 简化实现:检查是否为简单的累加/累乘模式
for (auto& use : var->getUses()) {
if (auto* binInst = dynamic_cast<BinaryInst*>(use->getUser())) {
if (binInst->getKind() == Instruction::kAdd || binInst->getKind() == Instruction::kMul) {
// 检查是否为 var = var op something 的模式
if (binInst->getLhs() == var || binInst->getRhs() == var) {
return true;
}
}
}
}
return false;
}
} // namespace sysy