[midend-LICM]优化了特征分析中对循环不变量的识别,实现了LICM遍,格式化副作用分析代码
This commit is contained in:
@@ -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<SideEffectAnalysisResult>();
|
||||
|
||||
// 获取调用图分析结果
|
||||
callGraphAnalysis = AM.getAnalysisResult<CallGraphAnalysisResult, CallGraphAnalysisPass>();
|
||||
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<SideEffectAnalysisResult>();
|
||||
|
||||
// 获取调用图分析结果
|
||||
callGraphAnalysis = AM.getAnalysisResult<CallGraphAnalysisResult, CallGraphAnalysisPass>();
|
||||
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<AnalysisResultBase> SysYSideEffectAnalysisPass::getResult() {
|
||||
return std::move(result);
|
||||
std::unique_ptr<AnalysisResultBase> 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<Function *> &scc,
|
||||
AnalysisManager &AM) {
|
||||
// 使用不动点算法处理递归函数群
|
||||
std::unordered_map<Function *, SideEffectInfo> currentEffects;
|
||||
std::unordered_map<Function *, SideEffectInfo> 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<Function*>& scc, AnalysisManager& AM) {
|
||||
// 使用不动点算法处理递归函数群
|
||||
std::unordered_map<Function*, SideEffectInfo> currentEffects;
|
||||
std::unordered_map<Function*, SideEffectInfo> previousEffects;
|
||||
|
||||
// 初始化:所有函数都假设为纯函数
|
||||
for (Function* func : scc) {
|
||||
SideEffectInfo initialEffect;
|
||||
initialEffect.isPure = true;
|
||||
currentEffects[func] = initialEffect;
|
||||
result->setFunctionSideEffect(func, initialEffect);
|
||||
bool SysYSideEffectAnalysisPass::hasConverged(const std::unordered_map<Function *, SideEffectInfo> &oldEffects,
|
||||
const std::unordered_map<Function *, SideEffectInfo> &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<Function*, SideEffectInfo>& oldEffects,
|
||||
const std::unordered_map<Function*, SideEffectInfo>& 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<CallInst *>(inst), currentFunc, AM);
|
||||
} else if (inst->isStore()) {
|
||||
return analyzeStoreInstruction(static_cast<StoreInst *>(inst), currentFunc, AM);
|
||||
} else if (inst->isMemset()) {
|
||||
return analyzeMemsetInstruction(static_cast<MemsetInst *>(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<CallInst*>(inst), currentFunc, AM);
|
||||
} else if (inst->isStore()) {
|
||||
return analyzeStoreInstruction(static_cast<StoreInst*>(inst), currentFunc, AM);
|
||||
} else if (inst->isMemset()) {
|
||||
return analyzeMemsetInstruction(static_cast<MemsetInst*>(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<AliasAnalysisResult, SysYAliasAnalysisPass>(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<AliasAnalysisResult, SysYAliasAnalysisPass>(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<AliasAnalysisResult, SysYAliasAnalysisPass>(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<AliasAnalysisResult, SysYAliasAnalysisPass>(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
|
||||
|
||||
Reference in New Issue
Block a user