[midend]重构中端,建立遍管理器,注册器等,初步构建支配树分析遍,增加基本块方法

This commit is contained in:
rain2133
2025-07-21 15:19:38 +08:00
parent 88604c1f94
commit 550f4017be
5 changed files with 538 additions and 1 deletions

181
src/Dom.cpp Normal file
View File

@@ -0,0 +1,181 @@
#include "Dom.h"
#include <limits> // for std::numeric_limits
#include <queue>
namespace sysy {
// 初始化 支配树静态 ID
char DominatorTreeAnalysisPass::ID = 0;
// ==============================================================
// DominatorTree 结果类的实现
// ==============================================================
DominatorTree::DominatorTree(Function *F) : AssociatedFunction(F) {
// 构造时可以不计算,在分析遍运行里计算并填充
}
const std::set<BasicBlock *> *DominatorTree::getDominators(BasicBlock *BB) const {
auto it = Dominators.find(BB);
if (it != Dominators.end()) {
return &(it->second);
}
return nullptr;
}
BasicBlock *DominatorTree::getImmediateDominator(BasicBlock *BB) const {
auto it = IDoms.find(BB);
if (it != IDoms.end()) {
return it->second;
}
return nullptr;
}
const std::set<BasicBlock *> *DominatorTree::getDominanceFrontier(BasicBlock *BB) const {
auto it = DominanceFrontiers.find(BB);
if (it != DominanceFrontiers.end()) {
return &(it->second);
}
return nullptr;
}
void DominatorTree::computeDominators(Function *F) {
// 经典的迭代算法计算支配者集合
// TODO: 可以替换为更高效的算法,如 Lengauer-Tarjan 算法
BasicBlock *entryBlock = F->getEntryBlock();
for (const auto &bb_ptr : F->getBasicBlocks()) {
BasicBlock *bb = bb_ptr.get();
if (bb == entryBlock) {
Dominators[bb].insert(bb);
} else {
for (const auto &all_bb_ptr : F->getBasicBlocks()) {
Dominators[bb].insert(all_bb_ptr.get());
}
}
}
bool changed = true;
while (changed) {
changed = false;
for (const auto &bb_ptr : F->getBasicBlocks()) {
BasicBlock *bb = bb_ptr.get();
if (bb == entryBlock)
continue;
std::set<BasicBlock *> newDom;
bool firstPred = true;
for (BasicBlock *pred : bb->getPredecessors()) {
if (Dominators.count(pred)) {
if (firstPred) {
newDom = Dominators[pred];
firstPred = false;
} else {
std::set<BasicBlock *> intersection;
std::set_intersection(newDom.begin(), newDom.end(), Dominators[pred].begin(), Dominators[pred].end(),
std::inserter(intersection, intersection.begin()));
newDom = intersection;
}
}
}
newDom.insert(bb);
if (newDom != Dominators[bb]) {
Dominators[bb] = newDom;
changed = true;
}
}
}
}
void DominatorTree::computeIDoms(Function *F) {
// 采用与之前类似的简化实现。TODO:Lengauer-Tarjan等算法。
BasicBlock *entryBlock = F->getEntryBlock();
IDoms[entryBlock] = nullptr;
for (const auto &bb_ptr : F->getBasicBlocks()) {
BasicBlock *bb = bb_ptr.get();
if (bb == entryBlock)
continue;
BasicBlock *currentIDom = nullptr;
const std::set<BasicBlock *> *domsOfBB = getDominators(bb);
if (!domsOfBB)
continue;
for (BasicBlock *D : *domsOfBB) {
if (D == bb)
continue;
bool isCandidateIDom = true;
for (BasicBlock *candidate : *domsOfBB) {
if (candidate == bb || candidate == D)
continue;
const std::set<BasicBlock *> *domsOfCandidate = getDominators(candidate);
if (domsOfCandidate && domsOfCandidate->count(D) == 0 && domsOfBB->count(candidate)) {
isCandidateIDom = false;
break;
}
}
if (isCandidateIDom) {
currentIDom = D;
break;
}
}
IDoms[bb] = currentIDom;
}
}
void DominatorTree::computeDominanceFrontiers(Function *F) {
// 经典的支配边界计算算法
for (const auto &bb_ptr_X : F->getBasicBlocks()) {
BasicBlock *X = bb_ptr_X.get();
DominanceFrontiers[X].clear();
for (BasicBlock *Y : X->getSuccessors()) {
const std::set<BasicBlock *> *domsOfY = getDominators(Y);
if (domsOfY && domsOfY->find(X) == domsOfY->end()) {
DominanceFrontiers[X].insert(Y);
}
}
const std::set<BasicBlock *> *domsOfX = getDominators(X);
if (!domsOfX)
continue;
for (const auto &bb_ptr_Z : F->getBasicBlocks()) {
BasicBlock *Z = bb_ptr_Z.get();
if (Z == X)
continue;
const std::set<BasicBlock *> *domsOfZ = getDominators(Z);
if (domsOfZ && domsOfZ->count(X) && Z != X) {
for (BasicBlock *Y : Z->getSuccessors()) {
const std::set<BasicBlock *> *domsOfY = getDominators(Y);
if (domsOfY && domsOfY->find(X) == domsOfY->end()) {
DominanceFrontiers[X].insert(Y);
}
}
}
}
}
}
// ==============================================================
// DominatorTreeAnalysisPass 的实现
// ==============================================================
bool DominatorTreeAnalysisPass::runOnFunction(Function* F) {
CurrentDominatorTree = std::make_unique<DominatorTree>(F);
CurrentDominatorTree->computeDominators(F);
CurrentDominatorTree->computeIDoms(F);
CurrentDominatorTree->computeDominanceFrontiers(F);
return false;
}
std::unique_ptr<AnalysisResultBase> DominatorTreeAnalysisPass::getResult() {
// 返回计算好的 DominatorTree 实例,所有权转移给 AnalysisManager
return std::move(CurrentDominatorTree);
}
} // namespace sysy