[midend]合并了SCCP和backend,修复了支配树的错误求解,修复了Mem2Reg的重命名alloca的栈管理
This commit is contained in:
@@ -75,11 +75,7 @@ private:
|
|||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
|
|
||||||
// 对支配树进行深度优先遍历,重命名变量并替换 load/store 指令
|
// 对支配树进行深度优先遍历,重命名变量并替换 load/store 指令
|
||||||
// alloca: 当前正在处理的 AllocaInst
|
void renameVariables(BasicBlock* currentBB);
|
||||||
// currentBB: 当前正在遍历的基本块
|
|
||||||
// dt: 支配树分析结果
|
|
||||||
// valueStack: 存储当前 AllocaInst 在当前路径上可见的 SSA 值栈
|
|
||||||
void renameVariables(AllocaInst* alloca, BasicBlock* currentBB);
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
// 阶段4: 清理
|
// 阶段4: 清理
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
#include "Dom.h"
|
#include "Dom.h"
|
||||||
|
#include <algorithm> // for std::set_intersection, std::set_difference, std::set_union
|
||||||
|
#include <iostream> // for debug output
|
||||||
#include <limits> // for std::numeric_limits
|
#include <limits> // for std::numeric_limits
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
@@ -38,7 +40,7 @@ const std::set<BasicBlock *> *DominatorTree::getDominanceFrontier(BasicBlock *BB
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::set<BasicBlock*>* DominatorTree::getDominatorTreeChildren(BasicBlock* BB) const {
|
const std::set<BasicBlock *> *DominatorTree::getDominatorTreeChildren(BasicBlock *BB) const {
|
||||||
auto it = DominatorTreeChildren.find(BB);
|
auto it = DominatorTreeChildren.find(BB);
|
||||||
if (it != DominatorTreeChildren.end()) {
|
if (it != DominatorTreeChildren.end()) {
|
||||||
return &(it->second);
|
return &(it->second);
|
||||||
@@ -46,37 +48,72 @@ const std::set<BasicBlock*>* DominatorTree::getDominatorTreeChildren(BasicBlock*
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DominatorTree::computeDominators(Function *F) {
|
// 辅助函数:打印 BasicBlock 集合
|
||||||
// 经典的迭代算法计算支配者集合
|
void printBBSet(const std::string &prefix, const std::set<BasicBlock *> &s) {
|
||||||
// TODO: 可以替换为更高效的算法,如 Lengauer-Tarjan 算法
|
if (!DEBUG)
|
||||||
BasicBlock *entryBlock = F->getEntryBlock();
|
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) {
|
||||||
|
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()) {
|
for (const auto &bb_ptr : F->getBasicBlocks()) {
|
||||||
BasicBlock *bb = bb_ptr.get();
|
BasicBlock *bb = bb_ptr.get();
|
||||||
|
bbs_in_order.push_back(bb); // 收集所有块
|
||||||
if (bb == entryBlock) {
|
if (bb == entryBlock) {
|
||||||
Dominators[bb].insert(bb);
|
Dominators[bb].insert(bb);
|
||||||
|
if (DEBUG)
|
||||||
|
std::cout << "Init Dominators[" << bb->getName() << "]: {" << bb->getName() << "}" << std::endl;
|
||||||
} else {
|
} else {
|
||||||
for (const auto &all_bb_ptr : F->getBasicBlocks()) {
|
for (const auto &all_bb_ptr : F->getBasicBlocks()) {
|
||||||
Dominators[bb].insert(all_bb_ptr.get());
|
Dominators[bb].insert(all_bb_ptr.get());
|
||||||
}
|
}
|
||||||
|
if (DEBUG) {
|
||||||
|
std::cout << "Init Dominators[" << bb->getName() << "]: ";
|
||||||
|
printBBSet("", Dominators[bb]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool changed = true;
|
bool changed = true;
|
||||||
|
int iteration = 0;
|
||||||
while (changed) {
|
while (changed) {
|
||||||
changed = false;
|
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();
|
BasicBlock *bb = bb_ptr.get();
|
||||||
if (bb == entryBlock)
|
if (bb == entryBlock)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// 计算所有前驱的支配者集合的交集
|
||||||
std::set<BasicBlock *> newDom;
|
std::set<BasicBlock *> newDom;
|
||||||
bool firstPred = true;
|
bool firstPredProcessed = false;
|
||||||
|
|
||||||
for (BasicBlock *pred : bb->getPredecessors()) {
|
for (BasicBlock *pred : bb->getPredecessors()) {
|
||||||
|
// 确保前驱的支配者集合已经计算过
|
||||||
if (Dominators.count(pred)) {
|
if (Dominators.count(pred)) {
|
||||||
if (firstPred) {
|
if (!firstPredProcessed) {
|
||||||
newDom = Dominators[pred];
|
newDom = Dominators[pred];
|
||||||
firstPred = false;
|
firstPredProcessed = true;
|
||||||
} else {
|
} else {
|
||||||
std::set<BasicBlock *> intersection;
|
std::set<BasicBlock *> intersection;
|
||||||
std::set_intersection(newDom.begin(), newDom.end(), Dominators[pred].begin(), Dominators[pred].end(),
|
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 (newDom != Dominators[bb]) {
|
||||||
|
if (DEBUG) {
|
||||||
|
std::cout << " Dominators[" << bb->getName() << "] changed from ";
|
||||||
|
printBBSet("", Dominators[bb]);
|
||||||
|
std::cout << " to ";
|
||||||
|
printBBSet("", newDom);
|
||||||
|
}
|
||||||
Dominators[bb] = newDom;
|
Dominators[bb] = newDom;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (DEBUG)
|
||||||
|
std::cout << "--- Dominators Computation Finished ---" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DominatorTree::computeIDoms(Function *F) {
|
void DominatorTree::computeIDoms(Function *F) {
|
||||||
// 采用与之前类似的简化实现。TODO:Lengauer-Tarjan等算法。
|
if (DEBUG)
|
||||||
BasicBlock *entryBlock = F->getEntryBlock();
|
std::cout << "--- Computing Immediate Dominators (IDoms) ---" << std::endl;
|
||||||
IDoms[entryBlock] = nullptr;
|
|
||||||
|
|
||||||
|
BasicBlock *entryBlock = F->getEntryBlock();
|
||||||
|
IDoms[entryBlock] = nullptr; // 入口块没有即时支配者
|
||||||
|
|
||||||
|
// 遍历所有非入口块
|
||||||
for (const auto &bb_ptr : F->getBasicBlocks()) {
|
for (const auto &bb_ptr : F->getBasicBlocks()) {
|
||||||
BasicBlock *bb = bb_ptr.get();
|
BasicBlock *bb = bb_ptr.get();
|
||||||
if (bb == entryBlock)
|
if (bb == entryBlock)
|
||||||
@@ -107,91 +155,138 @@ void DominatorTree::computeIDoms(Function *F) {
|
|||||||
|
|
||||||
BasicBlock *currentIDom = nullptr;
|
BasicBlock *currentIDom = nullptr;
|
||||||
const std::set<BasicBlock *> *domsOfBB = getDominators(bb);
|
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;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for (BasicBlock *D : *domsOfBB) {
|
// 遍历bb的所有严格支配者 D (即 bb 的支配者中除了 bb 自身)
|
||||||
if (D == bb)
|
for (BasicBlock *D_candidate : *domsOfBB) {
|
||||||
continue;
|
if (D_candidate == bb)
|
||||||
|
continue; // 跳过bb自身
|
||||||
|
|
||||||
bool isCandidateIDom = true;
|
bool D_candidate_is_IDom = true;
|
||||||
for (BasicBlock *candidate : *domsOfBB) {
|
// 检查是否存在另一个块 X,使得 D_candidate 严格支配 X 且 X 严格支配 bb
|
||||||
if (candidate == bb || candidate == D)
|
// 或者更直接的,检查 D_candidate 是否被 bb 的所有其他严格支配者所支配
|
||||||
continue;
|
for (BasicBlock *X_other_dom : *domsOfBB) {
|
||||||
const std::set<BasicBlock *> *domsOfCandidate = getDominators(candidate);
|
if (X_other_dom == bb || X_other_dom == D_candidate)
|
||||||
if (domsOfCandidate && domsOfCandidate->count(D) == 0 && domsOfBB->count(candidate)) {
|
continue; // 跳过bb自身和D_candidate
|
||||||
isCandidateIDom = false;
|
|
||||||
|
// 如果 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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isCandidateIDom) {
|
if (D_candidate_is_IDom) {
|
||||||
currentIDom = D;
|
currentIDom = D_candidate;
|
||||||
break;
|
break; // 找到即时支配者,可以退出循环,因为它是唯一的
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IDoms[bb] = currentIDom;
|
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) {
|
void DominatorTree::computeDominanceFrontiers(Function *F) {
|
||||||
// 经典的支配边界计算算法
|
if (DEBUG)
|
||||||
|
std::cout << "--- Computing Dominance Frontiers ---" << std::endl;
|
||||||
|
|
||||||
for (const auto &bb_ptr_X : F->getBasicBlocks()) {
|
for (const auto &bb_ptr_X : F->getBasicBlocks()) {
|
||||||
BasicBlock *X = bb_ptr_X.get();
|
BasicBlock *X = bb_ptr_X.get();
|
||||||
DominanceFrontiers[X].clear();
|
DominanceFrontiers[X].clear();
|
||||||
|
|
||||||
for (BasicBlock *Y : X->getSuccessors()) {
|
// 遍历所有可能的 Z (X支配Z,或者Z就是X)
|
||||||
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()) {
|
for (const auto &bb_ptr_Z : F->getBasicBlocks()) {
|
||||||
BasicBlock *Z = bb_ptr_Z.get();
|
BasicBlock *Z = bb_ptr_Z.get();
|
||||||
if (Z == X)
|
|
||||||
continue;
|
|
||||||
const std::set<BasicBlock *> *domsOfZ = getDominators(Z);
|
const std::set<BasicBlock *> *domsOfZ = getDominators(Z);
|
||||||
if (domsOfZ && domsOfZ->count(X) && Z != X) {
|
|
||||||
|
|
||||||
|
// 如果 X 不支配 Z,则 Z 与 DF(X) 无关
|
||||||
|
if (!domsOfZ || domsOfZ->find(X) == domsOfZ->end()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 遍历 Z 的所有后继 Y
|
||||||
for (BasicBlock *Y : Z->getSuccessors()) {
|
for (BasicBlock *Y : Z->getSuccessors()) {
|
||||||
|
// 如果 Y 不被 X 严格支配,则 Y 在 DF(X) 中
|
||||||
|
// Y 不被 X 严格支配意味着 (Y不被X支配) 或 (Y就是X)
|
||||||
const std::set<BasicBlock *> *domsOfY = getDominators(Y);
|
const std::set<BasicBlock *> *domsOfY = getDominators(Y);
|
||||||
if (domsOfY && domsOfY->find(X) == domsOfY->end()) {
|
if (Y == X || (domsOfY && domsOfY->find(X) == domsOfY->end())) {
|
||||||
DominanceFrontiers[X].insert(Y);
|
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) {
|
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()) {
|
for (auto &bb_ptr : F->getBasicBlocks()) {
|
||||||
BasicBlock *B = bb_ptr.get();
|
BasicBlock *B = bb_ptr.get();
|
||||||
auto it = getImmediateDominator(B);
|
BasicBlock *A = getImmediateDominator(B); // A 是 B 的即时支配者
|
||||||
if (it != nullptr) {
|
|
||||||
BasicBlock *A = it;
|
if (A) { // 如果 B 有即时支配者 A (即 B 不是入口块)
|
||||||
if (A) {
|
|
||||||
DominatorTreeChildren[A].insert(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 的实现
|
// DominatorTreeAnalysisPass 的实现
|
||||||
// ==============================================================
|
// ==============================================================
|
||||||
|
|
||||||
|
bool DominatorTreeAnalysisPass::runOnFunction(Function *F, AnalysisManager &AM) {
|
||||||
bool DominatorTreeAnalysisPass::runOnFunction(Function* F, AnalysisManager &AM) {
|
// 每次运行时清空旧数据,确保重新计算
|
||||||
CurrentDominatorTree = std::make_unique<DominatorTree>(F);
|
CurrentDominatorTree = std::make_unique<DominatorTree>(F);
|
||||||
|
// 不需要手动清空map,unique_ptr会创建新的DominatorTree对象,其map是空的
|
||||||
|
|
||||||
CurrentDominatorTree->computeDominators(F);
|
CurrentDominatorTree->computeDominators(F);
|
||||||
CurrentDominatorTree->computeIDoms(F);
|
CurrentDominatorTree->computeIDoms(F); // 修正后的IDoms算法
|
||||||
CurrentDominatorTree->computeDominanceFrontiers(F);
|
CurrentDominatorTree->computeDominanceFrontiers(F);
|
||||||
CurrentDominatorTree->computeDominatorTreeChildren(F);
|
CurrentDominatorTree->computeDominatorTreeChildren(F);
|
||||||
return false;
|
return false; // 分析遍通常返回 false,表示不修改 IR
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<AnalysisResultBase> DominatorTreeAnalysisPass::getResult() {
|
std::unique_ptr<AnalysisResultBase> DominatorTreeAnalysisPass::getResult() {
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ void Mem2RegContext::run(Function *func, AnalysisManager *AM) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 从入口基本块开始,对支配树进行 DFS 遍历,进行变量重命名
|
// 从入口基本块开始,对支配树进行 DFS 遍历,进行变量重命名
|
||||||
renameVariables(nullptr, func->getEntryBlock()); // 第一个参数 alloca 在这里不使用,因为是递归入口点
|
renameVariables(func->getEntryBlock()); // 第一个参数 alloca 在这里不使用,因为是递归入口点
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
// 阶段4: 清理
|
// 阶段4: 清理
|
||||||
@@ -209,9 +209,14 @@ void Mem2RegContext::insertPhis(AllocaInst *alloca, const std::unordered_set<Bas
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 对支配树进行深度优先遍历,重命名变量并替换 load/store 指令
|
// 对支配树进行深度优先遍历,重命名变量并替换 load/store 指令
|
||||||
void Mem2RegContext::renameVariables(AllocaInst *currentAlloca, BasicBlock *currentBB) {
|
// 移除了 AllocaInst *currentAlloca 参数,因为这个函数是为整个基本块处理所有可提升的 Alloca
|
||||||
// 维护一个局部栈,用于存储当前基本块中为 Phi 和 Store 创建的 SSA 值,以便在退出时弹出
|
void Mem2RegContext::renameVariables(BasicBlock *currentBB) {
|
||||||
std::stack<Value *> localStackPushed;
|
// 1. 在函数开始时,记录每个 promotableAlloca 的当前栈深度。
|
||||||
|
// 这将用于在函数返回时精确地回溯栈状态。
|
||||||
|
std::map<AllocaInst *, size_t> originalStackSizes;
|
||||||
|
for (auto alloca : promotableAllocas) {
|
||||||
|
originalStackSizes[alloca] = allocaToValueStackMap[alloca].size();
|
||||||
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
// 处理当前基本块的指令
|
// 处理当前基本块的指令
|
||||||
@@ -227,55 +232,69 @@ void Mem2RegContext::renameVariables(AllocaInst *currentAlloca, BasicBlock *curr
|
|||||||
if (allocaToPhiMap[alloca].count(currentBB) && allocaToPhiMap[alloca][currentBB] == phiInst) {
|
if (allocaToPhiMap[alloca].count(currentBB) && allocaToPhiMap[alloca][currentBB] == phiInst) {
|
||||||
// 为 Phi 指令的输出创建一个新的 SSA 值,并压入值栈
|
// 为 Phi 指令的输出创建一个新的 SSA 值,并压入值栈
|
||||||
allocaToValueStackMap[alloca].push(phiInst);
|
allocaToValueStackMap[alloca].push(phiInst);
|
||||||
localStackPushed.push(phiInst); // 记录以便弹出
|
if (DEBUG) {
|
||||||
|
std::cout << "Mem2Reg: Pushed Phi " << (phiInst->getName().empty() ? "anonymous" : phiInst->getName()) << " for alloca " << alloca->getName()
|
||||||
|
<< ". Stack size: " << allocaToValueStackMap[alloca].size() << std::endl;
|
||||||
|
}
|
||||||
break; // 找到对应的 alloca,处理下一个指令
|
break; // 找到对应的 alloca,处理下一个指令
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 处理 LoadInst
|
// 处理 LoadInst
|
||||||
else if (auto loadInst = dynamic_cast<LoadInst *>(inst)) {
|
else if (auto loadInst = dynamic_cast<LoadInst *>(inst)) {
|
||||||
// 检查这个 LoadInst 是否是为某个可提升的 alloca
|
|
||||||
for (auto alloca : promotableAllocas) {
|
for (auto alloca : promotableAllocas) {
|
||||||
if (loadInst->getPointer() == alloca) {
|
// 检查 LoadInst 的指针是否直接是 alloca,或者是指向 alloca 的 GEP
|
||||||
// loadInst->getPointer() 返回 AllocaInst*
|
Value *ptrOperand = loadInst->getPointer();
|
||||||
// 将 LoadInst 的所有用途替换为当前 alloca 值栈顶部的 SSA 值
|
if (ptrOperand == alloca || (dynamic_cast<GetElementPtrInst *>(ptrOperand) &&
|
||||||
|
dynamic_cast<GetElementPtrInst *>(ptrOperand)->getBasePointer() == alloca)) {
|
||||||
assert(!allocaToValueStackMap[alloca].empty() && "Value stack empty for alloca during load replacement!");
|
assert(!allocaToValueStackMap[alloca].empty() && "Value stack empty for alloca during load replacement!");
|
||||||
if(DEBUG){
|
if (DEBUG) {
|
||||||
std::cout << "Mem2Reg: Replacing load " << loadInst->getPointer()->getName() << " with SSA value." << std::endl;
|
std::cout << "Mem2Reg: Replacing load "
|
||||||
|
<< (ptrOperand->getName().empty() ? "anonymous" : ptrOperand->getName()) << " with SSA value "
|
||||||
|
<< (allocaToValueStackMap[alloca].top()->getName().empty()
|
||||||
|
? "anonymous"
|
||||||
|
: allocaToValueStackMap[alloca].top()->getName())
|
||||||
|
<< " for alloca " << alloca->getName() << std::endl;
|
||||||
|
std::cout << "Mem2Reg: allocaToValueStackMap[" << alloca->getName()
|
||||||
|
<< "] size: " << allocaToValueStackMap[alloca].size() << std::endl;
|
||||||
}
|
}
|
||||||
loadInst->replaceAllUsesWith(allocaToValueStackMap[alloca].top());
|
loadInst->replaceAllUsesWith(allocaToValueStackMap[alloca].top());
|
||||||
instIter = SysYIROptUtils::usedelete(instIter);
|
instIter = SysYIROptUtils::usedelete(instIter);
|
||||||
instDeleted = true;
|
instDeleted = true;
|
||||||
// std::cerr << "Mem2Reg: Replaced load " << loadInst->name() << " with SSA value." << std::endl;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 处理 StoreInst
|
// 处理 StoreInst
|
||||||
else if (auto storeInst = dynamic_cast<StoreInst *>(inst)) {
|
else if (auto storeInst = dynamic_cast<StoreInst *>(inst)) {
|
||||||
// 检查这个 StoreInst 是否是为某个可提升的 alloca
|
|
||||||
for (auto alloca : promotableAllocas) {
|
for (auto alloca : promotableAllocas) {
|
||||||
if (storeInst->getPointer() == alloca) {
|
// 检查 StoreInst 的指针是否直接是 alloca,或者是指向 alloca 的 GEP
|
||||||
// 假设 storeInst->getPointer() 返回 AllocaInst*
|
Value *ptrOperand = storeInst->getPointer();
|
||||||
// 将 StoreInst 存储的值作为新的 SSA 值,压入值栈
|
if (ptrOperand == alloca || (dynamic_cast<GetElementPtrInst *>(ptrOperand) &&
|
||||||
if(DEBUG){
|
dynamic_cast<GetElementPtrInst *>(ptrOperand)->getBasePointer() == alloca)) {
|
||||||
std::cout << "Mem2Reg: Replacing store to " << storeInst->getPointer()->getName() << " with SSA value." << std::endl;
|
if (DEBUG) {
|
||||||
|
std::cout << "Mem2Reg: Replacing store to "
|
||||||
|
<< (ptrOperand->getName().empty() ? "anonymous" : ptrOperand->getName()) << " with SSA value "
|
||||||
|
<< (storeInst->getValue()->getName().empty() ? "anonymous" : storeInst->getValue()->getName())
|
||||||
|
<< " for alloca " << alloca->getName() << std::endl;
|
||||||
|
std::cout << "Mem2Reg: allocaToValueStackMap[" << alloca->getName()
|
||||||
|
<< "] size before push: " << allocaToValueStackMap[alloca].size() << std::endl;
|
||||||
}
|
}
|
||||||
allocaToValueStackMap[alloca].push(storeInst->getValue());
|
allocaToValueStackMap[alloca].push(storeInst->getValue());
|
||||||
localStackPushed.push(storeInst->getValue()); // 记录以便弹出
|
|
||||||
instIter = SysYIROptUtils::usedelete(instIter);
|
instIter = SysYIROptUtils::usedelete(instIter);
|
||||||
instDeleted = true;
|
instDeleted = true;
|
||||||
// std::cerr << "Mem2Reg: Replaced store to " << storeInst->ptr()->name() << " with SSA value." << std::endl;
|
if (DEBUG) {
|
||||||
|
std::cout << "Mem2Reg: allocaToValueStackMap[" << alloca->getName()
|
||||||
|
<< "] size after push: " << allocaToValueStackMap[alloca].size() << std::endl;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!instDeleted) {
|
if (!instDeleted) {
|
||||||
++instIter; // 如果指令没有被删除,移动到下一个
|
++instIter; // 如果指令没有被删除,移动到下一个
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
// 处理后继基本块的 Phi 指令参数
|
// 处理后继基本块的 Phi 指令参数
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
@@ -290,40 +309,57 @@ void Mem2RegContext::renameVariables(AllocaInst *currentAlloca, BasicBlock *curr
|
|||||||
// 参数值是当前 alloca 值栈顶部的 SSA 值
|
// 参数值是当前 alloca 值栈顶部的 SSA 值
|
||||||
assert(!allocaToValueStackMap[alloca].empty() && "Value stack empty for alloca when setting phi operand!");
|
assert(!allocaToValueStackMap[alloca].empty() && "Value stack empty for alloca when setting phi operand!");
|
||||||
phiInst->addIncoming(allocaToValueStackMap[alloca].top(), currentBB);
|
phiInst->addIncoming(allocaToValueStackMap[alloca].top(), currentBB);
|
||||||
|
if (DEBUG) {
|
||||||
|
std::cout << "Mem2Reg: Added incoming arg to Phi "
|
||||||
|
<< (phiInst->getName().empty() ? "anonymous" : phiInst->getName()) << " from "
|
||||||
|
<< currentBB->getName() << " with value "
|
||||||
|
<< (allocaToValueStackMap[alloca].top()->getName().empty()
|
||||||
|
? "anonymous"
|
||||||
|
: allocaToValueStackMap[alloca].top()->getName())
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
// 递归访问支配树的子节点
|
// 递归访问支配树的子节点
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
const std::set<BasicBlock *> *dominatedBlocks = dt->getDominatorTreeChildren(currentBB);
|
const std::set<BasicBlock *> *dominatedBlocks = dt->getDominatorTreeChildren(currentBB);
|
||||||
if(dominatedBlocks){
|
if (dominatedBlocks) { // 检查是否存在子节点
|
||||||
for (auto dominatedBB : *dominatedBlocks) {
|
|
||||||
if (dominatedBB) {
|
|
||||||
if(DEBUG){
|
if(DEBUG){
|
||||||
std::cout << "Mem2Reg: Recursively renaming variables in dominated block: " << dominatedBB->getName() << std::endl;
|
std::cout << "Mem2Reg: Processing dominated blocks for " << currentBB->getName() << std::endl;
|
||||||
|
for (auto dominatedBB : *dominatedBlocks) {
|
||||||
|
std::cout << "Mem2Reg: Dominated block: " << (dominatedBB ? dominatedBB->getName() : "null") << std::endl;
|
||||||
}
|
}
|
||||||
renameVariables(currentAlloca, dominatedBB);
|
}
|
||||||
|
for (auto dominatedBB : *dominatedBlocks) {
|
||||||
|
if (dominatedBB) { // 确保子块有效
|
||||||
|
if (DEBUG) {
|
||||||
|
std::cout << "Mem2Reg: Recursively renaming variables in dominated block: " << dominatedBB->getName()
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
renameVariables(dominatedBB); // 递归调用,不再传递 currentAlloca
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
// 退出基本块时,弹出在此块中压入值栈的 SSA 值
|
// 退出基本块时,弹出在此块中压入值栈的 SSA 值,恢复栈到进入该块时的状态
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
while (!localStackPushed.empty()) {
|
|
||||||
Value *val = localStackPushed.top();
|
|
||||||
localStackPushed.pop();
|
|
||||||
// 找到是哪个 alloca 对应的栈
|
|
||||||
for (auto alloca : promotableAllocas) {
|
for (auto alloca : promotableAllocas) {
|
||||||
if (!allocaToValueStackMap[alloca].empty() && allocaToValueStackMap[alloca].top() == val) {
|
while (allocaToValueStackMap[alloca].size() > originalStackSizes[alloca]) {
|
||||||
|
if (DEBUG) {
|
||||||
|
std::cout << "Mem2Reg: Popping value "
|
||||||
|
<< (allocaToValueStackMap[alloca].top()->getName().empty()
|
||||||
|
? "anonymous"
|
||||||
|
: allocaToValueStackMap[alloca].top()->getName())
|
||||||
|
<< " for alloca " << alloca->getName() << ". Stack size: " << allocaToValueStackMap[alloca].size()
|
||||||
|
<< " -> " << (allocaToValueStackMap[alloca].size() - 1) << std::endl;
|
||||||
|
}
|
||||||
allocaToValueStackMap[alloca].pop();
|
allocaToValueStackMap[alloca].pop();
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除所有原始的 AllocaInst、LoadInst 和 StoreInst
|
// 删除所有原始的 AllocaInst、LoadInst 和 StoreInst
|
||||||
|
|||||||
Reference in New Issue
Block a user