#include "SideEffectAnalysis.h" #include "AliasAnalysis.h" #include "CallGraphAnalysis.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; } // 如果没有找到,检查是否为已知的库函数 if (func) { std::string funcName = func->getName(); const SideEffectInfo *knownInfo = getKnownFunctionSideEffect(funcName); if (knownInfo) { return *knownInfo; } } // 返回默认的无副作用信息 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::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); } } 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); } 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; } 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); } // 检查是否收敛 converged = hasConverged(previousEffects, currentEffects); iterations++; } if (iterations >= maxIterations) { std::cerr << "Warning: SideEffect analysis did not converge for SCC after " << maxIterations << " iterations" << std::endl; } } 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::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; 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; } 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; } return info; } } // namespace sysy