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

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

View File

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