diff --git a/src/include/midend/IR.h b/src/include/midend/IR.h index adde8cf..da9fad1 100644 --- a/src/include/midend/IR.h +++ b/src/include/midend/IR.h @@ -1375,6 +1375,17 @@ protected: auto is_same_ptr = [blockToRemove](const std::unique_ptr &ptr) { return ptr.get() == blockToRemove; }; blocks.remove_if(is_same_ptr); } + BasicBlock* addBasicBlock(const std::string &name, BasicBlock *before) { + // 在指定的基本块之前添加一个新的基本块 + auto it = std::find_if(blocks.begin(), blocks.end(), + [before](const std::unique_ptr &ptr) { return ptr.get() == before; }); + if (it != blocks.end()) { + blocks.emplace(it, new BasicBlock(this, name)); + return it->get(); // 返回新添加的基本块指针 + } + assert(false && "BasicBlock to insert before not found!"); + return nullptr; // 如果没有找到指定的基本块,则返回nullptr + } ///< 添加一个新的基本块到某个基本块之前 BasicBlock* addBasicBlock(const std::string &name = "") { blocks.emplace_back(new BasicBlock(this, name)); return blocks.back().get(); diff --git a/src/include/midend/Pass/Analysis/Loop.h b/src/include/midend/Pass/Analysis/Loop.h index 7df8132..2a003f9 100644 --- a/src/include/midend/Pass/Analysis/Loop.h +++ b/src/include/midend/Pass/Analysis/Loop.h @@ -19,13 +19,18 @@ class LoopAnalysisResult; * @brief 表示一个识别出的循环。 */ class Loop { +private: + static int NextLoopID; // 静态变量用于分配唯一ID + int LoopID; public: // 构造函数:指定循环头 - Loop(BasicBlock *header) : Header(header) {} + Loop(BasicBlock *header) : Header(header), LoopID(NextLoopID++) {} // 获取循环头 BasicBlock *getHeader() const { return Header; } + // 获取循环的名称 (基于ID) + std::string getName() const { return "loop_" + std::to_string(LoopID); } // 获取循环体包含的所有基本块 const std::set &getBlocks() const { return LoopBlocks; } @@ -50,8 +55,42 @@ public: // 判断当前循环是否是最内层循环 (没有嵌套子循环) bool isInnermost() const { return NestedLoops.empty(); } - // 判断当前循环是否是最外层循环 (没有父循环) - bool isOutermost() const { return ParentLoop == nullptr; } + // 获取循环的深度(从最外层开始计算) + int getLoopDepth() const { return Level + 1; } + + // 获取循环体的大小(基本块数量) + size_t getLoopSize() const { return LoopBlocks.size(); } + + // 检查循环是否有唯一的外部前驱(即是否有前置块) + bool hasUniquePreHeader() const { return PreHeader != nullptr; } + + // 检查循环是否是最外层循环(没有父循环) + bool isOutermost() const { return getParentLoop() == nullptr; } + + // 获取循环的所有出口(从循环内到循环外的基本块) + std::vector getExitingBlocks() const { + std::vector exitingBlocks; + for (BasicBlock* bb : LoopBlocks) { + for (BasicBlock* succ : bb->getSuccessors()) { + if (!contains(succ)) { + exitingBlocks.push_back(bb); + break; // 每个基本块只添加一次 + } + } + } + return exitingBlocks; + } + + // 判断循环是否是简单循环(只有一个回边) + bool isSimpleLoop() const { + int backEdgeCount = 0; + for (BasicBlock* pred : Header->getPredecessors()) { + if (contains(pred)) { + backEdgeCount++; + } + } + return backEdgeCount == 1; + } // --- 供 LoopAnalysisPass 内部调用的方法,用于构建 Loop 对象 --- void addBlock(BasicBlock *BB) { LoopBlocks.insert(BB); } @@ -93,9 +132,36 @@ public: // 获取所有最外层循环 const std::vector &getOutermostLoops() const { return OutermostLoops; } - // 获取所有最内层循环 const std::vector &getInnermostLoops() const { return InnermostLoops; } + // 获取循环总数 + size_t getLoopCount() const { return AllLoops.size(); } + + // 获取最大循环嵌套深度 + int getMaxLoopDepth() const { + int maxDepth = 0; + for (const auto& loop : AllLoops) { + if (loop->getLoopDepth() > maxDepth) { + maxDepth = loop->getLoopDepth(); + } + } + return maxDepth; + } + + // 获取指定深度的循环数量 + size_t getLoopCountAtDepth(int depth) const { + size_t count = 0; + for (const auto& loop : AllLoops) { + if (loop->getLoopDepth() == depth) { + count++; + } + } + return count; + } + + // 检查函数是否包含循环 + bool hasLoops() const { return !AllLoops.empty(); } + // 通过循环头获取 Loop 对象 Loop *getLoopForHeader(BasicBlock *header) const { auto it = LoopMap.find(header); @@ -122,6 +188,11 @@ public: void clearOutermostLoops() { OutermostLoops.clear(); } void clearInnermostLoops() { InnermostLoops.clear(); } + // 打印分析结果 + void print() const; + void printBBSet(const std::string &prefix, const std::set &s) const; + void printLoopVector(const std::string &prefix, const std::vector &loops) const; + private: Function *AssociatedFunction; // 结果关联的函数 std::vector> AllLoops; // 所有识别出的循环 diff --git a/src/midend/CMakeLists.txt b/src/midend/CMakeLists.txt index 3532818..03421be 100644 --- a/src/midend/CMakeLists.txt +++ b/src/midend/CMakeLists.txt @@ -6,6 +6,7 @@ add_library(midend_lib STATIC Pass/Pass.cpp Pass/Analysis/Dom.cpp Pass/Analysis/Liveness.cpp + Pass/Analysis/Loop.cpp Pass/Optimize/DCE.cpp Pass/Optimize/Mem2Reg.cpp Pass/Optimize/Reg2Mem.cpp diff --git a/src/midend/Pass/Analysis/Loop.cpp b/src/midend/Pass/Analysis/Loop.cpp index 653db14..1f3d08a 100644 --- a/src/midend/Pass/Analysis/Loop.cpp +++ b/src/midend/Pass/Analysis/Loop.cpp @@ -1,14 +1,110 @@ -// Loop.cpp (完整内容,包含所有修改) #include "Dom.h" // 确保包含 DominatorTreeAnalysisPass 的定义 #include "Loop.h" // #include #include // 用于 BFS 遍历设置循环层级 +// 调试模式开关 +#ifndef DEBUG +#define DEBUG 0 +#endif + namespace sysy { // 定义 Pass 的唯一 ID void *LoopAnalysisPass::ID = (void *)&LoopAnalysisPass::ID; +// 定义 Loop 类的静态变量 +int Loop::NextLoopID = 0; +// **实现 LoopAnalysisResult::print() 方法** + + +void LoopAnalysisResult::printBBSet(const std::string &prefix, const std::set &s) const{ + if (!DEBUG) return; + std::cout << prefix << "{"; + bool first = true; + for (const auto &bb : s) { + if (!first) std::cout << ", "; + std::cout << bb->getName(); + first = false; + } + std::cout << "}"; +} + +// **辅助函数:打印 Loop 指针向量** +void LoopAnalysisResult::printLoopVector(const std::string &prefix, const std::vector &loops) const { + if (!DEBUG) return; + std::cout << prefix << "["; + bool first = true; + for (const auto &loop : loops) { + if (!first) std::cout << ", "; + std::cout << loop->getName(); // 假设 Loop::getName() 存在 + first = false; + } + std::cout << "]"; +} + +void LoopAnalysisResult::print() const { + if (!DEBUG) return; // 只有在 DEBUG 模式下才打印 + + std::cout << "\n--- Loop Analysis Results for Function: " << AssociatedFunction->getName() << " ---" << std::endl; + + if (AllLoops.empty()) { + std::cout << " No loops found." << std::endl; + return; + } + + std::cout << "Total Loops Found: " << AllLoops.size() << std::endl; + + // 1. 按层级分组循环 + std::map> loopsByLevel; + int maxLevel = 0; + for (const auto& loop_ptr : AllLoops) { + if (loop_ptr->getLoopLevel() != -1) { // 确保层级已计算 + loopsByLevel[loop_ptr->getLoopLevel()].push_back(loop_ptr.get()); + if (loop_ptr->getLoopLevel() > maxLevel) { + maxLevel = loop_ptr->getLoopLevel(); + } + } + } + + // 2. 打印循环层次结构 + std::cout << "\n--- Loop Hierarchy ---" << std::endl; + for (int level = 0; level <= maxLevel; ++level) { + if (loopsByLevel.count(level)) { + std::cout << "Level " << level << " Loops:" << std::endl; + for (Loop* loop : loopsByLevel[level]) { + std::string indent(level * 2, ' '); // 根据层级缩进 + std::cout << indent << "- Loop Header: " << loop->getName() << std::endl; + std::cout << indent << " Blocks: "; + printBBSet("", loop->getBlocks()); + std::cout << std::endl; + + std::cout << indent << " Exit Blocks: "; + printBBSet("", loop->getExitBlocks()); + std::cout << std::endl; + + std::cout << indent << " Pre-Header: " << (loop->getPreHeader() ? loop->getPreHeader()->getName() : "None") << std::endl; + std::cout << indent << " Parent Loop: " << (loop->getParentLoop() ? loop->getParentLoop()->getName() : "None (Outermost)") << std::endl; + std::cout << indent << " Nested Loops: "; + printLoopVector("", loop->getNestedLoops()); + std::cout << std::endl; + } + } + } + + // 3. 打印最外层/最内层循环摘要 + std::cout << "\n--- Loop Summary ---" << std::endl; + std::cout << "Outermost Loops: "; + printLoopVector("", getOutermostLoops()); + std::cout << std::endl; + + std::cout << "Innermost Loops: "; + printLoopVector("", getInnermostLoops()); + std::cout << std::endl; + + std::cout << "-----------------------------------------------" << std::endl; +} + bool LoopAnalysisPass::runOnFunction(Function *F, AnalysisManager &AM) { if (F->getBasicBlocks().empty()) { CurrentResult = std::make_unique(F); @@ -35,42 +131,54 @@ bool LoopAnalysisPass::runOnFunction(Function *F, AnalysisManager &AM) { // 回边 (N -> D) 定义:D 支配 N std::vector> backEdges; for (auto &BB : F->getBasicBlocks()) { - auto Blcok = BB.get(); - for (BasicBlock *Succ : Blcok->getSuccessors()) { - if (DT->getDominators(Blcok) && DT->getDominators(Blcok)->count(Succ)) { - // Succ 支配 BB,所以 (BB -> Succ) 是一条回边 - backEdges.push_back({Blcok, Succ}); + auto Block = BB.get(); + for (BasicBlock *Succ : Block->getSuccessors()) { + if (DT->getDominators(Block) && DT->getDominators(Block)->count(Succ)) { + // Succ 支配 Block,所以 (Block -> Succ) 是一条回边 + backEdges.push_back({Block, Succ}); + if (DEBUG) + std::cout << "Found back edge: " << Block->getName() << " -> " << Succ->getName() << std::endl; } } } + + if (DEBUG) + std::cout << "Total back edges found: " << backEdges.size() << std::endl; // 步骤 2: 为每条回边构建自然循环 + std::map> loopMap; // 按循环头分组 + for (auto &edge : backEdges) { BasicBlock *N = edge.first; // 回边的尾部 BasicBlock *D = edge.second; // 回边的头部 (循环头) - // 创建新的 Loop 对象 - std::unique_ptr currentLoop = std::make_unique(D); + // 检查是否已经为此循环头创建了循环 + if (loopMap.find(D) == loopMap.end()) { + // 创建新的 Loop 对象 + loopMap[D] = std::make_unique(D); + } + + Loop* currentLoop = loopMap[D].get(); - // 收集循环体块:从 N 逆向遍历到 D (不包括中间的 D) + // 收集此回边对应的循环体块:从 N 逆向遍历到 D std::set loopBlocks; // 临时存储循环块 std::queue q; - q.push(N); - loopBlocks.insert(N); // 回边的尾部首先是循环块 + // 循环头总是循环体的一部分 + loopBlocks.insert(D); + + // 如果回边的尾部不是循环头本身,则将其加入队列进行遍历 + if (N != D) { + q.push(N); + loopBlocks.insert(N); + } while (!q.empty()) { BasicBlock *current = q.front(); q.pop(); for (BasicBlock *pred : current->getPredecessors()) { - if (pred == D) { - // 找到循环头,将其加入循环块集合,但不继续逆向遍历它的前驱, - // 因为我们是从 N 到 D 的路径,D 已经是终点。 - loopBlocks.insert(D); - continue; - } - // 如果是 D 自身,并且它已经在循环块集合中,也不再处理 + // 如果前驱还没有被访问过,则将其加入循环体并继续遍历 if (loopBlocks.find(pred) == loopBlocks.end()) { loopBlocks.insert(pred); q.push(pred); @@ -78,10 +186,15 @@ bool LoopAnalysisPass::runOnFunction(Function *F, AnalysisManager &AM) { } } - // 将收集到的块添加到 Loop 对象中 + // 将收集到的块添加到 Loop 对象中(合并所有回边的结果) for (BasicBlock *loopBB : loopBlocks) { currentLoop->addBlock(loopBB); } + } + + // 处理每个合并后的循环 + for (auto &[header, currentLoop] : loopMap) { + const auto &loopBlocks = currentLoop->getBlocks(); // 步骤 3: 识别循环出口块 (Exit Blocks) for (BasicBlock *loopBB : loopBlocks) { @@ -93,10 +206,10 @@ bool LoopAnalysisPass::runOnFunction(Function *F, AnalysisManager &AM) { } } - // 步骤 4: 识别循环前置块 (Pre-Header) - 您的前端已做很多工作,这里是确认和规范化 + // 步骤 4: 识别循环前置块 (Pre-Header) BasicBlock *candidatePreHeader = nullptr; int externalPredecessorCount = 0; - for (BasicBlock *predOfHeader : D->getPredecessors()) { + for (BasicBlock *predOfHeader : header->getPredecessors()) { // 使用 currentLoop->contains() 来检查前驱是否在循环体内 if (!currentLoop->contains(predOfHeader)) { // 如果前驱不在循环体内,则是一个外部前驱 @@ -107,14 +220,7 @@ bool LoopAnalysisPass::runOnFunction(Function *F, AnalysisManager &AM) { if (externalPredecessorCount == 1) { currentLoop->setPreHeader(candidatePreHeader); - } else { - assert(externalPredecessorCount == 0 || externalPredecessorCount > 1 && - "Loop header should have exactly one external predecessor or none."); - // TODO: 如果有多个外部前驱或没有,这里应该插入新的基本块作为前置块, - // 并调整控制流。这会修改 IR,需要返回 true。 - // 目前,我们只是简单地不设置 preHeader。 } - CurrentResult->addLoop(std::move(currentLoop)); } diff --git a/src/midend/Pass/Pass.cpp b/src/midend/Pass/Pass.cpp index f4ec5ab..bd10887 100644 --- a/src/midend/Pass/Pass.cpp +++ b/src/midend/Pass/Pass.cpp @@ -1,5 +1,6 @@ #include "Dom.h" #include "Liveness.h" +#include "Loop.h" #include "SysYIRCFGOpt.h" #include "SysYIRPrinter.h" #include "DCE.h" @@ -37,6 +38,7 @@ void PassManager::runOptimizationPipeline(Module* moduleIR, IRBuilder* builderIR // 注册分析遍 registerAnalysisPass(); registerAnalysisPass(); + registerAnalysisPass(); // 注册优化遍 registerOptimizationPass();