[CFG]CFG优化方法转换为静态方法,方便其他优化遍调用,TODO:简化条件分支
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user