#include "Reg2Mem.h" #include #include #include #include namespace sysy { /** * 删除phi节点 * 删除phi节点后可能会生成冗余存储代码 */ void Reg2Mem::DeletePhiInst(){ auto &functions = pModule->getFunctions(); for (auto &function : functions) { auto basicBlocks = function.second->getBasicBlocks(); for (auto &basicBlock : basicBlocks) { for (auto iter = basicBlock->begin(); iter != basicBlock->end();) { auto &instruction = *iter; if (instruction->isPhi()) { auto predBlocks = basicBlock->getPredecessors(); // 寻找源和目的 // 目的就是phi指令的第一个操作数 // 源就是phi指令的后续操作数 auto destination = instruction->getOperand(0); int predBlockindex = 0; for (auto &predBlock : predBlocks) { ++predBlockindex; // 判断前驱块儿只有一个后继还是多个后继 // 如果有多个 auto source = instruction->getOperand(predBlockindex); if (source == destination) { continue; } // std::cout << predBlock->getNumSuccessors() << std::endl; if (predBlock->getNumSuccessors() > 1) { // 创建一个basicblock auto newbasicBlock = function.second->addBasicBlock(); std::stringstream ss; ss << " phidel.L" << pBuilder->getLabelIndex(); newbasicBlock->setName(ss.str()); ss.str(""); // // 修改前驱后继关系 basicBlock->replacePredecessor(predBlock, newbasicBlock); // predBlock = newbasicBlock; newbasicBlock->addPredecessor(predBlock); newbasicBlock->addSuccessor(basicBlock.get()); predBlock->removeSuccessor(basicBlock.get()); predBlock->addSuccessor(newbasicBlock); // std::cout << "the block name is " << basicBlock->getName() << std::endl; // for (auto pb : basicBlock->getPredecessors()) { // // newbasicBlock->addPredecessor(pb); // std::cout << pb->getName() << std::endl; // } // sysy::BasicBlock::conectBlocks(newbasicBlock, static_cast(basicBlock.get())); // 若后为跳转指令,应该修改跳转指令所到达的位置 auto thelastinst = predBlock->end(); (--thelastinst); if (thelastinst->get()->isConditional() || thelastinst->get()->isUnconditional()) { // 如果是跳转指令 auto opnum = thelastinst->get()->getNumOperands(); for (size_t i = 0; i < opnum; i++) { if (thelastinst->get()->getOperand(i) == basicBlock.get()) { thelastinst->get()->replaceOperand(i, newbasicBlock); } } } // 在新块中插入store指令 pBuilder->setPosition(newbasicBlock, newbasicBlock->end()); // pBuilder->createStoreInst(source, destination); if (source->isInt() || source->isFloat()) { pBuilder->createStoreInst(source, destination); } else { auto loadInst = pBuilder->createLoadInst(source); pBuilder->createStoreInst(loadInst, destination); } // pBuilder->createMoveInst(Instruction::kMove, destination->getType(), destination, source, // newbasicBlock); pBuilder->setPosition(newbasicBlock, newbasicBlock->end()); pBuilder->createUncondBrInst(basicBlock.get(), {}); } else { // 如果前驱块只有一个后继 auto thelastinst = predBlock->end(); (--thelastinst); // std::cout << predBlock->getName() << std::endl; // std::cout << thelastinst->get() << std::endl; // std::cout << "First point 11 " << std::endl; if (thelastinst->get()->isConditional() || thelastinst->get()->isUnconditional()) { // 在跳转语句前insert st指令 pBuilder->setPosition(predBlock, thelastinst); } else { pBuilder->setPosition(predBlock, predBlock->end()); } if (source->isInt() || source->isFloat()) { pBuilder->createStoreInst(source, destination); } else { auto loadInst = pBuilder->createLoadInst(source); pBuilder->createStoreInst(loadInst, destination); } } } // 删除phi指令 auto &instructions = basicBlock->getInstructions(); usedelete(iter->get()); iter = instructions.erase(iter); if (basicBlock->getNumInstructions() == 0) { if (basicBlock->getNumSuccessors() == 1) { pBuilder->setPosition(basicBlock.get(), basicBlock->end()); pBuilder->createUncondBrInst(basicBlock->getSuccessors()[0], {}); } } } else { break; } } } } } void Reg2Mem::usedelete(Instruction *instr) { for (auto &use : instr->getOperands()) { auto val = use->getValue(); val->removeUse(use); } } } // namespace sysy