Files
mysysy/src/Pass.cpp

132 lines
4.8 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.
// Pass.cpp
#include "Pass.h"
#include "SysYIRCFGOpt.h"
#include "SysYIRPrinter.h"
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <algorithm>
#include <vector>
#include "Dom.h"
#include "Liveness.h"
namespace sysy {
extern int DEBUG; // 全局调试标志
// ======================================================================
// 封装优化流程的函数包含Pass注册和迭代运行逻辑
// ======================================================================
void PassManager::runOptimizationPipeline(Module* moduleIR, int optLevel) {
if (DEBUG) std::cout << "--- Starting Middle-End Optimizations (Level -O" << optLevel << ") ---\n";
// 1. 注册所有可用的分析遍和优化遍
// 这些注册只需执行一次。
sysy::registerAnalysisPass<sysy::DominatorTreeAnalysisPass>();
sysy::registerAnalysisPass<sysy::LivenessAnalysisPass>();
// 2. 创建遍管理器
sysy::PassManager pm(moduleIR);
// 3. 根据优化级别添加不同的优化遍
if (optLevel >= 1) {
if (DEBUG) std::cout << "Applying -O1 optimizations.\n";
// 4. 循环执行遍,直到 IR 稳定 (不再有任何遍修改 IR)
bool changed_in_iteration = true;
int iteration_count = 0;
while(changed_in_iteration) {
iteration_count++;
if (DEBUG) std::cout << "Optimization iteration: " << iteration_count << std::endl;
changed_in_iteration = pm.run(); // 运行一次所有添加到 PassManager 的遍
if (DEBUG && changed_in_iteration) {
std::cout << "=== IR after iteration " << iteration_count << " ===\n";
SysYPrinter printer_iter(moduleIR);
printer_iter.printIR();
}
}
if (DEBUG) std::cout << "Optimizations stabilized after " << iteration_count << " iterations.\n";
}
if (DEBUG) {
std::cout << "=== Final IR After Middle-End Optimizations (Level -O" << optLevel << ") ===\n";
SysYPrinter printer(moduleIR);
printer.printIR();
}
}
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;
}
} // namespace sysy