[midend-LICM]优化了特征分析中对循环不变量的识别,实现了LICM遍,格式化副作用分析代码
This commit is contained in:
@@ -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); // 简单的内存模式检查
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
40
src/include/midend/Pass/Optimize/LICM.h
Normal file
40
src/include/midend/Pass/Optimize/LICM.h
Normal 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
|
||||||
@@ -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
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,9 +13,7 @@ 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);
|
||||||
@@ -99,7 +97,6 @@ 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 {
|
||||||
@@ -166,11 +163,21 @@ bool SysYSideEffectAnalysisPass::runOnModule(Module* M, AnalysisManager& AM) {
|
|||||||
|
|
||||||
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,9 +188,7 @@ 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;
|
||||||
@@ -205,7 +210,8 @@ 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;
|
||||||
@@ -238,8 +244,8 @@ 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,11 +263,9 @@ bool SysYSideEffectAnalysisPass::hasConverged(const std::unordered_map<Function*
|
|||||||
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,7 +273,8 @@ 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;
|
||||||
|
|
||||||
// 根据指令类型进行分析
|
// 根据指令类型进行分析
|
||||||
@@ -292,7 +297,8 @@ 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;
|
||||||
|
|
||||||
// 获取被调用的函数
|
// 获取被调用的函数
|
||||||
@@ -345,7 +351,8 @@ 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;
|
||||||
@@ -368,7 +375,8 @@ 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;
|
||||||
|
|||||||
84
src/midend/Pass/Optimize/LICM.cpp
Normal file
84
src/midend/Pass/Optimize/LICM.cpp
Normal 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
|
||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user