diff --git a/src/include/midend/IR.h b/src/include/midend/IR.h index 6c1bbf4..adde8cf 100644 --- a/src/include/midend/IR.h +++ b/src/include/midend/IR.h @@ -576,7 +576,9 @@ public: if (iter != predecessors.end()) { predecessors.erase(iter); } else { - assert(false); + // 如果没有找到前驱块,可能是因为它已经被移除或不存在 + // 这可能是一个错误情况,或者是因为在CFG优化过程中已经处理 + // assert(false && "Predecessor block not found in BasicBlock"); } } void removeSuccessor(BasicBlock *block) { @@ -584,7 +586,9 @@ public: if (iter != successors.end()) { successors.erase(iter); } else { - assert(false); + // 如果没有找到后继块,可能是因为它已经被移除或不存在 + // 这可能是一个错误情况,或者是因为在CFG优化过程中已经处理 + // assert(false && "Successor block not found in BasicBlock"); } } void replacePredecessor(BasicBlock *oldBlock, BasicBlock *newBlock) { @@ -916,10 +920,23 @@ class PhiInst : public Instruction { Value* getIncomingValue(unsigned k) const {return getOperand(2 * k);} ///< 获取位置为k的值 BasicBlock* getIncomingBlock(unsigned k) const {return dynamic_cast(getOperand(2 * k + 1));} + Value* getIncomingValue(BasicBlock* blk) const { + return getvalfromBlk(blk); + } ///< 获取指定基本块的传入值 + + BasicBlock* getIncomingBlock(Value* val) const { + return getBlkfromVal(val); + } ///< 获取指定值的传入基本块 + + void replaceIncoming(BasicBlock *oldBlock, BasicBlock *newBlock, Value *newValue){ + delBlk(oldBlock); + addIncoming(newValue, newBlock); + } + auto& getincomings() const {return blk2val;} ///< 获取所有的基本块和对应的值 - Value* getvalfromBlk(BasicBlock* blk); - BasicBlock* getBlkfromVal(Value* val); + Value* getvalfromBlk(BasicBlock* blk) const ; + BasicBlock* getBlkfromVal(Value* val) const ; unsigned getNumIncomingValues() const { return vsize; } ///< 获取传入值的数量 void addIncoming(Value *value, BasicBlock *block) { @@ -930,6 +947,10 @@ class PhiInst : public Instruction { vsize++; } ///< 添加传入值和对应的基本块 + void removeIncoming(BasicBlock *block){ + delBlk(block); + } + void delValue(Value* val); void delBlk(BasicBlock* blk); diff --git a/src/midend/IR.cpp b/src/midend/IR.cpp index 0fd6198..b61a766 100644 --- a/src/midend/IR.cpp +++ b/src/midend/IR.cpp @@ -569,15 +569,15 @@ void User::replaceOperand(unsigned index, Value *value) { * phi相关函数 */ -Value* PhiInst::getvalfromBlk(BasicBlock* blk){ - refreshB2VMap(); +Value* PhiInst::getvalfromBlk(BasicBlock* blk) const { + // refreshB2VMap(); if( blk2val.find(blk) != blk2val.end()) { return blk2val.at(blk); } return nullptr; } -BasicBlock* PhiInst::getBlkfromVal(Value* val){ +BasicBlock* PhiInst::getBlkfromVal(Value* val) const { // 返回第一个值对应的基本块 for(unsigned i = 0; i < vsize; i++) { if(getValue(i) == val) { @@ -591,6 +591,9 @@ void PhiInst::delValue(Value* val){ //根据value删除对应的基本块和值 unsigned i = 0; BasicBlock* blk = getBlkfromVal(val); + if(blk == nullptr) { + return; // 如果val没有对应的基本块,直接返回 + } for(i = 0; i < vsize; i++) { if(getValue(i) == val) { break; @@ -606,6 +609,9 @@ void PhiInst::delBlk(BasicBlock* blk){ //根据Blk删除对应的基本块和值 unsigned i = 0; Value* val = getvalfromBlk(blk); + if(val == nullptr) { + return; // 如果blk没有对应的值,直接返回 + } for(i = 0; i < vsize; i++) { if(getBlock(i) == blk) { break; @@ -618,9 +624,12 @@ void PhiInst::delBlk(BasicBlock* blk){ } void PhiInst::replaceBlk(BasicBlock* newBlk, unsigned k){ - refreshB2VMap(); + // refreshB2VMap(); BasicBlock* oldBlk = getBlock(k); Value* val = blk2val.at(oldBlk); + if(newBlk == oldBlk || oldBlk == nullptr) { + return; // 如果新旧基本块相同,直接返回 + } // Value* val = blk2val.at(getBlock(k)); // 替换基本块 setOperand(2 * k + 1, newBlk); @@ -630,7 +639,7 @@ void PhiInst::replaceBlk(BasicBlock* newBlk, unsigned k){ } void PhiInst::replaceold2new(BasicBlock* oldBlk, BasicBlock* newBlk){ - refreshB2VMap(); + // refreshB2VMap(); Value* val = blk2val.at(oldBlk); // 替换基本块 delBlk(oldBlk); diff --git a/src/midend/Pass/Optimize/SysYIRCFGOpt.cpp b/src/midend/Pass/Optimize/SysYIRCFGOpt.cpp index a589453..a4c584b 100644 --- a/src/midend/Pass/Optimize/SysYIRCFGOpt.cpp +++ b/src/midend/Pass/Optimize/SysYIRCFGOpt.cpp @@ -1,12 +1,12 @@ #include "SysYIRCFGOpt.h" #include "SysYIROptUtils.h" #include +#include #include #include #include -#include -#include #include // 引入队列,SysYDelNoPreBLock需要 +#include namespace sysy { @@ -18,7 +18,6 @@ void *SysYBlockMergePass::ID = (void *)&SysYBlockMergePass::ID; void *SysYAddReturnPass::ID = (void *)&SysYAddReturnPass::ID; void *SysYCondBr2BrPass::ID = (void *)&SysYCondBr2BrPass::ID; - // ====================================================================== // SysYCFGOptUtils: 辅助工具类,包含实际的CFG优化逻辑 // ====================================================================== @@ -26,40 +25,42 @@ void *SysYCondBr2BrPass::ID = (void *)&SysYCondBr2BrPass::ID; // 删除br后的无用指令 bool SysYCFGOptUtils::SysYDelInstAfterBr(Function *func) { bool changed = false; - + auto basicBlocks = func->getBasicBlocks(); for (auto &basicBlock : basicBlocks) { bool Branch = false; auto &instructions = basicBlock->getInstructions(); auto Branchiter = instructions.end(); for (auto iter = instructions.begin(); iter != instructions.end(); ++iter) { - if ((*iter)->isTerminator()){ + if ((*iter)->isTerminator()) { Branch = true; Branchiter = iter; break; } } - if (Branchiter != instructions.end()) ++Branchiter; + if (Branchiter != instructions.end()) + ++Branchiter; while (Branchiter != instructions.end()) { changed = true; Branchiter = instructions.erase(Branchiter); } - - if (Branch) { // 更新前驱后继关系 - auto thelastinstinst = basicBlock->getInstructions().end(); - --thelastinstinst; + + if (Branch) { // 更新前驱后继关系 + auto thelastinstinst = basicBlock->terminator(); auto &Successors = basicBlock->getSuccessors(); for (auto iterSucc = Successors.begin(); iterSucc != Successors.end();) { (*iterSucc)->removePredecessor(basicBlock.get()); basicBlock->removeSuccessor(*iterSucc); } if (thelastinstinst->get()->isUnconditional()) { - BasicBlock* branchBlock = dynamic_cast(thelastinstinst->get()->getOperand(0)); + auto brinst = dynamic_cast(thelastinstinst->get()); + BasicBlock *branchBlock = dynamic_cast(brinst->getBlock()); basicBlock->addSuccessor(branchBlock); branchBlock->addPredecessor(basicBlock.get()); } else if (thelastinstinst->get()->isConditional()) { - BasicBlock* thenBlock = dynamic_cast(thelastinstinst->get()->getOperand(1)); - BasicBlock* elseBlock = dynamic_cast(thelastinstinst->get()->getOperand(2)); + auto brinst = dynamic_cast(thelastinstinst->get()); + BasicBlock *thenBlock = dynamic_cast(brinst->getThenBlock()); + BasicBlock *elseBlock = dynamic_cast(brinst->getElseBlock()); basicBlock->addSuccessor(thenBlock); basicBlock->addSuccessor(elseBlock); thenBlock->addPredecessor(basicBlock.get()); @@ -75,26 +76,26 @@ bool SysYCFGOptUtils::SysYDelInstAfterBr(Function *func) { bool SysYCFGOptUtils::SysYBlockMerge(Function *func) { bool changed = false; - for (auto blockiter = func->getBasicBlocks().begin(); - blockiter != func->getBasicBlocks().end();) { + for (auto blockiter = func->getBasicBlocks().begin(); blockiter != func->getBasicBlocks().end();) { if (blockiter->get()->getNumSuccessors() == 1) { // 如果当前块只有一个后继块 // 且后继块只有一个前驱块 // 则将当前块和后继块合并 if (((blockiter->get())->getSuccessors()[0])->getNumPredecessors() == 1) { // std::cout << "merge block: " << blockiter->get()->getName() << std::endl; - BasicBlock* block = blockiter->get(); - BasicBlock* nextBlock = blockiter->get()->getSuccessors()[0]; + BasicBlock *block = blockiter->get(); + BasicBlock *nextBlock = blockiter->get()->getSuccessors()[0]; // auto nextarguments = nextBlock->getArguments(); // 删除br指令 if (block->getNumInstructions() != 0) { - auto thelastinstinst = block->end(); - (--thelastinstinst); + auto thelastinstinst = block->terminator(); if (thelastinstinst->get()->isUnconditional()) { thelastinstinst = SysYIROptUtils::usedelete(thelastinstinst); } else if (thelastinstinst->get()->isConditional()) { - // 如果是条件分支,判断条件是否相同,主要优化相同布尔表达式 - if (thelastinstinst->get()->getOperand(1)->getName() == thelastinstinst->get()->getOperand(1)->getName()) { + // 按道理不会走到这个分支 + // 如果是条件分支,查看then else是否相同 + auto brinst = dynamic_cast(thelastinstinst->get()); + if (brinst->getThenBlock() == brinst->getElseBlock()) { thelastinstinst = SysYIROptUtils::usedelete(thelastinstinst); } } @@ -104,7 +105,7 @@ bool SysYCFGOptUtils::SysYBlockMerge(Function *func) { for (auto institer = nextBlock->begin(); institer != nextBlock->end();) { institer->get()->setParent(block); block->getInstructions().emplace_back(institer->release()); - institer = nextBlock->getInstructions().erase(institer); + institer = nextBlock->getInstructions().erase(institer); } // 更新前驱后继关系,类似树节点操作 block->removeSuccessor(nextBlock); @@ -135,318 +136,431 @@ bool SysYCFGOptUtils::SysYBlockMerge(Function *func) { // 删除无前驱块,兼容SSA后的处理 bool SysYCFGOptUtils::SysYDelNoPreBLock(Function *func) { - - bool changed = false; + bool changed = false; // 标记是否有基本块被删除 + std::set reachableBlocks; // 用于存储所有可达的基本块 + std::queue blockQueue; // BFS 遍历队列 - for (auto &block : func->getBasicBlocks()) { - block->setreachableFalse(); + BasicBlock *entryBlock = func->getEntryBlock(); + if (entryBlock) { // 确保函数有入口块 + reachableBlocks.insert(entryBlock); // 将入口块标记为可达 + blockQueue.push(entryBlock); // 入口块入队 } - // 对函数基本块做一个拓扑排序,排查不可达基本块 - auto entryBlock = func->getEntryBlock(); - entryBlock->setreachableTrue(); - std::queue blockqueue; - blockqueue.push(entryBlock); - while (!blockqueue.empty()) { - auto block = blockqueue.front(); - blockqueue.pop(); - for (auto &succ : block->getSuccessors()) { - if (!succ->getreachable()) { - succ->setreachableTrue(); - blockqueue.push(succ); + // 如果没有入口块(比如一个空函数),则没有块是可达的,所有块都将被删除。 + + while (!blockQueue.empty()) { // BFS 遍历:只要队列不空 + BasicBlock *currentBlock = blockQueue.front(); + blockQueue.pop(); // 取出当前块 + + for (auto &succ : currentBlock->getSuccessors()) { // 遍历当前块的所有后继 + // 如果后继块不在 reachableBlocks 中(即尚未被访问过) + if (reachableBlocks.find(succ) == reachableBlocks.end()) { + reachableBlocks.insert(succ); // 标记为可达 + blockQueue.push(succ); // 入队,以便继续遍历 } } } - // 删除不可达基本块指令 - for (auto blockIter = func->getBasicBlocks().begin(); blockIter != func->getBasicBlocks().end(); blockIter++) { - if (!blockIter->get()->getreachable()) { - for (auto instIter = blockIter->get()->getInstructions().begin(); - instIter != blockIter->get()->getInstructions().end();) { - instIter = SysYIROptUtils::usedelete(instIter); + std::vector blocksToDelete; // 用于存储所有不可达的基本块 + + for (auto &blockPtr : func->getBasicBlocks()) { + BasicBlock *block = blockPtr.get(); + // 如果当前块不在 reachableBlocks 集合中,说明它是不可达的 + if (reachableBlocks.find(block) == reachableBlocks.end()) { + blocksToDelete.push_back(block); // 将其加入待删除列表 + changed = true; // 只要找到一个不可达块,就说明函数发生了改变 + } + } + + for (BasicBlock *unreachableBlock : blocksToDelete) { + // 遍历不可达块中的所有指令,并删除它们 + for (auto instIter = unreachableBlock->getInstructions().begin(); + instIter != unreachableBlock->getInstructions().end();) { + instIter = SysYIROptUtils::usedelete(instIter); + } + } + + for (BasicBlock *unreachableBlock : blocksToDelete) { + for (BasicBlock *succBlock : unreachableBlock->getSuccessors()) { + // 只有当后继块自身是可达的(没有被删除)时才需要处理 + if (reachableBlocks.count(succBlock)) { + for (auto &phiInstPtr : succBlock->getInstructions()) { + // Phi 指令总是在基本块的开头。一旦遇到非 Phi 指令即可停止。 + if (phiInstPtr->getKind() != Instruction::kPhi) { + break; + } + // 将这个 Phi 节点中来自不可达前驱(unreachableBlock)的输入参数删除 + dynamic_cast(phiInstPtr.get())->delBlk(unreachableBlock); + } } } } - for (auto blockIter = func->getBasicBlocks().begin(); blockIter != func->getBasicBlocks().end();) { - if (!blockIter->get()->getreachable()) { - for (auto succblock : blockIter->get()->getSuccessors()) { - for (auto &phiinst : succblock->getInstructions()) { - if (phiinst->getKind() != Instruction::kPhi) { - break; - } - // 使用 delBlk 方法正确地删除对应于被删除基本块的传入值 - dynamic_cast(phiinst.get())->delBlk(blockIter->get()); - } - } - // 删除不可达基本块,注意迭代器不可达问题 + BasicBlock *currentBlock = blockIter->get(); + // 如果当前块不在可达块集合中,则将其从函数中移除 + if (reachableBlocks.find(currentBlock) == reachableBlocks.end()) { + // func->removeBasicBlock 应该返回下一个有效的迭代器 func->removeBasicBlock((blockIter++)->get()); - changed = true; } else { - blockIter++; + blockIter++; // 如果可达,则移动到下一个块 } } - + return changed; } -// 删除空块 -bool SysYCFGOptUtils::SysYDelEmptyBlock(Function *func, IRBuilder* pBuilder) { +bool SysYCFGOptUtils::SysYDelEmptyBlock(Function *func, IRBuilder *pBuilder) { bool changed = false; - // 收集不可达基本块 - // 这里的不可达基本块是指没有实际指令的基本块 - // 当一个基本块没有实际指令例如只有phi指令和一个uncondbr指令时,也会被视作不可达 - auto basicBlocks = func->getBasicBlocks(); - std::map EmptyBlocks; - // 空块儿和后继的基本块的映射 - for (auto &basicBlock : basicBlocks) { - if (basicBlock->getNumInstructions() == 0) { - if (basicBlock->getNumSuccessors() == 1) { - EmptyBlocks[basicBlock.get()] = basicBlock->getSuccessors().front(); - } - } - else{ - // 如果只有phi指令和一个uncondbr。(phi)*(uncondbr)? - // 判断除了最后一个指令之外是不是只有phi指令 - bool onlyPhi = true; - for (auto &inst : basicBlock->getInstructions()) { - if (!inst->isPhi() && !inst->isUnconditional()) { - onlyPhi = false; - break; - } - } - if(onlyPhi && basicBlock->getNumSuccessors() == 1) // 确保有后继且只有一个 - EmptyBlocks[basicBlock.get()] = basicBlock->getSuccessors().front(); - } + // 步骤 1: 识别并映射所有符合“空块”定义的基本块及其目标后继 + // 使用 std::map 来存储 <空块, 空块跳转目标> + // 这样可以处理空块链:A -> B -> C,如果 B 是空块,A 应该跳到 C + std::map emptyBlockRedirectMap; + + // 为了避免在遍历 func->getBasicBlocks() 时修改它导致迭代器失效, + // 我们先收集所有的基本块。 + std::vector allBlocks; + for (auto &blockPtr : func->getBasicBlocks()) { + allBlocks.push_back(blockPtr.get()); } - // 更新基本块信息,增加必要指令 - for (auto &basicBlock : basicBlocks) { - // 把空块转换成只有跳转指令的不可达块 (这段逻辑在优化遍中可能需要调整,这里是原样保留) - // 通常,DelEmptyBlock 应该在BlockMerge之后运行,如果存在完全空块,它会尝试填充一个Br指令。 - // 但是,它主要目的是重定向跳转。 - if (distance(basicBlock->begin(), basicBlock->end()) == 0) { - if (basicBlock->getNumSuccessors() == 0) { - continue; - } - if (basicBlock->getNumSuccessors() > 1) { - // 如果一个空块有多个后继,说明CFG结构有问题或者需要特殊处理,这里简单assert - assert(false && "Empty block with multiple successors found during SysYDelEmptyBlock"); - } - // 这里的逻辑有点问题,如果一个块是空的,且只有一个后继,应该直接跳转到后继。 - // 如果这个块最终被删除了,那么其前驱也需要重定向。 - // 这个循环的目的是重定向现有的跳转指令,而不是创建新的。 - // 所以下面的逻辑才是核心。 - // pBuilder->setPosition(basicBlock.get(), basicBlock->end()); - // pBuilder->createUncondBrInst(basicBlock->getSuccessors()[0], {}); + + for (BasicBlock *block : allBlocks) { + // 入口块通常不应该被认为是空块并删除,除非它没有实际指令且只有一个后继, + // 但为了安全起见,通常会跳过入口块的删除。 + // 如果入口块是空的,它应该被合并到它的后继,但处理起来更复杂,这里先不处理入口块为空的情况 + if (block == func->getEntryBlock()) { continue; } - auto thelastinst = basicBlock->getInstructions().end(); - --thelastinst; - - // 根据br指令传递的后继块信息,跳过空块链 - if (thelastinst->get()->isUnconditional()) { - BasicBlock* OldBrBlock = dynamic_cast(thelastinst->get()->getOperand(0)); - BasicBlock *thelastBlockOld = nullptr; - // 如果空块链表为多个块 - while (EmptyBlocks.count(dynamic_cast(thelastinst->get()->getOperand(0)))) { - thelastBlockOld = dynamic_cast(thelastinst->get()->getOperand(0)); - thelastinst->get()->replaceOperand(0, EmptyBlocks[thelastBlockOld]); - } - - // 如果有重定向发生 - if (thelastBlockOld != nullptr) { - basicBlock->removeSuccessor(OldBrBlock); - OldBrBlock->removePredecessor(basicBlock.get()); - basicBlock->addSuccessor(dynamic_cast(thelastinst->get()->getOperand(0))); - dynamic_cast(thelastinst->get()->getOperand(0))->addPredecessor(basicBlock.get()); - changed = true; // 标记IR被修改 - } - - - if (thelastBlockOld != nullptr) { - for (auto &InstInNew : dynamic_cast(thelastinst->get()->getOperand(0))->getInstructions()) { - if (InstInNew->isPhi()) { - // 使用 delBlk 方法删除 oldBlock 对应的传入值 - dynamic_cast(InstInNew.get())->delBlk(thelastBlockOld); - } else { + // 检查基本块是否是空的:除了Phi指令外,只包含一个终止指令 (Terminator) + // 且该终止指令必须是无条件跳转。 + // 空块必须只有一个后继才能被简化 + if (block->getNumSuccessors() == 1) { + bool hasNonPhiNonTerminator = false; + // 遍历除了最后一个指令之外的指令 + for (auto instIter = block->getInstructions().begin(); instIter != block->getInstructions().end();) { + // 如果是终止指令(例如 br, ret),且不是最后一个指令,则该块有问题 + if ((*instIter)->isTerminator() && instIter != block->terminator()) { + hasNonPhiNonTerminator = true; break; } - } - } - - } else if (thelastinst->get()->getKind() == Instruction::kCondBr) { - auto OldThenBlock = dynamic_cast(thelastinst->get()->getOperand(1)); - auto OldElseBlock = dynamic_cast(thelastinst->get()->getOperand(2)); - bool thenChanged = false; - bool elseChanged = false; - - - BasicBlock *thelastBlockOld = nullptr; - while (EmptyBlocks.count(dynamic_cast(thelastinst->get()->getOperand(1)))) { - thelastBlockOld = dynamic_cast(thelastinst->get()->getOperand(1)); - thelastinst->get()->replaceOperand( - 1, EmptyBlocks[dynamic_cast(thelastinst->get()->getOperand(1))]); - thenChanged = true; - } - - if (thenChanged) { - basicBlock->removeSuccessor(OldThenBlock); - OldThenBlock->removePredecessor(basicBlock.get()); - basicBlock->addSuccessor(dynamic_cast(thelastinst->get()->getOperand(1))); - dynamic_cast(thelastinst->get()->getOperand(1))->addPredecessor(basicBlock.get()); - changed = true; // 标记IR被修改 - } - - // 处理 then 和 else 分支合并的情况 - if (dynamic_cast(thelastinst->get()->getOperand(1)) == - dynamic_cast(thelastinst->get()->getOperand(2))) { - auto thebrBlock = dynamic_cast(thelastinst->get()->getOperand(1)); - thelastinst = SysYIROptUtils::usedelete(thelastinst); - pBuilder->setPosition(basicBlock.get(), basicBlock->end()); - pBuilder->createUncondBrInst(thebrBlock); - changed = true; // 标记IR被修改 - continue; - } - - if (thelastBlockOld != nullptr) { - for (auto &InstInNew : dynamic_cast(thelastinst->get()->getOperand(1))->getInstructions()) { - if (InstInNew->isPhi()) { - // 使用 delBlk 方法删除 oldBlock 对应的传入值 - dynamic_cast(InstInNew.get())->delBlk(thelastBlockOld); - } else { - break; + // 如果不是 Phi 指令且不是终止指令 + if (!(*instIter)->isPhi() && !(*instIter)->isTerminator()) { + hasNonPhiNonTerminator = true; + break; + } + ++instIter; + if (!hasNonPhiNonTerminator && + instIter == block->getInstructions().end()) { // 如果块中只有 Phi 指令和一个 Terminator + // 确保最后一个指令是无条件跳转 + auto lastInst = block->terminator()->get(); + if (lastInst && lastInst->isUnconditional()) { + emptyBlockRedirectMap[block] = block->getSuccessors().front(); } - } - } - - thelastBlockOld = nullptr; - while (EmptyBlocks.count(dynamic_cast(thelastinst->get()->getOperand(2)))) { - thelastBlockOld = dynamic_cast(thelastinst->get()->getOperand(2)); - thelastinst->get()->replaceOperand( - 2, EmptyBlocks[dynamic_cast(thelastinst->get()->getOperand(2))]); - elseChanged = true; - } - - if (elseChanged) { - basicBlock->removeSuccessor(OldElseBlock); - OldElseBlock->removePredecessor(basicBlock.get()); - basicBlock->addSuccessor(dynamic_cast(thelastinst->get()->getOperand(2))); - dynamic_cast(thelastinst->get()->getOperand(2))->addPredecessor(basicBlock.get()); - changed = true; // 标记IR被修改 - } - - // 处理 then 和 else 分支合并的情况 - if (dynamic_cast(thelastinst->get()->getOperand(1)) == - dynamic_cast(thelastinst->get()->getOperand(2))) { - auto thebrBlock = dynamic_cast(thelastinst->get()->getOperand(1)); - thelastinst = SysYIROptUtils::usedelete(thelastinst); - pBuilder->setPosition(basicBlock.get(), basicBlock->end()); - pBuilder->createUncondBrInst(thebrBlock); - changed = true; // 标记IR被修改 - continue; - } - - - // 如果有重定向发生 - // 需要更新后继块的前驱关系 - if (thelastBlockOld != nullptr) { - for (auto &InstInNew : dynamic_cast(thelastinst->get()->getOperand(2))->getInstructions()) { - if (InstInNew->isPhi()) { - // 使用 delBlk 方法删除 oldBlock 对应的传入值 - dynamic_cast(InstInNew.get())->delBlk(thelastBlockOld); - } else { - break; - } - } - } - - } else { - // 如果不是终止指令,但有后继 (例如,末尾没有显式终止指令的块) - // 这段逻辑可能需要更严谨的CFG检查来确保正确性 - if (basicBlock->getNumSuccessors() == 1) { - // 这里的逻辑似乎是想为没有terminator的块添加一个,但通常这应该在CFG构建阶段完成。 - // 如果这里仍然执行,确保它符合预期。 - // pBuilder->setPosition(basicBlock.get(), basicBlock->end()); - // pBuilder->createUncondBrInst(basicBlock->getSuccessors()[0], {}); - // auto thelastinst = basicBlock->getInstructions().end(); - // (--thelastinst); - // auto OldBrBlock = dynamic_cast(thelastinst->get()->getOperand(0)); - // sysy::BasicBlock *thelastBlockOld = nullptr; - // while (EmptyBlocks.find(dynamic_cast(thelastinst->get()->getOperand(0))) != - // EmptyBlocks.end()) { - // thelastBlockOld = dynamic_cast(thelastinst->get()->getOperand(0)); - - // thelastinst->get()->replaceOperand( - // 0, EmptyBlocks[dynamic_cast(thelastinst->get()->getOperand(0))]); - // } - - // basicBlock->removeSuccessor(OldBrBlock); - // OldBrBlock->removePredecessor(basicBlock.get()); - // basicBlock->addSuccessor(dynamic_cast(thelastinst->get()->getOperand(0))); - // dynamic_cast(thelastinst->get()->getOperand(0))->addPredecessor(basicBlock.get()); - // changed = true; // 标记IR被修改 - // if (thelastBlockOld != nullptr) { - // int indexphi = 0; - // for (auto &pred : dynamic_cast(thelastinst->get()->getOperand(0))->getPredecessors()) { - // if (pred == thelastBlockOld) { - // break; - // } - // indexphi++; - // } - - // for (auto &InstInNew : dynamic_cast(thelastinst->get()->getOperand(0))->getInstructions()) { - // if (InstInNew->isPhi()) { - // dynamic_cast(InstInNew.get())->removeOperand(indexphi + 1); - // } else { - // break; - // } - // } - // } + } } } } - // 真正的删除空块 - for (auto iter = func->getBasicBlocks().begin(); iter != func->getBasicBlocks().end();) { - - if (EmptyBlocks.count(iter->get())) { - // EntryBlock跳过 - if (iter->get() == func->getEntryBlock()) { - ++iter; - continue; + // 步骤 2: 遍历 emptyBlockRedirectMap,处理空块链 + // 确保每个空块都直接重定向到其最终的非空后继块 + for (auto const &[emptyBlock, directSucc] : emptyBlockRedirectMap) { + BasicBlock *targetBlock = directSucc; + // 沿着空块链一直找到最终的非空块目标 + while (emptyBlockRedirectMap.count(targetBlock)) { + targetBlock = emptyBlockRedirectMap[targetBlock]; + } + emptyBlockRedirectMap[emptyBlock] = targetBlock; // 更新映射到最终目标 + } + + // 步骤 3: 遍历所有基本块,重定向其终止指令,绕过空块 + // 注意:这里需要再次遍历所有块,包括可能成为新目标的块 + for (BasicBlock *currentBlock : allBlocks) { + // 如果 currentBlock 本身就是个空块,它会通过其前驱的重定向被处理,这里跳过 + if (emptyBlockRedirectMap.count(currentBlock)) { + continue; + } + + // 获取当前块的最后一个指令(终止指令) + if (currentBlock->getInstructions().empty()) { + // 理论上,除了入口块和可能被合并的空块外,所有块都应该有终止指令 + // 如果这里碰到空块,可能是逻辑错误或者需要特殊处理 + continue; + } + + std::function getUltimateSourceValue = [&](Value *val, + BasicBlock *currentDefBlock) -> Value * { + // 如果值不是指令,例如常量或函数参数,则它本身就是最终来源 + if (auto instr = dynamic_cast(val)) { // Assuming Value* has a method to check if it's an instruction + return val; } - for (auto instIter = iter->get()->getInstructions().begin(); - instIter != iter->get()->getInstructions().end();) { - instIter = SysYIROptUtils::usedelete(instIter); + Instruction *inst = dynamic_cast(val); + // 如果定义指令不在任何空块中,它就是最终来源 + if (!emptyBlockRedirectMap.count(currentDefBlock)) { + return val; } - // 删除不可达基本块的phi指令的操作数 - for (auto &succ : iter->get()->getSuccessors()) { - for (auto &instinsucc : succ->getInstructions()) { - if (instinsucc->isPhi()) { - // iter->get() 就是当前被删除的空基本块,它作为前驱连接到这里的Phi指令 - dynamic_cast(instinsucc.get())->delBlk(iter->get()); + + // 如果是 Phi 指令,且它在空块中,则继续追溯其在空块链中前驱的传入值 + if (inst->getKind() == Instruction::kPhi) { + PhiInst *phi = dynamic_cast(inst); + // 查找哪个前驱是空块链中的上一个块 + for (size_t i = 0; i < phi->getNumOperands(); i += 2) { + BasicBlock *incomingBlock = dynamic_cast(phi->getOperand(i + 1)); + // 检查 incomingBlock 是否是当前空块的前驱,且也在空块映射中(或就是 P) + // 找到在空块链中导致 currentDefBlock 的那个前驱块 + if (emptyBlockRedirectMap.count(incomingBlock) || incomingBlock == currentBlock) { + // 递归追溯该传入值 + return getUltimateSourceValue(phi->getIncomingValue(incomingBlock), incomingBlock); + } + } + } + // 如果是其他指令或者无法追溯到Phi链,则认为它在空块中产生,无法安全传播,返回null或原值 + // 在严格的空块定义下,除了Phi和Terminator,不应有其他指令产生值。 + return val; // Fallback: If not a Phi, or unable to trace, return itself (may be dangling) + }; + + auto lastInst = currentBlock->getInstructions().back().get(); + + if (lastInst->isUnconditional()) { // 无条件跳转 + UncondBrInst *brInst = dynamic_cast(lastInst); + BasicBlock *oldTarget = dynamic_cast(brInst->getBlock()); // 原始跳转目标 + + if (emptyBlockRedirectMap.count(oldTarget)) { // 如果目标是空块 + BasicBlock *newTarget = emptyBlockRedirectMap[oldTarget]; // 获取最终目标 + + // 更新 CFG 关系 + currentBlock->removeSuccessor(oldTarget); + oldTarget->removePredecessor(currentBlock); + + brInst->replaceOperand(0, newTarget); // 更新跳转指令的操作数 + currentBlock->addSuccessor(newTarget); + newTarget->addPredecessor(currentBlock); + + changed = true; // 标记发生改变 + + for (auto &phiInstPtr : newTarget->getInstructions()) { + if (phiInstPtr->getKind() == Instruction::kPhi) { + PhiInst *phiInst = dynamic_cast(phiInstPtr.get()); + BasicBlock *actualEmptyPredecessorOfS = nullptr; + for (size_t i = 0; i < phiInst->getNumOperands(); i += 2) { + BasicBlock *incomingBlock = dynamic_cast(phiInst->getOperand(i + 1)); + if (incomingBlock && emptyBlockRedirectMap.count(incomingBlock) && + emptyBlockRedirectMap[incomingBlock] == newTarget) { + actualEmptyPredecessorOfS = incomingBlock; + break; + } + } + + if (actualEmptyPredecessorOfS) { + // 获取 Phi 节点原本从 actualEmptyPredecessorOfS 接收的值 + Value *valueFromEmptyPredecessor = phiInst->getIncomingValue(actualEmptyPredecessorOfS); + + // 追溯这个值,找到它在非空块中的最终来源 + // currentBlock 是 P + // oldTarget 是 E1 (链的起点) + // actualEmptyPredecessorOfS 是 En (链的终点,S 的前驱) + Value *ultimateSourceValue = getUltimateSourceValue(valueFromEmptyPredecessor, actualEmptyPredecessorOfS); + + // 替换 Phi 节点的传入块和传入值 + if (ultimateSourceValue) { // 确保成功追溯到有效来源 + phiInst->replaceIncoming(actualEmptyPredecessorOfS, currentBlock, ultimateSourceValue); + } else { + assert(false && "[DelEmptyBlock] Unable to trace a valid source for Phi instruction"); + // 无法追溯到有效来源,这可能是个错误或特殊情况 + // 此时可能需要移除该 Phi 项,或者插入一个 undef 值 + phiInst->removeIncoming(actualEmptyPredecessorOfS); + } + } } else { - // Phi 指令通常在基本块的开头,如果不是 Phi 指令就停止检查 break; } } } - func->removeBasicBlock((iter++)->get()); - changed = true; - } else { - ++iter; + } else if (lastInst->getKind() == Instruction::kCondBr) { // 条件跳转 + CondBrInst *condBrInst = dynamic_cast(lastInst); + BasicBlock *oldThenTarget = dynamic_cast(condBrInst->getThenBlock()); + BasicBlock *oldElseTarget = dynamic_cast(condBrInst->getElseBlock()); + + bool thenPathChanged = false; + bool elsePathChanged = false; + + // 处理 Then 分支 + if (emptyBlockRedirectMap.count(oldThenTarget)) { + BasicBlock *newThenTarget = emptyBlockRedirectMap[oldThenTarget]; + condBrInst->replaceOperand(1, newThenTarget); // 更新跳转指令操作数 + + currentBlock->removeSuccessor(oldThenTarget); + oldThenTarget->removePredecessor(currentBlock); + currentBlock->addSuccessor(newThenTarget); + newThenTarget->addPredecessor(currentBlock); + thenPathChanged = true; + changed = true; + + // 处理新 Then 目标块中的 Phi 指令 + // for (auto &phiInstPtr : newThenTarget->getInstructions()) { + // if (phiInstPtr->getKind() == Instruction::kPhi) { + // dynamic_cast(phiInstPtr.get())->delBlk(oldThenTarget); + // } else { + // break; + // } + // } + for (auto &phiInstPtr : newThenTarget->getInstructions()) { + if (phiInstPtr->getKind() == Instruction::kPhi) { + PhiInst *phiInst = dynamic_cast(phiInstPtr.get()); + BasicBlock *actualEmptyPredecessorOfS = nullptr; + for (size_t i = 0; i < phiInst->getNumOperands(); i += 2) { + BasicBlock *incomingBlock = dynamic_cast(phiInst->getOperand(i + 1)); + if (incomingBlock && emptyBlockRedirectMap.count(incomingBlock) && + emptyBlockRedirectMap[incomingBlock] == newThenTarget) { + actualEmptyPredecessorOfS = incomingBlock; + break; + } + } + + if (actualEmptyPredecessorOfS) { + // 获取 Phi 节点原本从 actualEmptyPredecessorOfS 接收的值 + Value *valueFromEmptyPredecessor = phiInst->getIncomingValue(actualEmptyPredecessorOfS); + + // 追溯这个值,找到它在非空块中的最终来源 + // currentBlock 是 P + // oldTarget 是 E1 (链的起点) + // actualEmptyPredecessorOfS 是 En (链的终点,S 的前驱) + Value *ultimateSourceValue = getUltimateSourceValue(valueFromEmptyPredecessor, actualEmptyPredecessorOfS); + + // 替换 Phi 节点的传入块和传入值 + if (ultimateSourceValue) { // 确保成功追溯到有效来源 + phiInst->replaceIncoming(actualEmptyPredecessorOfS, currentBlock, ultimateSourceValue); + } else { + assert(false && "[DelEmptyBlock] Unable to trace a valid source for Phi instruction"); + // 无法追溯到有效来源,这可能是个错误或特殊情况 + // 此时可能需要移除该 Phi 项,或者插入一个 undef 值 + phiInst->removeIncoming(actualEmptyPredecessorOfS); + } + } + } else { + break; + } + } + + } + + // 处理 Else 分支 + if (emptyBlockRedirectMap.count(oldElseTarget)) { + BasicBlock *newElseTarget = emptyBlockRedirectMap[oldElseTarget]; + condBrInst->replaceOperand(2, newElseTarget); // 更新跳转指令操作数 + + currentBlock->removeSuccessor(oldElseTarget); + oldElseTarget->removePredecessor(currentBlock); + currentBlock->addSuccessor(newElseTarget); + newElseTarget->addPredecessor(currentBlock); + elsePathChanged = true; + changed = true; + + // 处理新 Else 目标块中的 Phi 指令 + // for (auto &phiInstPtr : newElseTarget->getInstructions()) { + // if (phiInstPtr->getKind() == Instruction::kPhi) { + // dynamic_cast(phiInstPtr.get())->delBlk(oldElseTarget); + // } else { + // break; + // } + // } + for (auto &phiInstPtr : newElseTarget->getInstructions()) { + if (phiInstPtr->getKind() == Instruction::kPhi) { + PhiInst *phiInst = dynamic_cast(phiInstPtr.get()); + BasicBlock *actualEmptyPredecessorOfS = nullptr; + for (size_t i = 0; i < phiInst->getNumOperands(); i += 2) { + BasicBlock *incomingBlock = dynamic_cast(phiInst->getOperand(i + 1)); + if (incomingBlock && emptyBlockRedirectMap.count(incomingBlock) && + emptyBlockRedirectMap[incomingBlock] == newElseTarget) { + actualEmptyPredecessorOfS = incomingBlock; + break; + } + } + + if (actualEmptyPredecessorOfS) { + // 获取 Phi 节点原本从 actualEmptyPredecessorOfS 接收的值 + Value *valueFromEmptyPredecessor = phiInst->getIncomingValue(actualEmptyPredecessorOfS); + + // 追溯这个值,找到它在非空块中的最终来源 + // currentBlock 是 P + // oldTarget 是 E1 (链的起点) + // actualEmptyPredecessorOfS 是 En (链的终点,S 的前驱) + Value *ultimateSourceValue = getUltimateSourceValue(valueFromEmptyPredecessor, actualEmptyPredecessorOfS); + + // 替换 Phi 节点的传入块和传入值 + if (ultimateSourceValue) { // 确保成功追溯到有效来源 + phiInst->replaceIncoming(actualEmptyPredecessorOfS, currentBlock, ultimateSourceValue); + } else { + assert(false && "[DelEmptyBlock] Unable to trace a valid source for Phi instruction"); + // 无法追溯到有效来源,这可能是个错误或特殊情况 + // 此时可能需要移除该 Phi 项,或者插入一个 undef 值 + phiInst->removeIncoming(actualEmptyPredecessorOfS); + } + } + } else { + break; + } + } + } + + // 额外处理:如果条件跳转的两个分支现在指向同一个块,则可以简化为无条件跳转 + if (condBrInst->getThenBlock() == condBrInst->getElseBlock()) { + BasicBlock *commonTarget = dynamic_cast(condBrInst->getThenBlock()); + SysYIROptUtils::usedelete(lastInst); // 删除旧的条件跳转指令 + pBuilder->setPosition(currentBlock, currentBlock->end()); + pBuilder->createUncondBrInst(commonTarget); // 插入新的无条件跳转指令 + + // 更安全地更新 CFG 关系 + std::set currentSuccessors; + currentSuccessors.insert(oldThenTarget); + currentSuccessors.insert(oldElseTarget); + + // 移除旧的后继关系 + for (BasicBlock *succ : currentSuccessors) { + currentBlock->removeSuccessor(succ); + succ->removePredecessor(currentBlock); + } + // 添加新的后继关系 + currentBlock->addSuccessor(commonTarget); + commonTarget->addPredecessor(currentBlock); + + changed = true; + } } } - + + // 步骤 4: 真正地删除空基本块 + // 注意:只能在所有跳转和 Phi 指令都更新完毕后才能删除这些块 + for (auto blockIter = func->getBasicBlocks().begin(); blockIter != func->getBasicBlocks().end();) { + BasicBlock *currentBlock = blockIter->get(); + if (emptyBlockRedirectMap.count(currentBlock)) { // 如果在空块映射中 + // 入口块不应该被删除,即使它符合空块定义,因为函数需要一个入口 + if (currentBlock == func->getEntryBlock()) { + ++blockIter; + continue; + } + + // 在删除块之前,确保其内部指令被正确删除(虽然这类块指令很少) + for (auto instIter = currentBlock->getInstructions().begin(); + instIter != currentBlock->getInstructions().end();) { + instIter = SysYIROptUtils::usedelete(instIter); + } + + // 移除块 + func->removeBasicBlock((blockIter++)->get()); + changed = true; + } else { + ++blockIter; + } + } + return changed; } // 如果函数没有返回指令,则添加一个默认返回指令(主要解决void函数没有返回指令的问题) -bool SysYCFGOptUtils::SysYAddReturn(Function *func, IRBuilder* pBuilder) { +bool SysYCFGOptUtils::SysYAddReturn(Function *func, IRBuilder *pBuilder) { bool changed = false; auto basicBlocks = func->getBasicBlocks(); for (auto &block : basicBlocks) { @@ -460,7 +574,8 @@ bool SysYCFGOptUtils::SysYAddReturn(Function *func, IRBuilder* pBuilder) { auto thelastinst = block->getInstructions().end(); --thelastinst; if (thelastinst->get()->getKind() != Instruction::kReturn) { - // std::cout << "Warning: Function " << func->getName() << " has no return instruction, adding default return." << std::endl; + // std::cout << "Warning: Function " << func->getName() << " has no return instruction, adding default + // return." << std::endl; pBuilder->setPosition(block.get(), block->end()); // TODO: 如果int float函数缺少返回值是否需要报错 @@ -476,7 +591,7 @@ bool SysYCFGOptUtils::SysYAddReturn(Function *func, IRBuilder* pBuilder) { } } } - + return changed; } @@ -484,18 +599,18 @@ bool SysYCFGOptUtils::SysYAddReturn(Function *func, IRBuilder* pBuilder) { // 主要针对已知条件值的分支转换为无条件分支 // 例如 if (cond) { ... } else { ... } 中的 cond 已经 // 确定为 true 或 false 的情况 -bool SysYCFGOptUtils::SysYCondBr2Br(Function *func, IRBuilder* pBuilder) { +bool SysYCFGOptUtils::SysYCondBr2Br(Function *func, IRBuilder *pBuilder) { bool changed = false; for (auto &basicblock : func->getBasicBlocks()) { if (basicblock->getNumInstructions() == 0) continue; - - auto thelast = basicblock->getInstructions().end(); - --thelast; - if (thelast->get()->isConditional()){ - ConstantValue *constOperand = dynamic_cast(thelast->get()->getOperand(0)); + auto thelast = basicblock->terminator(); + + if (thelast->get()->isConditional()) { + auto condBrInst = dynamic_cast(thelast->get()); + ConstantValue *constOperand = dynamic_cast(condBrInst->getCondition()); std::string opname; int constint = 0; float constfloat = 0.0F; @@ -514,27 +629,27 @@ bool SysYCFGOptUtils::SysYCondBr2Br(Function *func, IRBuilder* pBuilder) { if (constfloat_Use || constint_Use) { changed = true; - auto thenBlock = dynamic_cast(thelast->get()->getOperand(1)); - auto elseBlock = dynamic_cast(thelast->get()->getOperand(2)); + auto thenBlock = dynamic_cast(condBrInst->getThenBlock()); + auto elseBlock = dynamic_cast(condBrInst->getElseBlock()); thelast = SysYIROptUtils::usedelete(thelast); if ((constfloat_Use && constfloat == 1.0F) || (constint_Use && constint == 1)) { // cond为true或非0 pBuilder->setPosition(basicblock.get(), basicblock->end()); pBuilder->createUncondBrInst(thenBlock); - + // 更新CFG关系 basicblock->removeSuccessor(elseBlock); elseBlock->removePredecessor(basicblock.get()); - + // 删除elseBlock的phi指令中对应的basicblock.get()的传入值 for (auto &phiinst : elseBlock->getInstructions()) { if (phiinst->getKind() != Instruction::kPhi) { break; } // 使用 delBlk 方法删除 basicblock.get() 对应的传入值 - dynamic_cast(phiinst.get())->delBlk(basicblock.get()); + dynamic_cast(phiinst.get())->removeIncoming(basicblock.get()); } - + } else { // cond为false或0 pBuilder->setPosition(basicblock.get(), basicblock->end()); @@ -550,9 +665,8 @@ bool SysYCFGOptUtils::SysYCondBr2Br(Function *func, IRBuilder* pBuilder) { break; } // 使用 delBlk 方法删除 basicblock.get() 对应的传入值 - dynamic_cast(phiinst.get())->delBlk(basicblock.get()); + dynamic_cast(phiinst.get())->removeIncoming(basicblock.get()); } - } } } @@ -565,28 +679,28 @@ bool SysYCFGOptUtils::SysYCondBr2Br(Function *func, IRBuilder* pBuilder) { // 独立的CFG优化遍的实现 // ====================================================================== -bool SysYDelInstAfterBrPass::runOnFunction(Function *F, AnalysisManager& AM) { +bool SysYDelInstAfterBrPass::runOnFunction(Function *F, AnalysisManager &AM) { return SysYCFGOptUtils::SysYDelInstAfterBr(F); } -bool SysYDelEmptyBlockPass::runOnFunction(Function *F, AnalysisManager& AM) { +bool SysYDelEmptyBlockPass::runOnFunction(Function *F, AnalysisManager &AM) { return SysYCFGOptUtils::SysYDelEmptyBlock(F, pBuilder); } -bool SysYDelNoPreBLockPass::runOnFunction(Function *F, AnalysisManager& AM) { +bool SysYDelNoPreBLockPass::runOnFunction(Function *F, AnalysisManager &AM) { return SysYCFGOptUtils::SysYDelNoPreBLock(F); } -bool SysYBlockMergePass::runOnFunction(Function *F, AnalysisManager& AM) { - return SysYCFGOptUtils::SysYBlockMerge(F); +bool SysYBlockMergePass::runOnFunction(Function *F, AnalysisManager &AM) { + return SysYCFGOptUtils::SysYBlockMerge(F); } -bool SysYAddReturnPass::runOnFunction(Function *F, AnalysisManager& AM) { +bool SysYAddReturnPass::runOnFunction(Function *F, AnalysisManager &AM) { return SysYCFGOptUtils::SysYAddReturn(F, pBuilder); } -bool SysYCondBr2BrPass::runOnFunction(Function *F, AnalysisManager& AM) { +bool SysYCondBr2BrPass::runOnFunction(Function *F, AnalysisManager &AM) { return SysYCFGOptUtils::SysYCondBr2Br(F, pBuilder); } -} // namespace sysy \ No newline at end of file +} // namespace sysy \ No newline at end of file