#include "SysYIRCFGOpt.h" #include "SysYIROptUtils.h" #include #include #include #include #include #include #include // 引入队列,SysYDelNoPreBLock需要 namespace sysy { // 定义静态ID void *SysYDelInstAfterBrPass::ID = (void *)&SysYDelInstAfterBrPass::ID; void *SysYDelEmptyBlockPass::ID = (void *)&SysYDelEmptyBlockPass::ID; void *SysYDelNoPreBLockPass::ID = (void *)&SysYDelNoPreBLockPass::ID; void *SysYBlockMergePass::ID = (void *)&SysYBlockMergePass::ID; void *SysYAddReturnPass::ID = (void *)&SysYAddReturnPass::ID; void *SysYCondBr2BrPass::ID = (void *)&SysYCondBr2BrPass::ID; // ====================================================================== // SysYCFGOptUtils: 辅助工具类,包含实际的CFG优化逻辑 // ====================================================================== // 删除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()){ Branch = true; Branchiter = iter; break; } } if (Branchiter != instructions.end()) ++Branchiter; while (Branchiter != instructions.end()) { changed = true; Branchiter = instructions.erase(Branchiter); } if (Branch) { // 更新前驱后继关系 auto thelastinstinst = basicBlock->getInstructions().end(); --thelastinstinst; 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)); 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)); basicBlock->addSuccessor(thenBlock); basicBlock->addSuccessor(elseBlock); thenBlock->addPredecessor(basicBlock.get()); elseBlock->addPredecessor(basicBlock.get()); } } } return changed; } // 合并基本块 bool SysYCFGOptUtils::SysYBlockMerge(Function *func) { bool changed = false; 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]; // auto nextarguments = nextBlock->getArguments(); // 删除br指令 if (block->getNumInstructions() != 0) { auto thelastinstinst = block->end(); (--thelastinstinst); if (thelastinstinst->get()->isUnconditional()) { SysYIROptUtils::usedelete(thelastinstinst->get()); thelastinstinst = block->getInstructions().erase(thelastinstinst); } else if (thelastinstinst->get()->isConditional()) { // 如果是条件分支,判断条件是否相同,主要优化相同布尔表达式 if (thelastinstinst->get()->getOperand(1)->getName() == thelastinstinst->get()->getOperand(1)->getName()) { SysYIROptUtils::usedelete(thelastinstinst->get()); thelastinstinst = block->getInstructions().erase(thelastinstinst); } } } // 将后继块的指令移动到当前块 // 并将后继块的父指针改为当前块 for (auto institer = nextBlock->begin(); institer != nextBlock->end();) { institer->get()->setParent(block); block->getInstructions().emplace_back(institer->release()); institer = nextBlock->getInstructions().erase(institer); } // 更新前驱后继关系,类似树节点操作 block->removeSuccessor(nextBlock); nextBlock->removePredecessor(block); std::list succshoulddel; for (auto &succ : nextBlock->getSuccessors()) { block->addSuccessor(succ); succ->replacePredecessor(nextBlock, block); succshoulddel.push_back(succ); } for (auto del : succshoulddel) { nextBlock->removeSuccessor(del); } func->removeBasicBlock(nextBlock); changed = true; } else { blockiter++; } } else { blockiter++; } } return changed; } // 删除无前驱块,兼容SSA后的处理 bool SysYCFGOptUtils::SysYDelNoPreBLock(Function *func) { bool changed = false; for (auto &block : func->getBasicBlocks()) { block->setreachableFalse(); } // 对函数基本块做一个拓扑排序,排查不可达基本块 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); } } } // 删除不可达基本块指令 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();) { SysYIROptUtils::usedelete(instIter->get()); instIter = blockIter->get()->getInstructions().erase(instIter); } } } 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()); } } // 删除不可达基本块,注意迭代器不可达问题 func->removeBasicBlock((blockIter++)->get()); changed = true; } else { blockIter++; } } return changed; } // 删除空块 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(); } } // 更新基本块信息,增加必要指令 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], {}); 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 { 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)); SysYIROptUtils::usedelete(thelastinst->get()); thelastinst = basicBlock->getInstructions().erase(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; } } } 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)); SysYIROptUtils::usedelete(thelastinst->get()); thelastinst = basicBlock->getInstructions().erase(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; } for (auto instIter = iter->get()->getInstructions().begin(); instIter != iter->get()->getInstructions().end();) { SysYIROptUtils::usedelete(instIter->get()); // 仅删除 use 关系 // 显式地从基本块中删除指令并更新迭代器 instIter = iter->get()->getInstructions().erase(instIter); } // 删除不可达基本块的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()); } else { // Phi 指令通常在基本块的开头,如果不是 Phi 指令就停止检查 break; } } } func->removeBasicBlock((iter++)->get()); changed = true; } else { ++iter; } } return changed; } // 如果函数没有返回指令,则添加一个默认返回指令(主要解决void函数没有返回指令的问题) bool SysYCFGOptUtils::SysYAddReturn(Function *func, IRBuilder* pBuilder) { bool changed = false; auto basicBlocks = func->getBasicBlocks(); for (auto &block : basicBlocks) { if (block->getNumSuccessors() == 0) { // 如果基本块没有后继块,则添加一个返回指令 if (block->getNumInstructions() == 0) { pBuilder->setPosition(block.get(), block->end()); pBuilder->createReturnInst(); changed = true; // 标记IR被修改 } else { 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; pBuilder->setPosition(block.get(), block->end()); // TODO: 如果int float函数缺少返回值是否需要报错 if (func->getReturnType()->isInt()) { pBuilder->createReturnInst(ConstantInteger::get(0)); } else if (func->getReturnType()->isFloat()) { pBuilder->createReturnInst(ConstantFloating::get(0.0F)); } else { pBuilder->createReturnInst(); } changed = true; // 标记IR被修改 } } } } return changed; } // 条件分支转换为无条件分支 // 主要针对已知条件值的分支转换为无条件分支 // 例如 if (cond) { ... } else { ... } 中的 cond 已经 // 确定为 true 或 false 的情况 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)); std::string opname; int constint = 0; float constfloat = 0.0F; bool constint_Use = false; bool constfloat_Use = false; if (constOperand != nullptr) { if (constOperand->isFloat()) { constfloat = constOperand->getFloat(); constfloat_Use = true; } else { constint = constOperand->getInt(); constint_Use = true; } } // 如果可以计算 if (constfloat_Use || constint_Use) { changed = true; auto thenBlock = dynamic_cast(thelast->get()->getOperand(1)); auto elseBlock = dynamic_cast(thelast->get()->getOperand(2)); SysYIROptUtils::usedelete(thelast->get()); thelast = basicblock->getInstructions().erase(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()); } } else { // cond为false或0 pBuilder->setPosition(basicblock.get(), basicblock->end()); pBuilder->createUncondBrInst(elseBlock, {}); // 更新CFG关系 basicblock->removeSuccessor(thenBlock); thenBlock->removePredecessor(basicblock.get()); // 删除thenBlock的phi指令中对应的basicblock.get()的传入值 for (auto &phiinst : thenBlock->getInstructions()) { if (phiinst->getKind() != Instruction::kPhi) { break; } // 使用 delBlk 方法删除 basicblock.get() 对应的传入值 dynamic_cast(phiinst.get())->delBlk(basicblock.get()); } } } } } return changed; } // ====================================================================== // 独立的CFG优化遍的实现 // ====================================================================== bool SysYDelInstAfterBrPass::runOnFunction(Function *F, AnalysisManager& AM) { return SysYCFGOptUtils::SysYDelInstAfterBr(F); } bool SysYDelEmptyBlockPass::runOnFunction(Function *F, AnalysisManager& AM) { return SysYCFGOptUtils::SysYDelEmptyBlock(F, pBuilder); } bool SysYDelNoPreBLockPass::runOnFunction(Function *F, AnalysisManager& AM) { return SysYCFGOptUtils::SysYDelNoPreBLock(F); } bool SysYBlockMergePass::runOnFunction(Function *F, AnalysisManager& AM) { return SysYCFGOptUtils::SysYBlockMerge(F); } bool SysYAddReturnPass::runOnFunction(Function *F, AnalysisManager& AM) { return SysYCFGOptUtils::SysYAddReturn(F, pBuilder); } bool SysYCondBr2BrPass::runOnFunction(Function *F, AnalysisManager& AM) { return SysYCFGOptUtils::SysYCondBr2Br(F, pBuilder); } } // namespace sysy