Files
mysysy/src/midend/Pass/Pass.cpp
2025-08-04 16:43:43 +08:00

257 lines
8.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "Dom.h"
#include "Liveness.h"
#include "SysYIRCFGOpt.h"
#include "SysYIRPrinter.h"
#include "DCE.h"
#include "Mem2Reg.h"
#include "Reg2Mem.h"
#include "SCCP.h"
#include "BuildCFG.h"
#include "LargeArrayToGlobal.h"
#include "Pass.h"
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <algorithm>
#include <vector>
extern int DEBUG; // 全局调试标志
namespace sysy {
// ======================================================================
// 封装优化流程的函数包含Pass注册和迭代运行逻辑
// ======================================================================
void PassManager::runOptimizationPipeline(Module* moduleIR, IRBuilder* builderIR, int optLevel) {
if (DEBUG) std::cout << "--- Starting Middle-End Optimizations (Level -O" << optLevel << ") ---\n";
/*
中端开发框架基本流程:
1) 分析pass
1. 实现分析pass并引入Pass.cpp
2. 注册分析pass
2) 优化pass
1. 实现优化pass并引入Pass.cpp
2. 注册优化pass
3. 添加优化passid
*/
// 注册分析遍
registerAnalysisPass<DominatorTreeAnalysisPass>();
registerAnalysisPass<LivenessAnalysisPass>();
// 注册优化遍
registerOptimizationPass<BuildCFG>();
registerOptimizationPass<LargeArrayToGlobalPass>();
registerOptimizationPass<SysYDelInstAfterBrPass>();
registerOptimizationPass<SysYDelNoPreBLockPass>();
registerOptimizationPass<SysYBlockMergePass>();
registerOptimizationPass<SysYDelEmptyBlockPass>(builderIR);
registerOptimizationPass<SysYCondBr2BrPass>(builderIR);
registerOptimizationPass<SysYAddReturnPass>(builderIR);
registerOptimizationPass<DCE>();
registerOptimizationPass<Mem2Reg>(builderIR);
registerOptimizationPass<Reg2Mem>(builderIR);
registerOptimizationPass<SCCP>(builderIR);
if (optLevel >= 1) {
//经过设计安排优化遍的执行顺序以及执行逻辑
if (DEBUG) std::cout << "Applying -O1 optimizations.\n";
if (DEBUG) std::cout << "--- Running custom optimization sequence ---\n";
if(DEBUG) {
std::cout << "=== IR Before CFGOpt Optimizations ===\n";
printPasses();
}
this->clearPasses();
this->addPass(&BuildCFG::ID);
this->addPass(&LargeArrayToGlobalPass::ID);
this->run();
this->clearPasses();
this->addPass(&SysYDelInstAfterBrPass::ID);
this->addPass(&SysYDelNoPreBLockPass::ID);
this->addPass(&SysYBlockMergePass::ID);
this->addPass(&SysYDelEmptyBlockPass::ID);
this->addPass(&SysYCondBr2BrPass::ID);
this->addPass(&SysYAddReturnPass::ID);
this->run();
this->clearPasses();
this->addPass(&BuildCFG::ID);
this->run();
if(DEBUG) {
std::cout << "=== IR After CFGOpt Optimizations ===\n";
printPasses();
}
this->clearPasses();
this->addPass(&DCE::ID);
this->run();
if(DEBUG) {
std::cout << "=== IR After DCE Optimizations ===\n";
printPasses();
}
this->clearPasses();
this->addPass(&Mem2Reg::ID);
this->run();
if(DEBUG) {
std::cout << "=== IR After Mem2Reg Optimizations ===\n";
printPasses();
}
this->clearPasses();
this->addPass(&SCCP::ID);
this->run();
if(DEBUG) {
std::cout << "=== IR After SCCP Optimizations ===\n";
printPasses();
}
this->clearPasses();
this->addPass(&Reg2Mem::ID);
this->run();
if(DEBUG) {
std::cout << "=== IR After Reg2Mem Optimizations ===\n";
printPasses();
}
this->clearPasses();
this->addPass(&BuildCFG::ID);
this->run();
if (DEBUG) std::cout << "--- Custom optimization sequence finished ---\n";
}
// 2. 创建遍管理器
// 3. 根据优化级别添加不同的优化遍
// TODO : 根据 optLevel 添加不同的优化遍
// 讨论 是不动点迭代进行优化遍还是手动客制化优化遍的顺序?
if (DEBUG) {
std::cout << "=== Final IR After Middle-End Optimizations (Level -O" << optLevel << ") ===\n";
SysYPrinter printer(moduleIR);
printer.printIR();
}
}
void PassManager::clearPasses() {
passes.clear();
}
void PassManager::addPass(void *passID) {
PassRegistry &registry = PassRegistry::getPassRegistry();
std::unique_ptr<Pass> P = registry.createPass(passID);
if (!P) {
// Error: Pass not found or failed to create
return;
}
passes.push_back(std::move(P));
}
// 运行所有注册的遍
bool PassManager::run() {
bool changed = false;
for (const auto &p : passes) {
bool passChanged = false; // 记录当前遍是否修改了 IR
// 处理优化遍的分析依赖和失效
if (p->getPassKind() == Pass::PassKind::Optimization) {
OptimizationPass *optPass = static_cast<OptimizationPass *>(p.get());
std::set<void *> analysisDependencies;
std::set<void *> analysisInvalidations;
optPass->getAnalysisUsage(analysisDependencies, analysisInvalidations);
// PassManager 不显式运行分析依赖。
// 而是优化遍在 runOnFunction 内部通过 AnalysisManager.getAnalysisResult 按需请求。
}
if (p->getGranularity() == Pass::Granularity::Module) {
passChanged = p->runOnModule(pmodule, analysisManager);
} else if (p->getGranularity() == Pass::Granularity::Function) {
for (auto &funcPair : pmodule->getFunctions()) {
Function *F = funcPair.second.get();
passChanged = p->runOnFunction(F, analysisManager) || passChanged;
if (passChanged && p->getPassKind() == Pass::PassKind::Optimization) {
OptimizationPass *optPass = static_cast<OptimizationPass *>(p.get());
std::set<void *> analysisDependencies;
std::set<void *> analysisInvalidations;
optPass->getAnalysisUsage(analysisDependencies, analysisInvalidations);
for (void *invalidationID : analysisInvalidations) {
analysisManager.invalidateAnalysis(invalidationID, F);
}
}
}
} else if (p->getGranularity() == Pass::Granularity::BasicBlock) {
for (auto &funcPair : pmodule->getFunctions()) {
Function *F = funcPair.second.get();
for (auto &bbPtr : funcPair.second->getBasicBlocks()) {
passChanged = p->runOnBasicBlock(bbPtr.get(), analysisManager) || passChanged;
if (passChanged && p->getPassKind() == Pass::PassKind::Optimization) {
OptimizationPass *optPass = static_cast<OptimizationPass *>(p.get());
std::set<void *> analysisDependencies;
std::set<void *> analysisInvalidations;
optPass->getAnalysisUsage(analysisDependencies, analysisInvalidations);
for (void *invalidationID : analysisInvalidations) {
analysisManager.invalidateAnalysis(invalidationID, F);
}
}
}
}
}
changed = changed || passChanged;
}
return changed;
}
void PassManager::printPasses() const {
std::cout << "Registered Passes:\n";
for (const auto &p : passes) {
std::cout << " - " << p->getName() << " (Granularity: "
<< static_cast<int>(p->getGranularity())
<< ", Kind: " << static_cast<int>(p->getPassKind()) << ")\n";
}
std::cout << "Total Passes: " << passes.size() << "\n";
if (pmodule) {
SysYPrinter printer(pmodule);
std::cout << "Module IR:\n";
printer.printIR();
}
}
template <typename AnalysisPassType> void registerAnalysisPass() {
PassRegistry::getPassRegistry().registerPass(&AnalysisPassType::ID,
[]() { return std::make_unique<AnalysisPassType>(); });
}
template <typename OptimizationPassType, typename std::enable_if<
std::is_constructible<OptimizationPassType, IRBuilder*>::value, int>::type>
void registerOptimizationPass(IRBuilder* builder) {
PassRegistry::getPassRegistry().registerPass(&OptimizationPassType::ID,
[builder]() { return std::make_unique<OptimizationPassType>(builder); });
}
template <typename OptimizationPassType, typename std::enable_if<
!std::is_constructible<OptimizationPassType, IRBuilder*>::value, int>::type>
void registerOptimizationPass() {
PassRegistry::getPassRegistry().registerPass(&OptimizationPassType::ID,
[]() { return std::make_unique<OptimizationPassType>(); });
}
} // namespace sysy