增加Reg2Mem,但是会生成死存储指令,需要死代码删除支持识别死存储指令
This commit is contained in:
129
src/Reg2Mem.cpp
129
src/Reg2Mem.cpp
@@ -0,0 +1,129 @@
|
||||
#include "Reg2Mem.h"
|
||||
#include <cstddef>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
|
||||
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 *>(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
|
||||
|
||||
Reference in New Issue
Block a user