[midend]合并了SCCP和backend,修复了支配树的错误求解,修复了Mem2Reg的重命名alloca的栈管理

This commit is contained in:
rain2133
2025-08-01 15:18:33 +08:00
parent 999f2c6615
commit a0b69f20fb
3 changed files with 232 additions and 105 deletions

View File

@@ -1,5 +1,7 @@
#include "Dom.h"
#include <limits> // for std::numeric_limits
#include <algorithm> // for std::set_intersection, std::set_difference, std::set_union
#include <iostream> // for debug output
#include <limits> // for std::numeric_limits
#include <queue>
namespace sysy {
@@ -38,45 +40,80 @@ const std::set<BasicBlock *> *DominatorTree::getDominanceFrontier(BasicBlock *BB
return nullptr;
}
const std::set<BasicBlock*>* DominatorTree::getDominatorTreeChildren(BasicBlock* BB) const {
auto it = DominatorTreeChildren.find(BB);
if (it != DominatorTreeChildren.end()) {
return &(it->second);
}
return nullptr;
const std::set<BasicBlock *> *DominatorTree::getDominatorTreeChildren(BasicBlock *BB) const {
auto it = DominatorTreeChildren.find(BB);
if (it != DominatorTreeChildren.end()) {
return &(it->second);
}
return nullptr;
}
// 辅助函数:打印 BasicBlock 集合
void printBBSet(const std::string &prefix, const std::set<BasicBlock *> &s) {
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 << "}" << std::endl;
}
void DominatorTree::computeDominators(Function *F) {
// 经典的迭代算法计算支配者集合
// TODO: 可以替换为更高效的算法,如 Lengauer-Tarjan 算法
BasicBlock *entryBlock = F->getEntryBlock();
if (DEBUG)
std::cout << "--- Computing Dominators ---" << std::endl;
BasicBlock *entryBlock = F->getEntryBlock();
std::vector<BasicBlock *> bbs_in_order; // 用于确定遍历顺序,如果需要的话
// 初始化:入口块只被自己支配,其他块被所有块支配
for (const auto &bb_ptr : F->getBasicBlocks()) {
BasicBlock *bb = bb_ptr.get();
bbs_in_order.push_back(bb); // 收集所有块
if (bb == entryBlock) {
Dominators[bb].insert(bb);
if (DEBUG)
std::cout << "Init Dominators[" << bb->getName() << "]: {" << bb->getName() << "}" << std::endl;
} else {
for (const auto &all_bb_ptr : F->getBasicBlocks()) {
Dominators[bb].insert(all_bb_ptr.get());
}
if (DEBUG) {
std::cout << "Init Dominators[" << bb->getName() << "]: ";
printBBSet("", Dominators[bb]);
}
}
}
bool changed = true;
int iteration = 0;
while (changed) {
changed = false;
for (const auto &bb_ptr : F->getBasicBlocks()) {
iteration++;
if (DEBUG)
std::cout << "Iteration " << iteration << std::endl;
// 确保遍历顺序一致性例如可以按照DFS或BFS顺序或者简单的迭代器顺序
// 如果Function::getBasicBlocks()返回的迭代器顺序稳定则无需bbs_in_order
for (const auto &bb_ptr : F->getBasicBlocks()) { // 假设这个迭代器顺序稳定
BasicBlock *bb = bb_ptr.get();
if (bb == entryBlock)
continue;
// 计算所有前驱的支配者集合的交集
std::set<BasicBlock *> newDom;
bool firstPred = true;
bool firstPredProcessed = false;
for (BasicBlock *pred : bb->getPredecessors()) {
// 确保前驱的支配者集合已经计算过
if (Dominators.count(pred)) {
if (firstPred) {
if (!firstPredProcessed) {
newDom = Dominators[pred];
firstPred = false;
firstPredProcessed = true;
} else {
std::set<BasicBlock *> intersection;
std::set_intersection(newDom.begin(), newDom.end(), Dominators[pred].begin(), Dominators[pred].end(),
@@ -85,21 +122,32 @@ void DominatorTree::computeDominators(Function *F) {
}
}
}
newDom.insert(bb);
newDom.insert(bb); // BB 永远支配自己
if (newDom != Dominators[bb]) {
if (DEBUG) {
std::cout << " Dominators[" << bb->getName() << "] changed from ";
printBBSet("", Dominators[bb]);
std::cout << " to ";
printBBSet("", newDom);
}
Dominators[bb] = newDom;
changed = true;
}
}
}
if (DEBUG)
std::cout << "--- Dominators Computation Finished ---" << std::endl;
}
void DominatorTree::computeIDoms(Function *F) {
// 采用与之前类似的简化实现。TODO:Lengauer-Tarjan等算法。
BasicBlock *entryBlock = F->getEntryBlock();
IDoms[entryBlock] = nullptr;
if (DEBUG)
std::cout << "--- Computing Immediate Dominators (IDoms) ---" << std::endl;
BasicBlock *entryBlock = F->getEntryBlock();
IDoms[entryBlock] = nullptr; // 入口块没有即时支配者
// 遍历所有非入口块
for (const auto &bb_ptr : F->getBasicBlocks()) {
BasicBlock *bb = bb_ptr.get();
if (bb == entryBlock)
@@ -107,91 +155,138 @@ void DominatorTree::computeIDoms(Function *F) {
BasicBlock *currentIDom = nullptr;
const std::set<BasicBlock *> *domsOfBB = getDominators(bb);
if (!domsOfBB)
if (!domsOfBB) {
if (DEBUG)
std::cerr << "Warning: Dominators for " << bb->getName() << " not found!" << std::endl;
continue;
}
for (BasicBlock *D : *domsOfBB) {
if (D == bb)
continue;
// 遍历bb的所有严格支配者 D (即 bb 的支配者中除了 bb 自身)
for (BasicBlock *D_candidate : *domsOfBB) {
if (D_candidate == bb)
continue; // 跳过bb自身
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;
bool D_candidate_is_IDom = true;
// 检查是否存在另一个块 X使得 D_candidate 严格支配 X 且 X 严格支配 bb
// 或者更直接的,检查 D_candidate 是否被 bb 的所有其他严格支配者所支配
for (BasicBlock *X_other_dom : *domsOfBB) {
if (X_other_dom == bb || X_other_dom == D_candidate)
continue; // 跳过bb自身和D_candidate
// 如果 X_other_dom 严格支配 bb (它在 domsOfBB 中且不是bb自身)
// 并且 X_other_dom 不被 D_candidate 支配,那么 D_candidate 就不是 IDom
const std::set<BasicBlock *> *domsOfX_other_dom = getDominators(X_other_dom);
if (domsOfX_other_dom && domsOfX_other_dom->count(D_candidate)) { // X_other_dom 支配 D_candidate
// D_candidate 被另一个支配者 X_other_dom 支配
// 这说明 D_candidate 位于 X_other_dom 的“下方”X_other_dom 更接近 bb
// 因此 D_candidate 不是 IDom
D_candidate_is_IDom = false;
break;
}
}
if (isCandidateIDom) {
currentIDom = D;
break;
if (D_candidate_is_IDom) {
currentIDom = D_candidate;
break; // 找到即时支配者,可以退出循环,因为它是唯一的
}
}
IDoms[bb] = currentIDom;
if (DEBUG) {
std::cout << " IDom[" << bb->getName() << "] = " << (currentIDom ? currentIDom->getName() : "nullptr")
<< std::endl;
}
}
if (DEBUG)
std::cout << "--- Immediate Dominators Computation Finished ---" << std::endl;
}
/*
for each node n in a postorder traversal of the dominator tree:
df[n] = empty set
// compute DF_local(n)
for each child y of n in the CFG:
if idom[y] != n:
df[n] = df[n] U {y}
// compute DF_up(n)
for each child c of n in the dominator tree:
for each element w in df[c]:
if idom[w] != n:
df[n] = df[n] U {w}
*/
void DominatorTree::computeDominanceFrontiers(Function *F) {
// 经典的支配边界计算算法
if (DEBUG)
std::cout << "--- Computing Dominance Frontiers ---" << std::endl;
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;
// 遍历所有可能的 Z (X支配Z或者Z就是X)
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);
}
// 如果 X 不支配 Z则 Z 与 DF(X) 无关
if (!domsOfZ || domsOfZ->find(X) == domsOfZ->end()) {
continue;
}
// 遍历 Z 的所有后继 Y
for (BasicBlock *Y : Z->getSuccessors()) {
// 如果 Y 不被 X 严格支配,则 Y 在 DF(X) 中
// Y 不被 X 严格支配意味着 (Y不被X支配) 或 (Y就是X)
const std::set<BasicBlock *> *domsOfY = getDominators(Y);
if (Y == X || (domsOfY && domsOfY->find(X) == domsOfY->end())) {
DominanceFrontiers[X].insert(Y);
}
}
}
if (DEBUG) {
std::cout << " DF(" << X->getName() << "): ";
printBBSet("", DominanceFrontiers[X]);
}
}
if (DEBUG)
std::cout << "--- Dominance Frontiers Computation Finished ---" << std::endl;
}
void DominatorTree::computeDominatorTreeChildren(Function *F) {
if (DEBUG)
std::cout << "--- Computing Dominator Tree Children ---" << std::endl;
// 首先清空,确保重新计算时是空的
for (auto &bb_ptr : F->getBasicBlocks()) {
DominatorTreeChildren[bb_ptr.get()].clear();
}
for (auto &bb_ptr : F->getBasicBlocks()) {
BasicBlock *B = bb_ptr.get();
auto it = getImmediateDominator(B);
if (it != nullptr) {
BasicBlock *A = it;
if (A) {
DominatorTreeChildren[A].insert(B);
BasicBlock *A = getImmediateDominator(B); // A 是 B 的即时支配者
if (A) { // 如果 B 有即时支配者 A (即 B 不是入口块)
DominatorTreeChildren[A].insert(B);
if (DEBUG) {
std::cout << " " << B->getName() << " is child of " << A->getName() << std::endl;
}
}
}
if (DEBUG)
std::cout << "--- Dominator Tree Children Computation Finished ---" << std::endl;
}
// ==============================================================
// DominatorTreeAnalysisPass 的实现
// ==============================================================
bool DominatorTreeAnalysisPass::runOnFunction(Function* F, AnalysisManager &AM) {
bool DominatorTreeAnalysisPass::runOnFunction(Function *F, AnalysisManager &AM) {
// 每次运行时清空旧数据,确保重新计算
CurrentDominatorTree = std::make_unique<DominatorTree>(F);
// 不需要手动清空mapunique_ptr会创建新的DominatorTree对象其map是空的
CurrentDominatorTree->computeDominators(F);
CurrentDominatorTree->computeIDoms(F);
CurrentDominatorTree->computeIDoms(F); // 修正后的IDoms算法
CurrentDominatorTree->computeDominanceFrontiers(F);
CurrentDominatorTree->computeDominatorTreeChildren(F);
return false;
return false; // 分析遍通常返回 false表示不修改 IR
}
std::unique_ptr<AnalysisResultBase> DominatorTreeAnalysisPass::getResult() {