[CFG]CFG优化方法转换为静态方法,方便其他优化遍调用,TODO:简化条件分支

This commit is contained in:
rain2133
2025-07-17 15:54:37 +08:00
parent f7e318e623
commit 009f54863e
2 changed files with 415 additions and 395 deletions

View File

@@ -13,10 +13,10 @@ 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();
@@ -30,8 +30,10 @@ void SysYCFGOpt::SysYDelInstAfterBr() {
} }
} }
if (Branchiter != instructions.end()) ++Branchiter; if (Branchiter != instructions.end()) ++Branchiter;
while (Branchiter != instructions.end()) while (Branchiter != instructions.end()) {
changed = true;
Branchiter = instructions.erase(Branchiter); Branchiter = instructions.erase(Branchiter);
}
if (Branch) { // 更新前驱后继关系 if (Branch) { // 更新前驱后继关系
auto thelastinstinst = basicBlock->getInstructions().end(); auto thelastinstinst = basicBlock->getInstructions().end();
@@ -55,15 +57,14 @@ void SysYCFGOpt::SysYDelInstAfterBr() {
} }
} }
} }
}
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();
auto &func = function.second;
for (auto blockiter = func->getBasicBlocks().begin(); for (auto blockiter = func->getBasicBlocks().begin();
blockiter != func->getBasicBlocks().end();) { blockiter != func->getBasicBlocks().end();) {
if (blockiter->get()->getNumSuccessors() == 1) { if (blockiter->get()->getNumSuccessors() == 1) {
@@ -117,6 +118,7 @@ void SysYCFGOpt::SysYBlockMerge() {
} }
func->removeBasicBlock(nextBlock); func->removeBasicBlock(nextBlock);
changed = true;
} else { } else {
blockiter++; blockiter++;
@@ -125,15 +127,14 @@ void SysYCFGOpt::SysYBlockMerge() {
blockiter++; 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();
@@ -156,7 +157,6 @@ void SysYCFGOpt::SysYDelNoPreBLock() {
// 删除不可达基本块指令 // 删除不可达基本块指令
for (auto blockIter = func->getBasicBlocks().begin(); blockIter != func->getBasicBlocks().end();blockIter++) { for (auto blockIter = func->getBasicBlocks().begin(); blockIter != func->getBasicBlocks().end();blockIter++) {
if (!blockIter->get()->getreachable()) if (!blockIter->get()->getreachable())
for (auto &iterInst : blockIter->get()->getInstructions()) for (auto &iterInst : blockIter->get()->getInstructions())
SysYIROptUtils::usedelete(iterInst.get()); SysYIROptUtils::usedelete(iterInst.get());
@@ -183,20 +183,23 @@ void SysYCFGOpt::SysYDelNoPreBLock() {
} }
// 删除不可达基本块,注意迭代器不可达问题 // 删除不可达基本块,注意迭代器不可达问题
func->removeBasicBlock((blockIter++)->get()); func->removeBasicBlock((blockIter++)->get());
changed = true;
} else { } else {
blockIter++; blockIter++;
} }
} }
}
return changed;
} }
void SysYCFGOpt::SysYDelEmptyBlock() { // 删除空块
auto &functions = pModule->getFunctions(); bool SysYCFGOpt::SysYDelEmptyBlock(Function *func, IRBuilder* pBuilder) {
for (auto &function : functions) { bool changed = false;
// 收集不可达基本块 // 收集不可达基本块
// 这里的不可达基本块是指没有实际指令的基本块 // 这里的不可达基本块是指没有实际指令的基本块
// 当一个基本块没有实际指令例如只有phi指令和一个uncondbr指令时也会被视作不可达 // 当一个基本块没有实际指令例如只有phi指令和一个uncondbr指令时也会被视作不可达
auto basicBlocks = function.second->getBasicBlocks(); auto basicBlocks = func->getBasicBlocks();
std::map<sysy::BasicBlock *, BasicBlock *> EmptyBlocks; std::map<sysy::BasicBlock *, BasicBlock *> EmptyBlocks;
// 空块儿和后继的基本块的映射 // 空块儿和后继的基本块的映射
for (auto &basicBlock : basicBlocks) { for (auto &basicBlock : basicBlocks) {
@@ -399,11 +402,11 @@ void SysYCFGOpt::SysYDelEmptyBlock() {
} }
} }
for (auto iter = function.second->getBasicBlocks().begin(); iter != function.second->getBasicBlocks().end();) { for (auto iter = func->getBasicBlocks().begin(); iter != func->getBasicBlocks().end();) {
if (EmptyBlocks.find(iter->get()) != EmptyBlocks.end()) { if (EmptyBlocks.find(iter->get()) != EmptyBlocks.end()) {
// EntryBlock跳过 // EntryBlock跳过
if (iter->get() == function.second->getEntryBlock()) { if (iter->get() == func->getEntryBlock()) {
++iter; ++iter;
continue; continue;
} }
@@ -429,22 +432,24 @@ void SysYCFGOpt::SysYDelEmptyBlock() {
} }
} }
function.second->removeBasicBlock((iter++)->get()); func->removeBasicBlock((iter++)->get());
changed = true;
} else { } else {
++iter; ++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 &func = function.second;
auto basicBlocks = func->getBasicBlocks(); auto basicBlocks = func->getBasicBlocks();
for (auto &block : basicBlocks) { for (auto &block : basicBlocks) {
if (block->getNumSuccessors() == 0) { if (block->getNumSuccessors() == 0) {
changed = true;
// 如果基本块没有后继块,则添加一个返回指令 // 如果基本块没有后继块,则添加一个返回指令
if (block->getNumInstructions() == 0) { if (block->getNumInstructions() == 0) {
pBuilder->setPosition(block.get(), block->end()); pBuilder->setPosition(block.get(), block->end());
@@ -467,7 +472,8 @@ void SysYCFGOpt::SysYAddReturn() {
} }
} }
} }
}
return changed;
} }
} // namespace sysy } // namespace sysy

View File

@@ -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(); // 空块删除 }
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生成实现回填机制 // 也可以修改IR生成实现回填机制
void SysYAddReturn(); // 添加return指令(主要针对Void函数) static bool SysYAddReturn(Function *func, IRBuilder* pBuilder); // 添加return指令(主要针对Void函数)
}; };
} // namespace sysy } // namespace sysy