From f63427385243f91fec0f58e8c516667dbd10bac4 Mon Sep 17 00:00:00 2001 From: rain2133 <1370973498@qq.com> Date: Tue, 12 Aug 2025 15:53:57 +0800 Subject: [PATCH] =?UTF-8?q?[midend-LICM]=E4=BC=98=E5=8C=96=E4=BA=86?= =?UTF-8?q?=E7=89=B9=E5=BE=81=E5=88=86=E6=9E=90=E4=B8=AD=E5=AF=B9=E5=BE=AA?= =?UTF-8?q?=E7=8E=AF=E4=B8=8D=E5=8F=98=E9=87=8F=E7=9A=84=E8=AF=86=E5=88=AB?= =?UTF-8?q?=EF=BC=8C=E5=AE=9E=E7=8E=B0=E4=BA=86LICM=E9=81=8D=EF=BC=8C?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E5=8C=96=E5=89=AF=E4=BD=9C=E7=94=A8=E5=88=86?= =?UTF-8?q?=E6=9E=90=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Pass/Analysis/LoopCharacteristics.h | 8 +- src/include/midend/Pass/Optimize/LICM.h | 40 ++ src/midend/CMakeLists.txt | 1 + .../Pass/Analysis/LoopCharacteristics.cpp | 80 ++- .../Pass/Analysis/SideEffectAnalysis.cpp | 656 +++++++++--------- src/midend/Pass/Optimize/LICM.cpp | 84 +++ src/midend/Pass/Pass.cpp | 14 + 7 files changed, 523 insertions(+), 360 deletions(-) create mode 100644 src/include/midend/Pass/Optimize/LICM.h create mode 100644 src/midend/Pass/Optimize/LICM.cpp diff --git a/src/include/midend/Pass/Analysis/LoopCharacteristics.h b/src/include/midend/Pass/Analysis/LoopCharacteristics.h index aa0e751..a9e3d5b 100644 --- a/src/include/midend/Pass/Analysis/LoopCharacteristics.h +++ b/src/include/midend/Pass/Analysis/LoopCharacteristics.h @@ -38,8 +38,8 @@ struct LoopCharacteristics { std::map inductionSteps; // 归纳变量的步长(简化) // ========== 基础循环不变量分析 ========== - std::set loopInvariants; // 循环不变量 - std::set invariantInsts; // 可提升的不变指令 + std::unordered_set loopInvariants; // 循环不变量 + std::unordered_set invariantInsts; // 可提升的不变指令 // ========== 基础边界分析 ========== std::optional staticTripCount; // 静态循环次数(如果可确定) @@ -293,7 +293,7 @@ private: // 基础归纳变量识别 void identifyBasicInductionVariables(Loop* loop, LoopCharacteristics* characteristics); - // 基础循环不变量识别 + // 循环不变量识别 void identifyBasicLoopInvariants(Loop* loop, LoopCharacteristics* characteristics); // 基础边界分析 @@ -306,8 +306,8 @@ private: void evaluateBasicOptimizationOpportunities(Loop* loop, LoopCharacteristics* characteristics); // ========== 辅助方法 ========== + bool isClassicLoopInvariant(Value* val, Loop* loop, const std::unordered_set& invariants); bool isBasicInductionVariable(Value* val, Loop* loop); - bool isBasicLoopInvariant(Value* val, Loop* loop); bool hasSimpleMemoryPattern(Loop* loop); // 简单的内存模式检查 }; diff --git a/src/include/midend/Pass/Optimize/LICM.h b/src/include/midend/Pass/Optimize/LICM.h new file mode 100644 index 0000000..130e93d --- /dev/null +++ b/src/include/midend/Pass/Optimize/LICM.h @@ -0,0 +1,40 @@ +#pragma once +#include "Pass.h" +#include "Loop.h" +#include "LoopCharacteristics.h" +#include "Dom.h" +#include +#include + +namespace sysy{ + +class LICMContext { +public: + LICMContext(Function* func, Loop* loop, IRBuilder* builder, const LoopCharacteristics* chars) + : func(func), loop(loop), builder(builder), chars(chars) {} + // 运行LICM主流程,返回IR是否被修改 + bool run(); + +private: + Function* func; + Loop* loop; + IRBuilder* builder; + const LoopCharacteristics* chars; // 特征分析结果 + + // 外提所有可提升指令 + bool hoistInstructions(); +}; + + +class LICM : public OptimizationPass{ +private: + IRBuilder *builder; ///< IR构建器,用于插入指令 +public: + static void *ID; + LICM(IRBuilder *builder = nullptr) : OptimizationPass("LICM", Granularity::Function) , builder(builder) {} + bool runOnFunction(Function *F, AnalysisManager &AM) override; + void getAnalysisUsage(std::set &, std::set &) const override; + void *getPassID() const override { return &ID; } +}; + +} // namespace sysy \ No newline at end of file diff --git a/src/midend/CMakeLists.txt b/src/midend/CMakeLists.txt index 0e906aa..870e965 100644 --- a/src/midend/CMakeLists.txt +++ b/src/midend/CMakeLists.txt @@ -18,6 +18,7 @@ add_library(midend_lib STATIC Pass/Optimize/SysYIRCFGOpt.cpp Pass/Optimize/SCCP.cpp Pass/Optimize/LoopNormalization.cpp + Pass/Optimize/LICM.cpp Pass/Optimize/BuildCFG.cpp Pass/Optimize/LargeArrayToGlobal.cpp ) diff --git a/src/midend/Pass/Analysis/LoopCharacteristics.cpp b/src/midend/Pass/Analysis/LoopCharacteristics.cpp index 84f0dca..58c0c11 100644 --- a/src/midend/Pass/Analysis/LoopCharacteristics.cpp +++ b/src/midend/Pass/Analysis/LoopCharacteristics.cpp @@ -303,26 +303,32 @@ void LoopCharacteristicsPass::identifyBasicInductionVariables(Loop* loop, LoopCh } void LoopCharacteristicsPass::identifyBasicLoopInvariants(Loop* loop, LoopCharacteristics* characteristics) { - // 收集基础循环不变量(简化版本) - for (BasicBlock* bb : loop->getBlocks()) { - for (auto& inst : bb->getInstructions()) { - Value* val = inst.get(); - - // 跳过phi指令和终结指令 - if (dynamic_cast(val)) continue; - if (auto* instPtr = dynamic_cast(val)) { - if (instPtr->isTerminator()) continue; - } - - if (isBasicLoopInvariant(val, loop)) { - characteristics->loopInvariants.insert(val); - characteristics->invariantInsts.insert(static_cast(val)); - - if (DEBUG) - std::cout << " Found basic loop invariant: " << val->getName() << std::endl; + // 经典推进法:反复遍历,直到收敛 + bool changed; + std::unordered_set invariants = characteristics->loopInvariants; // 可能为空 + + do { + changed = false; + for (BasicBlock* bb : loop->getBlocks()) { + for (auto& inst : bb->getInstructions()) { + Instruction* I = inst.get(); + // 跳过phi和terminator + if (dynamic_cast(I)) continue; + if (I->isTerminator()) continue; + if (invariants.count(I)) continue; + + if (isClassicLoopInvariant(I, loop, invariants)) { + invariants.insert(I); + characteristics->invariantInsts.insert(I); + if (DEBUG) + std::cout << " Found loop invariant: " << I->getName() << std::endl; + changed = true; + } } } - } + } while (changed); + + characteristics->loopInvariants = std::move(invariants); } void LoopCharacteristicsPass::analyzeBasicLoopBounds(Loop* loop, LoopCharacteristics* characteristics) { @@ -385,22 +391,32 @@ bool LoopCharacteristicsPass::isBasicInductionVariable(Value* val, Loop* loop) { return false; } -bool LoopCharacteristicsPass::isBasicLoopInvariant(Value* val, Loop* loop) { - auto* inst = dynamic_cast(val); - if (!inst) return true; // 非指令(如常量)认为是不变的 - - // 如果指令不在循环内定义,则是不变的 - if (!loop->contains(inst->getParent())) { +// 递归/推进式判定 +bool LoopCharacteristicsPass::isClassicLoopInvariant(Value* val, Loop* loop, const std::unordered_set& invariants) { + // 1. 常量 + if (auto* constval = dynamic_cast(val)) return true; + + // 2. 参数(函数参数)通常不在任何BasicBlock内,直接判定为不变量 + if (auto* arg = dynamic_cast(val)) return true; + + // 3. 指令且定义在循环外 + if (auto* inst = dynamic_cast(val)) { + if (!loop->contains(inst->getParent())) + return true; + + // 4. 跳转 phi指令 副作用 不外提 + if (inst->isTerminator() || inst->isPhi() || sideEffectAnalysis->hasSideEffect(inst)) + return false; + + // 5. 所有操作数都是不变量 + for (size_t i = 0; i < inst->getNumOperands(); ++i) { + Value* op = inst->getOperand(i); + if (!isClassicLoopInvariant(op, loop, invariants) && !invariants.count(op)) + return false; + } return true; } - - // 简化的基础不变量检测:load指令且指针是循环外的 - if (auto* loadInst = dynamic_cast(inst)) { - Value* ptr = loadInst->getPointer(); - return isBasicLoopInvariant(ptr, loop); - } - - // 保守:对于其他指令,认为是变化的 + // 其它情况 return false; } diff --git a/src/midend/Pass/Analysis/SideEffectAnalysis.cpp b/src/midend/Pass/Analysis/SideEffectAnalysis.cpp index 060055c..805f98b 100644 --- a/src/midend/Pass/Analysis/SideEffectAnalysis.cpp +++ b/src/midend/Pass/Analysis/SideEffectAnalysis.cpp @@ -7,388 +7,396 @@ namespace sysy { // 副作用分析遍的静态 ID -void* SysYSideEffectAnalysisPass::ID = (void*)&SysYSideEffectAnalysisPass::ID; +void *SysYSideEffectAnalysisPass::ID = (void *)&SysYSideEffectAnalysisPass::ID; // ====================================================================== // SideEffectAnalysisResult 类的实现 // ====================================================================== -SideEffectAnalysisResult::SideEffectAnalysisResult() { - initializeKnownFunctions(); +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::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; } -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::setInstructionSideEffect(Instruction* inst, const SideEffectInfo& info) { - instructionSideEffects[inst] = info; +void SideEffectAnalysisResult::setFunctionSideEffect(Function *func, const SideEffectInfo &info) { + functionSideEffects[func] = 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::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::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::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; +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; - + // 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; +const SideEffectInfo *SideEffectAnalysisResult::getKnownFunctionSideEffect(const std::string &funcName) const { + auto it = knownFunctions.find(funcName); + return (it != knownFunctions.end()) ? &it->second : nullptr; } // ====================================================================== // SysYSideEffectAnalysisPass 类的实现 // ====================================================================== -bool SysYSideEffectAnalysisPass::runOnModule(Module* M, AnalysisManager& AM) { - if (DEBUG) { - std::cout << "Running SideEffect analysis on module" << std::endl; - } - - // 创建分析结果(构造函数中已经调用了initializeKnownFunctions) - result = std::make_unique(); - - // 获取调用图分析结果 - callGraphAnalysis = AM.getAnalysisResult(); - if (!callGraphAnalysis) { - std::cerr << "Warning: CallGraphAnalysis not available, falling back to conservative analysis" << std::endl; - } - - // 按拓扑序分析函数,确保被调用函数先于调用者分析 - if (callGraphAnalysis) { - // 使用调用图的拓扑排序结果 - const auto& topOrder = callGraphAnalysis->getTopologicalOrder(); - - // 处理强连通分量(递归函数群) - const auto& sccs = callGraphAnalysis->getStronglyConnectedComponents(); - for (const auto& scc : sccs) { - if (scc.size() > 1) { - // 多个函数的强连通分量,使用不动点算法 - analyzeStronglyConnectedComponent(scc, AM); - } else { - // 单个函数,检查是否自递归 - Function* func = scc[0]; - if (callGraphAnalysis->isSelfRecursive(func)) { - // 自递归函数也需要不动点算法 - analyzeStronglyConnectedComponent(scc, AM); - } else { - // 非递归函数,直接分析 - SideEffectInfo funcEffect = analyzeFunction(func, AM); - result->setFunctionSideEffect(func, funcEffect); - } - } - } - } else { - // 没有调用图,保守地分析每个函数 - for (auto& pair : M->getFunctions()) { - Function* func = pair.second.get(); - SideEffectInfo funcEffect = analyzeFunction(func, AM); - result->setFunctionSideEffect(func, funcEffect); +bool SysYSideEffectAnalysisPass::runOnModule(Module *M, AnalysisManager &AM) { + if (DEBUG) { + std::cout << "Running SideEffect analysis on module" << std::endl; + } + + // 创建分析结果(构造函数中已经调用了initializeKnownFunctions) + result = std::make_unique(); + + // 获取调用图分析结果 + callGraphAnalysis = AM.getAnalysisResult(); + if (!callGraphAnalysis) { + std::cerr << "Warning: CallGraphAnalysis not available, falling back to conservative analysis" << std::endl; + } + + // 按拓扑序分析函数,确保被调用函数先于调用者分析 + if (callGraphAnalysis) { + // 使用调用图的拓扑排序结果 + const auto &topOrder = callGraphAnalysis->getTopologicalOrder(); + + // 处理强连通分量(递归函数群) + const auto &sccs = callGraphAnalysis->getStronglyConnectedComponents(); + for (const auto &scc : sccs) { + if (scc.size() > 1) { + // 多个函数的强连通分量,使用不动点算法 + analyzeStronglyConnectedComponent(scc, AM); + } else { + // 单个函数,检查是否自递归 + Function *func = scc[0]; + if (callGraphAnalysis->isSelfRecursive(func)) { + // 自递归函数也需要不动点算法 + analyzeStronglyConnectedComponent(scc, AM); + } else { + // 非递归函数,直接分析 + SideEffectInfo funcEffect = analyzeFunction(func, AM); + result->setFunctionSideEffect(func, funcEffect); } + } } - - if (DEBUG) { - std::cout << "---- Side Effect Analysis Results for Module ----\n"; - for (auto& pair : M->getFunctions()) { - Function* func = pair.second.get(); - const auto& funcInfo = result->getFunctionSideEffect(func); - - std::cout << "Function " << func->getName() << ": "; - switch (funcInfo.type) { - case SideEffectType::NO_SIDE_EFFECT: std::cout << "No Side Effect"; 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 << " (Pure: " << (funcInfo.isPure ? "Yes" : "No") - << ", Modifies Global: " << (funcInfo.mayModifyGlobal ? "Yes" : "No") << ")\n"; - } - std::cout << "--------------------------------------------------\n"; + } else { + // 没有调用图,保守地分析每个函数 + for (auto &pair : M->getFunctions()) { + Function *func = pair.second.get(); + SideEffectInfo funcEffect = analyzeFunction(func, AM); + result->setFunctionSideEffect(func, funcEffect); } - - return false; // Analysis passes return false since they don't modify the IR + } + + if (DEBUG) { + std::cout << "---- Side Effect Analysis Results for Module ----\n"; + for (auto &pair : M->getFunctions()) { + Function *func = pair.second.get(); + const auto &funcInfo = result->getFunctionSideEffect(func); + + std::cout << "Function " << func->getName() << ": "; + switch (funcInfo.type) { + case SideEffectType::NO_SIDE_EFFECT: + std::cout << "No Side Effect"; + 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 << " (Pure: " << (funcInfo.isPure ? "Yes" : "No") + << ", Modifies Global: " << (funcInfo.mayModifyGlobal ? "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); +std::unique_ptr SysYSideEffectAnalysisPass::getResult() { return std::move(result); } + +SideEffectInfo SysYSideEffectAnalysisPass::analyzeFunction(Function *func, AnalysisManager &AM) { + SideEffectInfo functionSideEffect; + + // 为每个指令分析副作用 + for (auto &BB : func->getBasicBlocks()) { + for (auto &I : BB->getInstructions_Range()) { + Instruction *inst = I.get(); + SideEffectInfo instEffect = analyzeInstruction(inst, func, AM); + + // 记录指令的副作用信息 + result->setInstructionSideEffect(inst, instEffect); + + // 合并到函数级别的副作用信息中 + functionSideEffect = functionSideEffect.merge(instEffect); + } + } + + return functionSideEffect; } -SideEffectInfo SysYSideEffectAnalysisPass::analyzeFunction(Function* func, AnalysisManager& AM) { - SideEffectInfo functionSideEffect; - - // 为每个指令分析副作用 - for (auto& BB : func->getBasicBlocks()) { - for (auto& I : BB->getInstructions_Range()) { - Instruction* inst = I.get(); - SideEffectInfo instEffect = analyzeInstruction(inst, func, AM); - - // 记录指令的副作用信息 - result->setInstructionSideEffect(inst, instEffect); - - // 合并到函数级别的副作用信息中 - functionSideEffect = functionSideEffect.merge(instEffect); - } +void SysYSideEffectAnalysisPass::analyzeStronglyConnectedComponent(const std::vector &scc, + AnalysisManager &AM) { + // 使用不动点算法处理递归函数群 + std::unordered_map currentEffects; + std::unordered_map previousEffects; + + // 初始化:所有函数都假设为纯函数 + for (Function *func : scc) { + SideEffectInfo initialEffect; + initialEffect.isPure = true; + currentEffects[func] = initialEffect; + result->setFunctionSideEffect(func, initialEffect); + } + + bool converged = false; + int iterations = 0; + const int maxIterations = 10; // 防止无限循环 + + while (!converged && iterations < maxIterations) { + previousEffects = currentEffects; + + // 重新分析每个函数 + for (Function *func : scc) { + SideEffectInfo newEffect = analyzeFunction(func, AM); + currentEffects[func] = newEffect; + result->setFunctionSideEffect(func, newEffect); } - - return functionSideEffect; + + // 检查是否收敛 + converged = hasConverged(previousEffects, currentEffects); + iterations++; + } + + if (iterations >= maxIterations) { + std::cerr << "Warning: SideEffect analysis did not converge for SCC after " << maxIterations << " iterations" + << std::endl; + } } -void SysYSideEffectAnalysisPass::analyzeStronglyConnectedComponent(const std::vector& scc, AnalysisManager& AM) { - // 使用不动点算法处理递归函数群 - std::unordered_map currentEffects; - std::unordered_map previousEffects; - - // 初始化:所有函数都假设为纯函数 - for (Function* func : scc) { - SideEffectInfo initialEffect; - initialEffect.isPure = true; - currentEffects[func] = initialEffect; - result->setFunctionSideEffect(func, initialEffect); +bool SysYSideEffectAnalysisPass::hasConverged(const std::unordered_map &oldEffects, + const std::unordered_map &newEffects) const { + for (const auto &pair : oldEffects) { + Function *func = pair.first; + const SideEffectInfo &oldEffect = pair.second; + + auto it = newEffects.find(func); + if (it == newEffects.end()) { + return false; // 函数不存在于新结果中 } - - bool converged = false; - int iterations = 0; - const int maxIterations = 10; // 防止无限循环 - - while (!converged && iterations < maxIterations) { - previousEffects = currentEffects; - - // 重新分析每个函数 - for (Function* func : scc) { - SideEffectInfo newEffect = analyzeFunction(func, AM); - currentEffects[func] = newEffect; - result->setFunctionSideEffect(func, newEffect); - } - - // 检查是否收敛 - converged = hasConverged(previousEffects, currentEffects); - iterations++; - } - - if (iterations >= maxIterations) { - std::cerr << "Warning: SideEffect analysis did not converge for SCC after " - << maxIterations << " iterations" << std::endl; + + const SideEffectInfo &newEffect = it->second; + + // 比较关键属性是否相同 + if (oldEffect.type != newEffect.type || oldEffect.mayModifyGlobal != newEffect.mayModifyGlobal || + oldEffect.mayModifyMemory != newEffect.mayModifyMemory || + oldEffect.mayCallFunction != newEffect.mayCallFunction || oldEffect.isPure != newEffect.isPure) { + return false; } + } + + return true; } -bool SysYSideEffectAnalysisPass::hasConverged(const std::unordered_map& oldEffects, - const std::unordered_map& newEffects) const { - for (const auto& pair : oldEffects) { - Function* func = pair.first; - const SideEffectInfo& oldEffect = pair.second; - - auto it = newEffects.find(func); - if (it == newEffects.end()) { - return false; // 函数不存在于新结果中 - } - - const SideEffectInfo& newEffect = it->second; - - // 比较关键属性是否相同 - if (oldEffect.type != newEffect.type || - oldEffect.mayModifyGlobal != newEffect.mayModifyGlobal || - oldEffect.mayModifyMemory != newEffect.mayModifyMemory || - oldEffect.mayCallFunction != newEffect.mayCallFunction || - oldEffect.isPure != newEffect.isPure) { - return false; - } - } - - return true; +SideEffectInfo SysYSideEffectAnalysisPass::analyzeInstruction(Instruction *inst, Function *currentFunc, + AnalysisManager &AM) { + SideEffectInfo info; + + // 根据指令类型进行分析 + if (inst->isCall()) { + return analyzeCallInstruction(static_cast(inst), currentFunc, AM); + } else if (inst->isStore()) { + return analyzeStoreInstruction(static_cast(inst), currentFunc, AM); + } else if (inst->isMemset()) { + return analyzeMemsetInstruction(static_cast(inst), currentFunc, 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::analyzeInstruction(Instruction* inst, Function* currentFunc, AnalysisManager& AM) { - SideEffectInfo info; - - // 根据指令类型进行分析 - if (inst->isCall()) { - return analyzeCallInstruction(static_cast(inst), currentFunc, AM); - } else if (inst->isStore()) { - return analyzeStoreInstruction(static_cast(inst), currentFunc, AM); - } else if (inst->isMemset()) { - return analyzeMemsetInstruction(static_cast(inst), currentFunc, 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, Function *currentFunc, + AnalysisManager &AM) { + SideEffectInfo info; -SideEffectInfo SysYSideEffectAnalysisPass::analyzeCallInstruction(CallInst* call, Function* currentFunc, 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; - } - - // 利用调用图分析结果进行精确分析 - if (callGraphAnalysis) { - // 检查被调用函数是否已分析过 - const SideEffectInfo& funcEffect = result->getFunctionSideEffect(calledFunc); - if (funcEffect.type != SideEffectType::NO_SIDE_EFFECT || !funcEffect.isPure) { - return funcEffect; - } - - // 检查递归调用 - if (callGraphAnalysis->isRecursive(calledFunc)) { - // 递归函数保守处理(在不动点算法中会精确分析) - info.type = SideEffectType::FUNCTION_CALL; - info.mayModifyGlobal = true; - info.mayModifyMemory = true; - info.mayCallFunction = true; - info.isPure = false; - return info; - } - } - - // 对于未分析的用户函数,保守处理 - info.type = SideEffectType::FUNCTION_CALL; + // 获取被调用的函数 + 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; + } + + // 利用调用图分析结果进行精确分析 + if (callGraphAnalysis) { + // 检查被调用函数是否已分析过 + const SideEffectInfo &funcEffect = result->getFunctionSideEffect(calledFunc); + if (funcEffect.type != SideEffectType::NO_SIDE_EFFECT || !funcEffect.isPure) { + return funcEffect; + } + + // 检查递归调用 + if (callGraphAnalysis->isRecursive(calledFunc)) { + // 递归函数保守处理(在不动点算法中会精确分析) + info.type = SideEffectType::FUNCTION_CALL; + info.mayModifyGlobal = true; + info.mayModifyMemory = true; + info.mayCallFunction = true; + info.isPure = false; + return info; + } + } + + // 对于未分析的用户函数,保守处理 + info.type = SideEffectType::FUNCTION_CALL; + info.mayModifyGlobal = true; + info.mayModifyMemory = true; + info.mayCallFunction = true; + info.isPure = false; + + return info; } -SideEffectInfo SysYSideEffectAnalysisPass::analyzeStoreInstruction(StoreInst* store, Function* currentFunc, AnalysisManager& AM) { - SideEffectInfo info; - info.type = SideEffectType::MEMORY_WRITE; - info.mayModifyMemory = true; - info.isPure = false; - - // 获取函数的别名分析结果 - AliasAnalysisResult* aliasAnalysis = AM.getAnalysisResult(currentFunc); - if (aliasAnalysis) { - Value* storePtr = store->getPointer(); - - // 如果存储到全局变量或可能别名的位置,则可能修改全局状态 - if (!aliasAnalysis->isLocalArray(storePtr)) { - info.mayModifyGlobal = true; - } - } else { - // 没有别名分析结果,保守处理 - info.mayModifyGlobal = true; +SideEffectInfo SysYSideEffectAnalysisPass::analyzeStoreInstruction(StoreInst *store, Function *currentFunc, + AnalysisManager &AM) { + SideEffectInfo info; + info.type = SideEffectType::MEMORY_WRITE; + info.mayModifyMemory = true; + info.isPure = false; + + // 获取函数的别名分析结果 + AliasAnalysisResult *aliasAnalysis = AM.getAnalysisResult(currentFunc); + if (aliasAnalysis) { + Value *storePtr = store->getPointer(); + + // 如果存储到全局变量或可能别名的位置,则可能修改全局状态 + if (!aliasAnalysis->isLocalArray(storePtr)) { + info.mayModifyGlobal = true; } - - return info; + } else { + // 没有别名分析结果,保守处理 + info.mayModifyGlobal = true; + } + + return info; } -SideEffectInfo SysYSideEffectAnalysisPass::analyzeMemsetInstruction(MemsetInst* memset, Function* currentFunc, AnalysisManager& AM) { - SideEffectInfo info; - info.type = SideEffectType::MEMORY_WRITE; - info.mayModifyMemory = true; - info.isPure = false; - - // 获取函数的别名分析结果 - AliasAnalysisResult* aliasAnalysis = AM.getAnalysisResult(currentFunc); - if (aliasAnalysis) { - Value* memsetPtr = memset->getPointer(); - - // 如果memset操作全局变量或可能别名的位置,则可能修改全局状态 - if (!aliasAnalysis->isLocalArray(memsetPtr)) { - info.mayModifyGlobal = true; - } - } else { - // 没有别名分析结果,保守处理 - info.mayModifyGlobal = true; +SideEffectInfo SysYSideEffectAnalysisPass::analyzeMemsetInstruction(MemsetInst *memset, Function *currentFunc, + AnalysisManager &AM) { + SideEffectInfo info; + info.type = SideEffectType::MEMORY_WRITE; + info.mayModifyMemory = true; + info.isPure = false; + + // 获取函数的别名分析结果 + AliasAnalysisResult *aliasAnalysis = AM.getAnalysisResult(currentFunc); + if (aliasAnalysis) { + Value *memsetPtr = memset->getPointer(); + + // 如果memset操作全局变量或可能别名的位置,则可能修改全局状态 + if (!aliasAnalysis->isLocalArray(memsetPtr)) { + info.mayModifyGlobal = true; } - - return info; + } else { + // 没有别名分析结果,保守处理 + info.mayModifyGlobal = true; + } + + return info; } } // namespace sysy diff --git a/src/midend/Pass/Optimize/LICM.cpp b/src/midend/Pass/Optimize/LICM.cpp new file mode 100644 index 0000000..da9b432 --- /dev/null +++ b/src/midend/Pass/Optimize/LICM.cpp @@ -0,0 +1,84 @@ +#include "LICM.h" +#include "IR.h" + +extern int DEBUG; + +namespace sysy { + +void *LICM::ID = (void *)&LICM::ID; + +bool LICMContext::run() { return hoistInstructions(); } + +bool LICMContext::hoistInstructions() { + bool changed = false; + BasicBlock *preheader = loop->getPreHeader(); + if (!preheader || !chars){ + if(DEBUG) { + std::cerr << "LICM: No preheader or loop characteristics found, skipping hoisting." << std::endl; + } + return false; + } + + for (auto *inst : chars->invariantInsts) { + if (!inst) { + if(DEBUG) { + std::cerr << "LICM: Invalid instruction found, skipping." << std::endl; + } + continue; // 跳过无效指令 + } + else{ + if(DEBUG) { + std::cout << "LICM: Processing instruction " << inst->getName() << " for hoisting." << std::endl; + } + } + BasicBlock *parent = inst->getParent(); + // 只外提当前还在循环体内的指令 + if (parent && loop->contains(parent)) { + // 获取源和槽的迭代器并移动指令到前置块 + if(DEBUG) { + std::cout << "LICM: Hoisting instruction " << inst->getName() << " from " + << parent->getName() << " to preheader " << preheader->getName() << std::endl; + } + auto sourcePos = parent->findInstIterator(inst); + auto targetPos = preheader->terminator(); + parent->moveInst(sourcePos, targetPos, preheader); + changed = true; + } + } + return changed; +} + +// ---- LICM Pass Implementation ---- + +bool LICM::runOnFunction(Function *F, AnalysisManager &AM) { + auto *loopAnalysis = AM.getAnalysisResult(F); + auto *loopCharsResult = AM.getAnalysisResult(F); + if (!loopAnalysis || !loopCharsResult) + return false; + + bool changed = false; + // 对每个函数内的所有循环做处理 + for (const auto &loop_ptr : loopAnalysis->getAllLoops()) { + Loop *loop = loop_ptr.get(); + if(DEBUG){ + std::cout << "LICM: Processing loop in function " << F->getName() << ": " << loop->getName() << std::endl; + } + const LoopCharacteristics *chars = loopCharsResult->getCharacteristics(loop); + if (!chars || !loop->getPreHeader()) + continue; // 没有分析结果或没有前置块则跳过 + LICMContext ctx(F, loop, builder, chars); + changed |= ctx.run(); + } + return changed; +} + +void LICM::getAnalysisUsage(std::set &analysisDependencies, std::set &analysisInvalidations) const { + + analysisDependencies.insert(&LoopAnalysisPass::ID); + analysisDependencies.insert(&LoopCharacteristicsPass::ID); + + analysisInvalidations.insert(&LoopCharacteristicsPass::ID); + analysisInvalidations.insert(&LivenessAnalysisPass::ID); +} + +} // namespace sysy \ No newline at end of file diff --git a/src/midend/Pass/Pass.cpp b/src/midend/Pass/Pass.cpp index 499a64f..74c1a67 100644 --- a/src/midend/Pass/Pass.cpp +++ b/src/midend/Pass/Pass.cpp @@ -13,6 +13,8 @@ #include "SCCP.h" #include "BuildCFG.h" #include "LargeArrayToGlobal.h" +#include "LoopNormalization.h" +#include "LICM.h" #include "Pass.h" #include #include @@ -66,6 +68,8 @@ void PassManager::runOptimizationPipeline(Module* moduleIR, IRBuilder* builderIR registerOptimizationPass(); registerOptimizationPass(builderIR); + registerOptimizationPass(builderIR); + registerOptimizationPass(builderIR); registerOptimizationPass(builderIR); registerOptimizationPass(builderIR); @@ -130,6 +134,16 @@ void PassManager::runOptimizationPipeline(Module* moduleIR, IRBuilder* builderIR printPasses(); } + this->clearPasses(); + this->addPass(&LoopNormalizationPass::ID); + this->addPass(&LICM::ID); + this->run(); + + if(DEBUG) { + std::cout << "=== IR After Loop Normalization and LICM Optimizations ===\n"; + printPasses(); + } + this->clearPasses(); this->addPass(&Reg2Mem::ID); this->run();