From 22cf18a1d649a8837161789b317e151863c8f0b5 Mon Sep 17 00:00:00 2001 From: rain2133 <1370973498@qq.com> Date: Sun, 3 Aug 2025 16:14:31 +0800 Subject: [PATCH] =?UTF-8?q?[midend-BuildCFG]=E4=BF=AE=E5=A4=8D=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/include/midend/Pass/Optimize/BuildCFG.h | 25 +-- src/midend/CMakeLists.txt | 1 + src/midend/Pass/Optimize/BuildCFG.cpp | 160 ++++++++------------ src/midend/Pass/Pass.cpp | 9 +- 4 files changed, 71 insertions(+), 124 deletions(-) diff --git a/src/include/midend/Pass/Optimize/BuildCFG.h b/src/include/midend/Pass/Optimize/BuildCFG.h index 4054c54..a7fb6cb 100644 --- a/src/include/midend/Pass/Optimize/BuildCFG.h +++ b/src/include/midend/Pass/Optimize/BuildCFG.h @@ -1,33 +1,20 @@ #pragma once -#include "Pass.h" #include "IR.h" -#include "Instruction.h" +#include "Pass.h" #include #include namespace sysy { -class DominatorTreeAnalysisPass; -class LivenessAnalysisPass; - class BuildCFG : public OptimizationPass { public: - // Pass的唯一ID,用于PassRegistry - static char ID; + static void *ID; + BuildCFG() : OptimizationPass("BuildCFG", Granularity::Function) {} + bool runOnFunction(Function *F, AnalysisManager &AM) override; + void getAnalysisUsage(std::set &analysisDependencies, std::set &analysisInvalidations) const override; + void *getPassID() const override { return &ID; } - BuildCFG() : OptimizationPass("BuildCFG", Pass::Granularity::Function, Pass::PassKind::Optimization) {} - - // 重载 runOnFunction 方法,实现具体的优化逻辑 - bool runOnFunction(Function *F, AnalysisManager& AM) override; - - // 提供PassID - void *getPassID() const override { return &ID; } - - // 声明Pass的分析使用 - // BuildCFG不依赖任何分析,但会使其他依赖CFG的分析失效 - void getAnalysisUsage(std::set &analysisDependencies, - std::set &analysisInvalidations) override; }; } // namespace sysy \ No newline at end of file diff --git a/src/midend/CMakeLists.txt b/src/midend/CMakeLists.txt index 3532818..f944a3c 100644 --- a/src/midend/CMakeLists.txt +++ b/src/midend/CMakeLists.txt @@ -11,6 +11,7 @@ add_library(midend_lib STATIC Pass/Optimize/Reg2Mem.cpp Pass/Optimize/SysYIRCFGOpt.cpp Pass/Optimize/SCCP.cpp + Pass/Optimize/BuildCFG.cpp ) # 包含中端模块所需的头文件路径 diff --git a/src/midend/Pass/Optimize/BuildCFG.cpp b/src/midend/Pass/Optimize/BuildCFG.cpp index 823d126..07cdd4e 100644 --- a/src/midend/Pass/Optimize/BuildCFG.cpp +++ b/src/midend/Pass/Optimize/BuildCFG.cpp @@ -1,121 +1,79 @@ #include "BuildCFG.h" -#include "Instruction.h" -#include "IR.h" -#include "Liveness.h" // 包含活跃性分析的头文件以引用其ID -#include "Dom.h" // 包含支配树分析的头文件以引用其ID +#include "Dom.h" +#include "Liveness.h" #include #include #include namespace sysy { -char BuildCFG::ID = 0; +void *BuildCFG::ID = (void *)&BuildCFG::ID; // 定义唯一的 Pass ID // 声明Pass的分析使用 -void BuildCFG::getAnalysisUsage(std::set &analysisDependencies, - std::set &analysisInvalidations) { - // BuildCFG不依赖其他分析 - // analysisDependencies.insert(&DominatorTreeAnalysisPass::ID); // 错误的例子 +void BuildCFG::getAnalysisUsage(std::set &analysisDependencies, std::set &analysisInvalidations) const { + // BuildCFG不依赖其他分析 + // analysisDependencies.insert(&DominatorTreeAnalysisPass::ID); // 错误的例子 - // BuildCFG会使所有依赖于CFG的分析结果失效,所以它必须声明这些失效 - analysisInvalidations.insert(&DominatorTreeAnalysisPass::ID); - analysisInvalidations.insert(&LivenessAnalysisPass::ID); + // BuildCFG会使所有依赖于CFG的分析结果失效,所以它必须声明这些失效 + analysisInvalidations.insert(&DominatorTreeAnalysisPass::ID); + analysisInvalidations.insert(&LivenessAnalysisPass::ID); } -bool BuildCFG::runOnFunction(Function *F, AnalysisManager& AM) { - if (DEBUG) { - std::cout << "Running BuildCFG pass on function: " << F->getName() << std::endl; +bool BuildCFG::runOnFunction(Function *F, AnalysisManager &AM) { + if (DEBUG) { + std::cout << "Running BuildCFG pass on function: " << F->getName() << std::endl; + } + + bool changed = false; + + // 1. 清空所有基本块的前驱和后继列表 + for (auto &bb : F->getBasicBlocks()) { + bb->clearPredecessors(); + bb->clearSuccessors(); + } + + // 2. 遍历每个基本块,重建CFG + for (auto &bb : F->getBasicBlocks()) { + // 获取基本块的最后一条指令 + auto &inst = *bb->terminator(); + Instruction *termInst = inst.get(); + // 确保基本块有终结指令 + if (!termInst) { + continue; } - bool changed = false; + // 根据终结指令类型,建立前驱后继关系 + if (termInst->isBranch()) { + // 无条件跳转 + if (termInst->isUnconditional()) { + auto brInst = dynamic_cast(termInst); + BasicBlock *succ = dynamic_cast(brInst->getBlock()); + assert(succ && "Branch instruction's target must be a BasicBlock"); + bb->addSuccessor(succ); + succ->addPredecessor(bb.get()); + changed = true; - // 1. 清空所有基本块的前驱和后继列表 - for (auto &bb : *F) { - bb->predecessors.clear(); - bb->successors.clear(); + // 条件跳转 + } else if (termInst->isConditional()) { + auto brInst = dynamic_cast(termInst); + BasicBlock *trueSucc = dynamic_cast(brInst->getThenBlock()); + BasicBlock *falseSucc = dynamic_cast(brInst->getElseBlock()); + + assert(trueSucc && falseSucc && "Branch instruction's targets must be BasicBlocks"); + + bb->addSuccessor(trueSucc); + trueSucc->addPredecessor(bb.get()); + bb->addSuccessor(falseSucc); + falseSucc->addPredecessor(bb.get()); + changed = true; + } + } else if (auto retInst = dynamic_cast(termInst)) { + // RetInst没有后继,无需处理 + // ... } + } - // 2. 遍历每个基本块,重建CFG - for (auto &bb : *F) { - // 获取基本块的最后一条指令 - Instruction *termInst = bb->getTerminator(); - - // 确保基本块有终结指令 - if (!termInst) { - continue; - } - - // 根据终结指令类型,建立前驱后继关系 - if (auto brInst = dynamic_cast(termInst)) { - // 无条件跳转 - if (brInst->getNumOperands() == 1) { - BasicBlock *succ = dynamic_cast(brInst->getOperand(0)); - assert(succ && "Branch instruction's target must be a BasicBlock"); - - bb->successors.push_back(succ); - succ->predecessors.push_back(bb.get()); - changed = true; - - // 条件跳转 - } else if (brInst->getNumOperands() == 3) { - BasicBlock *trueSucc = dynamic_cast(brInst->getOperand(1)); - BasicBlock *falseSucc = dynamic_cast(brInst->getOperand(2)); - - assert(trueSucc && falseSucc && "Branch instruction's targets must be BasicBlocks"); - - bb->successors.push_back(trueSucc); - trueSucc->predecessors.push_back(bb.get()); - - bb->successors.push_back(falseSucc); - falseSucc->predecessors.push_back(bb.get()); - changed = true; - } - } else if (auto retInst = dynamic_cast(termInst)) { - // RetInst没有后继,无需处理 - // ... - } - } - - // 3. 额外处理:可达性分析,标记不可达基本块 - std::queue q; - std::set visited; - - // 默认所有块不可达 - for (auto &bb : *F) { - bb->setreachableFalse(); - } - - // 从函数入口基本块开始 - BasicBlock* entryBB = F->getEntryBlock(); - if (entryBB) { - q.push(entryBB); - visited.insert(entryBB); - entryBB->setreachableTrue(); - } - - // 广度优先搜索 (BFS) 遍历所有可达的基本块 - while (!q.empty()) { - BasicBlock* currentBB = q.front(); - q.pop(); - - for (auto& succ : currentBB->successors) { - if (visited.find(succ) == visited.end()) { - q.push(succ); - visited.insert(succ); - succ->setreachableTrue(); - } - } - } - - // 将未访问到的基本块标记为不可达 - for (auto& bb : *F) { - if (visited.find(bb.get()) == visited.end()) { - bb->setreachableFalse(); - changed = true; // 发现不可达块,视为改变 - } - } - - return changed; + return changed; } } // namespace sysy \ No newline at end of file diff --git a/src/midend/Pass/Pass.cpp b/src/midend/Pass/Pass.cpp index c293853..c2c8371 100644 --- a/src/midend/Pass/Pass.cpp +++ b/src/midend/Pass/Pass.cpp @@ -36,11 +36,12 @@ void PassManager::runOptimizationPipeline(Module* moduleIR, IRBuilder* builderIR 3. 添加优化passid */ // 注册分析遍 - registerAnalysisPass(); - registerAnalysisPass(); + registerAnalysisPass(); + registerAnalysisPass(); // 注册优化遍 - registerOptimizationPass(builderIR); + registerOptimizationPass(); + registerOptimizationPass(); registerOptimizationPass(); registerOptimizationPass(); @@ -66,7 +67,7 @@ void PassManager::runOptimizationPipeline(Module* moduleIR, IRBuilder* builderIR } this->clearPasses(); - this->addPass(&&BuildCFG::ID); + this->addPass(&BuildCFG::ID); this->run(); this->clearPasses();