600 lines
24 KiB
C++
600 lines
24 KiB
C++
#include "SysYIRCFGOpt.h"
|
||
#include "SysYIROptUtils.h"
|
||
#include <cassert>
|
||
#include <list>
|
||
#include <map>
|
||
#include <memory>
|
||
#include <string>
|
||
#include <iostream>
|
||
#include <queue> // 引入队列,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<BasicBlock *>(thelastinstinst->get()->getOperand(0));
|
||
basicBlock->addSuccessor(branchBlock);
|
||
branchBlock->addPredecessor(basicBlock.get());
|
||
} else if (thelastinstinst->get()->isConditional()) {
|
||
BasicBlock* thenBlock = dynamic_cast<BasicBlock *>(thelastinstinst->get()->getOperand(1));
|
||
BasicBlock* elseBlock = dynamic_cast<BasicBlock *>(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<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 {
|
||
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<BasicBlock *> 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 *>(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<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 && 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<BasicBlock *>(thelastinst->get()->getOperand(0));
|
||
BasicBlock *thelastBlockOld = nullptr;
|
||
// 如果空块链表为多个块
|
||
while (EmptyBlocks.count(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0)))) {
|
||
thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0));
|
||
thelastinst->get()->replaceOperand(0, EmptyBlocks[thelastBlockOld]);
|
||
}
|
||
|
||
// 如果有重定向发生
|
||
if (thelastBlockOld != nullptr) {
|
||
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());
|
||
changed = true; // 标记IR被修改
|
||
}
|
||
|
||
|
||
if (thelastBlockOld != nullptr) {
|
||
for (auto &InstInNew : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->getInstructions()) {
|
||
if (InstInNew->isPhi()) {
|
||
// 使用 delBlk 方法删除 oldBlock 对应的传入值
|
||
dynamic_cast<PhiInst *>(InstInNew.get())->delBlk(thelastBlockOld);
|
||
} else {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
} 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));
|
||
bool thenChanged = false;
|
||
bool elseChanged = false;
|
||
|
||
|
||
BasicBlock *thelastBlockOld = nullptr;
|
||
while (EmptyBlocks.count(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)))) {
|
||
thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1));
|
||
thelastinst->get()->replaceOperand(
|
||
1, EmptyBlocks[dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1))]);
|
||
thenChanged = true;
|
||
}
|
||
|
||
if (thenChanged) {
|
||
basicBlock->removeSuccessor(OldThenBlock);
|
||
OldThenBlock->removePredecessor(basicBlock.get());
|
||
basicBlock->addSuccessor(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)));
|
||
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1))->addPredecessor(basicBlock.get());
|
||
changed = true; // 标记IR被修改
|
||
}
|
||
|
||
// 处理 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, {});
|
||
changed = true; // 标记IR被修改
|
||
continue;
|
||
}
|
||
|
||
if (thelastBlockOld != nullptr) {
|
||
for (auto &InstInNew : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1))->getInstructions()) {
|
||
if (InstInNew->isPhi()) {
|
||
// 使用 delBlk 方法删除 oldBlock 对应的传入值
|
||
dynamic_cast<PhiInst *>(InstInNew.get())->delBlk(thelastBlockOld);
|
||
} else {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
thelastBlockOld = nullptr;
|
||
while (EmptyBlocks.count(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2)))) {
|
||
thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2));
|
||
thelastinst->get()->replaceOperand(
|
||
2, EmptyBlocks[dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))]);
|
||
elseChanged = true;
|
||
}
|
||
|
||
if (elseChanged) {
|
||
basicBlock->removeSuccessor(OldElseBlock);
|
||
OldElseBlock->removePredecessor(basicBlock.get());
|
||
basicBlock->addSuccessor(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2)));
|
||
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))->addPredecessor(basicBlock.get());
|
||
changed = true; // 标记IR被修改
|
||
}
|
||
|
||
// 处理 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, {});
|
||
changed = true; // 标记IR被修改
|
||
continue;
|
||
}
|
||
|
||
|
||
// 如果有重定向发生
|
||
// 需要更新后继块的前驱关系
|
||
if (thelastBlockOld != nullptr) {
|
||
for (auto &InstInNew : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))->getInstructions()) {
|
||
if (InstInNew->isPhi()) {
|
||
// 使用 delBlk 方法删除 oldBlock 对应的传入值
|
||
dynamic_cast<PhiInst *>(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<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());
|
||
// changed = true; // 标记IR被修改
|
||
// 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 = 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<PhiInst *>(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<ConstantValue *>(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<BasicBlock *>(thelast->get()->getOperand(1));
|
||
auto elseBlock = dynamic_cast<BasicBlock *>(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 *>(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 *>(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
|