From 3dc4b28c9230eb468f7a65efcf88a6194ec28606 Mon Sep 17 00:00:00 2001 From: rain2133 <1370973498@qq.com> Date: Tue, 29 Jul 2025 03:25:56 +0800 Subject: [PATCH] =?UTF-8?q?[midend-mem2reg]dom=E5=A2=9E=E5=8A=A0=E8=AE=BF?= =?UTF-8?q?=E9=97=AE=E6=94=AF=E9=85=8D=E6=A0=91=E5=AD=90=E8=8A=82=E7=82=B9?= =?UTF-8?q?=E6=B1=82=E8=A7=A3=E5=92=8C=E8=AE=BF=E9=97=AE=E6=96=B9=E6=B3=95?= =?UTF-8?q?=EF=BC=8C=E4=BF=AE=E5=A4=8Dblock=E6=89=93=E5=8D=B0=EF=BC=8Cphi?= =?UTF-8?q?=E6=8C=87=E4=BB=A4=E5=91=BD=E5=90=8D=EF=BC=8CTODO=EF=BC=9Areg2m?= =?UTF-8?q?embug=E5=BE=85=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Dom.cpp | 22 ++++++++++++++++++++++ src/Mem2Reg.cpp | 14 +++++++++----- src/Reg2Mem.cpp | 12 ++++++++++-- src/SysYIRPrinter.cpp | 19 ++++++++++++++++--- src/include/Dom.h | 3 +++ src/include/IRBuilder.h | 11 ++++++++++- src/include/Pass.h | 5 +++++ src/include/SysYIRPrinter.h | 2 ++ 8 files changed, 77 insertions(+), 11 deletions(-) diff --git a/src/Dom.cpp b/src/Dom.cpp index d476c49..73726c5 100644 --- a/src/Dom.cpp +++ b/src/Dom.cpp @@ -38,6 +38,14 @@ const std::set *DominatorTree::getDominanceFrontier(BasicBlock *BB return nullptr; } +const std::set* DominatorTree::getDominatorTreeChildren(BasicBlock* BB) const { + auto it = DominatorTreeChildren.find(BB); + if (it != DominatorTreeChildren.end()) { + return &(it->second); + } + return nullptr; +} + void DominatorTree::computeDominators(Function *F) { // 经典的迭代算法计算支配者集合 // TODO: 可以替换为更高效的算法,如 Lengauer-Tarjan 算法 @@ -159,6 +167,19 @@ void DominatorTree::computeDominanceFrontiers(Function *F) { } } +void DominatorTree::computeDominatorTreeChildren(Function *F) { + 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); + } + } + } +} + // ============================================================== // DominatorTreeAnalysisPass 的实现 // ============================================================== @@ -169,6 +190,7 @@ bool DominatorTreeAnalysisPass::runOnFunction(Function* F, AnalysisManager &AM) CurrentDominatorTree->computeDominators(F); CurrentDominatorTree->computeIDoms(F); CurrentDominatorTree->computeDominanceFrontiers(F); + CurrentDominatorTree->computeDominatorTreeChildren(F); return false; } diff --git a/src/Mem2Reg.cpp b/src/Mem2Reg.cpp index 251b8ef..c6e856f 100644 --- a/src/Mem2Reg.cpp +++ b/src/Mem2Reg.cpp @@ -193,7 +193,7 @@ void Mem2RegContext::insertPhis(AllocaInst *alloca, const std::unordered_setsetPosition(frontierBlock, frontierBlock->begin()); // 设置插入位置为基本块开头 - auto phiInst = builder->createPhiInst(alloca->getAllocatedType(), {}, {frontierBlock}, ""); + PhiInst *phiInst = builder->createPhiInst(alloca->getAllocatedType(), {}, {}, ""); allocaToPhiMap[alloca][frontierBlock] = phiInst; // 记录 Phi 指令 @@ -294,12 +294,16 @@ void Mem2RegContext::renameVariables(AllocaInst *currentAlloca, BasicBlock *curr // -------------------------------------------------------------------- // 递归访问支配树的子节点 // -------------------------------------------------------------------- - const std::set *dominatedBlocks = dt->getDominators(currentBB); - for (auto dominatedBB : *dominatedBlocks) { - if (dominatedBB) { - renameVariables(currentAlloca, dominatedBB); + const std::set *dominatedBlocks = dt->getDominatorTreeChildren(currentBB); + if(dominatedBlocks){ + for (auto dominatedBB : *dominatedBlocks) { + if (dominatedBB) { + std::cout << "Mem2Reg: Recursively renaming variables in dominated block: " << dominatedBB->getName() << std::endl; + renameVariables(currentAlloca, dominatedBB); + } } } + // -------------------------------------------------------------------- // 退出基本块时,弹出在此块中压入值栈的 SSA 值 diff --git a/src/Reg2Mem.cpp b/src/Reg2Mem.cpp index 8b4a291..e82af20 100644 --- a/src/Reg2Mem.cpp +++ b/src/Reg2Mem.cpp @@ -1,6 +1,8 @@ #include "Reg2Mem.h" #include "SysYIROptUtils.h" // 如果有的话 +extern int DEBUG; // 全局调试标志 + namespace sysy { void *Reg2Mem::ID = (void *)&Reg2Mem::ID; @@ -30,6 +32,12 @@ void Reg2MemContext::run(Function *func) { bool Reg2MemContext::isPromotableToMemory(Value *val) { // 参数和指令结果是 SSA 值 + if(DEBUG){ + if(val->getName() == ""){ + assert(false && "Value name should not be empty in Reg2MemContext::isPromotableToMemory"); + } + std::cout << "Checking if value is promotable to memory: " << val->getName() << std::endl; + } if (dynamic_cast(val) || dynamic_cast(val)) { // 如果值已经是指针类型,则通常不为其分配额外的内存,因为它已经是一个地址。 // (除非我们想将其值也存储起来,这通常不用于 Reg2Mem) @@ -54,7 +62,7 @@ void Reg2MemContext::allocateMemoryForSSAValues(Function *func) { for (auto arg : func->getArguments()) { if (isPromotableToMemory(arg)) { // 参数的类型就是 AllocaInst 需要分配的类型 - AllocaInst *alloca = builder->createAllocaInst(arg->getType(), {}, arg->getName() + ".reg2mem"); + AllocaInst *alloca = builder->createAllocaInst(arg->getType(), {}); // 将参数值 store 到 alloca 中 (这是 Mem2Reg 逆转的关键一步) builder->createStoreInst(arg, alloca); valueToAllocaMap[arg] = alloca; @@ -82,7 +90,7 @@ void Reg2MemContext::allocateMemoryForSSAValues(Function *func) { // AllocaInst 应该在入口块,而不是当前指令所在块 // 这里我们只是创建,并稍后调整其位置 // 通常的做法是在循环结束后统一将 alloca 放到 entryBlock 的顶部 - AllocaInst *alloca = builder->createAllocaInst(inst.get()->getType(), {}, inst->getName() + ".reg2mem"); + AllocaInst *alloca = builder->createAllocaInst(inst.get()->getType(), {}); valueToAllocaMap[inst.get()] = alloca; } } diff --git a/src/SysYIRPrinter.cpp b/src/SysYIRPrinter.cpp index 50c56cf..9cfc6a6 100644 --- a/src/SysYIRPrinter.cpp +++ b/src/SysYIRPrinter.cpp @@ -79,6 +79,15 @@ std::string SysYPrinter::getValueName(Value *value) { return ""; } +std::string SysYPrinter::getBlockName(BasicBlock *block) { + static int blockId = 0; // 用于生成唯一的基本块ID + if (block->getName().empty()) { + return "bb" + std::to_string(blockId++); // 如果没有名字,生成一个唯一的基本块ID + } else { + return block->getName(); + } +} + void SysYPrinter::printType(Type *type) { std::cout << getTypeString(type); } @@ -128,6 +137,10 @@ void SysYPrinter::printGlobalVariable() { } } +void SysYPrinter::printBlock(BasicBlock *block) { + std::cout << getBlockName(block); +} + void SysYPrinter::printFunction(Function *function) { // Function signature std::cout << "define "; @@ -466,13 +479,13 @@ void SysYPrinter::printInst(Instruction *pInst) { // 如果你的 PhiInst 存储方式是 getIncomingValues() 和 getIncomingBlocks(),请相应调整 // LLVM IR 格式: phi type [value1, block1], [value2, block2] bool firstPair = true; - for (unsigned i = 0; i < phiInst->getNumOperands() / 2; ++i) { // 遍历成对的操作数 + for (unsigned i = 0; i < phiInst->getNumIncomingValues(); ++i) { // 遍历成对的操作数 if (!firstPair) std::cout << ", "; firstPair = false; std::cout << "[ "; - printValue(phiInst->getOperand(i * 2)); // value + printValue(phiInst->getValue(i)); std::cout << ", %"; - printValue(phiInst->getOperand(i * 2 + 1)); // block + printBlock(phiInst->getBlock(i)); std::cout << " ]"; } std::cout << std::endl; diff --git a/src/include/Dom.h b/src/include/Dom.h index f69dcb9..80e0883 100644 --- a/src/include/Dom.h +++ b/src/include/Dom.h @@ -16,17 +16,20 @@ public: const std::set* getDominators(BasicBlock* BB) const; BasicBlock* getImmediateDominator(BasicBlock* BB) const; const std::set* getDominanceFrontier(BasicBlock* BB) const; + const std::set* getDominatorTreeChildren(BasicBlock* BB) const; const std::map>& getDominatorsMap() const { return Dominators; } const std::map& getIDomsMap() const { return IDoms; } const std::map>& getDominanceFrontiersMap() const { return DominanceFrontiers; } void computeDominators(Function* F); void computeIDoms(Function* F); void computeDominanceFrontiers(Function* F); + void computeDominatorTreeChildren(Function* F); private: Function* AssociatedFunction; std::map> Dominators; std::map IDoms; std::map> DominanceFrontiers; + std::map> DominatorTreeChildren; }; diff --git a/src/include/IRBuilder.h b/src/include/IRBuilder.h index d9e92ef..760ef85 100644 --- a/src/include/IRBuilder.h +++ b/src/include/IRBuilder.h @@ -294,7 +294,16 @@ class IRBuilder { return inst; } ///< 创建store指令 PhiInst * createPhiInst(Type *type, const std::vector &vals = {}, const std::vector &blks = {}, const std::string &name = "") { - auto inst = new PhiInst(type, vals, blks, block, name); + std::string newName; + if (name.empty()) { + std::stringstream ss; + ss << tmpIndex; + newName = ss.str(); + tmpIndex++; + } else { + newName = name; + } + auto inst = new PhiInst(type, vals, blks, block, newName); assert(inst); block->getInstructions().emplace(block->begin(), inst); return inst; diff --git a/src/include/Pass.h b/src/include/Pass.h index ab71b50..887ad3f 100644 --- a/src/include/Pass.h +++ b/src/include/Pass.h @@ -11,6 +11,8 @@ #include "IR.h" #include "IRBuilder.h" +extern int DEBUG; // 全局调试标志 + namespace sysy { //前向声明 @@ -149,6 +151,9 @@ public: } AnalysisPass *analysisPass = static_cast(basePass.get()); + if(DEBUG){ + std::cout << "Running Analysis Pass: " << analysisPass->getName() << "\n"; + } // 根据分析遍的粒度处理 switch (analysisPass->getGranularity()) { case Pass::Granularity::Module: { diff --git a/src/include/SysYIRPrinter.h b/src/include/SysYIRPrinter.h index bfd78bd..deb22c0 100644 --- a/src/include/SysYIRPrinter.h +++ b/src/include/SysYIRPrinter.h @@ -22,6 +22,8 @@ public: static void printInst(Instruction *pInst); static void printType(Type *type); static void printValue(Value *value); + static void printBlock(BasicBlock *block); + static std::string getBlockName(BasicBlock *block); static std::string getOperandName(Value *operand); static std::string getTypeString(Type *type); static std::string getValueName(Value *value);