diff --git a/src/include/midend/Pass/Analysis/AliasAnalysis.h b/src/include/midend/Pass/Analysis/AliasAnalysis.h new file mode 100644 index 0000000..0adc4c5 --- /dev/null +++ b/src/include/midend/Pass/Analysis/AliasAnalysis.h @@ -0,0 +1,208 @@ +#pragma once + +#include "IR.h" +#include "Pass.h" +#include +#include +#include +#include + +namespace sysy { + +// 前向声明 +class MemoryLocation; +class AliasAnalysisResult; + +/** + * @brief 别名关系类型 + * 按风险等级递增排序 + */ +enum class AliasType { + NO_ALIAS = 0, // 确定无别名 (不同的局部数组) + SELF_ALIAS = 1, // 自别名 (同一数组的不同索引) + POSSIBLE_ALIAS = 2, // 可能有别名 (函数参数数组) + UNKNOWN_ALIAS = 3 // 未知 (保守估计) +}; + +/** + * @brief 内存位置信息 + * 描述一个内存访问的基础信息 + */ +struct MemoryLocation { + Value* basePointer; // 基指针 (剥离GEP后的真实基址) + Value* accessPointer; // 访问指针 (包含索引信息) + + // 分类信息 + bool isLocalArray; // 是否为局部数组 + bool isFunctionParameter; // 是否为函数参数 + bool isGlobalArray; // 是否为全局数组 + + // 索引信息 + std::vector indices; // GEP索引列表 + bool hasConstantIndices; // 是否为常量索引 + bool hasLoopVariableIndex; // 是否包含循环变量 + int constantOffset; // 常量偏移量 (仅当全部为常量时有效) + + // 访问模式 + bool hasReads; // 是否有读操作 + bool hasWrites; // 是否有写操作 + std::vector accessInsts; // 所有访问指令 + + MemoryLocation(Value* base, Value* access) + : basePointer(base), accessPointer(access), + isLocalArray(false), isFunctionParameter(false), isGlobalArray(false), + hasConstantIndices(false), hasLoopVariableIndex(false), constantOffset(0), + hasReads(false), hasWrites(false) {} +}; + +/** + * @brief 别名分析结果 + * 存储一个函数的完整别名分析信息 + */ +class AliasAnalysisResult : public AnalysisResultBase { +public: + AliasAnalysisResult(Function *F) : AssociatedFunction(F) {} + ~AliasAnalysisResult() override = default; + + // ========== 基础查询接口 ========== + + /** + * 查询两个指针之间的别名关系 + */ + AliasType queryAlias(Value* ptr1, Value* ptr2) const; + + /** + * 查询指针的内存位置信息 + */ + const MemoryLocation* getMemoryLocation(Value* ptr) const; + + /** + * 获取所有内存位置 + */ + const std::map>& getAllMemoryLocations() const { + return LocationMap; + } + + // ========== 高级查询接口 ========== + + /** + * 检查指针是否为局部数组 + */ + bool isLocalArray(Value* ptr) const; + + /** + * 检查指针是否为函数参数数组 + */ + bool isFunctionParameter(Value* ptr) const; + + /** + * 检查指针是否为全局数组 + */ + bool isGlobalArray(Value* ptr) const; + + /** + * 检查指针是否使用常量索引 + */ + bool hasConstantAccess(Value* ptr) const; + + // ========== 统计接口 ========== + + /** + * 获取各类别名类型的统计信息 + */ + struct Statistics { + int totalQueries; + int noAlias; + int selfAlias; + int possibleAlias; + int unknownAlias; + int localArrays; + int functionParameters; + int globalArrays; + int constantAccesses; + }; + + Statistics getStatistics() const; + + /** + * 打印别名分析结果 (调试用) + */ + void print() const; + + // ========== 内部方法 ========== + + void addMemoryLocation(std::unique_ptr location); + void addAliasRelation(Value* ptr1, Value* ptr2, AliasType type); + + // ========== 公开数据成员 (供Pass使用) ========== + std::map> LocationMap; // 内存位置映射 + std::map, AliasType> AliasMap; // 别名关系缓存 + +private: + Function *AssociatedFunction; // 关联的函数 + + // 分类存储 + std::vector ArrayParameters; // 数组参数 + std::vector LocalArrays; // 局部数组 + std::set AccessedGlobals; // 访问的全局变量 +}; + +/** + * @brief SysY语言特化的别名分析Pass + * 针对SysY语言特性优化的别名分析实现 + */ +class SysYAliasAnalysisPass : public AnalysisPass { +public: + // 唯一的 Pass ID + static void *ID; + + SysYAliasAnalysisPass() : AnalysisPass("SysYAliasAnalysis", Pass::Granularity::Function) {} + + // 实现 getPassID + void *getPassID() const override { return &ID; } + + // 核心运行方法 + bool runOnFunction(Function *F, AnalysisManager &AM) override; + + // 获取分析结果 + std::unique_ptr getResult() override { return std::move(CurrentResult); } + +private: + std::unique_ptr CurrentResult; // 当前函数的分析结果 + + // ========== 主要分析流程 ========== + + void collectMemoryAccesses(Function* F); // 收集内存访问 + void buildAliasRelations(Function* F); // 构建别名关系 + void optimizeForSysY(Function* F); // SysY特化优化 + + // ========== 内存位置分析 ========== + + std::unique_ptr createMemoryLocation(Value* ptr); + Value* getBasePointer(Value* ptr); // 获取基指针 + void analyzeMemoryType(MemoryLocation* location); // 分析内存类型 + void analyzeIndexPattern(MemoryLocation* location); // 分析索引模式 + + // ========== 别名关系推断 ========== + + AliasType analyzeAliasBetween(MemoryLocation* loc1, MemoryLocation* loc2); + AliasType compareLocalArrays(MemoryLocation* loc1, MemoryLocation* loc2); + AliasType compareParameters(MemoryLocation* loc1, MemoryLocation* loc2); + AliasType compareWithGlobal(MemoryLocation* loc1, MemoryLocation* loc2); + AliasType compareMixedTypes(MemoryLocation* loc1, MemoryLocation* loc2); + + // ========== SysY特化优化 ========== + + void applySysYConstraints(Function* F); // 应用SysY语言约束 + void optimizeParameterAnalysis(Function* F); // 优化参数分析 + void optimizeArrayAccessAnalysis(Function* F); // 优化数组访问分析 + + // ========== 辅助方法 ========== + + bool isConstantValue(Value* val); // 是否为常量 + bool hasLoopVariableInIndices(const std::vector& indices, Function* F); + int calculateConstantOffset(const std::vector& indices); + void printStatistics() const; // 打印统计信息 +}; + +} // namespace sysy diff --git a/src/include/midend/Pass/Analysis/Loop.h b/src/include/midend/Pass/Analysis/Loop.h index 2a003f9..06803ed 100644 --- a/src/include/midend/Pass/Analysis/Loop.h +++ b/src/include/midend/Pass/Analysis/Loop.h @@ -4,8 +4,10 @@ #include "IR.h" // 包含 IR 定义 #include "Pass.h" // 包含 Pass 框架 #include +#include #include #include +#include #include // 用于循环体块的逆向遍历 #include #include @@ -92,6 +94,65 @@ public: return backEdgeCount == 1; } + /** + * 获取所有出口目标块 (循环外接收循环出口边的块) + * 使用场景: 循环后置处理、phi节点分析 + */ + std::vector getExitTargetBlocks() const { + std::set exitTargetSet; + for (BasicBlock* bb : LoopBlocks) { + for (BasicBlock* succ : bb->getSuccessors()) { + if (!contains(succ)) { + exitTargetSet.insert(succ); + } + } + } + return std::vector(exitTargetSet.begin(), exitTargetSet.end()); + } + + /** + * 计算循环的"深度"相对于指定的祖先循环 + * 使用场景: 相对深度计算、嵌套分析 + */ + int getRelativeDepth(Loop* ancestor) const { + if (this == ancestor) return 0; + + int depth = 0; + Loop* current = this->ParentLoop; + while (current && current != ancestor) { + depth++; + current = current->ParentLoop; + } + + return current == ancestor ? depth : -1; // -1表示不是祖先关系 + } + + /** + * 检查循环是否包含函数调用 + * 使用场景: 内联决策、副作用分析 + */ + bool containsFunctionCalls() const { + for (BasicBlock* bb : LoopBlocks) { + for (auto& inst : bb->getInstructions()) { + if (dynamic_cast(inst.get())) { + return true; + } + } + } + return false; + } + + /** + * 估算循环的"热度" (基于嵌套深度和大小) + * 使用场景: 优化优先级、资源分配 + */ + double getLoopHotness() const { + // 简单的热度估算: 深度权重 + 大小惩罚 + double hotness = std::pow(2.0, Level); // 深度越深越热 + hotness /= std::sqrt(LoopBlocks.size()); // 大小越大相对热度降低 + return hotness; + } + // --- 供 LoopAnalysisPass 内部调用的方法,用于构建 Loop 对象 --- void addBlock(BasicBlock *BB) { LoopBlocks.insert(BB); } void addExitBlock(BasicBlock *BB) { ExitBlocks.insert(BB); } @@ -112,81 +173,345 @@ private: /** * @brief 循环分析结果类。 - * 包含一个函数中所有识别出的循环。 + * 包含一个函数中所有识别出的循环,并提供高效的查询缓存机制。 */ class LoopAnalysisResult : public AnalysisResultBase { public: LoopAnalysisResult(Function *F) : AssociatedFunction(F) {} ~LoopAnalysisResult() override = default; + // ========== 缓存统计结构 ========== + struct CacheStats { + size_t innermostLoopsCached; + size_t outermostLoopsCached; + size_t loopsByDepthCached; + size_t containingLoopsCached; + size_t allNestedLoopsCached; + size_t totalCachedQueries; + }; + +private: + // ========== 高频查询缓存 (必须缓存) ========== + mutable std::optional> cachedInnermostLoops; + mutable std::optional> cachedOutermostLoops; + mutable std::optional cachedMaxDepth; + mutable std::optional cachedLoopCount; + mutable std::map> cachedLoopsByDepth; + + // ========== 中频查询缓存 (选择性缓存) ========== + mutable std::map cachedInnermostContainingLoop; + mutable std::map> cachedAllNestedLoops; // 递归嵌套 + mutable std::map> cachedAllContainingLoops; + + // ========== 缓存状态管理 ========== + mutable bool cacheValid = true; + + // 内部辅助方法 + void invalidateCache() const { + cachedInnermostLoops.reset(); + cachedOutermostLoops.reset(); + cachedMaxDepth.reset(); + cachedLoopCount.reset(); + cachedLoopsByDepth.clear(); + cachedInnermostContainingLoop.clear(); + cachedAllNestedLoops.clear(); + cachedAllContainingLoops.clear(); + cacheValid = false; + } + + void ensureCacheValid() const { + if (!cacheValid) { + // 重新计算基础缓存 + computeBasicCache(); + cacheValid = true; + } + } + + void computeBasicCache() const { + // 计算最内层循环 + if (!cachedInnermostLoops) { + cachedInnermostLoops = std::vector(); + for (const auto& loop : AllLoops) { + if (loop->isInnermost()) { + cachedInnermostLoops->push_back(loop.get()); + } + } + } + + // 计算最外层循环 + if (!cachedOutermostLoops) { + cachedOutermostLoops = std::vector(); + for (const auto& loop : AllLoops) { + if (loop->isOutermost()) { + cachedOutermostLoops->push_back(loop.get()); + } + } + } + + // 计算最大深度 + if (!cachedMaxDepth) { + int maxDepth = 0; + for (const auto& loop : AllLoops) { + maxDepth = std::max(maxDepth, loop->getLoopDepth()); + } + cachedMaxDepth = maxDepth; + } + + // 计算循环总数 + if (!cachedLoopCount) { + cachedLoopCount = AllLoops.size(); + } + } + +public: + // ========== 基础接口 (保持向后兼容,但增加缓存失效) ========== + // 添加一个识别出的循环到结果中 void addLoop(std::unique_ptr loop) { + invalidateCache(); // 添加新循环时失效缓存 AllLoops.push_back(std::move(loop)); - // 也可以选择将 Loop* 存储到 map 中,方便通过 header 查找 LoopMap[AllLoops.back()->getHeader()] = AllLoops.back().get(); } // 获取所有识别出的循环(unique_ptr 管理内存) const std::vector> &getAllLoops() const { return AllLoops; } - // 获取所有最外层循环 - const std::vector &getOutermostLoops() const { return OutermostLoops; } - - const std::vector &getInnermostLoops() const { return InnermostLoops; } - - // 获取循环总数 - size_t getLoopCount() const { return AllLoops.size(); } - - // 获取最大循环嵌套深度 - int getMaxLoopDepth() const { - int maxDepth = 0; - for (const auto& loop : AllLoops) { - if (loop->getLoopDepth() > maxDepth) { - maxDepth = loop->getLoopDepth(); + // ========== 高频查询接口 (缓存优化) ========== + + /** + * 获取所有最内层循环 - 循环优化的主要目标 + * 使用场景: 循环展开、向量化、循环不变量外提 + */ + const std::vector& getInnermostLoops() const { + ensureCacheValid(); + if (!cachedInnermostLoops) { + cachedInnermostLoops = std::vector(); + for (const auto& loop : AllLoops) { + if (loop->isInnermost()) { + cachedInnermostLoops->push_back(loop.get()); + } } } - return maxDepth; + return *cachedInnermostLoops; + } + + /** + * 获取所有最外层循环 + * 使用场景: 循环树遍历、整体优化策略 + */ + const std::vector& getOutermostLoops() const { + ensureCacheValid(); + if (!cachedOutermostLoops) { + cachedOutermostLoops = std::vector(); + for (const auto& loop : AllLoops) { + if (loop->isOutermost()) { + cachedOutermostLoops->push_back(loop.get()); + } + } + } + return *cachedOutermostLoops; + } + + /** + * 获取指定深度的所有循环 + * 使用场景: 分层优化、循环展开决策、并行化分析 + */ + const std::vector& getLoopsAtDepth(int depth) const { + ensureCacheValid(); + if (cachedLoopsByDepth.find(depth) == cachedLoopsByDepth.end()) { + std::vector result; + for (const auto& loop : AllLoops) { + if (loop->getLoopDepth() == depth) { + result.push_back(loop.get()); + } + } + cachedLoopsByDepth[depth] = std::move(result); + } + return cachedLoopsByDepth[depth]; + } + + /** + * 获取最大循环嵌套深度 + * 使用场景: 优化预算分配、编译时间控制 + */ + int getMaxLoopDepth() const { + ensureCacheValid(); + if (!cachedMaxDepth) { + int maxDepth = 0; + for (const auto& loop : AllLoops) { + maxDepth = std::max(maxDepth, loop->getLoopDepth()); + } + cachedMaxDepth = maxDepth; + } + return *cachedMaxDepth; + } + + /** + * 获取循环总数 + * 使用场景: 统计信息、优化决策 + */ + size_t getLoopCount() const { + ensureCacheValid(); + if (!cachedLoopCount) { + cachedLoopCount = AllLoops.size(); + } + return *cachedLoopCount; } // 获取指定深度的循环数量 size_t getLoopCountAtDepth(int depth) const { - size_t count = 0; - for (const auto& loop : AllLoops) { - if (loop->getLoopDepth() == depth) { - count++; - } - } - return count; + return getLoopsAtDepth(depth).size(); } // 检查函数是否包含循环 bool hasLoops() const { return !AllLoops.empty(); } + // ========== 中频查询接口 (选择性缓存) ========== + + /** + * 获取包含指定基本块的最内层循环 + * 使用场景: 活跃性分析、寄存器分配、指令调度 + */ + Loop* getInnermostContainingLoop(BasicBlock* BB) const { + ensureCacheValid(); + if (cachedInnermostContainingLoop.find(BB) == cachedInnermostContainingLoop.end()) { + Loop* result = nullptr; + int maxDepth = -1; + for (const auto& loop : AllLoops) { + if (loop->contains(BB) && loop->getLoopDepth() > maxDepth) { + result = loop.get(); + maxDepth = loop->getLoopDepth(); + } + } + cachedInnermostContainingLoop[BB] = result; + } + return cachedInnermostContainingLoop[BB]; + } + + /** + * 获取包含指定基本块的所有循环 (从外到内排序) + * 使用场景: 循环间优化、依赖分析 + */ + const std::vector& getAllContainingLoops(BasicBlock* BB) const { + ensureCacheValid(); + if (cachedAllContainingLoops.find(BB) == cachedAllContainingLoops.end()) { + std::vector result; + for (const auto& loop : AllLoops) { + if (loop->contains(BB)) { + result.push_back(loop.get()); + } + } + // 按深度排序 (外层到内层) + std::sort(result.begin(), result.end(), + [](Loop* a, Loop* b) { return a->getLoopDepth() < b->getLoopDepth(); }); + cachedAllContainingLoops[BB] = std::move(result); + } + return cachedAllContainingLoops[BB]; + } + + /** + * 获取指定循环的所有嵌套子循环 (递归) + * 使用场景: 循环树分析、嵌套优化 + */ + const std::set& getAllNestedLoops(Loop* loop) const { + ensureCacheValid(); + if (cachedAllNestedLoops.find(loop) == cachedAllNestedLoops.end()) { + std::set result; + std::function collectNested = [&](Loop* current) { + for (Loop* nested : current->getNestedLoops()) { + result.insert(nested); + collectNested(nested); // 递归收集 + } + }; + collectNested(loop); + cachedAllNestedLoops[loop] = std::move(result); + } + return cachedAllNestedLoops[loop]; + } + + // ========== 低频查询接口 (按需计算,不缓存) ========== + + /** + * 检查两个循环是否有嵌套关系 + * 使用场景: 循环间依赖分析 + */ + bool isNestedLoop(Loop* inner, Loop* outer) const { + if (inner == outer) return false; + + Loop* current = inner->getParentLoop(); + while (current) { + if (current == outer) return true; + current = current->getParentLoop(); + } + return false; + } + + /** + * 获取两个循环的最近公共祖先循环 + * 使用场景: 循环融合分析、优化范围确定 + */ + Loop* getLowestCommonAncestor(Loop* loop1, Loop* loop2) const { + if (!loop1 || !loop2) return nullptr; + if (loop1 == loop2) return loop1; + + // 收集loop1的所有祖先 + std::set ancestors1; + Loop* current = loop1; + while (current) { + ancestors1.insert(current); + current = current->getParentLoop(); + } + + // 查找loop2祖先链中第一个在ancestors1中的循环 + current = loop2; + while (current) { + if (ancestors1.count(current)) { + return current; + } + current = current->getParentLoop(); + } + + return nullptr; // 没有公共祖先 + } + // 通过循环头获取 Loop 对象 Loop *getLoopForHeader(BasicBlock *header) const { auto it = LoopMap.find(header); return (it != LoopMap.end()) ? it->second : nullptr; } - // 通过某个基本块获取包含它的最内层循环 + // 通过某个基本块获取包含它的最内层循环 (向后兼容接口) Loop *getLoopContainingBlock(BasicBlock *BB) const { - // 遍历所有循环,找到包含 BB 且层级最深的循环 - Loop *innermostContainingLoop = nullptr; - for (const auto &loop_ptr : AllLoops) { - if (loop_ptr->contains(BB)) { - if (!innermostContainingLoop || loop_ptr->getLoopLevel() > innermostContainingLoop->getLoopLevel()) { - innermostContainingLoop = loop_ptr.get(); - } - } - } - return innermostContainingLoop; + return getInnermostContainingLoop(BB); } - // --- 供 LoopAnalysisPass 内部调用的方法,用于构建 LoopAnalysisResult 对象 --- - void addOutermostLoop(Loop *loop) { OutermostLoops.push_back(loop); } - void addInnermostLoop(Loop *loop) { InnermostLoops.push_back(loop); } - void clearOutermostLoops() { OutermostLoops.clear(); } - void clearInnermostLoops() { InnermostLoops.clear(); } + // ========== 缓存管理接口 ========== + + /** + * 手动失效缓存 (当IR结构改变时调用) + */ + void invalidateQueryCache() const { + invalidateCache(); + } + + /** + * 获取缓存统计信息 (用于性能调试) + */ + CacheStats getCacheStats() const { + CacheStats stats = {}; + stats.innermostLoopsCached = cachedInnermostLoops.has_value() ? 1 : 0; + stats.outermostLoopsCached = cachedOutermostLoops.has_value() ? 1 : 0; + stats.loopsByDepthCached = cachedLoopsByDepth.size(); + stats.containingLoopsCached = cachedInnermostContainingLoop.size(); + stats.allNestedLoopsCached = cachedAllNestedLoops.size(); + stats.totalCachedQueries = stats.innermostLoopsCached + stats.outermostLoopsCached + + stats.loopsByDepthCached + stats.containingLoopsCached + + stats.allNestedLoopsCached; + return stats; + } + + // --- 保留的内部接口 --- + // 注意:由于使用了缓存机制,不再需要手动维护最外层和最内层循环列表 // 打印分析结果 void print() const; @@ -197,8 +522,7 @@ private: Function *AssociatedFunction; // 结果关联的函数 std::vector> AllLoops; // 所有识别出的循环 std::map LoopMap; // 循环头到 Loop* 的映射,方便查找 - std::vector OutermostLoops; // 最外层循环的列表 - std::vector InnermostLoops; // 最内层循环的列表 + // 注意: 最外层和最内层循环列表已移除,现在通过缓存机制动态计算 }; /** diff --git a/src/include/midend/Pass/Analysis/LoopCharacteristics.h b/src/include/midend/Pass/Analysis/LoopCharacteristics.h new file mode 100644 index 0000000..ab7ebb5 --- /dev/null +++ b/src/include/midend/Pass/Analysis/LoopCharacteristics.h @@ -0,0 +1,301 @@ +#pragma once + +#include "Dom.h" // 支配树分析依赖 +#include "Loop.h" // 循环分析依赖 +#include "Liveness.h" // 活跃性分析依赖 +#include "AliasAnalysis.h" // 别名分析依赖 +#include "IR.h" // IR定义 +#include "Pass.h" // Pass框架 +#include +#include +#include +#include +#include +#include + +namespace sysy { + +// 前向声明 +class LoopCharacteristicsResult; + +/** + * @brief 循环特征信息结构 + * 存储单个循环的各种特征信息 + */ +struct LoopCharacteristics { + Loop* loop; // 关联的循环对象 + + // ========== 归纳变量分析 ========== + std::vector basicInductionVars; // 基本归纳变量 (i = phi(init, i+step)) + std::vector derivedInductionVars; // 派生归纳变量 (j = i * scale + offset) + std::map inductionSteps; // 归纳变量的步长 + std::map inductionInits; // 归纳变量的初始值 + + // ========== 循环不变量分析 ========== + std::set loopInvariants; // 循环不变量 (循环内定义但值不变) + std::set invariantInsts; // 不变指令 (可以外提的指令) + + // ========== 循环边界分析 ========== + std::optional staticTripCount; // 静态可确定的循环次数 + Value* dynamicTripCountExpr; // 动态循环次数表达式 + bool hasKnownBounds; // 是否有已知边界 + Value* lowerBound; // 循环下界 + Value* upperBound; // 循环上界 + + // ========== 循环形式分析 ========== + bool isCountingLoop; // 是否为计数循环 (for i=0; i loadInsts; // load指令列表 + std::vector storeInsts; // store指令列表 + + // 使用外部别名分析结果 + AliasType aliasType; // 别名类型(来自别名分析) + bool isArrayParameter; // 是否为数组参数访问 + bool isGlobalArray; // 是否为全局数组访问 + bool hasConstantIndices; // 是否使用常量索引 + }; + std::map 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), + isCountingLoop(false), isSimpleForLoop(false), hasComplexControlFlow(false), + isInnermost(false), isParallel(false), benefitsFromUnrolling(false), + benefitsFromVectorization(false), benefitsFromTiling(false), + suggestedUnrollFactor(1), instructionCount(0), memoryOperationCount(0), + arithmeticOperationCount(0), computeToMemoryRatio(0.0) {} +}; + +/** + * @brief 循环特征分析结果类 + * 包含函数中所有循环的特征信息,并提供查询接口 + */ +class LoopCharacteristicsResult : public AnalysisResultBase { +public: + LoopCharacteristicsResult(Function *F) : AssociatedFunction(F) {} + ~LoopCharacteristicsResult() override = default; + + // ========== 基础接口 ========== + + /** + * 添加循环特征信息 + */ + void addLoopCharacteristics(std::unique_ptr characteristics) { + auto* loop = characteristics->loop; + CharacteristicsMap[loop] = std::move(characteristics); + } + + /** + * 获取指定循环的特征信息 + */ + const LoopCharacteristics* getCharacteristics(Loop* loop) const { + auto it = CharacteristicsMap.find(loop); + return (it != CharacteristicsMap.end()) ? it->second.get() : nullptr; + } + + /** + * 获取所有循环特征信息 + */ + const std::map>& getAllCharacteristics() const { + return CharacteristicsMap; + } + + // ========== 查询接口 ========== + + /** + * 获取所有计数循环 + */ + std::vector getCountingLoops() const { + std::vector result; + for (const auto& [loop, chars] : CharacteristicsMap) { + if (chars->isCountingLoop) { + result.push_back(loop); + } + } + return result; + } + + /** + * 获取所有可向量化循环 + */ + std::vector getVectorizableLoops() const { + std::vector result; + for (const auto& [loop, chars] : CharacteristicsMap) { + if (chars->benefitsFromVectorization) { + result.push_back(loop); + } + } + return result; + } + + /** + * 获取所有适合展开的循环 + */ + std::vector getUnrollCandidateLoops() const { + std::vector result; + for (const auto& [loop, chars] : CharacteristicsMap) { + if (chars->benefitsFromUnrolling) { + result.push_back(loop); + } + } + return result; + } + + /** + * 获取所有可并行化循环 + */ + std::vector getParallelizableLoops() const { + std::vector result; + for (const auto& [loop, chars] : CharacteristicsMap) { + if (chars->isParallel) { + result.push_back(loop); + } + } + return result; + } + + /** + * 获取所有有静态已知循环次数的循环 + */ + std::vector getStaticBoundLoops() const { + std::vector result; + for (const auto& [loop, chars] : CharacteristicsMap) { + if (chars->staticTripCount.has_value()) { + result.push_back(loop); + } + } + return result; + } + + /** + * 根据热度排序循环 (用于优化优先级) + */ + std::vector getLoopsByHotness() const { + std::vector result; + for (const auto& [loop, chars] : CharacteristicsMap) { + result.push_back(loop); + } + + // 按循环热度排序 (嵌套深度 + 循环次数 + 指令数) + std::sort(result.begin(), result.end(), [](Loop* a, Loop* b) { + double hotnessA = a->getLoopHotness(); + double hotnessB = b->getLoopHotness(); + return hotnessA > hotnessB; // 降序排列 + }); + + return result; + } + + // ========== 统计接口 ========== + + /** + * 获取优化候选统计 + */ + struct OptimizationStats { + size_t totalLoops; + size_t countingLoops; + size_t vectorizableLoops; + size_t unrollCandidates; + size_t parallelizableLoops; + size_t staticBoundLoops; + double avgInstructionCount; + double avgComputeMemoryRatio; + }; + + OptimizationStats getOptimizationStats() const { + OptimizationStats stats = {}; + stats.totalLoops = CharacteristicsMap.size(); + + size_t totalInstructions = 0; + double totalComputeMemoryRatio = 0.0; + + 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++; + + totalInstructions += chars->instructionCount; + totalComputeMemoryRatio += chars->computeToMemoryRatio; + } + + if (stats.totalLoops > 0) { + stats.avgInstructionCount = static_cast(totalInstructions) / stats.totalLoops; + stats.avgComputeMemoryRatio = totalComputeMemoryRatio / stats.totalLoops; + } + + return stats; + } + + // 打印分析结果 + void print() const; + +private: + Function *AssociatedFunction; // 关联的函数 + std::map> CharacteristicsMap; // 循环特征映射 +}; + +/** + * @brief 循环特征分析遍 + * 基于循环分析结果,分析每个循环的特征信息,为优化决策提供依据 + */ +class LoopCharacteristicsPass : public AnalysisPass { +public: + // 唯一的 Pass ID + static void *ID; + + LoopCharacteristicsPass() : AnalysisPass("LoopCharacteristics", Pass::Granularity::Function) {} + + // 实现 getPassID + void *getPassID() const override { return &ID; } + + // 核心运行方法 + bool runOnFunction(Function *F, AnalysisManager &AM) override; + + // 获取分析结果 + std::unique_ptr getResult() override { return std::move(CurrentResult); } + +private: + std::unique_ptr 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 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); +}; + +} // namespace sysy diff --git a/src/include/midend/Pass/Analysis/SideEffectAnalysis.h b/src/include/midend/Pass/Analysis/SideEffectAnalysis.h new file mode 100644 index 0000000..d19a59a --- /dev/null +++ b/src/include/midend/Pass/Analysis/SideEffectAnalysis.h @@ -0,0 +1,126 @@ +#pragma once + +#include "Pass.h" +#include "IR.h" +#include "AliasAnalysis.h" +#include +#include + +namespace sysy { + +// 副作用类型枚举 +enum class SideEffectType { + NO_SIDE_EFFECT, // 无副作用 + MEMORY_WRITE, // 内存写入(store、memset) + FUNCTION_CALL, // 函数调用(可能有任意副作用) + IO_OPERATION, // I/O操作(printf、scanf等) + UNKNOWN // 未知副作用 +}; + +// 副作用信息结构 +struct SideEffectInfo { + SideEffectType type = SideEffectType::NO_SIDE_EFFECT; + bool mayModifyGlobal = false; // 可能修改全局变量 + bool mayModifyMemory = false; // 可能修改内存 + bool mayCallFunction = false; // 可能调用函数 + bool isPure = true; // 是否为纯函数(无副作用且结果只依赖参数) + + // 合并两个副作用信息 + SideEffectInfo merge(const SideEffectInfo& other) const { + SideEffectInfo result; + result.type = (type == SideEffectType::NO_SIDE_EFFECT) ? other.type : type; + result.mayModifyGlobal = mayModifyGlobal || other.mayModifyGlobal; + result.mayModifyMemory = mayModifyMemory || other.mayModifyMemory; + result.mayCallFunction = mayCallFunction || other.mayCallFunction; + result.isPure = isPure && other.isPure; + return result; + } +}; + +// 副作用分析结果类 +class SideEffectAnalysisResult : public AnalysisResultBase { +private: + // 指令级别的副作用信息 + std::unordered_map instructionSideEffects; + + // 函数级别的副作用信息 + std::unordered_map functionSideEffects; + + // 已知的SysY标准库函数副作用信息 + std::unordered_map knownFunctions; + +public: + SideEffectAnalysisResult(); + virtual ~SideEffectAnalysisResult() noexcept override = default; + + // 获取指令的副作用信息 + const SideEffectInfo& getInstructionSideEffect(Instruction* inst) const; + + // 获取函数的副作用信息 + const SideEffectInfo& getFunctionSideEffect(Function* func) const; + + // 设置指令的副作用信息 + void setInstructionSideEffect(Instruction* inst, const SideEffectInfo& info); + + // 设置函数的副作用信息 + void setFunctionSideEffect(Function* func, const SideEffectInfo& info); + + // 检查指令是否有副作用 + bool hasSideEffect(Instruction* inst) const; + + // 检查指令是否可能修改内存 + bool mayModifyMemory(Instruction* inst) const; + + // 检查指令是否可能修改全局状态 + bool mayModifyGlobal(Instruction* inst) const; + + // 检查函数是否为纯函数 + bool isPureFunction(Function* func) const; + + // 获取已知函数的副作用信息 + const SideEffectInfo* getKnownFunctionSideEffect(const std::string& funcName) const; + + // 初始化已知函数的副作用信息 + void initializeKnownFunctions(); + +private: +}; + +// 副作用分析遍类 +class SysYSideEffectAnalysisPass : public AnalysisPass { +public: + // 静态成员,作为该遍的唯一ID + static void* ID; + + SysYSideEffectAnalysisPass() : AnalysisPass("SysYSideEffectAnalysis", Granularity::Function) {} + + // 在函数上运行分析 + bool runOnFunction(Function* F, AnalysisManager& AM) override; + + // 获取分析结果 + std::unique_ptr getResult() override; + + // Pass 基类中的纯虚函数,必须实现 + void* getPassID() const override { return &ID; } + +private: + // 分析结果 + std::unique_ptr result; + + // 别名分析结果(在整个函数分析过程中重复使用) + AliasAnalysisResult* aliasAnalysis = nullptr; + + // 分析单个指令的副作用 + SideEffectInfo analyzeInstruction(Instruction* inst, AnalysisManager& AM); + + // 分析函数调用指令的副作用 + SideEffectInfo analyzeCallInstruction(CallInst* call, AnalysisManager& AM); + + // 分析存储指令的副作用 + SideEffectInfo analyzeStoreInstruction(StoreInst* store, AnalysisManager& AM); + + // 分析内存设置指令的副作用 + SideEffectInfo analyzeMemsetInstruction(MemsetInst* memset, AnalysisManager& AM); +}; + +} // namespace sysy diff --git a/src/include/midend/Pass/Pass.h b/src/include/midend/Pass/Pass.h index 887ad3f..d9153e1 100644 --- a/src/include/midend/Pass/Pass.h +++ b/src/include/midend/Pass/Pass.h @@ -151,17 +151,21 @@ public: } AnalysisPass *analysisPass = static_cast(basePass.get()); - if(DEBUG){ - std::cout << "Running Analysis Pass: " << analysisPass->getName() << "\n"; - } // 根据分析遍的粒度处理 switch (analysisPass->getGranularity()) { case Pass::Granularity::Module: { // 检查是否已存在有效结果 auto it = moduleCachedResults.find(analysisID); if (it != moduleCachedResults.end()) { + if(DEBUG) { + std::cout << "Using cached result for Analysis Pass: " << analysisPass->getName() << "\n"; + } return static_cast(it->second.get()); // 返回缓存结果 } + // 只有在实际运行时才打印调试信息 + if(DEBUG){ + std::cout << "Running Analysis Pass: " << analysisPass->getName() << "\n"; + } // 运行模块级分析遍 if (!pModuleRef) { std::cerr << "Error: Module reference not set for AnalysisManager to run Module Pass.\n"; @@ -183,8 +187,16 @@ public: // 检查是否已存在有效结果 auto it = functionCachedResults.find({F, analysisID}); if (it != functionCachedResults.end()) { + if(DEBUG) { + std::cout << "Using cached result for Analysis Pass: " << analysisPass->getName() << " (Function: " << F->getName() << ")\n"; + } return static_cast(it->second.get()); // 返回缓存结果 } + // 只有在实际运行时才打印调试信息 + if(DEBUG){ + std::cout << "Running Analysis Pass: " << analysisPass->getName() << "\n"; + std::cout << "Function: " << F->getName() << "\n"; + } // 运行函数级分析遍 analysisPass->runOnFunction(F, *this); // 获取结果并缓存 @@ -202,8 +214,16 @@ public: // 检查是否已存在有效结果 auto it = basicBlockCachedResults.find({BB, analysisID}); if (it != basicBlockCachedResults.end()) { + if(DEBUG) { + std::cout << "Using cached result for Analysis Pass: " << analysisPass->getName() << " (BasicBlock: " << BB->getName() << ")\n"; + } return static_cast(it->second.get()); // 返回缓存结果 } + // 只有在实际运行时才打印调试信息 + if(DEBUG){ + std::cout << "Running Analysis Pass: " << analysisPass->getName() << "\n"; + std::cout << "BasicBlock: " << BB->getName() << "\n"; + } // 运行基本块级分析遍 analysisPass->runOnBasicBlock(BB, *this); // 获取结果并缓存 diff --git a/src/midend/CMakeLists.txt b/src/midend/CMakeLists.txt index 03421be..d61ea91 100644 --- a/src/midend/CMakeLists.txt +++ b/src/midend/CMakeLists.txt @@ -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 diff --git a/src/midend/Pass/Analysis/AliasAnalysis.cpp b/src/midend/Pass/Analysis/AliasAnalysis.cpp new file mode 100644 index 0000000..ae363cf --- /dev/null +++ b/src/midend/Pass/Analysis/AliasAnalysis.cpp @@ -0,0 +1,380 @@ +#include "AliasAnalysis.h" +#include "SysYIRPrinter.h" +#include + +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 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(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(inst.get())) { + ptr = loadInst->getPointer(); + } else if (auto* storeInst = dynamic_cast(inst.get())) { + ptr = storeInst->getPointer(); + } + + if (ptr) { + // 创建内存位置信息 + auto location = createMemoryLocation(ptr); + location->accessInsts.push_back(inst.get()); + + // 更新读写标记 + if (dynamic_cast(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 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 SysYAliasAnalysisPass::createMemoryLocation(Value* ptr) { + Value* basePtr = getBasePointer(ptr); + auto location = std::make_unique(basePtr, ptr); + + // 分析内存类型和索引模式 + analyzeMemoryType(location.get()); + analyzeIndexPattern(location.get()); + + return location; +} + +Value* SysYAliasAnalysisPass::getBasePointer(Value* ptr) { + // 递归剥离GEP指令,找到真正的基指针 + if (auto* gepInst = dynamic_cast(ptr)) { + return getBasePointer(gepInst->getBasePointer()); + } + return ptr; +} + +void SysYAliasAnalysisPass::analyzeMemoryType(MemoryLocation* location) { + Value* base = location->basePointer; + + // 检查内存类型 + if (dynamic_cast(base)) { + location->isLocalArray = true; + } else if (dynamic_cast(base)) { + location->isFunctionParameter = true; + } else if (dynamic_cast(base)) { + location->isGlobalArray = true; + } +} + +void SysYAliasAnalysisPass::analyzeIndexPattern(MemoryLocation* location) { + // 分析GEP指令的索引模式 + if (auto* gepInst = dynamic_cast(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(location->basePointer)) { + containingFunc = inst->getParent()->getParent(); + } else if (auto* arg = dynamic_cast(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(val) != nullptr; // 简化,只检查整数常量 +} + +bool SysYAliasAnalysisPass::hasLoopVariableInIndices(const std::vector& indices, Function* F) { + // 简化版本:检查索引是否包含循环变量 + for (Value* index : indices) { + if (!isConstantValue(index)) { + return true; // 保守估计 + } + } + return false; +} + +int SysYAliasAnalysisPass::calculateConstantOffset(const std::vector& indices) { + int offset = 0; + for (Value* index : indices) { + if (auto* constInt = dynamic_cast(index)) { + // ConstantInteger的getVal()返回variant,需要提取int值 + auto val = constInt->getVal(); + if (std::holds_alternative(val)) { + offset += std::get(val); + } + } + } + return offset; +} + +void SysYAliasAnalysisPass::printStatistics() const { + if (CurrentResult) { + CurrentResult->print(); + } +} + +} // namespace sysy diff --git a/src/midend/Pass/Analysis/AliasAnalysis_new.cpp b/src/midend/Pass/Analysis/AliasAnalysis_new.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/midend/Pass/Analysis/Loop.cpp b/src/midend/Pass/Analysis/Loop.cpp index 1f3d08a..4c2233f 100644 --- a/src/midend/Pass/Analysis/Loop.cpp +++ b/src/midend/Pass/Analysis/Loop.cpp @@ -290,16 +290,14 @@ bool LoopAnalysisPass::runOnFunction(Function *F, AnalysisManager &AM) { } } - // 3. 计算循环层级 (Level) 并填充最外层/最内层循环列表 + // 3. 计算循环层级 (Level) std::queue 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; diff --git a/src/midend/Pass/Analysis/LoopCharacteristics.cpp b/src/midend/Pass/Analysis/LoopCharacteristics.cpp new file mode 100644 index 0000000..864b82a --- /dev/null +++ b/src/midend/Pass/Analysis/LoopCharacteristics.cpp @@ -0,0 +1,454 @@ +#include "LoopCharacteristics.h" +#include "Dom.h" +#include "Loop.h" +#include "Liveness.h" +#include +#include + +// 使用全局调试开关 +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(F); + return false; // 空函数 + } + + if (DEBUG) + std::cout << "Running LoopCharacteristicsPass on function: " << F->getName() << std::endl; + + // 获取循环分析结果 - 这是我们的核心依赖 + auto* loopAnalysisResult = AM.getAnalysisResult(F); + if (!loopAnalysisResult) { + std::cerr << "Error: LoopAnalysisResult not available for function " << F->getName() << std::endl; + CurrentResult = std::make_unique(F); + return false; + } + + // 如果没有循环,直接返回 + if (!loopAnalysisResult->hasLoops()) { + CurrentResult = std::make_unique(F); + return false; + } + + CurrentResult = std::make_unique(F); + + // 分析每个循环的特征 + for (const auto& loop_ptr : loopAnalysisResult->getAllLoops()) { + Loop* loop = loop_ptr.get(); + auto characteristics = std::make_unique(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(inst.get()) || dynamic_cast(inst.get())) { + memoryOps++; + } else if (dynamic_cast(inst.get())) { + // 检查是否为算术运算 + auto* binInst = dynamic_cast(inst.get()); + // 简化:假设所有二元运算都是算术运算 + arithmeticOps++; + } + } + } + + characteristics->instructionCount = totalInsts; + characteristics->memoryOperationCount = memoryOps; + characteristics->arithmeticOperationCount = arithmeticOps; + + // 计算计算与内存操作比率 + if (memoryOps > 0) { + characteristics->computeToMemoryRatio = static_cast(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(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(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(val)) { + continue; + } + + // 检查是否为终结指令 + if (auto* instPtr = dynamic_cast(val)) { + if (instPtr->isTerminator()) { + continue; + } + } + + if (isLoopInvariant(val, loop)) { + characteristics->loopInvariants.insert(val); + characteristics->invariantInsts.insert(static_cast(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> accessMap; + + // 收集所有内存访问 + for (BasicBlock* bb : loop->getBlocks()) { + for (auto& inst : bb->getInstructions()) { + if (auto* loadInst = dynamic_cast(inst.get())) { + Value* ptr = loadInst->getPointer(); + accessMap[ptr].push_back(loadInst); + } else if (auto* storeInst = dynamic_cast(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(inst)) { + pattern.loadInsts.push_back(inst); + } else { + pattern.storeInsts.push_back(inst); + } + } + + characteristics->memoryPatterns[ptr] = pattern; + + if (DEBUG && (static_cast(pattern.aliasType) >= 2)) { // POSSIBLE_ALIAS及以上 + std::cout << " Found potential aliasing for memory access, type: " + << static_cast(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(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(val); + if (!inst) return true; // 非指令(如常量)认为是不变的 + + // 如果指令不在循环内定义,则是不变的 + if (!loop->contains(inst->getParent())) { + return true; + } + + // 检查操作数是否都是循环不变的 + // 简化版本:如果是load指令且指针是不变的,认为可能是不变的 + if (auto* loadInst = dynamic_cast(inst)) { + Value* ptr = loadInst->getPointer(); + return isLoopInvariant(ptr, loop); + } + + // 简化:对于其他指令,保守地认为是变化的 + return false; +} + +bool LoopCharacteristicsPass::hasLoopCarriedDependence(Loop* loop) { + // 简化的依赖分析 + // 检查是否有写后读或写后写依赖跨越循环迭代 + + std::set writtenVars; + std::set readVars; + + for (BasicBlock* bb : loop->getBlocks()) { + for (auto& inst : bb->getInstructions()) { + if (auto* storeInst = dynamic_cast(inst.get())) { + writtenVars.insert(storeInst->getPointer()); + } else if (auto* loadInst = dynamic_cast(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 diff --git a/src/midend/Pass/Analysis/SideEffectAnalysis.cpp b/src/midend/Pass/Analysis/SideEffectAnalysis.cpp new file mode 100644 index 0000000..288fa0f --- /dev/null +++ b/src/midend/Pass/Analysis/SideEffectAnalysis.cpp @@ -0,0 +1,281 @@ +#include "SideEffectAnalysis.h" +#include "AliasAnalysis.h" +#include "SysYIRPrinter.h" +#include + +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(); + + // 获取别名分析结果,在整个函数分析过程中重复使用 + aliasAnalysis = AM.getAnalysisResult(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 SysYSideEffectAnalysisPass::getResult() { + return std::move(result); +} + +SideEffectInfo SysYSideEffectAnalysisPass::analyzeInstruction(Instruction* inst, AnalysisManager& AM) { + SideEffectInfo info; + + // 根据指令类型进行分析 + if (inst->isCall()) { + return analyzeCallInstruction(static_cast(inst), AM); + } else if (inst->isStore()) { + return analyzeStoreInstruction(static_cast(inst), AM); + } else if (inst->isMemset()) { + return analyzeMemsetInstruction(static_cast(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 diff --git a/src/midend/Pass/Pass.cpp b/src/midend/Pass/Pass.cpp index bd10887..6649f65 100644 --- a/src/midend/Pass/Pass.cpp +++ b/src/midend/Pass/Pass.cpp @@ -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(); registerAnalysisPass(); + registerAnalysisPass(); // 别名分析 (优先级高) + registerAnalysisPass(); // 副作用分析 (依赖别名分析) registerAnalysisPass(); + registerAnalysisPass(); // 循环特征分析依赖别名分析 // 注册优化遍 registerOptimizationPass();