[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 { namespace sysy {
// 初始化 支配树静态 ID // 初始化 支配树静态 ID
char DominatorTreeAnalysisPass::ID = 0; void *DominatorTreeAnalysisPass::ID = (void *)&DominatorTreeAnalysisPass::ID;
// ============================================================== // ==============================================================
// DominatorTree 结果类的实现 // DominatorTree 结果类的实现
// ============================================================== // ==============================================================

View File

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

View File

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

View File

@@ -6,14 +6,25 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include <iostream> #include <iostream>
#include "IR.h" #include <queue> // 引入队列SysYDelNoPreBLock需要
#include "IRBuilder.h"
namespace sysy { 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后的无用指令 // 删除br后的无用指令
bool SysYCFGOpt::SysYDelInstAfterBr(Function *func) { bool SysYCFGOptUtils::SysYDelInstAfterBr(Function *func) {
bool changed = false; bool changed = false;
auto basicBlocks = func->getBasicBlocks(); auto basicBlocks = func->getBasicBlocks();
@@ -22,11 +33,10 @@ bool SysYCFGOpt::SysYDelInstAfterBr(Function *func) {
auto &instructions = basicBlock->getInstructions(); auto &instructions = basicBlock->getInstructions();
auto Branchiter = instructions.end(); auto Branchiter = instructions.end();
for (auto iter = instructions.begin(); iter != instructions.end(); ++iter) { for (auto iter = instructions.begin(); iter != instructions.end(); ++iter) {
if (Branch) if ((*iter)->isTerminator()){
SysYIROptUtils::usedelete(iter->get());
else if ((*iter)->isTerminator()){
Branch = true; Branch = true;
Branchiter = iter; Branchiter = iter;
break;
} }
} }
if (Branchiter != instructions.end()) ++Branchiter; if (Branchiter != instructions.end()) ++Branchiter;
@@ -61,8 +71,8 @@ bool SysYCFGOpt::SysYDelInstAfterBr(Function *func) {
return changed; return changed;
} }
// 合并基本块 // 合并基本块
bool SysYCFGOpt::SysYBlockMerge(Function *func) { bool SysYCFGOptUtils::SysYBlockMerge(Function *func) {
bool changed = false; bool changed = false;
for (auto blockiter = func->getBasicBlocks().begin(); for (auto blockiter = func->getBasicBlocks().begin();
@@ -82,12 +92,12 @@ bool SysYCFGOpt::SysYBlockMerge(Function *func) {
(--thelastinstinst); (--thelastinstinst);
if (thelastinstinst->get()->isUnconditional()) { if (thelastinstinst->get()->isUnconditional()) {
SysYIROptUtils::usedelete(thelastinstinst->get()); SysYIROptUtils::usedelete(thelastinstinst->get());
block->getInstructions().erase(thelastinstinst); thelastinstinst = block->getInstructions().erase(thelastinstinst);
} else if (thelastinstinst->get()->isConditional()) { } else if (thelastinstinst->get()->isConditional()) {
// 如果是条件分支,判断条件是否相同,主要优化相同布尔表达式 // 如果是条件分支,判断条件是否相同,主要优化相同布尔表达式
if (thelastinstinst->get()->getOperand(1)->getName() == thelastinstinst->get()->getOperand(1)->getName()) { if (thelastinstinst->get()->getOperand(1)->getName() == thelastinstinst->get()->getOperand(1)->getName()) {
SysYIROptUtils::usedelete(thelastinstinst->get()); SysYIROptUtils::usedelete(thelastinstinst->get());
block->getInstructions().erase(thelastinstinst); thelastinstinst = block->getInstructions().erase(thelastinstinst);
} }
} }
} }
@@ -132,7 +142,7 @@ bool SysYCFGOpt::SysYBlockMerge(Function *func) {
} }
// 删除无前驱块兼容SSA后的处理 // 删除无前驱块兼容SSA后的处理
bool SysYCFGOpt::SysYDelNoPreBLock(Function *func) { bool SysYCFGOptUtils::SysYDelNoPreBLock(Function *func) {
bool changed = false; bool changed = false;
@@ -156,29 +166,26 @@ bool SysYCFGOpt::SysYDelNoPreBLock(Function *func) {
} }
// 删除不可达基本块指令 // 删除不可达基本块指令
for (auto blockIter = func->getBasicBlocks().begin(); blockIter != func->getBasicBlocks().end();blockIter++) { for (auto blockIter = func->getBasicBlocks().begin(); blockIter != func->getBasicBlocks().end(); blockIter++) {
if (!blockIter->get()->getreachable()) if (!blockIter->get()->getreachable()) {
for (auto &iterInst : blockIter->get()->getInstructions()) for (auto instIter = blockIter->get()->getInstructions().begin();
SysYIROptUtils::usedelete(iterInst.get()); 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();) { for (auto blockIter = func->getBasicBlocks().begin(); blockIter != func->getBasicBlocks().end();) {
if (!blockIter->get()->getreachable()) { if (!blockIter->get()->getreachable()) {
for (auto succblock : blockIter->get()->getSuccessors()) { 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()) { for (auto &phiinst : succblock->getInstructions()) {
if (phiinst->getKind() != Instruction::kPhi) { if (phiinst->getKind() != Instruction::kPhi) {
break; break;
} }
phiinst->removeOperand(indexphi); // 使用 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; bool changed = false;
// 收集不可达基本块 // 收集不可达基本块
@@ -218,24 +225,29 @@ bool SysYCFGOpt::SysYDelEmptyBlock(Function *func, IRBuilder* pBuilder) {
break; break;
} }
} }
if(onlyPhi) if(onlyPhi && basicBlock->getNumSuccessors() == 1) // 确保有后继且只有一个
EmptyBlocks[basicBlock.get()] = basicBlock->getSuccessors().front(); EmptyBlocks[basicBlock.get()] = basicBlock->getSuccessors().front();
} }
} }
// 更新基本块信息,增加必要指令 // 更新基本块信息,增加必要指令
for (auto &basicBlock : basicBlocks) { for (auto &basicBlock : basicBlocks) {
// 把空块转换成只有跳转指令的不可达块 // 把空块转换成只有跳转指令的不可达块 (这段逻辑在优化遍中可能需要调整,这里是原样保留)
// 通常DelEmptyBlock 应该在BlockMerge之后运行如果存在完全空块它会尝试填充一个Br指令。
// 但是,它主要目的是重定向跳转。
if (distance(basicBlock->begin(), basicBlock->end()) == 0) { if (distance(basicBlock->begin(), basicBlock->end()) == 0) {
if (basicBlock->getNumSuccessors() == 0) { if (basicBlock->getNumSuccessors() == 0) {
continue; continue;
} }
if (basicBlock->getNumSuccessors() > 1) { 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; continue;
} }
@@ -247,31 +259,26 @@ bool SysYCFGOpt::SysYDelEmptyBlock(Function *func, IRBuilder* pBuilder) {
BasicBlock* OldBrBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0)); BasicBlock* OldBrBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0));
BasicBlock *thelastBlockOld = nullptr; BasicBlock *thelastBlockOld = nullptr;
// 如果空块链表为多个块 // 如果空块链表为多个块
while (EmptyBlocks.find(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))) != while (EmptyBlocks.count(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0)))) {
EmptyBlocks.end()) {
thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0)); thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0));
thelastinst->get()->replaceOperand(0, EmptyBlocks[thelastBlockOld]); thelastinst->get()->replaceOperand(0, EmptyBlocks[thelastBlockOld]);
} }
// 如果有重定向发生
if (thelastBlockOld != nullptr) {
basicBlock->removeSuccessor(OldBrBlock); basicBlock->removeSuccessor(OldBrBlock);
OldBrBlock->removePredecessor(basicBlock.get()); OldBrBlock->removePredecessor(basicBlock.get());
basicBlock->addSuccessor(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))); basicBlock->addSuccessor(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0)));
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->addPredecessor(basicBlock.get()); dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->addPredecessor(basicBlock.get());
changed = true; // 标记IR被修改
}
if (thelastBlockOld != nullptr) { 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()) { for (auto &InstInNew : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->getInstructions()) {
if (InstInNew->isPhi()) { if (InstInNew->isPhi()) {
dynamic_cast<PhiInst *>(InstInNew.get())->removeOperand(indexphi + 1); // 使用 delBlk 方法删除 oldBlock 对应的传入值
dynamic_cast<PhiInst *>(InstInNew.get())->delBlk(thelastBlockOld);
} else { } else {
break; break;
} }
@@ -281,16 +288,26 @@ bool SysYCFGOpt::SysYDelEmptyBlock(Function *func, IRBuilder* pBuilder) {
} else if (thelastinst->get()->getKind() == Instruction::kCondBr) { } else if (thelastinst->get()->getKind() == Instruction::kCondBr) {
auto OldThenBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)); auto OldThenBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1));
auto OldElseBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2)); auto OldElseBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2));
bool thenChanged = false;
bool elseChanged = false;
BasicBlock *thelastBlockOld = nullptr; BasicBlock *thelastBlockOld = nullptr;
while (EmptyBlocks.find(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1))) != while (EmptyBlocks.count(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)))) {
EmptyBlocks.end()) {
thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)); thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1));
thelastinst->get()->replaceOperand( thelastinst->get()->replaceOperand(
1, EmptyBlocks[dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1))]); 1, EmptyBlocks[dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1))]);
thenChanged = true;
} }
if (thenChanged) {
basicBlock->removeSuccessor(OldThenBlock); basicBlock->removeSuccessor(OldThenBlock);
OldThenBlock->removePredecessor(basicBlock.get()); 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 分支合并的情况 // 处理 then 和 else 分支合并的情况
if (dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)) == if (dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)) ==
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))) { dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))) {
@@ -299,24 +316,15 @@ bool SysYCFGOpt::SysYDelEmptyBlock(Function *func, IRBuilder* pBuilder) {
thelastinst = basicBlock->getInstructions().erase(thelastinst); thelastinst = basicBlock->getInstructions().erase(thelastinst);
pBuilder->setPosition(basicBlock.get(), basicBlock->end()); pBuilder->setPosition(basicBlock.get(), basicBlock->end());
pBuilder->createUncondBrInst(thebrBlock, {}); pBuilder->createUncondBrInst(thebrBlock, {});
changed = true; // 标记IR被修改
continue; 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) { 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()) { for (auto &InstInNew : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1))->getInstructions()) {
if (InstInNew->isPhi()) { if (InstInNew->isPhi()) {
dynamic_cast<PhiInst *>(InstInNew.get())->removeOperand(indexphi + 1); // 使用 delBlk 方法删除 oldBlock 对应的传入值
dynamic_cast<PhiInst *>(InstInNew.get())->delBlk(thelastBlockOld);
} else { } else {
break; break;
} }
@@ -324,14 +332,21 @@ bool SysYCFGOpt::SysYDelEmptyBlock(Function *func, IRBuilder* pBuilder) {
} }
thelastBlockOld = nullptr; thelastBlockOld = nullptr;
while (EmptyBlocks.find(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))) != while (EmptyBlocks.count(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2)))) {
EmptyBlocks.end()) {
thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2)); thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2));
thelastinst->get()->replaceOperand( thelastinst->get()->replaceOperand(
2, EmptyBlocks[dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))]); 2, EmptyBlocks[dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))]);
elseChanged = true;
} }
if (elseChanged) {
basicBlock->removeSuccessor(OldElseBlock); basicBlock->removeSuccessor(OldElseBlock);
OldElseBlock->removePredecessor(basicBlock.get()); 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 分支合并的情况 // 处理 then 和 else 分支合并的情况
if (dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)) == if (dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)) ==
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))) { dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))) {
@@ -340,93 +355,94 @@ bool SysYCFGOpt::SysYDelEmptyBlock(Function *func, IRBuilder* pBuilder) {
thelastinst = basicBlock->getInstructions().erase(thelastinst); thelastinst = basicBlock->getInstructions().erase(thelastinst);
pBuilder->setPosition(basicBlock.get(), basicBlock->end()); pBuilder->setPosition(basicBlock.get(), basicBlock->end());
pBuilder->createUncondBrInst(thebrBlock, {}); pBuilder->createUncondBrInst(thebrBlock, {});
changed = true; // 标记IR被修改
continue; continue;
} }
basicBlock->addSuccessor(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2)));
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))->addPredecessor(basicBlock.get());
// 如果有重定向发生
// 需要更新后继块的前驱关系
if (thelastBlockOld != nullptr) { 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()) { for (auto &InstInNew : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))->getInstructions()) {
if (InstInNew->isPhi()) { if (InstInNew->isPhi()) {
dynamic_cast<PhiInst *>(InstInNew.get())->removeOperand(indexphi + 1); // 使用 delBlk 方法删除 oldBlock 对应的传入值
dynamic_cast<PhiInst *>(InstInNew.get())->delBlk(thelastBlockOld);
} else { } else {
break; break;
} }
} }
} }
} else { } else {
// 如果不是终止指令,但有后继 (例如,末尾没有显式终止指令的块)
// 这段逻辑可能需要更严谨的CFG检查来确保正确性
if (basicBlock->getNumSuccessors() == 1) { if (basicBlock->getNumSuccessors() == 1) {
pBuilder->setPosition(basicBlock.get(), basicBlock->end()); // 这里的逻辑似乎是想为没有terminator的块添加一个但通常这应该在CFG构建阶段完成。
pBuilder->createUncondBrInst(basicBlock->getSuccessors()[0], {}); // 如果这里仍然执行,确保它符合预期。
auto thelastinst = basicBlock->getInstructions().end(); // pBuilder->setPosition(basicBlock.get(), basicBlock->end());
(--thelastinst); // pBuilder->createUncondBrInst(basicBlock->getSuccessors()[0], {});
auto OldBrBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0)); // auto thelastinst = basicBlock->getInstructions().end();
sysy::BasicBlock *thelastBlockOld = nullptr; // (--thelastinst);
while (EmptyBlocks.find(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))) != // auto OldBrBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0));
EmptyBlocks.end()) { // sysy::BasicBlock *thelastBlockOld = nullptr;
thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0)); // while (EmptyBlocks.find(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))) !=
// EmptyBlocks.end()) {
// thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0));
thelastinst->get()->replaceOperand( // thelastinst->get()->replaceOperand(
0, EmptyBlocks[dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))]); // 0, EmptyBlocks[dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))]);
} // }
basicBlock->removeSuccessor(OldBrBlock); // basicBlock->removeSuccessor(OldBrBlock);
OldBrBlock->removePredecessor(basicBlock.get()); // OldBrBlock->removePredecessor(basicBlock.get());
basicBlock->addSuccessor(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))); // basicBlock->addSuccessor(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0)));
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->addPredecessor(basicBlock.get()); // dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->addPredecessor(basicBlock.get());
if (thelastBlockOld != nullptr) { // changed = true; // 标记IR被修改
int indexphi = 0; // if (thelastBlockOld != nullptr) {
for (auto &pred : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->getPredecessors()) { // int indexphi = 0;
if (pred == thelastBlockOld) { // for (auto &pred : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->getPredecessors()) {
break; // if (pred == thelastBlockOld) {
} // break;
indexphi++; // }
} // indexphi++;
// }
for (auto &InstInNew : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->getInstructions()) { // for (auto &InstInNew : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->getInstructions()) {
if (InstInNew->isPhi()) { // if (InstInNew->isPhi()) {
dynamic_cast<PhiInst *>(InstInNew.get())->removeOperand(indexphi + 1); // dynamic_cast<PhiInst *>(InstInNew.get())->removeOperand(indexphi + 1);
} else { // } else {
break; // break;
} // }
} // }
} // }
} }
} }
} }
// 真正的删除空块
for (auto iter = func->getBasicBlocks().begin(); iter != func->getBasicBlocks().end();) { for (auto iter = func->getBasicBlocks().begin(); iter != func->getBasicBlocks().end();) {
if (EmptyBlocks.find(iter->get()) != EmptyBlocks.end()) { if (EmptyBlocks.count(iter->get())) {
// EntryBlock跳过 // EntryBlock跳过
if (iter->get() == func->getEntryBlock()) { if (iter->get() == func->getEntryBlock()) {
++iter; ++iter;
continue; continue;
} }
for (auto &iterInst : iter->get()->getInstructions()) for (auto instIter = iter->get()->getInstructions().begin();
SysYIROptUtils::usedelete(iterInst.get()); instIter != iter->get()->getInstructions().end();) {
SysYIROptUtils::usedelete(instIter->get()); // 仅删除 use 关系
// 显式地从基本块中删除指令并更新迭代器
instIter = iter->get()->getInstructions().erase(instIter);
}
// 删除不可达基本块的phi指令的操作数 // 删除不可达基本块的phi指令的操作数
for (auto &succ : iter->get()->getSuccessors()) { 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()) { for (auto &instinsucc : succ->getInstructions()) {
if (instinsucc->isPhi()) { if (instinsucc->isPhi()) {
dynamic_cast<PhiInst *>(instinsucc.get())->removeOperand(index); // iter->get() 就是当前被删除的空基本块它作为前驱连接到这里的Phi指令
dynamic_cast<PhiInst *>(instinsucc.get())->delBlk(iter->get());
} else { } else {
// Phi 指令通常在基本块的开头,如果不是 Phi 指令就停止检查
break; break;
} }
} }
@@ -440,21 +456,20 @@ bool SysYCFGOpt::SysYDelEmptyBlock(Function *func, IRBuilder* pBuilder) {
} }
return changed; return changed;
} }
// 如果函数没有返回指令,则添加一个默认返回指令(主要解决void函数没有返回指令的问题) // 如果函数没有返回指令,则添加一个默认返回指令(主要解决void函数没有返回指令的问题)
bool SysYCFGOpt::SysYAddReturn(Function *func, IRBuilder* pBuilder) { bool SysYCFGOptUtils::SysYAddReturn(Function *func, IRBuilder* pBuilder) {
bool changed = false; bool changed = false;
auto basicBlocks = func->getBasicBlocks(); auto basicBlocks = func->getBasicBlocks();
for (auto &block : basicBlocks) { for (auto &block : basicBlocks) {
if (block->getNumSuccessors() == 0) { if (block->getNumSuccessors() == 0) {
changed = true;
// 如果基本块没有后继块,则添加一个返回指令 // 如果基本块没有后继块,则添加一个返回指令
if (block->getNumInstructions() == 0) { if (block->getNumInstructions() == 0) {
pBuilder->setPosition(block.get(), block->end()); pBuilder->setPosition(block.get(), block->end());
pBuilder->createReturnInst(); pBuilder->createReturnInst();
} changed = true; // 标记IR被修改
} else {
auto thelastinst = block->getInstructions().end(); auto thelastinst = block->getInstructions().end();
--thelastinst; --thelastinst;
if (thelastinst->get()->getKind() != Instruction::kReturn) { if (thelastinst->get()->getKind() != Instruction::kReturn) {
@@ -469,6 +484,8 @@ bool SysYCFGOpt::SysYAddReturn(Function *func, IRBuilder* pBuilder) {
} else { } else {
pBuilder->createReturnInst(); pBuilder->createReturnInst();
} }
changed = true; // 标记IR被修改
}
} }
} }
} }
@@ -480,7 +497,7 @@ bool SysYCFGOpt::SysYAddReturn(Function *func, IRBuilder* pBuilder) {
// 主要针对已知条件值的分支转换为无条件分支 // 主要针对已知条件值的分支转换为无条件分支
// 例如 if (cond) { ... } else { ... } 中的 cond 已经 // 例如 if (cond) { ... } else { ... } 中的 cond 已经
// 确定为 true 或 false 的情况 // 确定为 true 或 false 的情况
bool SysYCFGOpt::SysYCondBr2Br(Function *func, IRBuilder* pBuilder) { bool SysYCFGOptUtils::SysYCondBr2Br(Function *func, IRBuilder* pBuilder) {
bool changed = false; bool changed = false;
for (auto &basicblock : func->getBasicBlocks()) { for (auto &basicblock : func->getBasicBlocks()) {
@@ -515,45 +532,41 @@ bool SysYCFGOpt::SysYCondBr2Br(Function *func, IRBuilder* pBuilder) {
SysYIROptUtils::usedelete(thelast->get()); SysYIROptUtils::usedelete(thelast->get());
thelast = basicblock->getInstructions().erase(thelast); thelast = basicblock->getInstructions().erase(thelast);
if ((constfloat_Use && constfloat == 1.0F) || (constint_Use && constint == 1)) { if ((constfloat_Use && constfloat == 1.0F) || (constint_Use && constint == 1)) {
// cond为true或非0
pBuilder->setPosition(basicblock.get(), basicblock->end()); pBuilder->setPosition(basicblock.get(), basicblock->end());
pBuilder->createUncondBrInst(thenBlock, {}); 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()) { for (auto &phiinst : elseBlock->getInstructions()) {
if (phiinst->getKind() != Instruction::kPhi) { if (phiinst->getKind() != Instruction::kPhi) {
break; break;
} }
phiinst->removeOperand(phiindex); // 使用 delBlk 方法删除 basicblock.get() 对应的传入值
dynamic_cast<PhiInst *>(phiinst.get())->delBlk(basicblock.get());
} }
basicblock->removeSuccessor(elseBlock);
elseBlock->removePredecessor(basicblock.get()); } else { // cond为false或0
} else {
pBuilder->setPosition(basicblock.get(), basicblock->end()); pBuilder->setPosition(basicblock.get(), basicblock->end());
pBuilder->createUncondBrInst(elseBlock, {}); 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()) { for (auto &phiinst : thenBlock->getInstructions()) {
if (phiinst->getKind() != Instruction::kPhi) { if (phiinst->getKind() != Instruction::kPhi) {
break; 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; return changed;
} }
// ======================================================================
// 独立的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 } // namespace sysy

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,6 +2,7 @@
#include "IR.h" #include "IR.h"
#include "IRBuilder.h" #include "IRBuilder.h"
#include "Pass.h"
namespace sysy { namespace sysy {
@@ -17,44 +18,79 @@ namespace sysy {
// - 合并连续的跳转指令Jump Threading在合并不可达块中似乎已经实现了 // - 合并连续的跳转指令Jump Threading在合并不可达块中似乎已经实现了
// - 基本块重排序Block Reordering提升局部性 // - 基本块重排序Block Reordering提升局部性
class SysYCFGOpt { // 辅助工具类包含实际的CFG优化逻辑
private: // 这些方法可以被独立的Pass调用
Module *pModule; class SysYCFGOptUtils {
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);
}
}
}
public: public:
static bool SysYDelInstAfterBr(Function *func); // 删除br后面的指令 static bool SysYDelInstAfterBr(Function *func); // 删除br后面的指令
static bool SysYDelEmptyBlock(Function *func, IRBuilder* pBuilder); // 空块删除 static bool SysYDelEmptyBlock(Function *func, IRBuilder* pBuilder); // 空块删除
static bool SysYDelNoPreBLock(Function *func); // 删除无前驱块(不可达块) static bool SysYDelNoPreBLock(Function *func); // 删除无前驱块(不可达块)
static bool SysYBlockMerge(Function *func); // 合并基本块(主要针对嵌套if while的exit块 static bool SysYBlockMerge(Function *func); // 合并基本块
// 也可以修改IR生成实现回填机制 static bool SysYAddReturn(Function *func, IRBuilder* pBuilder); // 添加return指令
static bool SysYAddReturn(Function *func, IRBuilder* pBuilder); // 添加return指令(主要针对Void函数) static bool SysYCondBr2Br(Function *func, IRBuilder* pBuilder); // 条件分支转换为无条件分支
static bool SysYCondBr2Br(Function *func, IRBuilder* pBuilder); // 条件分支(已知cond的值)转换为无条件分支 };
// ======================================================================
// 独立的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 } // namespace sysy

View File

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

View File

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