From 87d38be255c8d3fc61b2d7710a836af04b84f7e0 Mon Sep 17 00:00:00 2001 From: rain2133 <1370973498@qq.com> Date: Wed, 23 Jul 2025 17:19:11 +0800 Subject: [PATCH] =?UTF-8?q?[midend]=E6=9B=B4=E6=96=B0=E9=81=8D=E9=9D=99?= =?UTF-8?q?=E6=80=81ID=E5=AE=9A=E4=B9=89=E6=96=B9=E6=B3=95=EF=BC=8C=20?= =?UTF-8?q?=E6=B3=A8=E5=86=8C=E9=81=8D=E6=A8=A1=E6=9D=BF=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E9=87=8D=E6=9E=84=EF=BC=88=E9=92=88=E5=AF=B9=E9=81=8D=E7=9A=84?= =?UTF-8?q?=E4=B8=8D=E5=90=8C=E6=9E=84=E9=80=A0=E6=96=B9=E6=B3=95=EF=BC=89?= =?UTF-8?q?=EF=BC=8C=20=E4=BF=AE=E5=A4=8Dphi=E6=8C=87=E4=BB=A4=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E5=BC=95=E8=B5=B7=E7=9A=84=E6=97=A7=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E9=94=99=E8=AF=AF=EF=BC=8C=20=E5=B0=86CFG=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E9=80=82=E9=85=8D=E5=88=B0=E7=8E=B0=E6=9C=89=E7=BB=88=E7=AB=AF?= =?UTF-8?q?=E6=A1=86=E6=9E=B6=E4=B8=AD=EF=BC=8C=20=E7=8B=AC=E7=AB=8BCFG?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=96=B9=E6=B3=95=E4=BD=BF=E5=BE=97=E5=85=B6?= =?UTF-8?q?=E4=BB=96=E4=BC=98=E5=8C=96=E9=81=8D=E8=83=BD=E7=8B=AC=E7=AB=8B?= =?UTF-8?q?=E8=B0=83=E7=94=A8=EF=BC=8C=20usedelete=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E5=9B=9E=E8=B0=83=E5=8F=96=E6=B6=88=E5=88=A0=E9=99=A4=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E3=80=82=20IRGenerator=E4=BB=A3=E7=A0=81=E9=A3=8E?= =?UTF-8?q?=E6=A0=BC=E4=BF=AE=E6=94=B9=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Pass_ID_List.md | 5 + src/Dom.cpp | 3 +- src/Liveness.cpp | 3 +- src/Pass.cpp | 70 +++++-- src/SysYIRCFGOpt.cpp | 389 +++++++++++++++++++---------------- src/SysYIRGenerator.cpp | 24 +-- src/include/Dom.h | 2 +- src/include/Liveness.h | 2 +- src/include/Pass.h | 185 ++++++++++++----- src/include/SysYIRCFGOpt.h | 106 ++++++---- src/include/SysYIROptUtils.h | 5 +- src/sysyc.cpp | 13 +- 12 files changed, 509 insertions(+), 298 deletions(-) create mode 100644 Pass_ID_List.md diff --git a/Pass_ID_List.md b/Pass_ID_List.md new file mode 100644 index 0000000..79de64c --- /dev/null +++ b/Pass_ID_List.md @@ -0,0 +1,5 @@ +# 记录中端遍的唯一标识ID + +| 名称 | 优化级别 | 开发进度 | +| ------------ | ------------ | ---------- | +| CFG优化 | 函数级 | 已完成 | \ No newline at end of file diff --git a/src/Dom.cpp b/src/Dom.cpp index e82dc7d..d476c49 100644 --- a/src/Dom.cpp +++ b/src/Dom.cpp @@ -5,8 +5,7 @@ namespace sysy { // 初始化 支配树静态 ID -char DominatorTreeAnalysisPass::ID = 0; - +void *DominatorTreeAnalysisPass::ID = (void *)&DominatorTreeAnalysisPass::ID; // ============================================================== // DominatorTree 结果类的实现 // ============================================================== diff --git a/src/Liveness.cpp b/src/Liveness.cpp index 2fc5142..11c0f71 100644 --- a/src/Liveness.cpp +++ b/src/Liveness.cpp @@ -7,8 +7,7 @@ namespace sysy { // 初始化静态 ID -char LivenessAnalysisPass::ID = 0; // 任何唯一的地址都可以,这里用 0 - +void *LivenessAnalysisPass::ID = (void *)&LivenessAnalysisPass::ID; // ============================================================== // LivenessAnalysisResult 结果类的实现 // ============================================================== diff --git a/src/Pass.cpp b/src/Pass.cpp index 87e541b..46c0588 100644 --- a/src/Pass.cpp +++ b/src/Pass.cpp @@ -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 #include #include #include #include #include -#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::registerAnalysisPass(); + /* + 中端开发框架基本流程: + 1) 分析pass + 1. 实现分析pass并引入Pass.cpp + 2. 注册分析pass + 2) 优化pass + 1. 实现优化pass并引入Pass.cpp + 2. 注册优化pass + 3. 添加优化passid + */ + // 注册分析遍 + registerAnalysisPass(); + registerAnalysisPass(); + // 注册优化遍 + registerOptimizationPass(); + registerOptimizationPass(); + registerOptimizationPass(); + + registerOptimizationPass(builderIR); + registerOptimizationPass(builderIR); + registerOptimizationPass(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 void registerAnalysisPass() { + PassRegistry::getPassRegistry().registerPass(&AnalysisPassType::ID, + []() { return std::make_unique(); }); +} + +template ::value, int>::type = 0> +void registerOptimizationPass(IRBuilder* builder) { + PassRegistry::getPassRegistry().registerPass(&OptimizationPassType::ID, + [builder]() { return std::make_unique(builder); }); +} + +template ::value, int>::type = 0> +void registerOptimizationPass() { + PassRegistry::getPassRegistry().registerPass(&OptimizationPassType::ID, + []() { return std::make_unique(); }); +} + } // namespace sysy \ No newline at end of file diff --git a/src/SysYIRCFGOpt.cpp b/src/SysYIRCFGOpt.cpp index c386379..63d67d4 100644 --- a/src/SysYIRCFGOpt.cpp +++ b/src/SysYIRCFGOpt.cpp @@ -6,14 +6,25 @@ #include #include #include -#include "IR.h" -#include "IRBuilder.h" +#include // 引入队列,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.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(thelastinst->get()->getOperand(0)); BasicBlock *thelastBlockOld = nullptr; // 如果空块链表为多个块 - while (EmptyBlocks.find(dynamic_cast(thelastinst->get()->getOperand(0))) != - EmptyBlocks.end()) { + while (EmptyBlocks.count(dynamic_cast(thelastinst->get()->getOperand(0)))) { thelastBlockOld = dynamic_cast(thelastinst->get()->getOperand(0)); thelastinst->get()->replaceOperand(0, EmptyBlocks[thelastBlockOld]); } - basicBlock->removeSuccessor(OldBrBlock); - OldBrBlock->removePredecessor(basicBlock.get()); - basicBlock->addSuccessor(dynamic_cast(thelastinst->get()->getOperand(0))); - dynamic_cast(thelastinst->get()->getOperand(0))->addPredecessor(basicBlock.get()); + // 如果有重定向发生 + if (thelastBlockOld != nullptr) { + basicBlock->removeSuccessor(OldBrBlock); + OldBrBlock->removePredecessor(basicBlock.get()); + basicBlock->addSuccessor(dynamic_cast(thelastinst->get()->getOperand(0))); + dynamic_cast(thelastinst->get()->getOperand(0))->addPredecessor(basicBlock.get()); + changed = true; // 标记IR被修改 + } + if (thelastBlockOld != nullptr) { - int indexphi = 0; - for (auto &pred : dynamic_cast(thelastinst->get()->getOperand(0))->getPredecessors()) { - if (pred == thelastBlockOld) { - break; - } - indexphi++; - } - - // 更新phi指令的操作数 - // 移除thelastBlockOld对应的phi操作数 for (auto &InstInNew : dynamic_cast(thelastinst->get()->getOperand(0))->getInstructions()) { - if (InstInNew->isPhi()) { - dynamic_cast(InstInNew.get())->removeOperand(indexphi + 1); - } else { - break; - } + if (InstInNew->isPhi()) { + // 使用 delBlk 方法删除 oldBlock 对应的传入值 + dynamic_cast(InstInNew.get())->delBlk(thelastBlockOld); + } else { + break; } + } } } else if (thelastinst->get()->getKind() == Instruction::kCondBr) { auto OldThenBlock = dynamic_cast(thelastinst->get()->getOperand(1)); auto OldElseBlock = dynamic_cast(thelastinst->get()->getOperand(2)); + bool thenChanged = false; + bool elseChanged = false; + BasicBlock *thelastBlockOld = nullptr; - while (EmptyBlocks.find(dynamic_cast(thelastinst->get()->getOperand(1))) != - EmptyBlocks.end()) { + while (EmptyBlocks.count(dynamic_cast(thelastinst->get()->getOperand(1)))) { thelastBlockOld = dynamic_cast(thelastinst->get()->getOperand(1)); thelastinst->get()->replaceOperand( 1, EmptyBlocks[dynamic_cast(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(thelastinst->get()->getOperand(1))); + dynamic_cast(thelastinst->get()->getOperand(1))->addPredecessor(basicBlock.get()); + changed = true; // 标记IR被修改 + } + // 处理 then 和 else 分支合并的情况 if (dynamic_cast(thelastinst->get()->getOperand(1)) == dynamic_cast(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(thelastinst->get()->getOperand(1))); - dynamic_cast(thelastinst->get()->getOperand(1))->addPredecessor(basicBlock.get()); - // auto indexInNew = dynamic_cast(thelastinst->get()->getOperand(0))->getPredecessors(). - + if (thelastBlockOld != nullptr) { - int indexphi = 0; - for (auto &pred : dynamic_cast(thelastinst->get()->getOperand(1))->getPredecessors()) { - if (pred == thelastBlockOld) { - break; - } - indexphi++; - } - for (auto &InstInNew : dynamic_cast(thelastinst->get()->getOperand(1))->getInstructions()) { if (InstInNew->isPhi()) { - dynamic_cast(InstInNew.get())->removeOperand(indexphi + 1); + // 使用 delBlk 方法删除 oldBlock 对应的传入值 + dynamic_cast(InstInNew.get())->delBlk(thelastBlockOld); } else { break; } - } + } } thelastBlockOld = nullptr; - while (EmptyBlocks.find(dynamic_cast(thelastinst->get()->getOperand(2))) != - EmptyBlocks.end()) { + while (EmptyBlocks.count(dynamic_cast(thelastinst->get()->getOperand(2)))) { thelastBlockOld = dynamic_cast(thelastinst->get()->getOperand(2)); thelastinst->get()->replaceOperand( 2, EmptyBlocks[dynamic_cast(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(thelastinst->get()->getOperand(2))); + dynamic_cast(thelastinst->get()->getOperand(2))->addPredecessor(basicBlock.get()); + changed = true; // 标记IR被修改 + } + // 处理 then 和 else 分支合并的情况 if (dynamic_cast(thelastinst->get()->getOperand(1)) == dynamic_cast(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(thelastinst->get()->getOperand(2))); - dynamic_cast(thelastinst->get()->getOperand(2))->addPredecessor(basicBlock.get()); + + // 如果有重定向发生 + // 需要更新后继块的前驱关系 if (thelastBlockOld != nullptr) { - int indexphi = 0; - for (auto &pred : dynamic_cast(thelastinst->get()->getOperand(2))->getPredecessors()) { - if (pred == thelastBlockOld) { - break; - } - indexphi++; - } for (auto &InstInNew : dynamic_cast(thelastinst->get()->getOperand(2))->getInstructions()) { if (InstInNew->isPhi()) { - dynamic_cast(InstInNew.get())->removeOperand(indexphi + 1); + // 使用 delBlk 方法删除 oldBlock 对应的传入值 + dynamic_cast(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(thelastinst->get()->getOperand(0)); - sysy::BasicBlock *thelastBlockOld = nullptr; - while (EmptyBlocks.find(dynamic_cast(thelastinst->get()->getOperand(0))) != - EmptyBlocks.end()) { - thelastBlockOld = dynamic_cast(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(thelastinst->get()->getOperand(0)); + // sysy::BasicBlock *thelastBlockOld = nullptr; + // while (EmptyBlocks.find(dynamic_cast(thelastinst->get()->getOperand(0))) != + // EmptyBlocks.end()) { + // thelastBlockOld = dynamic_cast(thelastinst->get()->getOperand(0)); - thelastinst->get()->replaceOperand( - 0, EmptyBlocks[dynamic_cast(thelastinst->get()->getOperand(0))]); - } + // thelastinst->get()->replaceOperand( + // 0, EmptyBlocks[dynamic_cast(thelastinst->get()->getOperand(0))]); + // } - basicBlock->removeSuccessor(OldBrBlock); - OldBrBlock->removePredecessor(basicBlock.get()); - basicBlock->addSuccessor(dynamic_cast(thelastinst->get()->getOperand(0))); - dynamic_cast(thelastinst->get()->getOperand(0))->addPredecessor(basicBlock.get()); - if (thelastBlockOld != nullptr) { - int indexphi = 0; - for (auto &pred : dynamic_cast(thelastinst->get()->getOperand(0))->getPredecessors()) { - if (pred == thelastBlockOld) { - break; - } - indexphi++; - } + // basicBlock->removeSuccessor(OldBrBlock); + // OldBrBlock->removePredecessor(basicBlock.get()); + // basicBlock->addSuccessor(dynamic_cast(thelastinst->get()->getOperand(0))); + // dynamic_cast(thelastinst->get()->getOperand(0))->addPredecessor(basicBlock.get()); + // changed = true; // 标记IR被修改 + // if (thelastBlockOld != nullptr) { + // int indexphi = 0; + // for (auto &pred : dynamic_cast(thelastinst->get()->getOperand(0))->getPredecessors()) { + // if (pred == thelastBlockOld) { + // break; + // } + // indexphi++; + // } - for (auto &InstInNew : dynamic_cast(thelastinst->get()->getOperand(0))->getInstructions()) { - if (InstInNew->isPhi()) { - dynamic_cast(InstInNew.get())->removeOperand(indexphi + 1); - } else { - break; - } - } - } + // for (auto &InstInNew : dynamic_cast(thelastinst->get()->getOperand(0))->getInstructions()) { + // if (InstInNew->isPhi()) { + // dynamic_cast(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(instinsucc.get())->removeOperand(index); + // iter->get() 就是当前被删除的空基本块,它作为前驱连接到这里的Phi指令 + dynamic_cast(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.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.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 \ No newline at end of file diff --git a/src/SysYIRGenerator.cpp b/src/SysYIRGenerator.cpp index 1122b3e..50c24ea 100644 --- a/src/SysYIRGenerator.cpp +++ b/src/SysYIRGenerator.cpp @@ -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()->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 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()->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()->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(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(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(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(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(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(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(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(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); diff --git a/src/include/Dom.h b/src/include/Dom.h index 1a09f34..f69dcb9 100644 --- a/src/include/Dom.h +++ b/src/include/Dom.h @@ -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) {} diff --git a/src/include/Liveness.h b/src/include/Liveness.h index 7cfe01c..f101b7c 100644 --- a/src/include/Liveness.h +++ b/src/include/Liveness.h @@ -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) {} diff --git a/src/include/Pass.h b/src/include/Pass.h index 61839fa..b928b91 100644 --- a/src/include/Pass.h +++ b/src/include/Pass.h @@ -7,7 +7,9 @@ #include #include // For std::type_index (although void* ID is more common in LLVM) #include +#include #include "IR.h" +#include "IRBuilder.h" namespace sysy { @@ -117,64 +119,142 @@ private: // ====================================================================== class AnalysisManager { private: - std::map, std::unique_ptr> cachedResults; - // cachedResults 存储分析结果,键是 (Function*, AnalysisPass ID) + Module *pModuleRef; // 指向被分析的Module + + // 缓存不同粒度的分析结果 + std::map> moduleCachedResults; + std::map, std::unique_ptr> functionCachedResults; + std::map, std::unique_ptr> basicBlockCachedResults; + + public: - AnalysisManager() = default; + // 构造函数接收 Module 指针 + AnalysisManager(Module *M) : pModuleRef(M) {} + AnalysisManager() = delete; // 禁止无参构造 + ~AnalysisManager() = default; - // 获取分析结果 + // 获取分析结果的通用模板函数 // T 是 AnalysisResult 的具体类型,E 是 AnalysisPass 的具体类型 - // PassManager 应该在运行 Pass 之前调用 registerAnalysisPass - template T *getAnalysisResult(Function *F) { // 针对函数级别的分析,需要传入 Function* - void *analysisID = E::ID; // 获取分析遍的唯一 ID + // F 和 BB 参数用于提供上下文,根据分析遍的粒度来使用 + template 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(it->second.get()); // 返回缓存结果 - } - - // 如果没有缓存结果,通过 PassRegistry 创建分析遍并运行它 - // 注意:这里需要 PassRegistry 实例。如果 AnalysisManager 独立于 PassManager, - // 则需要传入 PassRegistry 引用或指针。 - // 为了简化,假设 AnalysisManager 能够访问到 PassRegistry + // 尝试从注册表创建分析遍实例 std::unique_ptr 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(basePass.get()); - // 确保分析遍的粒度与请求的上下文匹配 - if (analysisPass->getGranularity() == Pass::Granularity::Function) { - analysisPass->runOnFunction(F, *this); // 运行分析遍 - // 获取结果并缓存 - std::unique_ptr result = analysisPass->getResult(); - T *specificResult = static_cast(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(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 result = analysisPass->getResult(); + T *specificResult = static_cast(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(it->second.get()); // 返回缓存结果 + } + // 运行函数级分析遍 + analysisPass->runOnFunction(F, *this); + // 获取结果并缓存 + std::unique_ptr result = analysisPass->getResult(); + T *specificResult = static_cast(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(it->second.get()); // 返回缓存结果 + } + // 运行基本块级分析遍 + analysisPass->runOnBasicBlock(BB, *this); + // 获取结果并缓存 + std::unique_ptr result = analysisPass->getResult(); + T *specificResult = static_cast(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> 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 void registerAnalysisPass() { - PassRegistry::getPassRegistry().registerPass(&AnalysisPassType::ID, - []() { return std::make_unique(); }); -} +template void registerAnalysisPass(); -// 用于优化遍的注册 -template void registerOptimizationPass() { - PassRegistry::getPassRegistry().registerPass(&OptimizationPassType::ID, - []() { return std::make_unique(); }); -} +// (1) 针对需要 IRBuilder 参数的优化遍的重载 +// 这个模板只在 OptimizationPassType 可以通过 IRBuilder* 构造时才有效 +template ::value, int>::type = 0> +void registerOptimizationPass(IRBuilder* builder); + +// (2) 针对不需要 IRBuilder 参数的所有其他优化遍的重载 +// 这个模板只在 OptimizationPassType 不能通过 IRBuilder* 构造时才有效 +template ::value, int>::type = 0> +void registerOptimizationPass(); } // namespace sysy \ No newline at end of file diff --git a/src/include/SysYIRCFGOpt.h b/src/include/SysYIRCFGOpt.h index 6b13a3f..4d025c8 100644 --- a/src/include/SysYIRCFGOpt.h +++ b/src/include/SysYIRCFGOpt.h @@ -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 &analysisDependencies, std::set &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 \ No newline at end of file diff --git a/src/include/SysYIROptUtils.h b/src/include/SysYIROptUtils.h index 66929d1..1b764ec 100644 --- a/src/include/SysYIROptUtils.h +++ b/src/include/SysYIROptUtils.h @@ -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); // 从基本块中删除指令 } // 判断是否是全局变量 diff --git a/src/sysyc.cpp b/src/sysyc.cpp index c22c0a8..1cf6fa7 100644 --- a/src/sysyc.cpp +++ b/src/sysyc.cpp @@ -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";