[CFG]CFG优化方法转换为静态方法,方便其他优化遍调用,TODO:简化条件分支
This commit is contained in:
@@ -13,248 +13,374 @@ namespace sysy {
|
|||||||
|
|
||||||
|
|
||||||
// 删除br后的无用指令
|
// 删除br后的无用指令
|
||||||
void SysYCFGOpt::SysYDelInstAfterBr() {
|
bool SysYCFGOpt::SysYDelInstAfterBr(Function *func) {
|
||||||
auto &functions = pModule->getFunctions();
|
bool changed = false;
|
||||||
for (auto &function : functions) {
|
|
||||||
auto basicBlocks = function.second->getBasicBlocks();
|
auto basicBlocks = func->getBasicBlocks();
|
||||||
for (auto &basicBlock : basicBlocks) {
|
for (auto &basicBlock : basicBlocks) {
|
||||||
bool Branch = false;
|
bool Branch = false;
|
||||||
auto &instructions = basicBlock->getInstructions();
|
auto &instructions = basicBlock->getInstructions();
|
||||||
auto Branchiter = instructions.end();
|
auto Branchiter = instructions.end();
|
||||||
for (auto iter = instructions.begin(); iter != instructions.end(); ++iter) {
|
for (auto iter = instructions.begin(); iter != instructions.end(); ++iter) {
|
||||||
if (Branch)
|
if (Branch)
|
||||||
SysYIROptUtils::usedelete(iter->get());
|
SysYIROptUtils::usedelete(iter->get());
|
||||||
else if ((*iter)->isTerminator()){
|
else if ((*iter)->isTerminator()){
|
||||||
Branch = true;
|
Branch = true;
|
||||||
Branchiter = iter;
|
Branchiter = iter;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (Branchiter != instructions.end()) ++Branchiter;
|
}
|
||||||
while (Branchiter != instructions.end())
|
if (Branchiter != instructions.end()) ++Branchiter;
|
||||||
Branchiter = instructions.erase(Branchiter);
|
while (Branchiter != instructions.end()) {
|
||||||
|
changed = true;
|
||||||
if (Branch) { // 更新前驱后继关系
|
Branchiter = instructions.erase(Branchiter);
|
||||||
auto thelastinstinst = basicBlock->getInstructions().end();
|
}
|
||||||
--thelastinstinst;
|
|
||||||
auto &Successors = basicBlock->getSuccessors();
|
if (Branch) { // 更新前驱后继关系
|
||||||
for (auto iterSucc = Successors.begin(); iterSucc != Successors.end();) {
|
auto thelastinstinst = basicBlock->getInstructions().end();
|
||||||
(*iterSucc)->removePredecessor(basicBlock.get());
|
--thelastinstinst;
|
||||||
basicBlock->removeSuccessor(*iterSucc);
|
auto &Successors = basicBlock->getSuccessors();
|
||||||
}
|
for (auto iterSucc = Successors.begin(); iterSucc != Successors.end();) {
|
||||||
if (thelastinstinst->get()->isUnconditional()) {
|
(*iterSucc)->removePredecessor(basicBlock.get());
|
||||||
BasicBlock* branchBlock = dynamic_cast<BasicBlock *>(thelastinstinst->get()->getOperand(0));
|
basicBlock->removeSuccessor(*iterSucc);
|
||||||
basicBlock->addSuccessor(branchBlock);
|
}
|
||||||
branchBlock->addPredecessor(basicBlock.get());
|
if (thelastinstinst->get()->isUnconditional()) {
|
||||||
} else if (thelastinstinst->get()->isConditional()) {
|
BasicBlock* branchBlock = dynamic_cast<BasicBlock *>(thelastinstinst->get()->getOperand(0));
|
||||||
BasicBlock* thenBlock = dynamic_cast<BasicBlock *>(thelastinstinst->get()->getOperand(1));
|
basicBlock->addSuccessor(branchBlock);
|
||||||
BasicBlock* elseBlock = dynamic_cast<BasicBlock *>(thelastinstinst->get()->getOperand(2));
|
branchBlock->addPredecessor(basicBlock.get());
|
||||||
basicBlock->addSuccessor(thenBlock);
|
} else if (thelastinstinst->get()->isConditional()) {
|
||||||
basicBlock->addSuccessor(elseBlock);
|
BasicBlock* thenBlock = dynamic_cast<BasicBlock *>(thelastinstinst->get()->getOperand(1));
|
||||||
thenBlock->addPredecessor(basicBlock.get());
|
BasicBlock* elseBlock = dynamic_cast<BasicBlock *>(thelastinstinst->get()->getOperand(2));
|
||||||
elseBlock->addPredecessor(basicBlock.get());
|
basicBlock->addSuccessor(thenBlock);
|
||||||
}
|
basicBlock->addSuccessor(elseBlock);
|
||||||
|
thenBlock->addPredecessor(basicBlock.get());
|
||||||
|
elseBlock->addPredecessor(basicBlock.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 合并空基本块
|
// 合并空基本块
|
||||||
void SysYCFGOpt::SysYBlockMerge() {
|
bool SysYCFGOpt::SysYBlockMerge(Function *func) {
|
||||||
auto &functions = pModule->getFunctions(); //std::map<std::string, std::unique_ptr<Function>>
|
bool changed = false;
|
||||||
for (auto &function : functions) {
|
|
||||||
// auto basicBlocks = function.second->getBasicBlocks();
|
for (auto blockiter = func->getBasicBlocks().begin();
|
||||||
auto &func = function.second;
|
blockiter != func->getBasicBlocks().end();) {
|
||||||
for (auto blockiter = func->getBasicBlocks().begin();
|
if (blockiter->get()->getNumSuccessors() == 1) {
|
||||||
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;
|
||||||
if (((blockiter->get())->getSuccessors()[0])->getNumPredecessors() == 1) {
|
BasicBlock* block = blockiter->get();
|
||||||
// std::cout << "merge block: " << blockiter->get()->getName() << std::endl;
|
BasicBlock* nextBlock = blockiter->get()->getSuccessors()[0];
|
||||||
BasicBlock* block = blockiter->get();
|
auto nextarguments = nextBlock->getArguments();
|
||||||
BasicBlock* nextBlock = blockiter->get()->getSuccessors()[0];
|
// 删除br指令
|
||||||
auto nextarguments = nextBlock->getArguments();
|
if (block->getNumInstructions() != 0) {
|
||||||
// 删除br指令
|
auto thelastinstinst = block->end();
|
||||||
if (block->getNumInstructions() != 0) {
|
(--thelastinstinst);
|
||||||
auto thelastinstinst = block->end();
|
if (thelastinstinst->get()->isUnconditional()) {
|
||||||
(--thelastinstinst);
|
SysYIROptUtils::usedelete(thelastinstinst->get());
|
||||||
if (thelastinstinst->get()->isUnconditional()) {
|
block->getInstructions().erase(thelastinstinst);
|
||||||
|
} else if (thelastinstinst->get()->isConditional()) {
|
||||||
|
// 如果是条件分支,判断条件是否相同,主要优化相同布尔表达式
|
||||||
|
if (thelastinstinst->get()->getOperand(1)->getName() == thelastinstinst->get()->getOperand(1)->getName()) {
|
||||||
SysYIROptUtils::usedelete(thelastinstinst->get());
|
SysYIROptUtils::usedelete(thelastinstinst->get());
|
||||||
block->getInstructions().erase(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());
|
|
||||||
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<BasicBlock *> 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<BasicBlock *> 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 {
|
} else {
|
||||||
blockiter++;
|
blockiter++;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
blockiter++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除无前驱块,兼容SSA后的处理
|
// 删除无前驱块,兼容SSA后的处理
|
||||||
void SysYCFGOpt::SysYDelNoPreBLock() {
|
bool SysYCFGOpt::SysYDelNoPreBLock(Function *func) {
|
||||||
|
|
||||||
auto &functions = pModule->getFunctions(); // std::map<std::string, std::unique_ptr<sysy::Function>>
|
bool changed = false;
|
||||||
for (auto &function : functions) {
|
|
||||||
auto &func = function.second;
|
|
||||||
|
|
||||||
for (auto &block : func->getBasicBlocks()) {
|
for (auto &block : func->getBasicBlocks()) {
|
||||||
block->setreachableFalse();
|
block->setreachableFalse();
|
||||||
}
|
}
|
||||||
// 对函数基本块做一个拓扑排序,排查不可达基本块
|
// 对函数基本块做一个拓扑排序,排查不可达基本块
|
||||||
auto entryBlock = func->getEntryBlock();
|
auto entryBlock = func->getEntryBlock();
|
||||||
entryBlock->setreachableTrue();
|
entryBlock->setreachableTrue();
|
||||||
std::queue<BasicBlock *> blockqueue;
|
std::queue<BasicBlock *> blockqueue;
|
||||||
blockqueue.push(entryBlock);
|
blockqueue.push(entryBlock);
|
||||||
while (!blockqueue.empty()) {
|
while (!blockqueue.empty()) {
|
||||||
auto block = blockqueue.front();
|
auto block = blockqueue.front();
|
||||||
blockqueue.pop();
|
blockqueue.pop();
|
||||||
for (auto &succ : block->getSuccessors()) {
|
for (auto &succ : block->getSuccessors()) {
|
||||||
if (!succ->getreachable()) {
|
if (!succ->getreachable()) {
|
||||||
succ->setreachableTrue();
|
succ->setreachableTrue();
|
||||||
blockqueue.push(succ);
|
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++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void SysYCFGOpt::SysYDelEmptyBlock() {
|
// 删除不可达基本块指令
|
||||||
auto &functions = pModule->getFunctions();
|
for (auto blockIter = func->getBasicBlocks().begin(); blockIter != func->getBasicBlocks().end();blockIter++) {
|
||||||
for (auto &function : functions) {
|
if (!blockIter->get()->getreachable())
|
||||||
// 收集不可达基本块
|
for (auto &iterInst : blockIter->get()->getInstructions())
|
||||||
// 这里的不可达基本块是指没有实际指令的基本块
|
SysYIROptUtils::usedelete(iterInst.get());
|
||||||
// 当一个基本块没有实际指令例如只有phi指令和一个uncondbr指令时,也会被视作不可达
|
|
||||||
auto basicBlocks = function.second->getBasicBlocks();
|
}
|
||||||
std::map<sysy::BasicBlock *, BasicBlock *> EmptyBlocks;
|
|
||||||
// 空块儿和后继的基本块的映射
|
|
||||||
for (auto &basicBlock : basicBlocks) {
|
for (auto blockIter = func->getBasicBlocks().begin(); blockIter != func->getBasicBlocks().end();) {
|
||||||
if (basicBlock->getNumInstructions() == 0) {
|
if (!blockIter->get()->getreachable()) {
|
||||||
if (basicBlock->getNumSuccessors() == 1) {
|
for (auto succblock : blockIter->get()->getSuccessors()) {
|
||||||
EmptyBlocks[basicBlock.get()] = basicBlock->getSuccessors().front();
|
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)?
|
func->removeBasicBlock((blockIter++)->get());
|
||||||
// 判断除了最后一个指令之外是不是只有phi指令
|
changed = true;
|
||||||
bool onlyPhi = true;
|
} else {
|
||||||
for (auto &inst : basicBlock->getInstructions()) {
|
blockIter++;
|
||||||
if (!inst->isPhi() && !inst->isUnconditional()) {
|
}
|
||||||
onlyPhi = false;
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除空块
|
||||||
|
bool SysYCFGOpt::SysYDelEmptyBlock(Function *func, IRBuilder* pBuilder) {
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
// 收集不可达基本块
|
||||||
|
// 这里的不可达基本块是指没有实际指令的基本块
|
||||||
|
// 当一个基本块没有实际指令例如只有phi指令和一个uncondbr指令时,也会被视作不可达
|
||||||
|
auto basicBlocks = func->getBasicBlocks();
|
||||||
|
std::map<sysy::BasicBlock *, BasicBlock *> 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<BasicBlock *>(thelastinst->get()->getOperand(0));
|
||||||
|
BasicBlock *thelastBlockOld = nullptr;
|
||||||
|
// 如果空块链表为多个块
|
||||||
|
while (EmptyBlocks.find(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))) !=
|
||||||
|
EmptyBlocks.end()) {
|
||||||
|
thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0));
|
||||||
|
thelastinst->get()->replaceOperand(0, EmptyBlocks[thelastBlockOld]);
|
||||||
|
}
|
||||||
|
|
||||||
|
basicBlock->removeSuccessor(OldBrBlock);
|
||||||
|
OldBrBlock->removePredecessor(basicBlock.get());
|
||||||
|
basicBlock->addSuccessor(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0)));
|
||||||
|
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->addPredecessor(basicBlock.get());
|
||||||
|
|
||||||
|
if (thelastBlockOld != nullptr) {
|
||||||
|
int indexphi = 0;
|
||||||
|
for (auto &pred : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->getPredecessors()) {
|
||||||
|
if (pred == thelastBlockOld) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
indexphi++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新phi指令的操作数
|
||||||
|
// 移除thelastBlockOld对应的phi操作数
|
||||||
|
for (auto &InstInNew : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->getInstructions()) {
|
||||||
|
if (InstInNew->isPhi()) {
|
||||||
|
dynamic_cast<PhiInst *>(InstInNew.get())->removeOperand(indexphi + 1);
|
||||||
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(onlyPhi)
|
|
||||||
EmptyBlocks[basicBlock.get()] = basicBlock->getSuccessors().front();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (thelastinst->get()->getKind() == Instruction::kCondBr) {
|
||||||
}
|
auto OldThenBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1));
|
||||||
// 更新基本块信息,增加必要指令
|
auto OldElseBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2));
|
||||||
for (auto &basicBlock : basicBlocks) {
|
|
||||||
// 把空块转换成只有跳转指令的不可达块
|
BasicBlock *thelastBlockOld = nullptr;
|
||||||
if (distance(basicBlock->begin(), basicBlock->end()) == 0) {
|
while (EmptyBlocks.find(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1))) !=
|
||||||
if (basicBlock->getNumSuccessors() == 0) {
|
EmptyBlocks.end()) {
|
||||||
continue;
|
thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1));
|
||||||
}
|
thelastinst->get()->replaceOperand(
|
||||||
if (basicBlock->getNumSuccessors() > 1) {
|
1, EmptyBlocks[dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1))]);
|
||||||
assert("");
|
}
|
||||||
}
|
basicBlock->removeSuccessor(OldThenBlock);
|
||||||
|
OldThenBlock->removePredecessor(basicBlock.get());
|
||||||
|
// 处理 then 和 else 分支合并的情况
|
||||||
|
if (dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)) ==
|
||||||
|
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))) {
|
||||||
|
auto thebrBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1));
|
||||||
|
SysYIROptUtils::usedelete(thelastinst->get());
|
||||||
|
thelastinst = basicBlock->getInstructions().erase(thelastinst);
|
||||||
pBuilder->setPosition(basicBlock.get(), basicBlock->end());
|
pBuilder->setPosition(basicBlock.get(), basicBlock->end());
|
||||||
pBuilder->createUncondBrInst(basicBlock->getSuccessors()[0], {});
|
pBuilder->createUncondBrInst(thebrBlock, {});
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
basicBlock->addSuccessor(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)));
|
||||||
|
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1))->addPredecessor(basicBlock.get());
|
||||||
|
// auto indexInNew = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->getPredecessors().
|
||||||
|
|
||||||
auto thelastinst = basicBlock->getInstructions().end();
|
if (thelastBlockOld != nullptr) {
|
||||||
--thelastinst;
|
int indexphi = 0;
|
||||||
|
for (auto &pred : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1))->getPredecessors()) {
|
||||||
// 根据br指令传递的后继块信息,跳过空块链
|
if (pred == thelastBlockOld) {
|
||||||
if (thelastinst->get()->isUnconditional()) {
|
break;
|
||||||
BasicBlock* OldBrBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0));
|
}
|
||||||
BasicBlock *thelastBlockOld = nullptr;
|
indexphi++;
|
||||||
// 如果空块链表为多个块
|
|
||||||
while (EmptyBlocks.find(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))) !=
|
|
||||||
EmptyBlocks.end()) {
|
|
||||||
thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0));
|
|
||||||
thelastinst->get()->replaceOperand(0, EmptyBlocks[thelastBlockOld]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto &InstInNew : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1))->getInstructions()) {
|
||||||
|
if (InstInNew->isPhi()) {
|
||||||
|
dynamic_cast<PhiInst *>(InstInNew.get())->removeOperand(indexphi + 1);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
thelastBlockOld = nullptr;
|
||||||
|
while (EmptyBlocks.find(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))) !=
|
||||||
|
EmptyBlocks.end()) {
|
||||||
|
thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2));
|
||||||
|
thelastinst->get()->replaceOperand(
|
||||||
|
2, EmptyBlocks[dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))]);
|
||||||
|
}
|
||||||
|
basicBlock->removeSuccessor(OldElseBlock);
|
||||||
|
OldElseBlock->removePredecessor(basicBlock.get());
|
||||||
|
// 处理 then 和 else 分支合并的情况
|
||||||
|
if (dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)) ==
|
||||||
|
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))) {
|
||||||
|
auto thebrBlock = dynamic_cast<BasicBlock *>(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<BasicBlock *>(thelastinst->get()->getOperand(2)));
|
||||||
|
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))->addPredecessor(basicBlock.get());
|
||||||
|
|
||||||
|
if (thelastBlockOld != nullptr) {
|
||||||
|
int indexphi = 0;
|
||||||
|
for (auto &pred : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))->getPredecessors()) {
|
||||||
|
if (pred == thelastBlockOld) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
indexphi++;
|
||||||
|
}
|
||||||
|
for (auto &InstInNew : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))->getInstructions()) {
|
||||||
|
if (InstInNew->isPhi()) {
|
||||||
|
dynamic_cast<PhiInst *>(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<BasicBlock *>(thelastinst->get()->getOperand(0));
|
||||||
|
sysy::BasicBlock *thelastBlockOld = nullptr;
|
||||||
|
while (EmptyBlocks.find(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))) !=
|
||||||
|
EmptyBlocks.end()) {
|
||||||
|
thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0));
|
||||||
|
|
||||||
|
thelastinst->get()->replaceOperand(
|
||||||
|
0, EmptyBlocks[dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))]);
|
||||||
|
}
|
||||||
|
|
||||||
basicBlock->removeSuccessor(OldBrBlock);
|
basicBlock->removeSuccessor(OldBrBlock);
|
||||||
OldBrBlock->removePredecessor(basicBlock.get());
|
OldBrBlock->removePredecessor(basicBlock.get());
|
||||||
basicBlock->addSuccessor(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0)));
|
basicBlock->addSuccessor(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0)));
|
||||||
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->addPredecessor(basicBlock.get());
|
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->addPredecessor(basicBlock.get());
|
||||||
|
|
||||||
if (thelastBlockOld != nullptr) {
|
if (thelastBlockOld != nullptr) {
|
||||||
int indexphi = 0;
|
int indexphi = 0;
|
||||||
for (auto &pred : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->getPredecessors()) {
|
for (auto &pred : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->getPredecessors()) {
|
||||||
@@ -264,8 +390,6 @@ void SysYCFGOpt::SysYDelEmptyBlock() {
|
|||||||
indexphi++;
|
indexphi++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新phi指令的操作数
|
|
||||||
// 移除thelastBlockOld对应的phi操作数
|
|
||||||
for (auto &InstInNew : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->getInstructions()) {
|
for (auto &InstInNew : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->getInstructions()) {
|
||||||
if (InstInNew->isPhi()) {
|
if (InstInNew->isPhi()) {
|
||||||
dynamic_cast<PhiInst *>(InstInNew.get())->removeOperand(indexphi + 1);
|
dynamic_cast<PhiInst *>(InstInNew.get())->removeOperand(indexphi + 1);
|
||||||
@@ -274,200 +398,82 @@ void SysYCFGOpt::SysYDelEmptyBlock() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (thelastinst->get()->getKind() == Instruction::kCondBr) {
|
|
||||||
auto OldThenBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1));
|
|
||||||
auto OldElseBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2));
|
|
||||||
|
|
||||||
BasicBlock *thelastBlockOld = nullptr;
|
|
||||||
while (EmptyBlocks.find(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1))) !=
|
|
||||||
EmptyBlocks.end()) {
|
|
||||||
thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1));
|
|
||||||
thelastinst->get()->replaceOperand(
|
|
||||||
1, EmptyBlocks[dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1))]);
|
|
||||||
}
|
|
||||||
basicBlock->removeSuccessor(OldThenBlock);
|
|
||||||
OldThenBlock->removePredecessor(basicBlock.get());
|
|
||||||
// 处理 then 和 else 分支合并的情况
|
|
||||||
if (dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)) ==
|
|
||||||
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))) {
|
|
||||||
auto thebrBlock = dynamic_cast<BasicBlock *>(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<BasicBlock *>(thelastinst->get()->getOperand(1)));
|
|
||||||
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1))->addPredecessor(basicBlock.get());
|
|
||||||
// auto indexInNew = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->getPredecessors().
|
|
||||||
|
|
||||||
if (thelastBlockOld != nullptr) {
|
|
||||||
int indexphi = 0;
|
|
||||||
for (auto &pred : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1))->getPredecessors()) {
|
|
||||||
if (pred == thelastBlockOld) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
indexphi++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto &InstInNew : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1))->getInstructions()) {
|
|
||||||
if (InstInNew->isPhi()) {
|
|
||||||
dynamic_cast<PhiInst *>(InstInNew.get())->removeOperand(indexphi + 1);
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
thelastBlockOld = nullptr;
|
|
||||||
while (EmptyBlocks.find(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))) !=
|
|
||||||
EmptyBlocks.end()) {
|
|
||||||
thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2));
|
|
||||||
thelastinst->get()->replaceOperand(
|
|
||||||
2, EmptyBlocks[dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))]);
|
|
||||||
}
|
|
||||||
basicBlock->removeSuccessor(OldElseBlock);
|
|
||||||
OldElseBlock->removePredecessor(basicBlock.get());
|
|
||||||
// 处理 then 和 else 分支合并的情况
|
|
||||||
if (dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)) ==
|
|
||||||
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))) {
|
|
||||||
auto thebrBlock = dynamic_cast<BasicBlock *>(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<BasicBlock *>(thelastinst->get()->getOperand(2)));
|
|
||||||
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))->addPredecessor(basicBlock.get());
|
|
||||||
|
|
||||||
if (thelastBlockOld != nullptr) {
|
|
||||||
int indexphi = 0;
|
|
||||||
for (auto &pred : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))->getPredecessors()) {
|
|
||||||
if (pred == thelastBlockOld) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
indexphi++;
|
|
||||||
}
|
|
||||||
for (auto &InstInNew : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))->getInstructions()) {
|
|
||||||
if (InstInNew->isPhi()) {
|
|
||||||
dynamic_cast<PhiInst *>(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<BasicBlock *>(thelastinst->get()->getOperand(0));
|
|
||||||
sysy::BasicBlock *thelastBlockOld = nullptr;
|
|
||||||
while (EmptyBlocks.find(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))) !=
|
|
||||||
EmptyBlocks.end()) {
|
|
||||||
thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0));
|
|
||||||
|
|
||||||
thelastinst->get()->replaceOperand(
|
|
||||||
0, EmptyBlocks[dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))]);
|
|
||||||
}
|
|
||||||
|
|
||||||
basicBlock->removeSuccessor(OldBrBlock);
|
|
||||||
OldBrBlock->removePredecessor(basicBlock.get());
|
|
||||||
basicBlock->addSuccessor(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0)));
|
|
||||||
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->addPredecessor(basicBlock.get());
|
|
||||||
if (thelastBlockOld != nullptr) {
|
|
||||||
int indexphi = 0;
|
|
||||||
for (auto &pred : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->getPredecessors()) {
|
|
||||||
if (pred == thelastBlockOld) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
indexphi++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto &InstInNew : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->getInstructions()) {
|
|
||||||
if (InstInNew->isPhi()) {
|
|
||||||
dynamic_cast<PhiInst *>(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<PhiInst *>(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<PhiInst *>(instinsucc.get())->removeOperand(index);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func->removeBasicBlock((iter++)->get());
|
||||||
|
changed = true;
|
||||||
|
} else {
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果函数没有返回指令,则添加一个默认返回指令(主要解决void函数没有返回指令的问题)
|
// 如果函数没有返回指令,则添加一个默认返回指令(主要解决void函数没有返回指令的问题)
|
||||||
void SysYCFGOpt::SysYAddReturn() {
|
bool SysYCFGOpt::SysYAddReturn(Function *func, IRBuilder* pBuilder) {
|
||||||
auto &functions = pModule->getFunctions();
|
bool changed = false;
|
||||||
for (auto &function : functions) {
|
auto basicBlocks = func->getBasicBlocks();
|
||||||
auto &func = function.second;
|
for (auto &block : basicBlocks) {
|
||||||
auto basicBlocks = func->getBasicBlocks();
|
if (block->getNumSuccessors() == 0) {
|
||||||
for (auto &block : basicBlocks) {
|
changed = true;
|
||||||
if (block->getNumSuccessors() == 0) {
|
// 如果基本块没有后继块,则添加一个返回指令
|
||||||
// 如果基本块没有后继块,则添加一个返回指令
|
if (block->getNumInstructions() == 0) {
|
||||||
if (block->getNumInstructions() == 0) {
|
pBuilder->setPosition(block.get(), block->end());
|
||||||
pBuilder->setPosition(block.get(), block->end());
|
pBuilder->createReturnInst();
|
||||||
pBuilder->createReturnInst();
|
}
|
||||||
}
|
auto thelastinst = block->getInstructions().end();
|
||||||
auto thelastinst = block->getInstructions().end();
|
--thelastinst;
|
||||||
--thelastinst;
|
if (thelastinst->get()->getKind() != Instruction::kReturn) {
|
||||||
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());
|
pBuilder->setPosition(block.get(), block->end());
|
||||||
// TODO: 如果int float函数缺少返回值是否需要报错
|
// TODO: 如果int float函数缺少返回值是否需要报错
|
||||||
if (func->getReturnType()->isInt()) {
|
if (func->getReturnType()->isInt()) {
|
||||||
pBuilder->createReturnInst(ConstantValue::get(0));
|
pBuilder->createReturnInst(ConstantValue::get(0));
|
||||||
} else if (func->getReturnType()->isFloat()) {
|
} else if (func->getReturnType()->isFloat()) {
|
||||||
pBuilder->createReturnInst(ConstantValue::get(0.0F));
|
pBuilder->createReturnInst(ConstantValue::get(0.0F));
|
||||||
} else {
|
} else {
|
||||||
pBuilder->createReturnInst();
|
pBuilder->createReturnInst();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sysy
|
} // namespace sysy
|
||||||
|
|||||||
@@ -26,18 +26,32 @@ class SysYCFGOpt {
|
|||||||
SysYCFGOpt(Module *pMoudle, IRBuilder *pBuilder) : pModule(pMoudle), pBuilder(pBuilder) {}
|
SysYCFGOpt(Module *pMoudle, IRBuilder *pBuilder) : pModule(pMoudle), pBuilder(pBuilder) {}
|
||||||
|
|
||||||
void SysYOptimizateAfterIR(){
|
void SysYOptimizateAfterIR(){
|
||||||
SysYDelInstAfterBr();
|
|
||||||
SysYBlockMerge();
|
auto &functions = pModule->getFunctions();
|
||||||
SysYDelNoPreBLock();
|
for (auto &function : functions) {
|
||||||
SysYDelEmptyBlock();
|
bool changed = false;
|
||||||
SysYAddReturn();
|
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(); // 空块删除
|
public:
|
||||||
void SysYDelNoPreBLock(); // 删除无前驱块(不可达块)
|
static bool SysYDelInstAfterBr(Function *func); // 删除br后面的指令
|
||||||
void SysYBlockMerge(); // 合并基本块(主要针对嵌套if while的exit块,
|
static bool SysYDelEmptyBlock(Function *func, IRBuilder* pBuilder); // 空块删除
|
||||||
|
static bool SysYDelNoPreBLock(Function *func); // 删除无前驱块(不可达块)
|
||||||
|
static bool SysYBlockMerge(Function *func); // 合并基本块(主要针对嵌套if while的exit块,
|
||||||
// 也可以修改IR生成实现回填机制
|
// 也可以修改IR生成实现回填机制
|
||||||
void SysYAddReturn(); // 添加return指令(主要针对Void函数)
|
static bool SysYAddReturn(Function *func, IRBuilder* pBuilder); // 添加return指令(主要针对Void函数)
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sysy
|
} // namespace sysy
|
||||||
|
|||||||
Reference in New Issue
Block a user