[midend-LoopAnalysis]移除基本循环特征分析中的向量化并行化内容,增加循环向量化并行化特征分析遍,TODO:构建循环优化遍验证分析遍正确性
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
if (characteristics->benefitsFromUnrolling) {
|
||||
std::cout << " Loop " << loop->getName() << " benefits from UNROLLING (factor="
|
||||
<< characteristics->suggestedUnrollFactor << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// 评估向量化机会
|
||||
characteristics->benefitsFromVectorization = benefitsFromVectorization(loop);
|
||||
|
||||
// 评估并行化机会
|
||||
characteristics->isParallel =
|
||||
!hasLoopCarriedDependence(loop) &&
|
||||
characteristics->isCountingLoop;
|
||||
|
||||
// 评估分块机会 (主要针对嵌套循环)
|
||||
characteristics->benefitsFromTiling =
|
||||
!loop->isInnermost() &&
|
||||
characteristics->memoryOperationCount > characteristics->arithmeticOperationCount;
|
||||
}
|
||||
|
||||
// ========== 辅助方法实现 ==========
|
||||
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user