diff --git a/src/SysYIRCFGOpt.cpp b/src/SysYIRCFGOpt.cpp index e141b67..4098008 100644 --- a/src/SysYIRCFGOpt.cpp +++ b/src/SysYIRCFGOpt.cpp @@ -13,248 +13,374 @@ namespace sysy { // 删除br后的无用指令 -void SysYCFGOpt::SysYDelInstAfterBr() { - auto &functions = pModule->getFunctions(); - for (auto &function : functions) { - auto basicBlocks = function.second->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 (Branch) - SysYIROptUtils::usedelete(iter->get()); - else if ((*iter)->isTerminator()){ - Branch = true; - Branchiter = iter; - } +bool SysYCFGOpt::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 (Branch) + SysYIROptUtils::usedelete(iter->get()); + else if ((*iter)->isTerminator()){ + Branch = true; + Branchiter = iter; } - if (Branchiter != instructions.end()) ++Branchiter; - while (Branchiter != instructions.end()) - 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()); - } + } + 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; } // 合并空基本块 -void SysYCFGOpt::SysYBlockMerge() { - auto &functions = pModule->getFunctions(); //std::map> - for (auto &function : functions) { - // auto basicBlocks = function.second->getBasicBlocks(); - auto &func = function.second; - 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()) { +bool SysYCFGOpt::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()); + block->getInstructions().erase(thelastinstinst); + } else if (thelastinstinst->get()->isConditional()) { + // 如果是条件分支,判断条件是否相同,主要优化相同布尔表达式 + if (thelastinstinst->get()->getOperand(1)->getName() == thelastinstinst->get()->getOperand(1)->getName()) { SysYIROptUtils::usedelete(thelastinstinst->get()); block->getInstructions().erase(thelastinstinst); - } else if (thelastinstinst->get()->isConditional()) { - // 如果是条件分支,判断条件是否相同,主要优化相同布尔表达式 - if (thelastinstinst->get()->getOperand(1)->getName() == thelastinstinst->get()->getOperand(1)->getName()) { - SysYIROptUtils::usedelete(thelastinstinst->get()); - 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); - } - // 合并参数 - // TODO:是否需要去重? - for (auto &argm : nextarguments) { - argm->setParent(block); - block->insertArgument(argm); - } - // 更新前驱后继关系,类似树节点操作 - 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); - - } else { - blockiter++; } + // 将后继块的指令移动到当前块 + // 并将后继块的父指针改为当前块 + for (auto institer = nextBlock->begin(); institer != nextBlock->end();) { + institer->get()->setParent(block); + block->getInstructions().emplace_back(institer->release()); + institer = nextBlock->getInstructions().erase(institer); + } + // 合并参数 + // TODO:是否需要去重? + for (auto &argm : nextarguments) { + argm->setParent(block); + block->insertArgument(argm); + } + // 更新前驱后继关系,类似树节点操作 + 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后的处理 -void SysYCFGOpt::SysYDelNoPreBLock() { +bool SysYCFGOpt::SysYDelNoPreBLock(Function *func) { - auto &functions = pModule->getFunctions(); // std::map> - for (auto &function : functions) { - auto &func = function.second; + 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 &iterInst : blockIter->get()->getInstructions()) - SysYIROptUtils::usedelete(iterInst.get()); - - } - - - for (auto blockIter = func->getBasicBlocks().begin(); blockIter != func->getBasicBlocks().end();) { - if (!blockIter->get()->getreachable()) { - for (auto succblock : blockIter->get()->getSuccessors()) { - int indexphi = 1; - for (auto pred : succblock->getPredecessors()) { - if (pred == blockIter->get()) { - break; - } - indexphi++; - } - for (auto &phiinst : succblock->getInstructions()) { - if (phiinst->getKind() != Instruction::kPhi) { - break; - } - phiinst->removeOperand(indexphi); - } - } - // 删除不可达基本块,注意迭代器不可达问题 - func->removeBasicBlock((blockIter++)->get()); - } else { - blockIter++; + 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); } } } -} -void SysYCFGOpt::SysYDelEmptyBlock() { - auto &functions = pModule->getFunctions(); - for (auto &function : functions) { - // 收集不可达基本块 - // 这里的不可达基本块是指没有实际指令的基本块 - // 当一个基本块没有实际指令例如只有phi指令和一个uncondbr指令时,也会被视作不可达 - auto basicBlocks = function.second->getBasicBlocks(); - std::map EmptyBlocks; - // 空块儿和后继的基本块的映射 - for (auto &basicBlock : basicBlocks) { - if (basicBlock->getNumInstructions() == 0) { - if (basicBlock->getNumSuccessors() == 1) { - EmptyBlocks[basicBlock.get()] = basicBlock->getSuccessors().front(); + // 删除不可达基本块指令 + for (auto blockIter = func->getBasicBlocks().begin(); blockIter != func->getBasicBlocks().end();blockIter++) { + if (!blockIter->get()->getreachable()) + for (auto &iterInst : blockIter->get()->getInstructions()) + SysYIROptUtils::usedelete(iterInst.get()); + + } + + + for (auto blockIter = func->getBasicBlocks().begin(); blockIter != func->getBasicBlocks().end();) { + if (!blockIter->get()->getreachable()) { + for (auto succblock : blockIter->get()->getSuccessors()) { + int indexphi = 1; + for (auto pred : succblock->getPredecessors()) { + if (pred == blockIter->get()) { + break; + } + indexphi++; + } + for (auto &phiinst : succblock->getInstructions()) { + if (phiinst->getKind() != Instruction::kPhi) { + break; + } + phiinst->removeOperand(indexphi); } } - else{ - // 如果只有phi指令和一个uncondbr。(phi)*(uncondbr)? - // 判断除了最后一个指令之外是不是只有phi指令 - bool onlyPhi = true; - for (auto &inst : basicBlock->getInstructions()) { - if (!inst->isPhi() && !inst->isUnconditional()) { - onlyPhi = false; + // 删除不可达基本块,注意迭代器不可达问题 + func->removeBasicBlock((blockIter++)->get()); + changed = true; + } else { + blockIter++; + } + } + + return changed; +} + +// 删除空块 +bool SysYCFGOpt::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) + EmptyBlocks[basicBlock.get()] = basicBlock->getSuccessors().front(); + } + + + } + // 更新基本块信息,增加必要指令 + for (auto &basicBlock : basicBlocks) { + // 把空块转换成只有跳转指令的不可达块 + if (distance(basicBlock->begin(), basicBlock->end()) == 0) { + if (basicBlock->getNumSuccessors() == 0) { + continue; + } + if (basicBlock->getNumSuccessors() > 1) { + assert(""); + } + 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.find(dynamic_cast(thelastinst->get()->getOperand(0))) != + EmptyBlocks.end()) { + thelastBlockOld = dynamic_cast(thelastinst->get()->getOperand(0)); + thelastinst->get()->replaceOperand(0, EmptyBlocks[thelastBlockOld]); + } + + basicBlock->removeSuccessor(OldBrBlock); + OldBrBlock->removePredecessor(basicBlock.get()); + basicBlock->addSuccessor(dynamic_cast(thelastinst->get()->getOperand(0))); + dynamic_cast(thelastinst->get()->getOperand(0))->addPredecessor(basicBlock.get()); + + if (thelastBlockOld != nullptr) { + int indexphi = 0; + for (auto &pred : dynamic_cast(thelastinst->get()->getOperand(0))->getPredecessors()) { + if (pred == thelastBlockOld) { + break; + } + indexphi++; + } + + // 更新phi指令的操作数 + // 移除thelastBlockOld对应的phi操作数 + for (auto &InstInNew : dynamic_cast(thelastinst->get()->getOperand(0))->getInstructions()) { + if (InstInNew->isPhi()) { + dynamic_cast(InstInNew.get())->removeOperand(indexphi + 1); + } else { break; } } - if(onlyPhi) - EmptyBlocks[basicBlock.get()] = basicBlock->getSuccessors().front(); } - - - } - // 更新基本块信息,增加必要指令 - for (auto &basicBlock : basicBlocks) { - // 把空块转换成只有跳转指令的不可达块 - if (distance(basicBlock->begin(), basicBlock->end()) == 0) { - if (basicBlock->getNumSuccessors() == 0) { - continue; - } - if (basicBlock->getNumSuccessors() > 1) { - assert(""); - } + + } else if (thelastinst->get()->getKind() == Instruction::kCondBr) { + auto OldThenBlock = dynamic_cast(thelastinst->get()->getOperand(1)); + auto OldElseBlock = dynamic_cast(thelastinst->get()->getOperand(2)); + + BasicBlock *thelastBlockOld = nullptr; + while (EmptyBlocks.find(dynamic_cast(thelastinst->get()->getOperand(1))) != + EmptyBlocks.end()) { + thelastBlockOld = dynamic_cast(thelastinst->get()->getOperand(1)); + thelastinst->get()->replaceOperand( + 1, EmptyBlocks[dynamic_cast(thelastinst->get()->getOperand(1))]); + } + basicBlock->removeSuccessor(OldThenBlock); + OldThenBlock->removePredecessor(basicBlock.get()); + // 处理 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(basicBlock->getSuccessors()[0], {}); + pBuilder->createUncondBrInst(thebrBlock, {}); continue; } + basicBlock->addSuccessor(dynamic_cast(thelastinst->get()->getOperand(1))); + dynamic_cast(thelastinst->get()->getOperand(1))->addPredecessor(basicBlock.get()); + // auto indexInNew = dynamic_cast(thelastinst->get()->getOperand(0))->getPredecessors(). - auto thelastinst = basicBlock->getInstructions().end(); - --thelastinst; - - // 根据br指令传递的后继块信息,跳过空块链 - if (thelastinst->get()->isUnconditional()) { - BasicBlock* OldBrBlock = dynamic_cast(thelastinst->get()->getOperand(0)); - 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[thelastBlockOld]); + if (thelastBlockOld != nullptr) { + int indexphi = 0; + for (auto &pred : dynamic_cast(thelastinst->get()->getOperand(1))->getPredecessors()) { + if (pred == thelastBlockOld) { + break; + } + indexphi++; } + for (auto &InstInNew : dynamic_cast(thelastinst->get()->getOperand(1))->getInstructions()) { + if (InstInNew->isPhi()) { + dynamic_cast(InstInNew.get())->removeOperand(indexphi + 1); + } else { + break; + } + } + } + + thelastBlockOld = nullptr; + while (EmptyBlocks.find(dynamic_cast(thelastinst->get()->getOperand(2))) != + EmptyBlocks.end()) { + thelastBlockOld = dynamic_cast(thelastinst->get()->getOperand(2)); + thelastinst->get()->replaceOperand( + 2, EmptyBlocks[dynamic_cast(thelastinst->get()->getOperand(2))]); + } + basicBlock->removeSuccessor(OldElseBlock); + OldElseBlock->removePredecessor(basicBlock.get()); + // 处理 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, {}); + continue; + } + basicBlock->addSuccessor(dynamic_cast(thelastinst->get()->getOperand(2))); + dynamic_cast(thelastinst->get()->getOperand(2))->addPredecessor(basicBlock.get()); + + if (thelastBlockOld != nullptr) { + int indexphi = 0; + for (auto &pred : dynamic_cast(thelastinst->get()->getOperand(2))->getPredecessors()) { + if (pred == thelastBlockOld) { + break; + } + indexphi++; + } + for (auto &InstInNew : dynamic_cast(thelastinst->get()->getOperand(2))->getInstructions()) { + if (InstInNew->isPhi()) { + dynamic_cast(InstInNew.get())->removeOperand(indexphi + 1); + } else { + break; + } + } + } + } else { + if (basicBlock->getNumSuccessors() == 1) { + 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()); - if (thelastBlockOld != nullptr) { int indexphi = 0; for (auto &pred : dynamic_cast(thelastinst->get()->getOperand(0))->getPredecessors()) { @@ -264,8 +390,6 @@ void SysYCFGOpt::SysYDelEmptyBlock() { indexphi++; } - // 更新phi指令的操作数 - // 移除thelastBlockOld对应的phi操作数 for (auto &InstInNew : dynamic_cast(thelastinst->get()->getOperand(0))->getInstructions()) { if (InstInNew->isPhi()) { dynamic_cast(InstInNew.get())->removeOperand(indexphi + 1); @@ -274,200 +398,82 @@ void SysYCFGOpt::SysYDelEmptyBlock() { } } } - - } else if (thelastinst->get()->getKind() == Instruction::kCondBr) { - auto OldThenBlock = dynamic_cast(thelastinst->get()->getOperand(1)); - auto OldElseBlock = dynamic_cast(thelastinst->get()->getOperand(2)); - - BasicBlock *thelastBlockOld = nullptr; - while (EmptyBlocks.find(dynamic_cast(thelastinst->get()->getOperand(1))) != - EmptyBlocks.end()) { - thelastBlockOld = dynamic_cast(thelastinst->get()->getOperand(1)); - thelastinst->get()->replaceOperand( - 1, EmptyBlocks[dynamic_cast(thelastinst->get()->getOperand(1))]); - } - basicBlock->removeSuccessor(OldThenBlock); - OldThenBlock->removePredecessor(basicBlock.get()); - // 处理 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, {}); - continue; - } - basicBlock->addSuccessor(dynamic_cast(thelastinst->get()->getOperand(1))); - dynamic_cast(thelastinst->get()->getOperand(1))->addPredecessor(basicBlock.get()); - // auto indexInNew = dynamic_cast(thelastinst->get()->getOperand(0))->getPredecessors(). - - if (thelastBlockOld != nullptr) { - int indexphi = 0; - for (auto &pred : dynamic_cast(thelastinst->get()->getOperand(1))->getPredecessors()) { - if (pred == thelastBlockOld) { - break; - } - indexphi++; - } - - for (auto &InstInNew : dynamic_cast(thelastinst->get()->getOperand(1))->getInstructions()) { - if (InstInNew->isPhi()) { - dynamic_cast(InstInNew.get())->removeOperand(indexphi + 1); - } else { - break; - } - } - } - - thelastBlockOld = nullptr; - while (EmptyBlocks.find(dynamic_cast(thelastinst->get()->getOperand(2))) != - EmptyBlocks.end()) { - thelastBlockOld = dynamic_cast(thelastinst->get()->getOperand(2)); - thelastinst->get()->replaceOperand( - 2, EmptyBlocks[dynamic_cast(thelastinst->get()->getOperand(2))]); - } - basicBlock->removeSuccessor(OldElseBlock); - OldElseBlock->removePredecessor(basicBlock.get()); - // 处理 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, {}); - continue; - } - basicBlock->addSuccessor(dynamic_cast(thelastinst->get()->getOperand(2))); - dynamic_cast(thelastinst->get()->getOperand(2))->addPredecessor(basicBlock.get()); - - if (thelastBlockOld != nullptr) { - int indexphi = 0; - for (auto &pred : dynamic_cast(thelastinst->get()->getOperand(2))->getPredecessors()) { - if (pred == thelastBlockOld) { - break; - } - indexphi++; - } - for (auto &InstInNew : dynamic_cast(thelastinst->get()->getOperand(2))->getInstructions()) { - if (InstInNew->isPhi()) { - dynamic_cast(InstInNew.get())->removeOperand(indexphi + 1); - } else { - break; - } - } - } - } else { - if (basicBlock->getNumSuccessors() == 1) { - 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()); - 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 = function.second->getBasicBlocks().begin(); iter != function.second->getBasicBlocks().end();) { - - if (EmptyBlocks.find(iter->get()) != EmptyBlocks.end()) { - // EntryBlock跳过 - if (iter->get() == function.second->getEntryBlock()) { - ++iter; - continue; - } - - for (auto &iterInst : iter->get()->getInstructions()) - SysYIROptUtils::usedelete(iterInst.get()); - // 删除不可达基本块的phi指令的操作数 - for (auto &succ : iter->get()->getSuccessors()) { - int index = 0; - for (auto &pred : succ->getPredecessors()) { - if (pred == iter->get()) { - break; - } - index++; - } - - for (auto &instinsucc : succ->getInstructions()) { - if (instinsucc->isPhi()) { - dynamic_cast(instinsucc.get())->removeOperand(index); - } else { - break; - } - } - } - - function.second->removeBasicBlock((iter++)->get()); - } else { - ++iter; } } } + + for (auto iter = func->getBasicBlocks().begin(); iter != func->getBasicBlocks().end();) { + + if (EmptyBlocks.find(iter->get()) != EmptyBlocks.end()) { + // EntryBlock跳过 + if (iter->get() == func->getEntryBlock()) { + ++iter; + continue; + } + + for (auto &iterInst : iter->get()->getInstructions()) + SysYIROptUtils::usedelete(iterInst.get()); + // 删除不可达基本块的phi指令的操作数 + for (auto &succ : iter->get()->getSuccessors()) { + int index = 0; + for (auto &pred : succ->getPredecessors()) { + if (pred == iter->get()) { + break; + } + index++; + } + + for (auto &instinsucc : succ->getInstructions()) { + if (instinsucc->isPhi()) { + dynamic_cast(instinsucc.get())->removeOperand(index); + } else { + break; + } + } + } + + func->removeBasicBlock((iter++)->get()); + changed = true; + } else { + ++iter; + } + } + + return changed; + } // 如果函数没有返回指令,则添加一个默认返回指令(主要解决void函数没有返回指令的问题) -void SysYCFGOpt::SysYAddReturn() { - auto &functions = pModule->getFunctions(); - for (auto &function : functions) { - auto &func = function.second; - auto basicBlocks = func->getBasicBlocks(); - for (auto &block : basicBlocks) { - if (block->getNumSuccessors() == 0) { - // 如果基本块没有后继块,则添加一个返回指令 - if (block->getNumInstructions() == 0) { - pBuilder->setPosition(block.get(), block->end()); - pBuilder->createReturnInst(); - } - 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; +bool SysYCFGOpt::SysYAddReturn(Function *func, IRBuilder* pBuilder) { + bool changed = false; + auto basicBlocks = func->getBasicBlocks(); + for (auto &block : basicBlocks) { + if (block->getNumSuccessors() == 0) { + changed = true; + // 如果基本块没有后继块,则添加一个返回指令 + if (block->getNumInstructions() == 0) { + pBuilder->setPosition(block.get(), block->end()); + pBuilder->createReturnInst(); + } + 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(ConstantValue::get(0)); - } else if (func->getReturnType()->isFloat()) { - pBuilder->createReturnInst(ConstantValue::get(0.0F)); - } else { - pBuilder->createReturnInst(); - } + pBuilder->setPosition(block.get(), block->end()); + // TODO: 如果int float函数缺少返回值是否需要报错 + if (func->getReturnType()->isInt()) { + pBuilder->createReturnInst(ConstantValue::get(0)); + } else if (func->getReturnType()->isFloat()) { + pBuilder->createReturnInst(ConstantValue::get(0.0F)); + } else { + pBuilder->createReturnInst(); } } } } + + return changed; } } // namespace sysy diff --git a/src/include/SysYIRCFGOpt.h b/src/include/SysYIRCFGOpt.h index 9c791aa..bf0e524 100644 --- a/src/include/SysYIRCFGOpt.h +++ b/src/include/SysYIRCFGOpt.h @@ -26,18 +26,32 @@ class SysYCFGOpt { SysYCFGOpt(Module *pMoudle, IRBuilder *pBuilder) : pModule(pMoudle), pBuilder(pBuilder) {} void SysYOptimizateAfterIR(){ - SysYDelInstAfterBr(); - SysYBlockMerge(); - SysYDelNoPreBLock(); - SysYDelEmptyBlock(); - SysYAddReturn(); + + auto &functions = pModule->getFunctions(); + for (auto &function : functions) { + bool changed = false; + while(changed){ + // 删除br后面的无用指令 + changed |= SysYDelInstAfterBr(function.second.get()); + // 合并空基本块 + changed |= SysYBlockMerge(function.second.get()); + // 删除无前驱块 + changed |= SysYDelNoPreBLock(function.second.get()); + // 删除空块 + changed |= SysYDelEmptyBlock(function.second.get(), pBuilder); + // 添加return指令 + changed |= SysYAddReturn(function.second.get(), pBuilder); + } + } } - void SysYDelInstAfterBr(); // 删除br后面的指令 - void SysYDelEmptyBlock(); // 空块删除 - void SysYDelNoPreBLock(); // 删除无前驱块(不可达块) - void SysYBlockMerge(); // 合并基本块(主要针对嵌套if while的exit块, + +public: + static bool SysYDelInstAfterBr(Function *func); // 删除br后面的指令 + static bool SysYDelEmptyBlock(Function *func, IRBuilder* pBuilder); // 空块删除 + static bool SysYDelNoPreBLock(Function *func); // 删除无前驱块(不可达块) + static bool SysYBlockMerge(Function *func); // 合并基本块(主要针对嵌套if while的exit块, // 也可以修改IR生成实现回填机制 - void SysYAddReturn(); // 添加return指令(主要针对Void函数) + static bool SysYAddReturn(Function *func, IRBuilder* pBuilder); // 添加return指令(主要针对Void函数) }; } // namespace sysy