[midend-LoopAnalysis]为项目添加别名分析遍,副作用分析遍,循环分析遍,循环特征分析遍

This commit is contained in:
rain2133
2025-08-08 00:56:50 +08:00
parent bd02f5f1eb
commit b1a46b7d58
12 changed files with 2166 additions and 53 deletions

View File

@@ -7,6 +7,9 @@ add_library(midend_lib STATIC
Pass/Analysis/Dom.cpp
Pass/Analysis/Liveness.cpp
Pass/Analysis/Loop.cpp
Pass/Analysis/LoopCharacteristics.cpp
Pass/Analysis/AliasAnalysis.cpp
Pass/Analysis/SideEffectAnalysis.cpp
Pass/Optimize/DCE.cpp
Pass/Optimize/Mem2Reg.cpp
Pass/Optimize/Reg2Mem.cpp

View File

@@ -0,0 +1,380 @@
#include "AliasAnalysis.h"
#include "SysYIRPrinter.h"
#include <iostream>
extern int DEBUG;
namespace sysy {
// 静态成员初始化
void *SysYAliasAnalysisPass::ID = (void *)&SysYAliasAnalysisPass::ID;
// ========== AliasAnalysisResult 实现 ==========
void AliasAnalysisResult::print() const {
std::cout << "---- Alias Analysis Results for Function: " << AssociatedFunction->getName() << " ----\n";
// 打印内存位置信息
std::cout << " Memory Locations (" << LocationMap.size() << "):\n";
for (const auto& pair : LocationMap) {
const auto& loc = pair.second;
std::cout << " - Base: " << loc->basePointer->getName();
std::cout << " (Type: ";
if (loc->isLocalArray) std::cout << "Local";
else if (loc->isFunctionParameter) std::cout << "Parameter";
else if (loc->isGlobalArray) std::cout << "Global";
else std::cout << "Unknown";
std::cout << ")\n";
}
// 打印别名关系
std::cout << " Alias Relations (" << AliasMap.size() << "):\n";
for (const auto& pair : AliasMap) {
std::cout << " - (" << pair.first.first->getName() << ", " << pair.first.second->getName() << "): ";
switch (pair.second) {
case AliasType::NO_ALIAS: std::cout << "No Alias"; break;
case AliasType::SELF_ALIAS: std::cout << "Self Alias"; break;
case AliasType::POSSIBLE_ALIAS: std::cout << "Possible Alias"; break;
case AliasType::UNKNOWN_ALIAS: std::cout << "Unknown Alias"; break;
}
std::cout << "\n";
}
std::cout << "-----------------------------------------------------------\n";
}
AliasType AliasAnalysisResult::queryAlias(Value* ptr1, Value* ptr2) const {
auto key = std::make_pair(ptr1, ptr2);
auto it = AliasMap.find(key);
if (it != AliasMap.end()) {
return it->second;
}
// 尝试反向查找
key = std::make_pair(ptr2, ptr1);
it = AliasMap.find(key);
if (it != AliasMap.end()) {
return it->second;
}
return AliasType::UNKNOWN_ALIAS; // 保守估计
}
const MemoryLocation* AliasAnalysisResult::getMemoryLocation(Value* ptr) const {
auto it = LocationMap.find(ptr);
return (it != LocationMap.end()) ? it->second.get() : nullptr;
}
bool AliasAnalysisResult::isLocalArray(Value* ptr) const {
const MemoryLocation* loc = getMemoryLocation(ptr);
return loc && loc->isLocalArray;
}
bool AliasAnalysisResult::isFunctionParameter(Value* ptr) const {
const MemoryLocation* loc = getMemoryLocation(ptr);
return loc && loc->isFunctionParameter;
}
bool AliasAnalysisResult::isGlobalArray(Value* ptr) const {
const MemoryLocation* loc = getMemoryLocation(ptr);
return loc && loc->isGlobalArray;
}
bool AliasAnalysisResult::hasConstantAccess(Value* ptr) const {
const MemoryLocation* loc = getMemoryLocation(ptr);
return loc && loc->hasConstantIndices;
}
AliasAnalysisResult::Statistics AliasAnalysisResult::getStatistics() const {
Statistics stats = {0};
stats.totalQueries = AliasMap.size();
for (auto& pair : AliasMap) {
switch (pair.second) {
case AliasType::NO_ALIAS: stats.noAlias++; break;
case AliasType::SELF_ALIAS: stats.selfAlias++; break;
case AliasType::POSSIBLE_ALIAS: stats.possibleAlias++; break;
case AliasType::UNKNOWN_ALIAS: stats.unknownAlias++; break;
}
}
for (auto& loc : LocationMap) {
if (loc.second->isLocalArray) stats.localArrays++;
if (loc.second->isFunctionParameter) stats.functionParameters++;
if (loc.second->isGlobalArray) stats.globalArrays++;
if (loc.second->hasConstantIndices) stats.constantAccesses++;
}
return stats;
}
// void AliasAnalysisResult::print() const {
// std::cout << "=== Alias Analysis Results ===" << std::endl;
// auto stats = getStatistics();
// std::cout << "Total queries: " << stats.totalQueries << std::endl;
// std::cout << "No alias: " << stats.noAlias << std::endl;
// std::cout << "Self alias: " << stats.selfAlias << std::endl;
// std::cout << "Possible alias: " << stats.possibleAlias << std::endl;
// std::cout << "Unknown alias: " << stats.unknownAlias << std::endl;
// std::cout << "Local arrays: " << stats.localArrays << std::endl;
// std::cout << "Function parameters: " << stats.functionParameters << std::endl;
// std::cout << "Global arrays: " << stats.globalArrays << std::endl;
// std::cout << "Constant accesses: " << stats.constantAccesses << std::endl;
// }
void AliasAnalysisResult::addMemoryLocation(std::unique_ptr<MemoryLocation> location) {
Value* ptr = location->accessPointer;
LocationMap[ptr] = std::move(location);
}
void AliasAnalysisResult::addAliasRelation(Value* ptr1, Value* ptr2, AliasType type) {
auto key = std::make_pair(ptr1, ptr2);
AliasMap[key] = type;
}
// ========== SysYAliasAnalysisPass 实现 ==========
bool SysYAliasAnalysisPass::runOnFunction(Function *F, AnalysisManager &AM) {
if (DEBUG) {
std::cout << "Running SysY Alias Analysis on function: " << F->getName() << std::endl;
}
// 创建分析结果
CurrentResult = std::make_unique<AliasAnalysisResult>(F);
// 执行主要分析步骤
collectMemoryAccesses(F);
buildAliasRelations(F);
optimizeForSysY(F);
if (DEBUG) {
CurrentResult->print();
}
return false; // 分析遍不修改IR
}
void SysYAliasAnalysisPass::collectMemoryAccesses(Function* F) {
// 收集函数中所有内存访问指令
for (auto& bb : F->getBasicBlocks()) {
for (auto& inst : bb->getInstructions()) {
Value* ptr = nullptr;
if (auto* loadInst = dynamic_cast<LoadInst*>(inst.get())) {
ptr = loadInst->getPointer();
} else if (auto* storeInst = dynamic_cast<StoreInst*>(inst.get())) {
ptr = storeInst->getPointer();
}
if (ptr) {
// 创建内存位置信息
auto location = createMemoryLocation(ptr);
location->accessInsts.push_back(inst.get());
// 更新读写标记
if (dynamic_cast<LoadInst*>(inst.get())) {
location->hasReads = true;
} else {
location->hasWrites = true;
}
CurrentResult->addMemoryLocation(std::move(location));
}
}
}
}
void SysYAliasAnalysisPass::buildAliasRelations(Function *F) {
// 构建所有内存访问之间的别名关系
auto& locationMap = CurrentResult->LocationMap;
std::vector<Value*> allPointers;
for (auto& pair : locationMap) {
allPointers.push_back(pair.first);
}
// 两两比较所有指针
for (size_t i = 0; i < allPointers.size(); ++i) {
for (size_t j = i + 1; j < allPointers.size(); ++j) {
Value* ptr1 = allPointers[i];
Value* ptr2 = allPointers[j];
MemoryLocation* loc1 = locationMap[ptr1].get();
MemoryLocation* loc2 = locationMap[ptr2].get();
AliasType aliasType = analyzeAliasBetween(loc1, loc2);
CurrentResult->addAliasRelation(ptr1, ptr2, aliasType);
}
}
}
void SysYAliasAnalysisPass::optimizeForSysY(Function* F) {
// SysY特化优化
applySysYConstraints(F);
optimizeParameterAnalysis(F);
optimizeArrayAccessAnalysis(F);
}
std::unique_ptr<MemoryLocation> SysYAliasAnalysisPass::createMemoryLocation(Value* ptr) {
Value* basePtr = getBasePointer(ptr);
auto location = std::make_unique<MemoryLocation>(basePtr, ptr);
// 分析内存类型和索引模式
analyzeMemoryType(location.get());
analyzeIndexPattern(location.get());
return location;
}
Value* SysYAliasAnalysisPass::getBasePointer(Value* ptr) {
// 递归剥离GEP指令找到真正的基指针
if (auto* gepInst = dynamic_cast<GetElementPtrInst*>(ptr)) {
return getBasePointer(gepInst->getBasePointer());
}
return ptr;
}
void SysYAliasAnalysisPass::analyzeMemoryType(MemoryLocation* location) {
Value* base = location->basePointer;
// 检查内存类型
if (dynamic_cast<AllocaInst*>(base)) {
location->isLocalArray = true;
} else if (dynamic_cast<Argument*>(base)) {
location->isFunctionParameter = true;
} else if (dynamic_cast<GlobalValue*>(base)) {
location->isGlobalArray = true;
}
}
void SysYAliasAnalysisPass::analyzeIndexPattern(MemoryLocation* location) {
// 分析GEP指令的索引模式
if (auto* gepInst = dynamic_cast<GetElementPtrInst*>(location->accessPointer)) {
// 收集所有索引
for (unsigned i = 0; i < gepInst->getNumIndices(); ++i) {
Value* index = gepInst->getIndex(i);
location->indices.push_back(index);
// 检查是否为常量索引
if (!isConstantValue(index)) {
location->hasConstantIndices = false;
}
}
// 如果没有非常量索引,则为常量访问
if (location->indices.empty()) {
location->hasConstantIndices = true;
}
// 检查是否包含循环变量
Function* containingFunc = nullptr;
if (auto* inst = dynamic_cast<Instruction*>(location->basePointer)) {
containingFunc = inst->getParent()->getParent();
} else if (auto* arg = dynamic_cast<Argument*>(location->basePointer)) {
containingFunc = arg->getParent();
}
if (containingFunc) {
location->hasLoopVariableIndex = hasLoopVariableInIndices(location->indices, containingFunc);
}
// 计算常量偏移
if (location->hasConstantIndices) {
location->constantOffset = calculateConstantOffset(location->indices);
}
}
}
AliasType SysYAliasAnalysisPass::analyzeAliasBetween(MemoryLocation* loc1, MemoryLocation* loc2) {
// 分析两个内存位置之间的别名关系
// 1. 相同基指针的自别名
if (loc1->basePointer == loc2->basePointer) {
return AliasType::SELF_ALIAS;
}
// 2. 不同类型的内存位置
if ((loc1->isLocalArray && loc2->isLocalArray)) {
return compareLocalArrays(loc1, loc2);
}
if ((loc1->isFunctionParameter && loc2->isFunctionParameter)) {
return compareParameters(loc1, loc2);
}
if ((loc1->isGlobalArray || loc2->isGlobalArray)) {
return compareWithGlobal(loc1, loc2);
}
return compareMixedTypes(loc1, loc2);
}
AliasType SysYAliasAnalysisPass::compareLocalArrays(MemoryLocation* loc1, MemoryLocation* loc2) {
// 不同局部数组不别名
return AliasType::NO_ALIAS;
}
AliasType SysYAliasAnalysisPass::compareParameters(MemoryLocation* loc1, MemoryLocation* loc2) {
// 不同函数参数可能别名
return AliasType::POSSIBLE_ALIAS;
}
AliasType SysYAliasAnalysisPass::compareWithGlobal(MemoryLocation* loc1, MemoryLocation* loc2) {
// 涉及全局数组的访问,保守估计
return AliasType::POSSIBLE_ALIAS;
}
AliasType SysYAliasAnalysisPass::compareMixedTypes(MemoryLocation* loc1, MemoryLocation* loc2) {
// 混合类型访问,保守估计
return AliasType::UNKNOWN_ALIAS;
}
void SysYAliasAnalysisPass::applySysYConstraints(Function* F) {
// 应用SysY语言特定的约束
// SysY没有指针运算简化别名分析
}
void SysYAliasAnalysisPass::optimizeParameterAnalysis(Function* F) {
// 优化参数别名分析
}
void SysYAliasAnalysisPass::optimizeArrayAccessAnalysis(Function* F) {
// 优化数组访问别名分析
}
bool SysYAliasAnalysisPass::isConstantValue(Value* val) {
return dynamic_cast<ConstantInteger*>(val) != nullptr; // 简化,只检查整数常量
}
bool SysYAliasAnalysisPass::hasLoopVariableInIndices(const std::vector<Value*>& indices, Function* F) {
// 简化版本:检查索引是否包含循环变量
for (Value* index : indices) {
if (!isConstantValue(index)) {
return true; // 保守估计
}
}
return false;
}
int SysYAliasAnalysisPass::calculateConstantOffset(const std::vector<Value*>& indices) {
int offset = 0;
for (Value* index : indices) {
if (auto* constInt = dynamic_cast<ConstantInteger*>(index)) {
// ConstantInteger的getVal()返回variant需要提取int值
auto val = constInt->getVal();
if (std::holds_alternative<int>(val)) {
offset += std::get<int>(val);
}
}
}
return offset;
}
void SysYAliasAnalysisPass::printStatistics() const {
if (CurrentResult) {
CurrentResult->print();
}
}
} // namespace sysy

View File

@@ -290,16 +290,14 @@ bool LoopAnalysisPass::runOnFunction(Function *F, AnalysisManager &AM) {
}
}
// 3. 计算循环层级 (Level) 并填充最外层/最内层循环列表
// 3. 计算循环层级 (Level)
std::queue<Loop *> q_level;
// 查找所有最外层循环没有父循环的设置其层级为0并加入队列
CurrentResult->clearOutermostLoops(); // 清空最外层循环列表
for (const auto &loop_ptr : allLoops) {
if (loop_ptr->isOutermost()) {
loop_ptr->setLoopLevel(0);
q_level.push(loop_ptr.get());
CurrentResult->addOutermostLoop(loop_ptr.get());
}
}
@@ -314,12 +312,24 @@ bool LoopAnalysisPass::runOnFunction(Function *F, AnalysisManager &AM) {
}
}
// 填充最内层循环列表
CurrentResult->clearInnermostLoops(); // 清空最内层循环列表
for (const auto &loop_ptr : allLoops) {
if (loop_ptr->isInnermost()) {
CurrentResult->addInnermostLoop(loop_ptr.get());
if (DEBUG) {
std::cout << "Loop Analysis completed for function: " << F->getName() << std::endl;
std::cout << "Total loops found: " << CurrentResult->getLoopCount() << std::endl;
std::cout << "Max loop depth: " << CurrentResult->getMaxLoopDepth() << std::endl;
std::cout << "Innermost loops: " << CurrentResult->getInnermostLoops().size() << std::endl;
std::cout << "Outermost loops: " << CurrentResult->getOutermostLoops().size() << std::endl;
// 打印各深度的循环分布
for (int depth = 1; depth <= CurrentResult->getMaxLoopDepth(); ++depth) {
int count = CurrentResult->getLoopCountAtDepth(depth);
if (count > 0) {
std::cout << "Loops at depth " << depth << ": " << count << std::endl;
}
}
// 输出缓存统计
auto cacheStats = CurrentResult->getCacheStats();
std::cout << "Cache statistics - Total cached queries: " << cacheStats.totalCachedQueries << std::endl;
}
return changed;

View File

@@ -0,0 +1,454 @@
#include "LoopCharacteristics.h"
#include "Dom.h"
#include "Loop.h"
#include "Liveness.h"
#include <iostream>
#include <cmath>
// 使用全局调试开关
extern int DEBUG;
namespace sysy {
// 定义 Pass 的唯一 ID
void *LoopCharacteristicsPass::ID = (void *)&LoopCharacteristicsPass::ID;
void LoopCharacteristicsResult::print() const {
if (!DEBUG) return; // 只有在 DEBUG 模式下才打印
std::cout << "\n--- Loop Characteristics Analysis Results for Function: "
<< AssociatedFunction->getName() << " ---" << std::endl;
if (CharacteristicsMap.empty()) {
std::cout << " No loop characteristics found." << std::endl;
return;
}
// 打印统计信息
auto stats = getOptimizationStats();
std::cout << "\n=== Optimization 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 << "Avg Instructions per Loop: " << stats.avgInstructionCount << std::endl;
std::cout << "Avg Compute/Memory Ratio: " << stats.avgComputeMemoryRatio << std::endl;
// 按热度排序并打印循环特征
auto loopsByHotness = getLoopsByHotness();
std::cout << "\n=== Loop Characteristics (by hotness) ===" << std::endl;
for (auto* loop : loopsByHotness) {
auto* chars = getCharacteristics(loop);
if (!chars) continue;
std::cout << "\n--- Loop: " << loop->getName() << " (Hotness: "
<< loop->getLoopHotness() << ") ---" << std::endl;
std::cout << " Level: " << loop->getLoopLevel() << std::endl;
std::cout << " Blocks: " << loop->getLoopSize() << std::endl;
std::cout << " Instructions: " << chars->instructionCount << std::endl;
std::cout << " Memory Operations: " << chars->memoryOperationCount << std::endl;
std::cout << " Compute/Memory Ratio: " << chars->computeToMemoryRatio << std::endl;
// 循环形式
std::cout << " Form: ";
if (chars->isCountingLoop) std::cout << "Counting ";
if (chars->isSimpleForLoop) std::cout << "SimpleFor ";
if (chars->isInnermost) std::cout << "Innermost ";
if (chars->hasComplexControlFlow) std::cout << "Complex ";
std::cout << std::endl;
// 边界信息
if (chars->staticTripCount.has_value()) {
std::cout << " Static Trip Count: " << *chars->staticTripCount << std::endl;
}
if (chars->hasKnownBounds) {
std::cout << " Has Known Bounds: Yes" << std::endl;
}
// 优化机会
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()) {
std::cout << " Loop Invariants: " << chars->loopInvariants.size() << std::endl;
}
if (!chars->invariantInsts.empty()) {
std::cout << " Hoistable Instructions: " << chars->invariantInsts.size() << std::endl;
}
}
std::cout << "-----------------------------------------------" << std::endl;
}
bool LoopCharacteristicsPass::runOnFunction(Function *F, AnalysisManager &AM) {
if (F->getBasicBlocks().empty()) {
CurrentResult = std::make_unique<LoopCharacteristicsResult>(F);
return false; // 空函数
}
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;
CurrentResult = std::make_unique<LoopCharacteristicsResult>(F);
return false;
}
// 如果没有循环,直接返回
if (!loopAnalysisResult->hasLoops()) {
CurrentResult = std::make_unique<LoopCharacteristicsResult>(F);
return false;
}
CurrentResult = std::make_unique<LoopCharacteristicsResult>(F);
// 分析每个循环的特征
for (const auto& loop_ptr : loopAnalysisResult->getAllLoops()) {
Loop* loop = loop_ptr.get();
auto characteristics = std::make_unique<LoopCharacteristics>(loop);
// 执行各种特征分析
analyzeLoop(loop, characteristics.get(), AM);
// 添加到结果中
CurrentResult->addLoopCharacteristics(std::move(characteristics));
}
if (DEBUG) {
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;
}
return false; // 特征分析不修改IR
}
void LoopCharacteristicsPass::analyzeLoop(Loop* loop, LoopCharacteristics* characteristics, AnalysisManager &AM) {
if (DEBUG)
std::cout << " Analyzing 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);
}
void LoopCharacteristicsPass::computePerformanceMetrics(Loop* loop, LoopCharacteristics* characteristics) {
size_t totalInsts = 0;
size_t memoryOps = 0;
size_t arithmeticOps = 0;
// 遍历循环中的所有指令
for (BasicBlock* bb : loop->getBlocks()) {
for (auto& inst : bb->getInstructions()) {
totalInsts++;
// 分类指令类型
if (dynamic_cast<LoadInst*>(inst.get()) || dynamic_cast<StoreInst*>(inst.get())) {
memoryOps++;
} else if (dynamic_cast<BinaryInst*>(inst.get())) {
// 检查是否为算术运算
auto* binInst = dynamic_cast<BinaryInst*>(inst.get());
// 简化:假设所有二元运算都是算术运算
arithmeticOps++;
}
}
}
characteristics->instructionCount = totalInsts;
characteristics->memoryOperationCount = memoryOps;
characteristics->arithmeticOperationCount = arithmeticOps;
// 计算计算与内存操作比率
if (memoryOps > 0) {
characteristics->computeToMemoryRatio = static_cast<double>(arithmeticOps) / memoryOps;
} else {
characteristics->computeToMemoryRatio = arithmeticOps; // 纯计算循环
}
}
void LoopCharacteristicsPass::analyzeLoopForm(Loop* loop, LoopCharacteristics* characteristics) {
// 基本形式判断
characteristics->isInnermost = loop->isInnermost();
// 检查是否为简单循环 (只有一个回边)
bool isSimple = loop->isSimpleLoop();
characteristics->isSimpleForLoop = isSimple;
// 检查复杂控制流 (多个出口表示可能有break/continue)
auto exitingBlocks = loop->getExitingBlocks();
characteristics->hasComplexControlFlow = exitingBlocks.size() > 1;
// 初步判断是否为计数循环 (需要更复杂的分析)
// 简化版本:如果是简单循环且是最内层,很可能是计数循环
characteristics->isCountingLoop = isSimple && loop->isInnermost() && exitingBlocks.size() == 1;
}
void LoopCharacteristicsPass::identifyInductionVariables(Loop* loop, LoopCharacteristics* characteristics) {
// 寻找基本归纳变量
BasicBlock* header = loop->getHeader();
// 遍历循环头的phi指令寻找归纳变量模式
for (auto& inst : header->getInstructions()) {
auto* phiInst = dynamic_cast<PhiInst*>(inst.get());
if (!phiInst) continue;
// 检查phi指令是否符合归纳变量模式
if (isInductionVariable(phiInst, loop)) {
characteristics->basicInductionVars.push_back(phiInst);
// 分析步长 (简化版本)
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) {
// 收集循环不变量
for (BasicBlock* bb : loop->getBlocks()) {
for (auto& inst : bb->getInstructions()) {
Value* val = inst.get();
// 跳过phi指令和终结指令
if (dynamic_cast<PhiInst*>(val)) {
continue;
}
// 检查是否为终结指令
if (auto* instPtr = dynamic_cast<Instruction*>(val)) {
if (instPtr->isTerminator()) {
continue;
}
}
if (isLoopInvariant(val, loop)) {
characteristics->loopInvariants.insert(val);
characteristics->invariantInsts.insert(static_cast<Instruction*>(val));
if (DEBUG)
std::cout << " Found loop invariant: " << val->getName() << std::endl;
}
}
}
}
void LoopCharacteristicsPass::analyzeLoopBounds(Loop* loop, LoopCharacteristics* characteristics) {
// 简化的边界分析
// 在实际实现中,需要分析循环的条件表达式来确定边界
// 检查是否有静态可确定的循环次数
if (characteristics->isCountingLoop && !characteristics->basicInductionVars.empty()) {
// 简化:如果是计数循环且有基本归纳变量,尝试确定循环次数
// 这里需要更复杂的符号执行或约束求解
// 暂时设置一个保守估计
if (characteristics->instructionCount < 10) {
characteristics->staticTripCount = 100; // 假设小循环执行100次
characteristics->hasKnownBounds = true;
}
}
}
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) {
// 评估循环展开机会
characteristics->benefitsFromUnrolling =
characteristics->isInnermost &&
characteristics->instructionCount > 3 &&
characteristics->instructionCount < 50 &&
!characteristics->hasComplexControlFlow;
if (characteristics->benefitsFromUnrolling) {
characteristics->suggestedUnrollFactor = estimateUnrollFactor(loop);
}
// 评估向量化机会
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) {
// 简化的归纳变量检测
auto* phiInst = dynamic_cast<PhiInst*>(val);
if (!phiInst) return false;
// 检查phi指令是否在循环头
if (phiInst->getParent() != loop->getHeader()) return false;
// 检查是否有来自循环内的更新
for (auto& [incomingBB, incomingVal] : phiInst->getIncomingValues()) {
if (loop->contains(incomingBB)) {
// 简化:如果有来自循环内的值,认为可能是归纳变量
return true;
}
}
return false;
}
bool LoopCharacteristicsPass::isLoopInvariant(Value* val, Loop* loop) {
auto* inst = dynamic_cast<Instruction*>(val);
if (!inst) return true; // 非指令(如常量)认为是不变的
// 如果指令不在循环内定义,则是不变的
if (!loop->contains(inst->getParent())) {
return true;
}
// 检查操作数是否都是循环不变的
// 简化版本如果是load指令且指针是不变的认为可能是不变的
if (auto* loadInst = dynamic_cast<LoadInst*>(inst)) {
Value* ptr = loadInst->getPointer();
return isLoopInvariant(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); // 没有明显的依赖
}
} // namespace sysy

View File

@@ -0,0 +1,281 @@
#include "SideEffectAnalysis.h"
#include "AliasAnalysis.h"
#include "SysYIRPrinter.h"
#include <iostream>
namespace sysy {
// 副作用分析遍的静态 ID
void* SysYSideEffectAnalysisPass::ID = (void*)&SysYSideEffectAnalysisPass::ID;
// ======================================================================
// SideEffectAnalysisResult 类的实现
// ======================================================================
SideEffectAnalysisResult::SideEffectAnalysisResult() {
initializeKnownFunctions();
}
const SideEffectInfo& SideEffectAnalysisResult::getInstructionSideEffect(Instruction* inst) const {
auto it = instructionSideEffects.find(inst);
if (it != instructionSideEffects.end()) {
return it->second;
}
// 返回默认的无副作用信息
static SideEffectInfo noEffect;
return noEffect;
}
const SideEffectInfo& SideEffectAnalysisResult::getFunctionSideEffect(Function* func) const {
auto it = functionSideEffects.find(func);
if (it != functionSideEffects.end()) {
return it->second;
}
// 返回默认的无副作用信息
static SideEffectInfo noEffect;
return noEffect;
}
void SideEffectAnalysisResult::setInstructionSideEffect(Instruction* inst, const SideEffectInfo& info) {
instructionSideEffects[inst] = info;
}
void SideEffectAnalysisResult::setFunctionSideEffect(Function* func, const SideEffectInfo& info) {
functionSideEffects[func] = info;
}
bool SideEffectAnalysisResult::hasSideEffect(Instruction* inst) const {
const auto& info = getInstructionSideEffect(inst);
return info.type != SideEffectType::NO_SIDE_EFFECT;
}
bool SideEffectAnalysisResult::mayModifyMemory(Instruction* inst) const {
const auto& info = getInstructionSideEffect(inst);
return info.mayModifyMemory;
}
bool SideEffectAnalysisResult::mayModifyGlobal(Instruction* inst) const {
const auto& info = getInstructionSideEffect(inst);
return info.mayModifyGlobal;
}
bool SideEffectAnalysisResult::isPureFunction(Function* func) const {
const auto& info = getFunctionSideEffect(func);
return info.isPure;
}
void SideEffectAnalysisResult::initializeKnownFunctions() {
// SysY标准库函数的副作用信息
// I/O函数 - 有副作用
SideEffectInfo ioEffect;
ioEffect.type = SideEffectType::IO_OPERATION;
ioEffect.mayModifyGlobal = true;
ioEffect.mayModifyMemory = true;
ioEffect.mayCallFunction = true;
ioEffect.isPure = false;
// knownFunctions["printf"] = ioEffect;
// knownFunctions["scanf"] = ioEffect;
knownFunctions["getint"] = ioEffect;
knownFunctions["getch"] = ioEffect;
knownFunctions["getfloat"] = ioEffect;
knownFunctions["getarray"] = ioEffect;
knownFunctions["getfarray"] = ioEffect;
knownFunctions["putint"] = ioEffect;
knownFunctions["putch"] = ioEffect;
knownFunctions["putfloat"] = ioEffect;
knownFunctions["putarray"] = ioEffect;
knownFunctions["putfarray"] = ioEffect;
// 时间函数 - 有副作用
SideEffectInfo timeEffect;
timeEffect.type = SideEffectType::FUNCTION_CALL;
timeEffect.mayModifyGlobal = true;
timeEffect.mayModifyMemory = false;
timeEffect.mayCallFunction = true;
timeEffect.isPure = false;
knownFunctions["_sysy_starttime"] = timeEffect;
knownFunctions["_sysy_stoptime"] = timeEffect;
}
const SideEffectInfo* SideEffectAnalysisResult::getKnownFunctionSideEffect(const std::string& funcName) const {
auto it = knownFunctions.find(funcName);
return (it != knownFunctions.end()) ? &it->second : nullptr;
}
// ======================================================================
// SysYSideEffectAnalysisPass 类的实现
// ======================================================================
bool SysYSideEffectAnalysisPass::runOnFunction(Function* F, AnalysisManager& AM) {
if (DEBUG) {
std::cout << "Running SideEffect analysis on function: " << F->getName() << std::endl;
}
// 创建分析结果构造函数中已经调用了initializeKnownFunctions
result = std::make_unique<SideEffectAnalysisResult>();
// 获取别名分析结果,在整个函数分析过程中重复使用
aliasAnalysis = AM.getAnalysisResult<AliasAnalysisResult, SysYAliasAnalysisPass>(F);
// 分析函数中的每条指令
SideEffectInfo functionSideEffect;
for (auto& BB : F->getBasicBlocks()) {
for (auto& I : BB->getInstructions_Range()) {
Instruction* inst = I.get();
SideEffectInfo instEffect = analyzeInstruction(inst, AM);
// 记录指令的副作用信息
result->setInstructionSideEffect(inst, instEffect);
// 合并到函数级别的副作用信息中
functionSideEffect = functionSideEffect.merge(instEffect);
}
}
// 记录函数级别的副作用信息
result->setFunctionSideEffect(F, functionSideEffect);
if (DEBUG) {
std::cout << "---- Side Effect Analysis Results for Function: " << F->getName() << " ----\n";
for (auto& BB : F->getBasicBlocks()) {
for (auto& I : BB->getInstructions_Range()) {
Instruction* inst = I.get();
const auto& info = result->getInstructionSideEffect(inst);
SysYPrinter::printInst(inst);
std::cout << " -> Side Effect: ";
switch (info.type) {
case SideEffectType::NO_SIDE_EFFECT: std::cout << "None"; break;
case SideEffectType::MEMORY_WRITE: std::cout << "Memory Write"; break;
case SideEffectType::FUNCTION_CALL: std::cout << "Function Call"; break;
case SideEffectType::IO_OPERATION: std::cout << "I/O Operation"; break;
case SideEffectType::UNKNOWN: std::cout << "Unknown"; break;
}
std::cout << " (Modifies Global: " << (info.mayModifyGlobal ? "Yes" : "No")
<< ", Modifies Memory: " << (info.mayModifyMemory ? "Yes" : "No")
<< ", Is Pure: " << (info.isPure ? "Yes" : "No") << ")\n";
}
}
std::cout << "------------------------------------------------------------------\n";
}
return false; // Analysis passes return false since they don't modify the IR
}
std::unique_ptr<AnalysisResultBase> SysYSideEffectAnalysisPass::getResult() {
return std::move(result);
}
SideEffectInfo SysYSideEffectAnalysisPass::analyzeInstruction(Instruction* inst, AnalysisManager& AM) {
SideEffectInfo info;
// 根据指令类型进行分析
if (inst->isCall()) {
return analyzeCallInstruction(static_cast<CallInst*>(inst), AM);
} else if (inst->isStore()) {
return analyzeStoreInstruction(static_cast<StoreInst*>(inst), AM);
} else if (inst->isMemset()) {
return analyzeMemsetInstruction(static_cast<MemsetInst*>(inst), AM);
} else if (inst->isBranch() || inst->isReturn()) {
// 控制流指令无副作用,但必须保留
info.type = SideEffectType::NO_SIDE_EFFECT;
info.isPure = true;
} else {
// 其他指令(算术、逻辑、比较等)通常无副作用
info.type = SideEffectType::NO_SIDE_EFFECT;
info.isPure = true;
}
return info;
}
SideEffectInfo SysYSideEffectAnalysisPass::analyzeCallInstruction(CallInst* call, AnalysisManager& AM) {
SideEffectInfo info;
// 获取被调用的函数
Function* calledFunc = call->getCallee();
if (!calledFunc) {
// 间接调用,保守处理
info.type = SideEffectType::UNKNOWN;
info.mayModifyGlobal = true;
info.mayModifyMemory = true;
info.mayCallFunction = true;
info.isPure = false;
return info;
}
std::string funcName = calledFunc->getName();
// 检查是否为已知的标准库函数
const SideEffectInfo* knownInfo = result->getKnownFunctionSideEffect(funcName);
if (knownInfo) {
return *knownInfo;
}
// 对于用户定义的函数,检查是否已经分析过
const SideEffectInfo& funcEffect = result->getFunctionSideEffect(calledFunc);
if (funcEffect.type != SideEffectType::NO_SIDE_EFFECT || !funcEffect.isPure) {
return funcEffect;
}
// 对于未分析的用户函数,保守处理
info.type = SideEffectType::FUNCTION_CALL;
info.mayModifyGlobal = true;
info.mayModifyMemory = true;
info.mayCallFunction = true;
info.isPure = false;
return info;
}
SideEffectInfo SysYSideEffectAnalysisPass::analyzeStoreInstruction(StoreInst* store, AnalysisManager& AM) {
SideEffectInfo info;
info.type = SideEffectType::MEMORY_WRITE;
info.mayModifyMemory = true;
info.isPure = false;
// 使用缓存的别名分析结果
if (aliasAnalysis) {
Value* storePtr = store->getPointer();
// 如果存储到全局变量或可能别名的位置,则可能修改全局状态
if (!aliasAnalysis->isLocalArray(storePtr)) {
info.mayModifyGlobal = true;
}
} else {
// 没有别名分析结果,保守处理
info.mayModifyGlobal = true;
}
return info;
}
SideEffectInfo SysYSideEffectAnalysisPass::analyzeMemsetInstruction(MemsetInst* memset, AnalysisManager& AM) {
SideEffectInfo info;
info.type = SideEffectType::MEMORY_WRITE;
info.mayModifyMemory = true;
info.isPure = false;
// 使用缓存的别名分析结果
if (aliasAnalysis) {
Value* memsetPtr = memset->getPointer();
// 如果memset操作全局变量或可能别名的位置则可能修改全局状态
if (!aliasAnalysis->isLocalArray(memsetPtr)) {
info.mayModifyGlobal = true;
}
} else {
// 没有别名分析结果,保守处理
info.mayModifyGlobal = true;
}
return info;
}
} // namespace sysy

View File

@@ -1,6 +1,9 @@
#include "Dom.h"
#include "Liveness.h"
#include "Loop.h"
#include "LoopCharacteristics.h"
#include "AliasAnalysis.h"
#include "SideEffectAnalysis.h"
#include "SysYIRCFGOpt.h"
#include "SysYIRPrinter.h"
#include "DCE.h"
@@ -38,7 +41,10 @@ void PassManager::runOptimizationPipeline(Module* moduleIR, IRBuilder* builderIR
// 注册分析遍
registerAnalysisPass<sysy::DominatorTreeAnalysisPass>();
registerAnalysisPass<sysy::LivenessAnalysisPass>();
registerAnalysisPass<SysYAliasAnalysisPass>(); // 别名分析 (优先级高)
registerAnalysisPass<SysYSideEffectAnalysisPass>(); // 副作用分析 (依赖别名分析)
registerAnalysisPass<LoopAnalysisPass>();
registerAnalysisPass<LoopCharacteristicsPass>(); // 循环特征分析依赖别名分析
// 注册优化遍
registerOptimizationPass<SysYDelInstAfterBrPass>();