#include "BuildCFG.h" #include "Dom.h" #include "Liveness.h" #include #include #include namespace sysy { void *BuildCFG::ID = (void *)&BuildCFG::ID; // 定义唯一的 Pass ID // 声明Pass的分析使用 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); } 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; } // 根据终结指令类型,建立前驱后继关系 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; // 条件跳转 } 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没有后继,无需处理 // ... } } return changed; } } // namespace sysy