[midend-LICM]优化了特征分析中对循环不变量的识别,实现了LICM遍,格式化副作用分析代码

This commit is contained in:
rain2133
2025-08-12 15:53:57 +08:00
parent 70f6a25ebc
commit f634273852
7 changed files with 523 additions and 360 deletions

View File

@@ -38,8 +38,8 @@ struct LoopCharacteristics {
std::map<Value*, int> inductionSteps; // 归纳变量的步长(简化) std::map<Value*, int> inductionSteps; // 归纳变量的步长(简化)
// ========== 基础循环不变量分析 ========== // ========== 基础循环不变量分析 ==========
std::set<Value*> loopInvariants; // 循环不变量 std::unordered_set<Value*> loopInvariants; // 循环不变量
std::set<Instruction*> invariantInsts; // 可提升的不变指令 std::unordered_set<Instruction*> invariantInsts; // 可提升的不变指令
// ========== 基础边界分析 ========== // ========== 基础边界分析 ==========
std::optional<int> staticTripCount; // 静态循环次数(如果可确定) std::optional<int> staticTripCount; // 静态循环次数(如果可确定)
@@ -293,7 +293,7 @@ private:
// 基础归纳变量识别 // 基础归纳变量识别
void identifyBasicInductionVariables(Loop* loop, LoopCharacteristics* characteristics); void identifyBasicInductionVariables(Loop* loop, LoopCharacteristics* characteristics);
// 基础循环不变量识别 // 循环不变量识别
void identifyBasicLoopInvariants(Loop* loop, LoopCharacteristics* characteristics); void identifyBasicLoopInvariants(Loop* loop, LoopCharacteristics* characteristics);
// 基础边界分析 // 基础边界分析
@@ -306,8 +306,8 @@ private:
void evaluateBasicOptimizationOpportunities(Loop* loop, LoopCharacteristics* characteristics); void evaluateBasicOptimizationOpportunities(Loop* loop, LoopCharacteristics* characteristics);
// ========== 辅助方法 ========== // ========== 辅助方法 ==========
bool isClassicLoopInvariant(Value* val, Loop* loop, const std::unordered_set<Value*>& invariants);
bool isBasicInductionVariable(Value* val, Loop* loop); bool isBasicInductionVariable(Value* val, Loop* loop);
bool isBasicLoopInvariant(Value* val, Loop* loop);
bool hasSimpleMemoryPattern(Loop* loop); // 简单的内存模式检查 bool hasSimpleMemoryPattern(Loop* loop); // 简单的内存模式检查
}; };

View File

@@ -0,0 +1,40 @@
#pragma once
#include "Pass.h"
#include "Loop.h"
#include "LoopCharacteristics.h"
#include "Dom.h"
#include <unordered_set>
#include <vector>
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<void *> &, std::set<void *> &) const override;
void *getPassID() const override { return &ID; }
};
} // namespace sysy

View File

@@ -18,6 +18,7 @@ add_library(midend_lib STATIC
Pass/Optimize/SysYIRCFGOpt.cpp Pass/Optimize/SysYIRCFGOpt.cpp
Pass/Optimize/SCCP.cpp Pass/Optimize/SCCP.cpp
Pass/Optimize/LoopNormalization.cpp Pass/Optimize/LoopNormalization.cpp
Pass/Optimize/LICM.cpp
Pass/Optimize/BuildCFG.cpp Pass/Optimize/BuildCFG.cpp
Pass/Optimize/LargeArrayToGlobal.cpp Pass/Optimize/LargeArrayToGlobal.cpp
) )

View File

