[midend]更新遍静态ID定义方法,

注册遍模板函数重构(针对遍的不同构造方法),
修复phi指令更新引起的旧代码错误,
将CFG优化适配到现有终端框架中,
独立CFG优化方法使得其他优化遍能独立调用,
usedelete方法回调取消删除功能。
IRGenerator代码风格修改。
This commit is contained in:
rain2133
2025-07-23 17:19:11 +08:00
parent 3df3d7a097
commit 87d38be255
12 changed files with 509 additions and 298 deletions

5
Pass_ID_List.md Normal file
View File

@ -0,0 +1,5 @@
# 记录中端遍的唯一标识ID
| 名称 | 优化级别 | 开发进度 |
| ------------ | ------------ | ---------- |
| CFG优化 | 函数级 | 已完成 |

View File

@ -5,8 +5,7 @@
namespace sysy {
// 初始化 支配树静态 ID
char DominatorTreeAnalysisPass::ID = 0;
void *DominatorTreeAnalysisPass::ID = (void *)&DominatorTreeAnalysisPass::ID;
// ==============================================================
// DominatorTree 结果类的实现
// ==============================================================

View File

@ -7,8 +7,7 @@
namespace sysy {
// 初始化静态 ID
char LivenessAnalysisPass::ID = 0; // 任何唯一的地址都可以,这里用 0
void *LivenessAnalysisPass::ID = (void *)&LivenessAnalysisPass::ID;
// ==============================================================
// LivenessAnalysisResult 结果类的实现
// ==============================================================

View File

@ -1,15 +1,14 @@
// Pass.cpp
#include "Pass.h"
#include "Dom.h"
#include "Liveness.h"
#include "SysYIRCFGOpt.h"
#include "SysYIRPrinter.h"
#include "Pass.h"
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <algorithm>
#include <vector>
#include "Dom.h"
#include "Liveness.h"
extern int DEBUG; // 全局调试标志
namespace sysy {
@ -18,18 +17,45 @@ namespace sysy {
// 封装优化流程的函数包含Pass注册和迭代运行逻辑
// ======================================================================
void PassManager::runOptimizationPipeline(Module* moduleIR, int optLevel) {
void PassManager::runOptimizationPipeline(Module* moduleIR, IRBuilder* builderIR, int optLevel) {
if (DEBUG) std::cout << "--- Starting Middle-End Optimizations (Level -O" << optLevel << ") ---\n";
// 1. 注册所有可用的分析遍和优化遍
// 这些注册只需执行一次。
sysy::registerAnalysisPass<sysy::DominatorTreeAnalysisPass>();
sysy::registerAnalysisPass<sysy::LivenessAnalysisPass>();
/*
中端开发框架基本流程:
1) 分析pass
1. 实现分析pass并引入Pass.cpp
2. 注册分析pass
2) 优化pass
1. 实现优化pass并引入Pass.cpp
2. 注册优化pass
3. 添加优化passid
*/
// 注册分析遍
registerAnalysisPass<sysy::DominatorTreeAnalysisPass>();
registerAnalysisPass<sysy::LivenessAnalysisPass>();
// 注册优化遍
registerOptimizationPass<SysYDelInstAfterBrPass>();
registerOptimizationPass<SysYDelNoPreBLockPass>();
registerOptimizationPass<SysYBlockMergePass>();
registerOptimizationPass<SysYDelEmptyBlockPass>(builderIR);
registerOptimizationPass<SysYCondBr2BrPass>(builderIR);
registerOptimizationPass<SysYAddReturnPass>(builderIR);
if (optLevel >= 1) {
if (DEBUG) std::cout << "Applying -O1 optimizations.\n";
// 只添加优化遍的 ID
this->addPass(&SysYDelInstAfterBrPass::ID);
this->addPass(&SysYDelNoPreBLockPass::ID);
this->addPass(&SysYBlockMergePass::ID);
this->addPass(&SysYDelEmptyBlockPass::ID);
this->addPass(&SysYCondBr2BrPass::ID);
this->addPass(&SysYAddReturnPass::ID);
}
// 2. 创建遍管理器
sysy::PassManager pm(moduleIR);
// 3. 根据优化级别添加不同的优化遍
// TODO : 根据 optLevel 添加不同的优化遍
// 讨论 是不动点迭代进行优化遍还是手动客制化优化遍的顺序?
@ -42,7 +68,7 @@ void PassManager::runOptimizationPipeline(Module* moduleIR, int optLevel) {
while(changed_in_iteration) {
iteration_count++;
if (DEBUG) std::cout << "Optimization iteration: " << iteration_count << std::endl;
changed_in_iteration = pm.run(); // 运行一次所有添加到 PassManager 的遍
changed_in_iteration = run(); // 运行一次所有添加到 PassManager 的遍
if (DEBUG && changed_in_iteration) {
std::cout << "=== IR after iteration " << iteration_count << " ===\n";
SysYPrinter printer_iter(moduleIR);
@ -130,4 +156,24 @@ bool PassManager::run() {
}
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 = 0>
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 = 0>
void registerOptimizationPass() {
PassRegistry::getPassRegistry().registerPass(&OptimizationPassType::ID,
[]() { return std::make_unique<OptimizationPassType>(); });
}
} // namespace sysy

View File

@ -6,14 +6,25 @@
#include <memory>
#include <string>
#include <iostream>
#include "IR.h"
#include "IRBuilder.h"
#include <queue> // 引入队列SysYDelNoPreBLock需要
namespace sysy {
// 定义静态ID
void *SysYDelInstAfterBrPass::ID = (void *)&SysYDelInstAfterBrPass::ID;
void *SysYDelEmptyBlockPass::ID = (void *)&SysYDelEmptyBlockPass::ID;
void *SysYDelNoPreBLockPass::ID = (void *)&SysYDelNoPreBLockPass::ID;
void *SysYBlockMergePass::ID = (void *)&SysYBlockMergePass::ID;
void *SysYAddReturnPass::ID = (void *)&SysYAddReturnPass::ID;
void *SysYCondBr2BrPass::ID = (void *)&SysYCondBr2BrPass::ID;
// ======================================================================
// SysYCFGOptUtils: 辅助工具类包含实际的CFG优化逻辑
// ======================================================================
// 删除br后的无用指令
bool SysYCFGOpt::SysYDelInstAfterBr(Function *func) {
bool SysYCFGOptUtils::SysYDelInstAfterBr(Function *func) {
bool changed = false;
auto basicBlocks = func->getBasicBlocks();
@ -22,11 +33,10 @@ bool SysYCFGOpt::SysYDelInstAfterBr(Function *func) {
auto &instructions = basicBlock->getInstructions();
auto Branchiter = instructions.end();
for (auto iter = instructions.begin(); iter != instructions.end(); ++iter) {
if (Branch)
SysYIROptUtils::usedelete(iter->get());
else if ((*iter)->isTerminator()){
if ((*iter)->isTerminator()){
Branch = true;
Branchiter = iter;
break;
}
}
if (Branchiter != instructions.end()) ++Branchiter;
@ -61,8 +71,8 @@ bool SysYCFGOpt::SysYDelInstAfterBr(Function *func) {
return changed;
}
// 合并基本块
bool SysYCFGOpt::SysYBlockMerge(Function *func) {
// 合并基本块
bool SysYCFGOptUtils::SysYBlockMerge(Function *func) {
bool changed = false;
for (auto blockiter = func->getBasicBlocks().begin();
@ -82,12 +92,12 @@ bool SysYCFGOpt::SysYBlockMerge(Function *func) {
(--thelastinstinst);
if (thelastinstinst->get()->isUnconditional()) {
SysYIROptUtils::usedelete(thelastinstinst->get());
block->getInstructions().erase(thelastinstinst);
thelastinstinst = block->getInstructions().erase(thelastinstinst);
} else if (thelastinstinst->get()->isConditional()) {
// 如果是条件分支,判断条件是否相同,主要优化相同布尔表达式
if (thelastinstinst->get()->getOperand(1)->getName() == thelastinstinst->get()->getOperand(1)->getName()) {
SysYIROptUtils::usedelete(thelastinstinst->get());
block->getInstructions().erase(thelastinstinst);
thelastinstinst = block->getInstructions().erase(thelastinstinst);
}
}
}
@ -132,7 +142,7 @@ bool SysYCFGOpt::SysYBlockMerge(Function *func) {
}
// 删除无前驱块兼容SSA后的处理
bool SysYCFGOpt::SysYDelNoPreBLock(Function *func) {
bool SysYCFGOptUtils::SysYDelNoPreBLock(Function *func) {
bool changed = false;
@ -156,29 +166,26 @@ bool SysYCFGOpt::SysYDelNoPreBLock(Function *func) {
}
// 删除不可达基本块指令
for (auto blockIter = func->getBasicBlocks().begin(); blockIter != func->getBasicBlocks().end();blockIter++) {
if (!blockIter->get()->getreachable())
for (auto &iterInst : blockIter->get()->getInstructions())
SysYIROptUtils::usedelete(iterInst.get());
for (auto blockIter = func->getBasicBlocks().begin(); blockIter != func->getBasicBlocks().end(); blockIter++) {
if (!blockIter->get()->getreachable()) {
for (auto instIter = blockIter->get()->getInstructions().begin();
instIter != blockIter->get()->getInstructions().end();) {
SysYIROptUtils::usedelete(instIter->get());
instIter = blockIter->get()->getInstructions().erase(instIter);
}
}
}
for (auto blockIter = func->getBasicBlocks().begin(); blockIter != func->getBasicBlocks().end();) {
if (!blockIter->get()->getreachable()) {
for (auto succblock : blockIter->get()->getSuccessors()) {
int indexphi = 1;
for (auto pred : succblock->getPredecessors()) {
if (pred == blockIter->get()) {
break;
}
indexphi++;
}
for (auto &phiinst : succblock->getInstructions()) {
if (phiinst->getKind() != Instruction::kPhi) {
break;
}
phiinst->removeOperand(indexphi);
if (phiinst->getKind() != Instruction::kPhi) {
break;
}
// 使用 delBlk 方法正确地删除对应于被删除基本块的传入值
dynamic_cast<PhiInst *>(phiinst.get())->delBlk(blockIter->get());
}
}
// 删除不可达基本块,注意迭代器不可达问题
@ -193,7 +200,7 @@ bool SysYCFGOpt::SysYDelNoPreBLock(Function *func) {
}
// 删除空块
bool SysYCFGOpt::SysYDelEmptyBlock(Function *func, IRBuilder* pBuilder) {
bool SysYCFGOptUtils::SysYDelEmptyBlock(Function *func, IRBuilder* pBuilder) {
bool changed = false;
// 收集不可达基本块
@ -218,24 +225,29 @@ bool SysYCFGOpt::SysYDelEmptyBlock(Function *func, IRBuilder* pBuilder) {
break;
}
}
if(onlyPhi)
if(onlyPhi && basicBlock->getNumSuccessors() == 1) // 确保有后继且只有一个
EmptyBlocks[basicBlock.get()] = basicBlock->getSuccessors().front();
}
}
// 更新基本块信息,增加必要指令
for (auto &basicBlock : basicBlocks) {
// 把空块转换成只有跳转指令的不可达块
// 把空块转换成只有跳转指令的不可达块 (这段逻辑在优化遍中可能需要调整,这里是原样保留)
// 通常DelEmptyBlock 应该在BlockMerge之后运行如果存在完全空块它会尝试填充一个Br指令。
// 但是,它主要目的是重定向跳转。
if (distance(basicBlock->begin(), basicBlock->end()) == 0) {
if (basicBlock->getNumSuccessors() == 0) {
continue;
}
if (basicBlock->getNumSuccessors() > 1) {
assert("");
// 如果一个空块有多个后继说明CFG结构有问题或者需要特殊处理这里简单assert
assert(false && "Empty block with multiple successors found during SysYDelEmptyBlock");
}
pBuilder->setPosition(basicBlock.get(), basicBlock->end());
pBuilder->createUncondBrInst(basicBlock->getSuccessors()[0], {});
// 这里的逻辑有点问题,如果一个块是空的,且只有一个后继,应该直接跳转到后继。
// 如果这个块最终被删除了,那么其前驱也需要重定向。
// 这个循环的目的是重定向现有的跳转指令,而不是创建新的。
// 所以下面的逻辑才是核心。
// pBuilder->setPosition(basicBlock.get(), basicBlock->end());
// pBuilder->createUncondBrInst(basicBlock->getSuccessors()[0], {});
continue;
}
@ -247,50 +259,55 @@ bool SysYCFGOpt::SysYDelEmptyBlock(Function *func, IRBuilder* pBuilder) {
BasicBlock* OldBrBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0));
BasicBlock *thelastBlockOld = nullptr;
// 如果空块链表为多个块
while (EmptyBlocks.find(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))) !=
EmptyBlocks.end()) {
while (EmptyBlocks.count(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0)))) {
thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0));
thelastinst->get()->replaceOperand(0, EmptyBlocks[thelastBlockOld]);
}
basicBlock->removeSuccessor(OldBrBlock);
OldBrBlock->removePredecessor(basicBlock.get());
basicBlock->addSuccessor(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0)));
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->addPredecessor(basicBlock.get());
// 如果有重定向发生
if (thelastBlockOld != nullptr) {
basicBlock->removeSuccessor(OldBrBlock);
OldBrBlock->removePredecessor(basicBlock.get());
basicBlock->addSuccessor(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0)));
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->addPredecessor(basicBlock.get());
changed = true; // 标记IR被修改
}
if (thelastBlockOld != nullptr) {
int indexphi = 0;
for (auto &pred : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->getPredecessors()) {
if (pred == thelastBlockOld) {
break;
}
indexphi++;
}
// 更新phi指令的操作数
// 移除thelastBlockOld对应的phi操作数
for (auto &InstInNew : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->getInstructions()) {
if (InstInNew->isPhi()) {
dynamic_cast<PhiInst *>(InstInNew.get())->removeOperand(indexphi + 1);
} else {
break;
}
if (InstInNew->isPhi()) {
// 使用 delBlk 方法删除 oldBlock 对应的传入值
dynamic_cast<PhiInst *>(InstInNew.get())->delBlk(thelastBlockOld);
} else {
break;
}
}
}
} else if (thelastinst->get()->getKind() == Instruction::kCondBr) {
auto OldThenBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1));
auto OldElseBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2));
bool thenChanged = false;
bool elseChanged = false;
BasicBlock *thelastBlockOld = nullptr;
while (EmptyBlocks.find(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1))) !=
EmptyBlocks.end()) {
while (EmptyBlocks.count(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)))) {
thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1));
thelastinst->get()->replaceOperand(
1, EmptyBlocks[dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1))]);
thenChanged = true;
}
basicBlock->removeSuccessor(OldThenBlock);
OldThenBlock->removePredecessor(basicBlock.get());
if (thenChanged) {
basicBlock->removeSuccessor(OldThenBlock);
OldThenBlock->removePredecessor(basicBlock.get());
basicBlock->addSuccessor(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)));
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1))->addPredecessor(basicBlock.get());
changed = true; // 标记IR被修改
}
// 处理 then 和 else 分支合并的情况
if (dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)) ==
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))) {
@ -299,39 +316,37 @@ bool SysYCFGOpt::SysYDelEmptyBlock(Function *func, IRBuilder* pBuilder) {
thelastinst = basicBlock->getInstructions().erase(thelastinst);
pBuilder->setPosition(basicBlock.get(), basicBlock->end());
pBuilder->createUncondBrInst(thebrBlock, {});
changed = true; // 标记IR被修改
continue;
}
basicBlock->addSuccessor(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)));
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1))->addPredecessor(basicBlock.get());
// auto indexInNew = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->getPredecessors().
if (thelastBlockOld != nullptr) {
int indexphi = 0;
for (auto &pred : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1))->getPredecessors()) {
if (pred == thelastBlockOld) {
break;
}
indexphi++;
}
for (auto &InstInNew : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1))->getInstructions()) {
if (InstInNew->isPhi()) {
dynamic_cast<PhiInst *>(InstInNew.get())->removeOperand(indexphi + 1);
// 使用 delBlk 方法删除 oldBlock 对应的传入值
dynamic_cast<PhiInst *>(InstInNew.get())->delBlk(thelastBlockOld);
} else {
break;
}
}
}
}
thelastBlockOld = nullptr;
while (EmptyBlocks.find(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))) !=
EmptyBlocks.end()) {
while (EmptyBlocks.count(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2)))) {
thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2));
thelastinst->get()->replaceOperand(
2, EmptyBlocks[dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))]);
elseChanged = true;
}
basicBlock->removeSuccessor(OldElseBlock);
OldElseBlock->removePredecessor(basicBlock.get());
if (elseChanged) {
basicBlock->removeSuccessor(OldElseBlock);
OldElseBlock->removePredecessor(basicBlock.get());
basicBlock->addSuccessor(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2)));
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))->addPredecessor(basicBlock.get());
changed = true; // 标记IR被修改
}
// 处理 then 和 else 分支合并的情况
if (dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)) ==
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))) {
@ -340,93 +355,94 @@ bool SysYCFGOpt::SysYDelEmptyBlock(Function *func, IRBuilder* pBuilder) {
thelastinst = basicBlock->getInstructions().erase(thelastinst);
pBuilder->setPosition(basicBlock.get(), basicBlock->end());
pBuilder->createUncondBrInst(thebrBlock, {});
changed = true; // 标记IR被修改
continue;
}
basicBlock->addSuccessor(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2)));
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))->addPredecessor(basicBlock.get());
// 如果有重定向发生
// 需要更新后继块的前驱关系
if (thelastBlockOld != nullptr) {
int indexphi = 0;
for (auto &pred : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))->getPredecessors()) {
if (pred == thelastBlockOld) {
break;
}
indexphi++;
}
for (auto &InstInNew : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))->getInstructions()) {
if (InstInNew->isPhi()) {
dynamic_cast<PhiInst *>(InstInNew.get())->removeOperand(indexphi + 1);
// 使用 delBlk 方法删除 oldBlock 对应的传入值
dynamic_cast<PhiInst *>(InstInNew.get())->delBlk(thelastBlockOld);
} else {
break;
}
}
}
}
} else {
// 如果不是终止指令,但有后继 (例如,末尾没有显式终止指令的块)
// 这段逻辑可能需要更严谨的CFG检查来确保正确性
if (basicBlock->getNumSuccessors() == 1) {
pBuilder->setPosition(basicBlock.get(), basicBlock->end());
pBuilder->createUncondBrInst(basicBlock->getSuccessors()[0], {});
auto thelastinst = basicBlock->getInstructions().end();
(--thelastinst);
auto OldBrBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0));
sysy::BasicBlock *thelastBlockOld = nullptr;
while (EmptyBlocks.find(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))) !=
EmptyBlocks.end()) {
thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0));
// 这里的逻辑似乎是想为没有terminator的块添加一个但通常这应该在CFG构建阶段完成。
// 如果这里仍然执行,确保它符合预期。
// pBuilder->setPosition(basicBlock.get(), basicBlock->end());
// pBuilder->createUncondBrInst(basicBlock->getSuccessors()[0], {});
// auto thelastinst = basicBlock->getInstructions().end();
// (--thelastinst);
// auto OldBrBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0));
// sysy::BasicBlock *thelastBlockOld = nullptr;
// while (EmptyBlocks.find(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))) !=
// EmptyBlocks.end()) {
// thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0));
thelastinst->get()->replaceOperand(
0, EmptyBlocks[dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))]);
}
// thelastinst->get()->replaceOperand(
// 0, EmptyBlocks[dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))]);
// }
basicBlock->removeSuccessor(OldBrBlock);
OldBrBlock->removePredecessor(basicBlock.get());
basicBlock->addSuccessor(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0)));
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->addPredecessor(basicBlock.get());
if (thelastBlockOld != nullptr) {
int indexphi = 0;
for (auto &pred : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->getPredecessors()) {
if (pred == thelastBlockOld) {
break;
}
indexphi++;
}
// basicBlock->removeSuccessor(OldBrBlock);
// OldBrBlock->removePredecessor(basicBlock.get());
// basicBlock->addSuccessor(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0)));
// dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->addPredecessor(basicBlock.get());
// changed = true; // 标记IR被修改
// if (thelastBlockOld != nullptr) {
// int indexphi = 0;
// for (auto &pred : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->getPredecessors()) {
// if (pred == thelastBlockOld) {
// break;
// }
// indexphi++;
// }
for (auto &InstInNew : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->getInstructions()) {
if (InstInNew->isPhi()) {
dynamic_cast<PhiInst *>(InstInNew.get())->removeOperand(indexphi + 1);
} else {
break;
}
}
}
// for (auto &InstInNew : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->getInstructions()) {
// if (InstInNew->isPhi()) {
// dynamic_cast<PhiInst *>(InstInNew.get())->removeOperand(indexphi + 1);
// } else {
// break;
// }
// }
// }
}
}
}
// 真正的删除空块
for (auto iter = func->getBasicBlocks().begin(); iter != func->getBasicBlocks().end();) {
if (EmptyBlocks.find(iter->get()) != EmptyBlocks.end()) {
if (EmptyBlocks.count(iter->get())) {
// EntryBlock跳过
if (iter->get() == func->getEntryBlock()) {
++iter;
continue;
}
for (auto &iterInst : iter->get()->getInstructions())
SysYIROptUtils::usedelete(iterInst.get());
for (auto instIter = iter->get()->getInstructions().begin();
instIter != iter->get()->getInstructions().end();) {
SysYIROptUtils::usedelete(instIter->get()); // 仅删除 use 关系
// 显式地从基本块中删除指令并更新迭代器
instIter = iter->get()->getInstructions().erase(instIter);
}
// 删除不可达基本块的phi指令的操作数
for (auto &succ : iter->get()->getSuccessors()) {
int index = 0;
for (auto &pred : succ->getPredecessors()) {
if (pred == iter->get()) {
break;
}
index++;
}
for (auto &instinsucc : succ->getInstructions()) {
if (instinsucc->isPhi()) {
dynamic_cast<PhiInst *>(instinsucc.get())->removeOperand(index);
// iter->get() 就是当前被删除的空基本块它作为前驱连接到这里的Phi指令
dynamic_cast<PhiInst *>(instinsucc.get())->delBlk(iter->get());
} else {
// Phi 指令通常在基本块的开头,如果不是 Phi 指令就停止检查
break;
}
}
@ -440,34 +456,35 @@ bool SysYCFGOpt::SysYDelEmptyBlock(Function *func, IRBuilder* pBuilder) {
}
return changed;
}
// 如果函数没有返回指令,则添加一个默认返回指令(主要解决void函数没有返回指令的问题)
bool SysYCFGOpt::SysYAddReturn(Function *func, IRBuilder* pBuilder) {
bool SysYCFGOptUtils::SysYAddReturn(Function *func, IRBuilder* pBuilder) {
bool changed = false;
auto basicBlocks = func->getBasicBlocks();
for (auto &block : basicBlocks) {
if (block->getNumSuccessors() == 0) {
changed = true;
// 如果基本块没有后继块,则添加一个返回指令
if (block->getNumInstructions() == 0) {
pBuilder->setPosition(block.get(), block->end());
pBuilder->createReturnInst();
}
auto thelastinst = block->getInstructions().end();
--thelastinst;
if (thelastinst->get()->getKind() != Instruction::kReturn) {
// std::cout << "Warning: Function " << func->getName() << " has no return instruction, adding default return." << std::endl;
changed = true; // 标记IR被修改
} else {
auto thelastinst = block->getInstructions().end();
--thelastinst;
if (thelastinst->get()->getKind() != Instruction::kReturn) {
// std::cout << "Warning: Function " << func->getName() << " has no return instruction, adding default return." << std::endl;
pBuilder->setPosition(block.get(), block->end());
// TODO: 如果int float函数缺少返回值是否需要报错
if (func->getReturnType()->isInt()) {
pBuilder->createReturnInst(ConstantInteger::get(0));
} else if (func->getReturnType()->isFloat()) {
pBuilder->createReturnInst(ConstantFloating::get(0.0F));
} else {
pBuilder->createReturnInst();
pBuilder->setPosition(block.get(), block->end());
// TODO: 如果int float函数缺少返回值是否需要报错
if (func->getReturnType()->isInt()) {
pBuilder->createReturnInst(ConstantInteger::get(0));
} else if (func->getReturnType()->isFloat()) {
pBuilder->createReturnInst(ConstantFloating::get(0.0F));
} else {
pBuilder->createReturnInst();
}
changed = true; // 标记IR被修改
}
}
}
@ -480,7 +497,7 @@ bool SysYCFGOpt::SysYAddReturn(Function *func, IRBuilder* pBuilder) {
// 主要针对已知条件值的分支转换为无条件分支
// 例如 if (cond) { ... } else { ... } 中的 cond 已经
// 确定为 true 或 false 的情况
bool SysYCFGOpt::SysYCondBr2Br(Function *func, IRBuilder* pBuilder) {
bool SysYCFGOptUtils::SysYCondBr2Br(Function *func, IRBuilder* pBuilder) {
bool changed = false;
for (auto &basicblock : func->getBasicBlocks()) {
@ -515,45 +532,41 @@ bool SysYCFGOpt::SysYCondBr2Br(Function *func, IRBuilder* pBuilder) {
SysYIROptUtils::usedelete(thelast->get());
thelast = basicblock->getInstructions().erase(thelast);
if ((constfloat_Use && constfloat == 1.0F) || (constint_Use && constint == 1)) {
// cond为true或非0
pBuilder->setPosition(basicblock.get(), basicblock->end());
pBuilder->createUncondBrInst(thenBlock, {});
int phiindex = 0;
for (auto pred : elseBlock->getPredecessors()) {
phiindex++;
if (pred == basicblock.get()) {
break;
}
}
// 更新CFG关系
basicblock->removeSuccessor(elseBlock);
elseBlock->removePredecessor(basicblock.get());
// 删除elseBlock的phi指令中对应的basicblock.get()的传入值
for (auto &phiinst : elseBlock->getInstructions()) {
if (phiinst->getKind() != Instruction::kPhi) {
break;
}
phiinst->removeOperand(phiindex);
// 使用 delBlk 方法删除 basicblock.get() 对应的传入值
dynamic_cast<PhiInst *>(phiinst.get())->delBlk(basicblock.get());
}
basicblock->removeSuccessor(elseBlock);
elseBlock->removePredecessor(basicblock.get());
} else {
} else { // cond为false或0
pBuilder->setPosition(basicblock.get(), basicblock->end());
pBuilder->createUncondBrInst(elseBlock, {});
int phiindex = 0;
for (auto pred : thenBlock->getPredecessors()) {
phiindex++;
if (pred == basicblock.get()) {
break;
}
}
// 更新CFG关系
basicblock->removeSuccessor(thenBlock);
thenBlock->removePredecessor(basicblock.get());
// 删除thenBlock的phi指令中对应的basicblock.get()的传入值
for (auto &phiinst : thenBlock->getInstructions()) {
if (phiinst->getKind() != Instruction::kPhi) {
break;
}
phiinst->removeOperand(phiindex);
// 使用 delBlk 方法删除 basicblock.get() 对应的传入值
dynamic_cast<PhiInst *>(phiinst.get())->delBlk(basicblock.get());
}
basicblock->removeSuccessor(thenBlock);
thenBlock->removePredecessor(basicblock.get());
}
}
}
@ -562,4 +575,32 @@ bool SysYCFGOpt::SysYCondBr2Br(Function *func, IRBuilder* pBuilder) {
return changed;
}
} // namespace sysy
// ======================================================================
// 独立的CFG优化遍的实现
// ======================================================================
bool SysYDelInstAfterBrPass::runOnFunction(Function *F, AnalysisManager& AM) {
return SysYCFGOptUtils::SysYDelInstAfterBr(F);
}
bool SysYDelEmptyBlockPass::runOnFunction(Function *F, AnalysisManager& AM) {
return SysYCFGOptUtils::SysYDelEmptyBlock(F, pBuilder);
}
bool SysYDelNoPreBLockPass::runOnFunction(Function *F, AnalysisManager& AM) {
return SysYCFGOptUtils::SysYDelNoPreBLock(F);
}
bool SysYBlockMergePass::runOnFunction(Function *F, AnalysisManager& AM) {
return SysYCFGOptUtils::SysYBlockMerge(F);
}
bool SysYAddReturnPass::runOnFunction(Function *F, AnalysisManager& AM) {
return SysYCFGOptUtils::SysYAddReturn(F, pBuilder);
}
bool SysYCondBr2BrPass::runOnFunction(Function *F, AnalysisManager& AM) {
return SysYCFGOptUtils::SysYCondBr2Br(F, pBuilder);
}
} // namespace sysy

View File

@ -64,7 +64,7 @@ Value* SysYIRGenerator::getGEPAddressInst(Value* basePointer, const std::vector<
// 遍历用户提供的索引不包括我们添加的第一个0逐步确定 GEP 的最终结果类型
// 每个索引都“深入”一个维度
for (size_t i = 0; i < indices.size(); ++i) { // 这里遍历的是用户提供的索引
for (int i = 0; i < indices.size(); ++i) { // 这里遍历的是用户提供的索引
if (finalTargetType && finalTargetType->isArray()) {
finalTargetType = finalTargetType->as<ArrayType>()->getElementType();
} else {
@ -247,7 +247,7 @@ std::any SysYIRGenerator::visitVarDecl(SysYParser::VarDeclContext *ctx) {
ConstantInteger::get(0));
}
else {
for (size_t k = 0; k < counterValues.size(); ++k) {
for (int k = 0; k < counterValues.size(); ++k) {
std::vector<Value *> currentIndices;
int tempLinearIndex = k;
@ -368,7 +368,7 @@ std::any SysYIRGenerator::visitFuncDef(SysYParser::FuncDefContext *ctx){
BasicBlock* entry = function->getEntryBlock();
builder.setPosition(entry, entry->end());
for (size_t i = 0; i < paramTypes.size(); ++i) {
for (int i = 0; i < paramTypes.size(); ++i) {
AllocaInst* alloca = builder.createAllocaInst(Type::getPointerType(paramTypes[i]),
paramDims[i], paramNames[i]);
entry->insertArgument(alloca);
@ -440,7 +440,7 @@ std::any SysYIRGenerator::visitAssignStmt(SysYParser::AssignStmtContext *ctx) {
Type* targetElementType = variable->getType()->as<PointerType>()->getBaseType(); // 从基指针指向的类型开始
// 模拟 GEP 路径,根据 dims 确定最终元素的类型
for (size_t i = 0; i < dims.size(); ++i) {
for (int i = 0; i < dims.size(); ++i) {
if (targetElementType && targetElementType->isArray()) {
targetElementType = targetElementType->as<ArrayType>()->getElementType();
} else {
@ -805,7 +805,7 @@ std::any SysYIRGenerator::visitCall(SysYParser::CallContext *ctx) {
}
auto params = function->getEntryBlock()->getArguments();
for (size_t i = 0; i < args.size(); i++) {
for (int i = 0; i < args.size(); i++) {
// 参数类型转换
if (params[i]->getType() != args[i]->getType() &&
(params[i]->getNumDims() != 0 ||
@ -891,7 +891,7 @@ std::any SysYIRGenerator::visitFuncRParams(SysYParser::FuncRParamsContext *ctx)
std::any SysYIRGenerator::visitMulExp(SysYParser::MulExpContext *ctx) {
Value * result = std::any_cast<Value *>(visitUnaryExp(ctx->unaryExp(0)));
for (size_t i = 1; i < ctx->unaryExp().size(); i++) {
for (int i = 1; i < ctx->unaryExp().size(); i++) {
auto opNode = dynamic_cast<antlr4::tree::TerminalNode*>(ctx->children[2*i-1]);
int opType = opNode->getSymbol()->getType();
@ -967,7 +967,7 @@ std::any SysYIRGenerator::visitMulExp(SysYParser::MulExpContext *ctx) {
std::any SysYIRGenerator::visitAddExp(SysYParser::AddExpContext *ctx) {
Value* result = std::any_cast<Value *>(visitMulExp(ctx->mulExp(0)));
for (size_t i = 1; i < ctx->mulExp().size(); i++) {
for (int i = 1; i < ctx->mulExp().size(); i++) {
auto opNode = dynamic_cast<antlr4::tree::TerminalNode*>(ctx->children[2*i-1]);
int opType = opNode->getSymbol()->getType();
@ -1028,7 +1028,7 @@ std::any SysYIRGenerator::visitAddExp(SysYParser::AddExpContext *ctx) {
std::any SysYIRGenerator::visitRelExp(SysYParser::RelExpContext *ctx) {
Value* result = std::any_cast<Value *>(visitAddExp(ctx->addExp(0)));
for (size_t i = 1; i < ctx->addExp().size(); i++) {
for (int i = 1; i < ctx->addExp().size(); i++) {
auto opNode = dynamic_cast<antlr4::tree::TerminalNode*>(ctx->children[2*i-1]);
int opType = opNode->getSymbol()->getType();
@ -1100,7 +1100,7 @@ std::any SysYIRGenerator::visitRelExp(SysYParser::RelExpContext *ctx) {
std::any SysYIRGenerator::visitEqExp(SysYParser::EqExpContext *ctx) {
Value * result = std::any_cast<Value *>(visitRelExp(ctx->relExp(0)));
for (size_t i = 1; i < ctx->relExp().size(); i++) {
for (int i = 1; i < ctx->relExp().size(); i++) {
auto opNode = dynamic_cast<antlr4::tree::TerminalNode*>(ctx->children[2*i-1]);
int opType = opNode->getSymbol()->getType();
@ -1174,7 +1174,7 @@ std::any SysYIRGenerator::visitLAndExp(SysYParser::LAndExpContext *ctx){
BasicBlock *falseBlock = builder.getFalseBlock();
auto conds = ctx->eqExp();
for (size_t i = 0; i < conds.size() - 1; i++) {
for (int i = 0; i < conds.size() - 1; i++) {
labelstring << "AND.L" << builder.getLabelIndex();
BasicBlock *newtrueBlock = function->addBasicBlock(labelstring.str());
@ -1205,7 +1205,7 @@ auto SysYIRGenerator::visitLOrExp(SysYParser::LOrExpContext *ctx) -> std::any {
Function *function = curBlock->getParent();
auto conds = ctx->lAndExp();
for (size_t i = 0; i < conds.size() - 1; i++) {
for (int i = 0; i < conds.size() - 1; i++) {
labelstring << "OR.L" << builder.getLabelIndex();
BasicBlock *newFalseBlock = function->addBasicBlock(labelstring.str());
labelstring.str("");
@ -1292,7 +1292,7 @@ void Utils::createExternalFunction(
auto entry = function->getEntryBlock();
pBuilder->setPosition(entry, entry->end());
for (size_t i = 0; i < paramTypes.size(); ++i) {
for (int i = 0; i < paramTypes.size(); ++i) {
auto alloca = pBuilder->createAllocaInst(
Type::getPointerType(paramTypes[i]), paramDims[i], paramNames[i]);
entry->insertArgument(alloca);

View File

@ -34,7 +34,7 @@ private:
class DominatorTreeAnalysisPass : public AnalysisPass {
public:
// 唯一的 Pass ID
static char ID; // LLVM 风格的唯一 ID
static void *ID;
DominatorTreeAnalysisPass() : AnalysisPass("DominatorTreeAnalysis", Pass::Granularity::Function) {}

View File

@ -49,7 +49,7 @@ private:
class LivenessAnalysisPass : public AnalysisPass {
public:
// 唯一的 Pass ID
static char ID; // LLVM 风格的唯一 ID
static void *ID; // LLVM 风格的唯一 ID
LivenessAnalysisPass() : AnalysisPass("LivenessAnalysis", Pass::Granularity::Function) {}

View File

@ -7,7 +7,9 @@
#include <string>
#include <typeindex> // For std::type_index (although void* ID is more common in LLVM)
#include <vector>
#include <type_traits>
#include "IR.h"
#include "IRBuilder.h"
namespace sysy {
@ -117,64 +119,142 @@ private:
// ======================================================================
class AnalysisManager {
private:
std::map<std::pair<Function *, void *>, std::unique_ptr<AnalysisResultBase>> cachedResults;
// cachedResults 存储分析结果,键是 (Function*, AnalysisPass ID)
Module *pModuleRef; // 指向被分析的Module
// 缓存不同粒度的分析结果
std::map<void *, std::unique_ptr<AnalysisResultBase>> moduleCachedResults;
std::map<std::pair<Function *, void *>, std::unique_ptr<AnalysisResultBase>> functionCachedResults;
std::map<std::pair<BasicBlock *, void *>, std::unique_ptr<AnalysisResultBase>> basicBlockCachedResults;
public:
AnalysisManager() = default;
// 构造函数接收 Module 指针
AnalysisManager(Module *M) : pModuleRef(M) {}
AnalysisManager() = delete; // 禁止无参构造
~AnalysisManager() = default;
// 获取分析结果
// 获取分析结果的通用模板函数
// T 是 AnalysisResult 的具体类型E 是 AnalysisPass 的具体类型
// PassManager 应该在运行 Pass 之前调用 registerAnalysisPass
template <typename T, typename E> T *getAnalysisResult(Function *F) { // 针对函数级别的分析,需要传入 Function*
void *analysisID = E::ID; // 获取分析遍的唯一 ID
// F 和 BB 参数用于提供上下文,根据分析遍的粒度来使用
template <typename T, typename E> T *getAnalysisResult(Function *F = nullptr, BasicBlock *BB = nullptr) {
void *analysisID = E::ID; // 获取分析遍的唯一 ID
// 检查是否已存在有效结果
auto it = cachedResults.find({F, analysisID});
if (it != cachedResults.end()) {
return static_cast<T *>(it->second.get()); // 返回缓存结果
}
// 如果没有缓存结果,通过 PassRegistry 创建分析遍并运行它
// 注意:这里需要 PassRegistry 实例。如果 AnalysisManager 独立于 PassManager
// 则需要传入 PassRegistry 引用或指针。
// 为了简化,假设 AnalysisManager 能够访问到 PassRegistry
// 尝试从注册表创建分析遍实例
std::unique_ptr<Pass> basePass = PassRegistry::getPassRegistry().createPass(analysisID);
if (!basePass) {
// Error: Analysis pass not registered
std::cerr << "Error: Analysis pass with ID " << analysisID << " not registered.\n";
return nullptr;
}
AnalysisPass *analysisPass = static_cast<AnalysisPass *>(basePass.get());
// 确保分析遍的粒度与请求的上下文匹配
if (analysisPass->getGranularity() == Pass::Granularity::Function) {
analysisPass->runOnFunction(F, *this); // 运行分析遍
// 获取结果并缓存
std::unique_ptr<AnalysisResultBase> result = analysisPass->getResult();
T *specificResult = static_cast<T *>(result.get());
cachedResults[{F, analysisID}] = std::move(result); // 缓存结果
return specificResult;
// 根据分析遍的粒度处理
switch (analysisPass->getGranularity()) {
case Pass::Granularity::Module: {
// 检查是否已存在有效结果
auto it = moduleCachedResults.find(analysisID);
if (it != moduleCachedResults.end()) {
return static_cast<T *>(it->second.get()); // 返回缓存结果
}
// 运行模块级分析遍
if (!pModuleRef) {
std::cerr << "Error: Module reference not set for AnalysisManager to run Module Pass.\n";
return nullptr;
}
analysisPass->runOnModule(pModuleRef, *this);
// 获取结果并缓存
std::unique_ptr<AnalysisResultBase> result = analysisPass->getResult();
T *specificResult = static_cast<T *>(result.get());
moduleCachedResults[analysisID] = std::move(result); // 缓存结果
return specificResult;
}
case Pass::Granularity::Function: {
// 检查请求的上下文是否正确
if (!F) {
std::cerr << "Error: Function context required for Function-level Analysis Pass.\n";
return nullptr;
}
// 检查是否已存在有效结果
auto it = functionCachedResults.find({F, analysisID});
if (it != functionCachedResults.end()) {
return static_cast<T *>(it->second.get()); // 返回缓存结果
}
// 运行函数级分析遍
analysisPass->runOnFunction(F, *this);
// 获取结果并缓存
std::unique_ptr<AnalysisResultBase> result = analysisPass->getResult();
T *specificResult = static_cast<T *>(result.get());
functionCachedResults[{F, analysisID}] = std::move(result); // 缓存结果
return specificResult;
}
case Pass::Granularity::BasicBlock: {
// 检查请求的上下文是否正确
if (!BB) {
std::cerr << "Error: BasicBlock context required for BasicBlock-level Analysis Pass.\n";
return nullptr;
}
// 检查是否已存在有效结果
auto it = basicBlockCachedResults.find({BB, analysisID});
if (it != basicBlockCachedResults.end()) {
return static_cast<T *>(it->second.get()); // 返回缓存结果
}
// 运行基本块级分析遍
analysisPass->runOnBasicBlock(BB, *this);
// 获取结果并缓存
std::unique_ptr<AnalysisResultBase> result = analysisPass->getResult();
T *specificResult = static_cast<T *>(result.get());
basicBlockCachedResults[{BB, analysisID}] = std::move(result); // 缓存结果
return specificResult;
}
}
// TODO: 处理 Module 或 BasicBlock 粒度的分析
return nullptr;
return nullptr; // 不会到达这里
}
// 使所有或特定分析结果失效 (当 IR 被修改时调用)
void invalidateAllAnalyses() { cachedResults.clear(); }
// 使所有分析结果失效 (当 IR 被修改时调用)
void invalidateAllAnalyses() {
moduleCachedResults.clear();
functionCachedResults.clear();
basicBlockCachedResults.clear();
}
// 使特定分析结果失效
void invalidateAnalysis(void *analysisID, Function *F = nullptr) {
if (F) {
// 使特定函数的特定分析结果失效
cachedResults.erase({F, analysisID});
// void *analysisID: 要失效的分析的ID
// Function *F: 如果是函数级分析指定函数如果是模块级或基本块级则为nullptr (取决于调用方式)
// BasicBlock *BB: 如果是基本块级分析指定基本块否则为nullptr
void invalidateAnalysis(void *analysisID, Function *F = nullptr, BasicBlock *BB = nullptr) {
if (BB) {
// 使特定基本块的特定分析结果失效
basicBlockCachedResults.erase({BB, analysisID});
} else if (F) {
// 使特定函数的特定分析结果失效 (也可能包含聚合的BasicBlock结果)
functionCachedResults.erase({F, analysisID});
// 遍历所有属于F的基本块使其BasicBlockCache失效 (如果该分析是BasicBlock粒度的)
// 这需要遍历F的所有基本块效率较低更推荐在BasicBlockPass的invalidateAnalysisUsage中精确指定
// 或者在Function级别的invalidate时清空该Function的所有BasicBlock分析
// 这里的实现简单地清空该Function下所有该ID的BasicBlock缓存
for (auto it = basicBlockCachedResults.begin(); it != basicBlockCachedResults.end(); ) {
// 假设BasicBlock::getParent()方法存在可以获取所属Function
if (it->first.second == analysisID /* && it->first.first->getParent() == F */) { // 需要BasicBlock能获取其父函数
it = basicBlockCachedResults.erase(it);
} else {
++it;
}
}
} else {
// 使所有函数的特定分析结果失效
// 遍历并删除匹配的元素,避免拷贝 unique_ptr
for (auto it = cachedResults.begin(); it != cachedResults.end(); ) {
// 使所有函数的特定分析结果失效 (Module级和所有Function/BasicBlock级)
moduleCachedResults.erase(analysisID);
for (auto it = functionCachedResults.begin(); it != functionCachedResults.end(); ) {
if (it->first.second == analysisID) {
it = cachedResults.erase(it); // erase 返回下一个元素的迭代器
it = functionCachedResults.erase(it);
} else {
++it;
}
}
for (auto it = basicBlockCachedResults.begin(); it != basicBlockCachedResults.end(); ) {
if (it->first.second == analysisID) {
it = basicBlockCachedResults.erase(it);
} else {
++it;
}
@ -191,26 +271,26 @@ private:
std::vector<std::unique_ptr<Pass>> passes;
AnalysisManager analysisManager;
Module *pmodule;
IRBuilder *pBuilder;
public:
PassManager() = default;
~PassManager() = default;
PassManager(Module *module) : pmodule(module) , analysisManager() {}
PassManager(Module *module, IRBuilder *builder) : pmodule(module) ,pBuilder(builder), analysisManager(module) {}
// 运行所有注册的遍
bool run();
// 运行优化管道主要负责注册和运行优化遍
// 这里可以根据 optLevel 和 DEBUG 控制不同的优化遍
void runOptimizationPipeline(Module* moduleIR, int optLevel);
void runOptimizationPipeline(Module* moduleIR, IRBuilder* builder, int optLevel);
// 添加遍:现在接受 Pass 的 ID而不是直接的 unique_ptr
void addPass(void *passID);
AnalysisManager &getAnalysisManager() { return analysisManager; }
};
// ======================================================================
@ -218,15 +298,18 @@ public:
// ======================================================================
// 用于分析遍的注册
template <typename AnalysisPassType> void registerAnalysisPass() {
PassRegistry::getPassRegistry().registerPass(&AnalysisPassType::ID,
[]() { return std::make_unique<AnalysisPassType>(); });
}
template <typename AnalysisPassType> void registerAnalysisPass();
// 用于优化遍的注册
template <typename OptimizationPassType> void registerOptimizationPass() {
PassRegistry::getPassRegistry().registerPass(&OptimizationPassType::ID,
[]() { return std::make_unique<OptimizationPassType>(); });
}
// (1) 针对需要 IRBuilder 参数的优化遍的重载
// 这个模板只在 OptimizationPassType 可以通过 IRBuilder* 构造时才有效
template <typename OptimizationPassType, typename std::enable_if<
std::is_constructible<OptimizationPassType, IRBuilder*>::value, int>::type = 0>
void registerOptimizationPass(IRBuilder* builder);
// (2) 针对不需要 IRBuilder 参数的所有其他优化遍的重载
// 这个模板只在 OptimizationPassType 不能通过 IRBuilder* 构造时才有效
template <typename OptimizationPassType, typename std::enable_if<
!std::is_constructible<OptimizationPassType, IRBuilder*>::value, int>::type = 0>
void registerOptimizationPass();
} // namespace sysy

View File

@ -2,6 +2,7 @@
#include "IR.h"
#include "IRBuilder.h"
#include "Pass.h"
namespace sysy {
@ -17,44 +18,79 @@ namespace sysy {
// - 合并连续的跳转指令Jump Threading在合并不可达块中似乎已经实现了
// - 基本块重排序Block Reordering提升局部性
class SysYCFGOpt {
private:
Module *pModule;
IRBuilder *pBuilder;
public:
SysYCFGOpt(Module *pMoudle, IRBuilder *pBuilder) : pModule(pMoudle), pBuilder(pBuilder) {}
void SysYOptimizateAfterIR(){
auto &functions = pModule->getFunctions();
for (auto &function : functions) {
bool changed = false;
while(changed){
changed = false;
changed |= SysYCondBr2Br(function.second.get(), pBuilder);
// 删除br后面的无用指令
changed |= SysYDelInstAfterBr(function.second.get());
// 合并空基本块
changed |= SysYBlockMerge(function.second.get());
// 删除无前驱块
changed |= SysYDelNoPreBLock(function.second.get());
// 删除空块
changed |= SysYDelEmptyBlock(function.second.get(), pBuilder);
// 添加return指令
changed |= SysYAddReturn(function.second.get(), pBuilder);
}
}
}
// 辅助工具类包含实际的CFG优化逻辑
// 这些方法可以被独立的Pass调用
class SysYCFGOptUtils {
public:
static bool SysYDelInstAfterBr(Function *func); // 删除br后面的指令
static bool SysYDelEmptyBlock(Function *func, IRBuilder* pBuilder); // 空块删除
static bool SysYDelNoPreBLock(Function *func); // 删除无前驱块(不可达块)
static bool SysYBlockMerge(Function *func); // 合并基本块(主要针对嵌套if while的exit块
// 也可以修改IR生成实现回填机制
static bool SysYAddReturn(Function *func, IRBuilder* pBuilder); // 添加return指令(主要针对Void函数)
static bool SysYCondBr2Br(Function *func, IRBuilder* pBuilder); // 条件分支(已知cond的值)转换为无条件分支
static bool SysYBlockMerge(Function *func); // 合并基本块
static bool SysYAddReturn(Function *func, IRBuilder* pBuilder); // 添加return指令
static bool SysYCondBr2Br(Function *func, IRBuilder* pBuilder); // 条件分支转换为无条件分支
};
} // namespace sysy
// ======================================================================
// 独立的CFG优化遍
// ======================================================================
class SysYDelInstAfterBrPass : public OptimizationPass {
public:
static void *ID; // 唯一ID
SysYDelInstAfterBrPass() : OptimizationPass("SysYDelInstAfterBrPass", Granularity::Function) {}
bool runOnFunction(Function *F, AnalysisManager& AM) override;
void getAnalysisUsage(std::set<void *> &analysisDependencies, std::set<void *> &analysisInvalidations) const override {
// 这个优化可能改变CFG结构使一些CFG相关的分析失效
// 可以在这里指定哪些分析会失效,例如支配树、活跃变量等
// analysisInvalidations.insert(DominatorTreeAnalysisPass::ID); // 示例
}
void *getPassID() const override { return &ID; }
};
class SysYDelEmptyBlockPass : public OptimizationPass {
private:
IRBuilder *pBuilder;
public:
static void *ID;
SysYDelEmptyBlockPass(IRBuilder *builder) : OptimizationPass("SysYDelEmptyBlockPass", Granularity::Function), pBuilder(builder) {}
bool runOnFunction(Function *F, AnalysisManager& AM) override;
void *getPassID() const override { return &ID; }
};
class SysYDelNoPreBLockPass : public OptimizationPass {
public:
static void *ID;
SysYDelNoPreBLockPass() : OptimizationPass("SysYDelNoPreBLockPass", Granularity::Function) {}
bool runOnFunction(Function *F, AnalysisManager& AM) override;
void *getPassID() const override { return &ID; }
};
class SysYBlockMergePass : public OptimizationPass {
public:
static void *ID;
SysYBlockMergePass() : OptimizationPass("SysYBlockMergePass", Granularity::Function) {}
bool runOnFunction(Function *F, AnalysisManager& AM) override;
void *getPassID() const override { return &ID; }
};
class SysYAddReturnPass : public OptimizationPass {
private:
IRBuilder *pBuilder;
public:
static void *ID;
SysYAddReturnPass(IRBuilder *builder) : OptimizationPass("SysYAddReturnPass", Granularity::Function), pBuilder(builder) {}
bool runOnFunction(Function *F, AnalysisManager& AM) override;
void *getPassID() const override { return &ID; }
};
class SysYCondBr2BrPass : public OptimizationPass {
private:
IRBuilder *pBuilder;
public:
static void *ID;
SysYCondBr2BrPass(IRBuilder *builder) : OptimizationPass("SysYCondBr2BrPass", Granularity::Function), pBuilder(builder) {}
bool runOnFunction(Function *F, AnalysisManager& AM) override;
void *getPassID() const override { return &ID; }
};
} // namespace sysy

View File

@ -10,15 +10,12 @@ namespace sysy {
class SysYIROptUtils{
public:
// 删除use关系
// 根据指令的使用情况删除其所有的use关系
// 找到指令的所有使用者,并从它们的使用列表中删除该指令
// 仅仅删除use关系
static void usedelete(Instruction *instr) {
for (auto &use : instr->getOperands()) {
Value* val = use->getValue();
val->removeUse(use);
}
instr->getParent()->removeInst(instr); // 从基本块中删除指令
}
// 判断是否是全局变量

View File

@ -129,14 +129,19 @@ int main(int argc, char **argv) {
DEBUG = 1; // 这里可能需要更精细地控制 DEBUG 的开启时机和范围
}
// 创建 Pass 管理器并运行优化管道
PassManager passManager(moduleIR); // 创建 Pass 管理器
passManager.runOptimizationPipeline(moduleIR, optLevel);
if (DEBUG) {
cout << "=== Init IR ===\n";
SysYPrinter(moduleIR).printIR(); // 临时打印器用于调试
}
// 创建 Pass 管理器并运行优化管道
PassManager passManager(moduleIR, builder); // 创建 Pass 管理器
// 好像都不用传递module和builder了因为 PassManager 初始化了
passManager.runOptimizationPipeline(moduleIR, builder, optLevel);
AddressCalculationExpansion ace(moduleIR, builder);
if (ace.run()) {
if (DEBUG) cout << "AddressCalculationExpansion made changes.\n";