[midend-Loop]循环分析构建,增加很多统计方法和循环信息方法
This commit is contained in:
@ -1375,6 +1375,17 @@ protected:
|
||||
auto is_same_ptr = [blockToRemove](const std::unique_ptr<BasicBlock> &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<BasicBlock> &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();
|
||||
|
||||
@ -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<BasicBlock *> &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<BasicBlock*> getExitingBlocks() const {
|
||||
std::vector<BasicBlock*> 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<Loop *> &getOutermostLoops() const { return OutermostLoops; }
|
||||
|
||||
// 获取所有最内层循环
|
||||
const std::vector<Loop *> &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<BasicBlock *> &s) const;
|
||||
void printLoopVector(const std::string &prefix, const std::vector<Loop *> &loops) const;
|
||||
|
||||
private:
|
||||
Function *AssociatedFunction; // 结果关联的函数
|
||||
std::vector<std::unique_ptr<Loop>> AllLoops; // 所有识别出的循环
|
||||
|
||||
@ -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
|
||||
|
||||
@ -1,14 +1,110 @@
|
||||
// Loop.cpp (完整内容,包含所有修改)
|
||||
#include "Dom.h" // 确保包含 DominatorTreeAnalysisPass 的定义
|
||||
#include "Loop.h" //
|
||||
#include <iostream>
|
||||
#include <queue> // 用于 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<BasicBlock *> &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<Loop *> &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<int, std::vector<Loop*>> 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<LoopAnalysisResult>(F);
|
||||
@ -35,42 +131,54 @@ bool LoopAnalysisPass::runOnFunction(Function *F, AnalysisManager &AM) {
|
||||
// 回边 (N -> D) 定义:D 支配 N
|
||||
std::vector<std::pair<BasicBlock *, BasicBlock *>> 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<BasicBlock*, std::unique_ptr<Loop>> loopMap; // 按循环头分组
|
||||
|
||||
for (auto &edge : backEdges) {
|
||||
BasicBlock *N = edge.first; // 回边的尾部
|
||||
BasicBlock *D = edge.second; // 回边的头部 (循环头)
|
||||
|
||||
// 创建新的 Loop 对象
|
||||
std::unique_ptr<Loop> currentLoop = std::make_unique<Loop>(D);
|
||||
// 检查是否已经为此循环头创建了循环
|
||||
if (loopMap.find(D) == loopMap.end()) {
|
||||
// 创建新的 Loop 对象
|
||||
loopMap[D] = std::make_unique<Loop>(D);
|
||||
}
|
||||
|
||||
Loop* currentLoop = loopMap[D].get();
|
||||
|
||||
// 收集循环体块:从 N 逆向遍历到 D (不包括中间的 D)
|
||||
// 收集此回边对应的循环体块:从 N 逆向遍历到 D
|
||||
std::set<BasicBlock *> loopBlocks; // 临时存储循环块
|
||||
std::queue<BasicBlock *> 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));
|
||||
}
|
||||
|
||||
|
||||
@ -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<sysy::DominatorTreeAnalysisPass>();
|
||||
registerAnalysisPass<sysy::LivenessAnalysisPass>();
|
||||
registerAnalysisPass<LoopAnalysisPass>();
|
||||
|
||||
// 注册优化遍
|
||||
registerOptimizationPass<SysYDelInstAfterBrPass>();
|
||||
|
||||
Reference in New Issue
Block a user