@@ -303,26 +303,32 @@ void LoopCharacteristicsPass::identifyBasicInductionVariables(Loop* loop, LoopCh
} }
void LoopCharacteristicsPass::identifyBasicLoopInvariants(Loop* loop, LoopCharacteristics* characteristics) { void LoopCharacteristicsPass::identifyBasicLoopInvariants(Loop* loop, LoopCharacteristics* characteristics) {
// 收集基础循环不变量(简化版本) // 经典推进法:反复遍历,直到收敛
bool changed;
std::unordered_set<Value*> invariants = characteristics->loopInvariants; // 可能为空
do {
changed = false;
for (BasicBlock* bb : loop->getBlocks()) { for (BasicBlock* bb : loop->getBlocks()) {
for (auto& inst : bb->getInstructions()) { for (auto& inst : bb->getInstructions()) {
Value* val = inst.get(); Instruction* I = inst.get();
// 跳过phi和terminator
// 跳过phi指令和终结指令 if (dynamic_cast<PhiInst*>(I)) continue;
if (dynamic_cast<PhiInst*>(val)) continue; if (I->isTerminator()) continue;
if (auto* instPtr = dynamic_cast<Instruction*>(val)) { if (invariants.count(I)) continue;
if (instPtr->isTerminator()) continue;
}
if (isBasicLoopInvariant(val, loop)) {
characteristics->loopInvariants.insert(val);
characteristics->invariantInsts.insert(static_cast<Instruction*>(val));
if (isClassicLoopInvariant(I, loop, invariants)) {
invariants.insert(I);
characteristics->invariantInsts.insert(I);
if (DEBUG) if (DEBUG)
std::cout << " Found basic loop invariant: " << val->getName() << std::endl; 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) { void LoopCharacteristicsPass::analyzeBasicLoopBounds(Loop* loop, LoopCharacteristics* characteristics) {
@@ -385,22 +391,32 @@ bool LoopCharacteristicsPass::isBasicInductionVariable(Value* val, Loop* loop) {
return false; return false;
} }
bool LoopCharacteristicsPass::isBasicLoopInvariant(Value* val, Loop* loop) { // 递归/推进式判定
auto* inst = dynamic_cast<Instruction*>(val); bool LoopCharacteristicsPass::isClassicLoopInvariant(Value* val, Loop* loop, const std::unordered_set<Value*>& invariants) {
if (!inst) return true; // 非指令(如常量)认为是不变的 // 1. 常量
if (auto* constval = dynamic_cast<ConstantValue*>(val)) return true;
// 如果指令不在循环内定义,则是不变 // 2. 参数函数参数通常不在任何BasicBlock内直接判定为不变
if (!loop->contains(inst->getParent())) { if (auto* arg = dynamic_cast<Argument*>(val)) return true;
// 3. 指令且定义在循环外
if (auto* inst = dynamic_cast<Instruction*>(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; return true;
} }
// 其它情况
// 简化的基础不变量检测load指令且指针是循环外的
if (auto* loadInst = dynamic_cast<LoadInst*>(inst)) {
Value* ptr = loadInst->getPointer();
return isBasicLoopInvariant(ptr, loop);
}
// 保守:对于其他指令,认为是变化的
return false; return false;
} }

View File

@@ -7,17 +7,15 @@
namespace sysy { namespace sysy {
// 副作用分析遍的静态 ID // 副作用分析遍的静态 ID
void* SysYSideEffectAnalysisPass::ID = (void*)&SysYSideEffectAnalysisPass::ID; void *SysYSideEffectAnalysisPass::ID = (void *)&SysYSideEffectAnalysisPass::ID;
// ====================================================================== // ======================================================================
// SideEffectAnalysisResult 类的实现 // SideEffectAnalysisResult 类的实现
// ====================================================================== // ======================================================================
SideEffectAnalysisResult::SideEffectAnalysisResult() { SideEffectAnalysisResult::SideEffectAnalysisResult() { initializeKnownFunctions(); }
initializeKnownFunctions();
}
const SideEffectInfo& SideEffectAnalysisResult::getInstructionSideEffect(Instruction* inst) const { const SideEffectInfo &SideEffectAnalysisResult::getInstructionSideEffect(Instruction *inst) const {
auto it = instructionSideEffects.find(inst); auto it = instructionSideEffects.find(inst);
if (it != instructionSideEffects.end()) { if (it != instructionSideEffects.end()) {
return it->second; return it->second;
@@ -27,7 +25,7 @@ const SideEffectInfo& SideEffectAnalysisResult::getInstructionSideEffect(Instruc
return noEffect; return noEffect;
} }
const SideEffectInfo& SideEffectAnalysisResult::getFunctionSideEffect(Function* func) const { const SideEffectInfo &SideEffectAnalysisResult::getFunctionSideEffect(Function *func) const {
auto it = functionSideEffects.find(func); auto it = functionSideEffects.find(func);
if (it != functionSideEffects.end()) { if (it != functionSideEffects.end()) {
return it->second; return it->second;
@@ -37,31 +35,31 @@ const SideEffectInfo& SideEffectAnalysisResult::getFunctionSideEffect(Function*
return noEffect; return noEffect;
} }
void SideEffectAnalysisResult::setInstructionSideEffect(Instruction* inst, const SideEffectInfo& info) { void SideEffectAnalysisResult::setInstructionSideEffect(Instruction *inst, const SideEffectInfo &info) {
instructionSideEffects[inst] = info; instructionSideEffects[inst] = info;
} }
void SideEffectAnalysisResult::setFunctionSideEffect(Function* func, const SideEffectInfo& info) { void SideEffectAnalysisResult::setFunctionSideEffect(Function *func, const SideEffectInfo &info) {
functionSideEffects[func] = info; functionSideEffects[func] = info;
} }
bool SideEffectAnalysisResult::hasSideEffect(Instruction* inst) const { bool SideEffectAnalysisResult::hasSideEffect(Instruction *inst) const {
const auto& info = getInstructionSideEffect(inst); const auto &info = getInstructionSideEffect(inst);
return info.type != SideEffectType::NO_SIDE_EFFECT; return info.type != SideEffectType::NO_SIDE_EFFECT;
} }
bool SideEffectAnalysisResult::mayModifyMemory(Instruction* inst) const { bool SideEffectAnalysisResult::mayModifyMemory(Instruction *inst) const {
const auto& info = getInstructionSideEffect(inst); const auto &info = getInstructionSideEffect(inst);
return info.mayModifyMemory; return info.mayModifyMemory;
} }
bool SideEffectAnalysisResult::mayModifyGlobal(Instruction* inst) const { bool SideEffectAnalysisResult::mayModifyGlobal(Instruction *inst) const {
const auto& info = getInstructionSideEffect(inst); const auto &info = getInstructionSideEffect(inst);
return info.mayModifyGlobal; return info.mayModifyGlobal;
} }
bool SideEffectAnalysisResult::isPureFunction(Function* func) const { bool SideEffectAnalysisResult::isPureFunction(Function *func) const {
const auto& info = getFunctionSideEffect(func); const auto &info = getFunctionSideEffect(func);
return info.isPure; return info.isPure;
} }
@@ -99,10 +97,9 @@ void SideEffectAnalysisResult::initializeKnownFunctions() {
knownFunctions["_sysy_starttime"] = timeEffect; knownFunctions["_sysy_starttime"] = timeEffect;
knownFunctions["_sysy_stoptime"] = timeEffect; knownFunctions["_sysy_stoptime"] = timeEffect;
} }
const SideEffectInfo* SideEffectAnalysisResult::getKnownFunctionSideEffect(const std::string& funcName) const { const SideEffectInfo *SideEffectAnalysisResult::getKnownFunctionSideEffect(const std::string &funcName) const {
auto it = knownFunctions.find(funcName); auto it = knownFunctions.find(funcName);
return (it != knownFunctions.end()) ? &it->second : nullptr; return (it != knownFunctions.end()) ? &it->second : nullptr;
} }
@@ -111,7 +108,7 @@ const SideEffectInfo* SideEffectAnalysisResult::getKnownFunctionSideEffect(const
// SysYSideEffectAnalysisPass 类的实现 // SysYSideEffectAnalysisPass 类的实现
// ====================================================================== // ======================================================================
bool SysYSideEffectAnalysisPass::runOnModule(Module* M, AnalysisManager& AM) { bool SysYSideEffectAnalysisPass::runOnModule(Module *M, AnalysisManager &AM) {
if (DEBUG) { if (DEBUG) {
std::cout << "Running SideEffect analysis on module" << std::endl; std::cout << "Running SideEffect analysis on module" << std::endl;
} }
@@ -128,17 +125,17 @@ bool SysYSideEffectAnalysisPass::runOnModule(Module* M, AnalysisManager& AM) {
// 按拓扑序分析函数,确保被调用函数先于调用者分析 // 按拓扑序分析函数,确保被调用函数先于调用者分析
if (callGraphAnalysis) { if (callGraphAnalysis) {
// 使用调用图的拓扑排序结果 // 使用调用图的拓扑排序结果
const auto& topOrder = callGraphAnalysis->getTopologicalOrder(); const auto &topOrder = callGraphAnalysis->getTopologicalOrder();
// 处理强连通分量(递归函数群) // 处理强连通分量(递归函数群)
const auto& sccs = callGraphAnalysis->getStronglyConnectedComponents(); const auto &sccs = callGraphAnalysis->getStronglyConnectedComponents();
for (const auto& scc : sccs) { for (const auto &scc : sccs) {
if (scc.size() > 1) { if (scc.size() > 1) {
// 多个函数的强连通分量,使用不动点算法 // 多个函数的强连通分量,使用不动点算法
analyzeStronglyConnectedComponent(scc, AM); analyzeStronglyConnectedComponent(scc, AM);
} else { } else {
// 单个函数,检查是否自递归 // 单个函数,检查是否自递归
Function* func = scc[0]; Function *func = scc[0];
if (callGraphAnalysis->isSelfRecursive(func)) { if (callGraphAnalysis->isSelfRecursive(func)) {
// 自递归函数也需要不动点算法 // 自递归函数也需要不动点算法
analyzeStronglyConnectedComponent(scc, AM); analyzeStronglyConnectedComponent(scc, AM);
@@ -151,8 +148,8 @@ bool SysYSideEffectAnalysisPass::runOnModule(Module* M, AnalysisManager& AM) {
} }
} else { } else {
// 没有调用图,保守地分析每个函数 // 没有调用图,保守地分析每个函数
for (auto& pair : M->getFunctions()) { for (auto &pair : M->getFunctions()) {
Function* func = pair.second.get(); Function *func = pair.second.get();
SideEffectInfo funcEffect = analyzeFunction(func, AM); SideEffectInfo funcEffect = analyzeFunction(func, AM);
result->setFunctionSideEffect(func, funcEffect); result->setFunctionSideEffect(func, funcEffect);
} }
@@ -160,17 +157,27 @@ bool SysYSideEffectAnalysisPass::runOnModule(Module* M, AnalysisManager& AM) {
if (DEBUG) { if (DEBUG) {
std::cout << "---- Side Effect Analysis Results for Module ----\n"; std::cout << "---- Side Effect Analysis Results for Module ----\n";
for (auto& pair : M->getFunctions()) { for (auto &pair : M->getFunctions()) {
Function* func = pair.second.get(); Function *func = pair.second.get();
const auto& funcInfo = result->getFunctionSideEffect(func); const auto &funcInfo = result->getFunctionSideEffect(func);
std::cout << "Function " << func->getName() << ": "; std::cout << "Function " << func->getName() << ": ";
switch (funcInfo.type) { switch (funcInfo.type) {
case SideEffectType::NO_SIDE_EFFECT: std::cout << "No Side Effect"; break; case SideEffectType::NO_SIDE_EFFECT:
case SideEffectType::MEMORY_WRITE: std::cout << "Memory Write"; break; std::cout << "No Side Effect";
case SideEffectType::FUNCTION_CALL: std::cout << "Function Call"; break; break;
case SideEffectType::IO_OPERATION: std::cout << "I/O Operation"; break; case SideEffectType::MEMORY_WRITE:
case SideEffectType::UNKNOWN: std::cout << "Unknown"; break; 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") std::cout << " (Pure: " << (funcInfo.isPure ? "Yes" : "No")
<< ", Modifies Global: " << (funcInfo.mayModifyGlobal ? "Yes" : "No") << ")\n"; << ", Modifies Global: " << (funcInfo.mayModifyGlobal ? "Yes" : "No") << ")\n";
@@ -181,17 +188,15 @@ bool SysYSideEffectAnalysisPass::runOnModule(Module* M, AnalysisManager& AM) {
return false; // Analysis passes return false since they don't modify the IR return false; // Analysis passes return false since they don't modify the IR
} }
std::unique_ptr<AnalysisResultBase> SysYSideEffectAnalysisPass::getResult() { std::unique_ptr<AnalysisResultBase> SysYSideEffectAnalysisPass::getResult() { return std::move(result); }
return std::move(result);
}
SideEffectInfo SysYSideEffectAnalysisPass::analyzeFunction(Function* func, AnalysisManager& AM) { SideEffectInfo SysYSideEffectAnalysisPass::analyzeFunction(Function *func, AnalysisManager &AM) {
SideEffectInfo functionSideEffect; SideEffectInfo functionSideEffect;
// 为每个指令分析副作用 // 为每个指令分析副作用
for (auto& BB : func->getBasicBlocks()) { for (auto &BB : func->getBasicBlocks()) {
for (auto& I : BB->getInstructions_Range()) { for (auto &I : BB->getInstructions_Range()) {
Instruction* inst = I.get(); Instruction *inst = I.get();
SideEffectInfo instEffect = analyzeInstruction(inst, func, AM); SideEffectInfo instEffect = analyzeInstruction(inst, func, AM);
// 记录指令的副作用信息 // 记录指令的副作用信息
@@ -205,13 +210,14 @@ SideEffectInfo SysYSideEffectAnalysisPass::analyzeFunction(Function* func, Analy
return functionSideEffect; return functionSideEffect;
} }
void SysYSideEffectAnalysisPass::analyzeStronglyConnectedComponent(const std::vector<Function*>& scc, AnalysisManager& AM) { void SysYSideEffectAnalysisPass::analyzeStronglyConnectedComponent(const std::vector<Function *> &scc,
AnalysisManager &AM) {
// 使用不动点算法处理递归函数群 // 使用不动点算法处理递归函数群
std::unordered_map<Function*, SideEffectInfo> currentEffects; std::unordered_map<Function *, SideEffectInfo> currentEffects;
std::unordered_map<Function*, SideEffectInfo> previousEffects; std::unordered_map<Function *, SideEffectInfo> previousEffects;
// 初始化:所有函数都假设为纯函数 // 初始化:所有函数都假设为纯函数
for (Function* func : scc) { for (Function *func : scc) {
SideEffectInfo initialEffect; SideEffectInfo initialEffect;
initialEffect.isPure = true; initialEffect.isPure = true;
currentEffects[func] = initialEffect; currentEffects[func] = initialEffect;
@@ -226,7 +232,7 @@ void SysYSideEffectAnalysisPass::analyzeStronglyConnectedComponent(const std::ve
previousEffects = currentEffects; previousEffects = currentEffects;
// 重新分析每个函数 // 重新分析每个函数
for (Function* func : scc) { for (Function *func : scc) {
SideEffectInfo newEffect = analyzeFunction(func, AM); SideEffectInfo newEffect = analyzeFunction(func, AM);
currentEffects[func] = newEffect; currentEffects[func] = newEffect;
result->setFunctionSideEffect(func, newEffect); result->setFunctionSideEffect(func, newEffect);
@@ -238,30 +244,28 @@ void SysYSideEffectAnalysisPass::analyzeStronglyConnectedComponent(const std::ve
} }
if (iterations >= maxIterations) { if (iterations >= maxIterations) {
std::cerr << "Warning: SideEffect analysis did not converge for SCC after " std::cerr << "Warning: SideEffect analysis did not converge for SCC after " << maxIterations << " iterations"
<< maxIterations << " iterations" << std::endl; << std::endl;
} }
} }
bool SysYSideEffectAnalysisPass::hasConverged(const std::unordered_map<Function*, SideEffectInfo>& oldEffects, bool SysYSideEffectAnalysisPass::hasConverged(const std::unordered_map<Function *, SideEffectInfo> &oldEffects,
const std::unordered_map<Function*, SideEffectInfo>& newEffects) const { const std::unordered_map<Function *, SideEffectInfo> &newEffects) const {
for (const auto& pair : oldEffects) { for (const auto &pair : oldEffects) {
Function* func = pair.first; Function *func = pair.first;
const SideEffectInfo& oldEffect = pair.second; const SideEffectInfo &oldEffect = pair.second;
auto it = newEffects.find(func); auto it = newEffects.find(func);
if (it == newEffects.end()) { if (it == newEffects.end()) {
return false; // 函数不存在于新结果中 return false; // 函数不存在于新结果中
} }
const SideEffectInfo& newEffect = it->second; const SideEffectInfo &newEffect = it->second;
// 比较关键属性是否相同 // 比较关键属性是否相同
if (oldEffect.type != newEffect.type || if (oldEffect.type != newEffect.type || oldEffect.mayModifyGlobal != newEffect.mayModifyGlobal ||
oldEffect.mayModifyGlobal != newEffect.mayModifyGlobal ||
oldEffect.mayModifyMemory != newEffect.mayModifyMemory || oldEffect.mayModifyMemory != newEffect.mayModifyMemory ||
oldEffect.mayCallFunction != newEffect.mayCallFunction || oldEffect.mayCallFunction != newEffect.mayCallFunction || oldEffect.isPure != newEffect.isPure) {
oldEffect.isPure != newEffect.isPure) {
return false; return false;
} }
} }
@@ -269,16 +273,17 @@ bool SysYSideEffectAnalysisPass::hasConverged(const std::unordered_map<Function*
return true; return true;
} }
SideEffectInfo SysYSideEffectAnalysisPass::analyzeInstruction(Instruction* inst, Function* currentFunc, AnalysisManager& AM) { SideEffectInfo SysYSideEffectAnalysisPass::analyzeInstruction(Instruction *inst, Function *currentFunc,
AnalysisManager &AM) {
SideEffectInfo info; SideEffectInfo info;
// 根据指令类型进行分析 // 根据指令类型进行分析
if (inst->isCall()) { if (inst->isCall()) {
return analyzeCallInstruction(static_cast<CallInst*>(inst), currentFunc, AM); return analyzeCallInstruction(static_cast<CallInst *>(inst), currentFunc, AM);
} else if (inst->isStore()) { } else if (inst->isStore()) {
return analyzeStoreInstruction(static_cast<StoreInst*>(inst), currentFunc, AM); return analyzeStoreInstruction(static_cast<StoreInst *>(inst), currentFunc, AM);
} else if (inst->isMemset()) { } else if (inst->isMemset()) {
return analyzeMemsetInstruction(static_cast<MemsetInst*>(inst), currentFunc, AM); return analyzeMemsetInstruction(static_cast<MemsetInst *>(inst), currentFunc, AM);
} else if (inst->isBranch() || inst->isReturn()) { } else if (inst->isBranch() || inst->isReturn()) {
// 控制流指令无副作用,但必须保留 // 控制流指令无副作用,但必须保留
info.type = SideEffectType::NO_SIDE_EFFECT; info.type = SideEffectType::NO_SIDE_EFFECT;
@@ -292,11 +297,12 @@ SideEffectInfo SysYSideEffectAnalysisPass::analyzeInstruction(Instruction* inst,
return info; return info;
} }
SideEffectInfo SysYSideEffectAnalysisPass::analyzeCallInstruction(CallInst* call, Function* currentFunc, AnalysisManager& AM) { SideEffectInfo SysYSideEffectAnalysisPass::analyzeCallInstruction(CallInst *call, Function *currentFunc,
AnalysisManager &AM) {
SideEffectInfo info; SideEffectInfo info;
// 获取被调用的函数 // 获取被调用的函数
Function* calledFunc = call->getCallee(); Function *calledFunc = call->getCallee();
if (!calledFunc) { if (!calledFunc) {
// 间接调用,保守处理 // 间接调用,保守处理
info.type = SideEffectType::UNKNOWN; info.type = SideEffectType::UNKNOWN;
@@ -310,7 +316,7 @@ SideEffectInfo SysYSideEffectAnalysisPass::analyzeCallInstruction(CallInst* call
std::string funcName = calledFunc->getName(); std::string funcName = calledFunc->getName();
// 检查是否为已知的标准库函数 // 检查是否为已知的标准库函数
const SideEffectInfo* knownInfo = result->getKnownFunctionSideEffect(funcName); const SideEffectInfo *knownInfo = result->getKnownFunctionSideEffect(funcName);
if (knownInfo) { if (knownInfo) {
return *knownInfo; return *knownInfo;
} }
@@ -318,7 +324,7 @@ SideEffectInfo SysYSideEffectAnalysisPass::analyzeCallInstruction(CallInst* call
// 利用调用图分析结果进行精确分析 // 利用调用图分析结果进行精确分析
if (callGraphAnalysis) { if (callGraphAnalysis) {
// 检查被调用函数是否已分析过 // 检查被调用函数是否已分析过
const SideEffectInfo& funcEffect = result->getFunctionSideEffect(calledFunc); const SideEffectInfo &funcEffect = result->getFunctionSideEffect(calledFunc);
if (funcEffect.type != SideEffectType::NO_SIDE_EFFECT || !funcEffect.isPure) { if (funcEffect.type != SideEffectType::NO_SIDE_EFFECT || !funcEffect.isPure) {
return funcEffect; return funcEffect;
} }
@@ -345,16 +351,17 @@ SideEffectInfo SysYSideEffectAnalysisPass::analyzeCallInstruction(CallInst* call
return info; return info;
} }
SideEffectInfo SysYSideEffectAnalysisPass::analyzeStoreInstruction(StoreInst* store, Function* currentFunc, AnalysisManager& AM) { SideEffectInfo SysYSideEffectAnalysisPass::analyzeStoreInstruction(StoreInst *store, Function *currentFunc,
AnalysisManager &AM) {
SideEffectInfo info; SideEffectInfo info;
info.type = SideEffectType::MEMORY_WRITE; info.type = SideEffectType::MEMORY_WRITE;
info.mayModifyMemory = true; info.mayModifyMemory = true;
info.isPure = false; info.isPure = false;
// 获取函数的别名分析结果 // 获取函数的别名分析结果
AliasAnalysisResult* aliasAnalysis = AM.getAnalysisResult<AliasAnalysisResult, SysYAliasAnalysisPass>(currentFunc); AliasAnalysisResult *aliasAnalysis = AM.getAnalysisResult<AliasAnalysisResult, SysYAliasAnalysisPass>(currentFunc);
if (aliasAnalysis) { if (aliasAnalysis) {
Value* storePtr = store->getPointer(); Value *storePtr = store->getPointer();
// 如果存储到全局变量或可能别名的位置,则可能修改全局状态 // 如果存储到全局变量或可能别名的位置,则可能修改全局状态
if (!aliasAnalysis->isLocalArray(storePtr)) { if (!aliasAnalysis->isLocalArray(storePtr)) {
@@ -368,16 +375,17 @@ SideEffectInfo SysYSideEffectAnalysisPass::analyzeStoreInstruction(StoreInst* st
return info; return info;
} }
SideEffectInfo SysYSideEffectAnalysisPass::analyzeMemsetInstruction(MemsetInst* memset, Function* currentFunc, AnalysisManager& AM) { SideEffectInfo SysYSideEffectAnalysisPass::analyzeMemsetInstruction(MemsetInst *memset, Function *currentFunc,
AnalysisManager &AM) {
SideEffectInfo info; SideEffectInfo info;
info.type = SideEffectType::MEMORY_WRITE; info.type = SideEffectType::MEMORY_WRITE;
info.mayModifyMemory = true; info.mayModifyMemory = true;
info.isPure = false; info.isPure = false;
// 获取函数的别名分析结果 // 获取函数的别名分析结果
AliasAnalysisResult* aliasAnalysis = AM.getAnalysisResult<AliasAnalysisResult, SysYAliasAnalysisPass>(currentFunc); AliasAnalysisResult *aliasAnalysis = AM.getAnalysisResult<AliasAnalysisResult, SysYAliasAnalysisPass>(currentFunc);
if (aliasAnalysis) { if (aliasAnalysis) {
Value* memsetPtr = memset->getPointer(); Value *memsetPtr = memset->getPointer();
// 如果memset操作全局变量或可能别名的位置则可能修改全局状态 // 如果memset操作全局变量或可能别名的位置则可能修改全局状态
if (!aliasAnalysis->isLocalArray(memsetPtr)) { if (!aliasAnalysis->isLocalArray(memsetPtr)) {

View File

@@ -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<LoopAnalysisResult, LoopAnalysisPass>(F);
auto *loopCharsResult = AM.getAnalysisResult<LoopCharacteristicsResult, LoopCharacteristicsPass>(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<void *> &analysisDependencies, std::set<void *> &analysisInvalidations) const {
analysisDependencies.insert(&LoopAnalysisPass::ID);
analysisDependencies.insert(&LoopCharacteristicsPass::ID);
analysisInvalidations.insert(&LoopCharacteristicsPass::ID);
analysisInvalidations.insert(&LivenessAnalysisPass::ID);
}
} // namespace sysy

View File

@@ -13,6 +13,8 @@
#include "SCCP.h" #include "SCCP.h"
#include "BuildCFG.h" #include "BuildCFG.h"
#include "LargeArrayToGlobal.h" #include "LargeArrayToGlobal.h"
#include "LoopNormalization.h"
#include "LICM.h"
#include "Pass.h" #include "Pass.h"
#include <iostream> #include <iostream>
#include <queue> #include <queue>
@@ -66,6 +68,8 @@ void PassManager::runOptimizationPipeline(Module* moduleIR, IRBuilder* builderIR
registerOptimizationPass<DCE>(); registerOptimizationPass<DCE>();
registerOptimizationPass<Mem2Reg>(builderIR); registerOptimizationPass<Mem2Reg>(builderIR);
registerOptimizationPass<LoopNormalizationPass>(builderIR);
registerOptimizationPass<LICM>(builderIR);
registerOptimizationPass<Reg2Mem>(builderIR); registerOptimizationPass<Reg2Mem>(builderIR);
registerOptimizationPass<SCCP>(builderIR); registerOptimizationPass<SCCP>(builderIR);
@@ -130,6 +134,16 @@ void PassManager::runOptimizationPipeline(Module* moduleIR, IRBuilder* builderIR
printPasses(); 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->clearPasses();
this->addPass(&Reg2Mem::ID); this->addPass(&Reg2Mem::ID);
this->run(); this->run();