[CFG]增加分支优化,为SCCP调用做铺垫,预备修改phi定义
This commit is contained in:
@@ -476,4 +476,90 @@ bool SysYCFGOpt::SysYAddReturn(Function *func, IRBuilder* pBuilder) {
|
|||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 条件分支转换为无条件分支
|
||||||
|
// 主要针对已知条件值的分支转换为无条件分支
|
||||||
|
// 例如 if (cond) { ... } else { ... } 中的 cond 已经
|
||||||
|
// 确定为 true 或 false 的情况
|
||||||
|
bool SysYCFGOpt::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)) {
|
||||||
|
|
||||||
|
pBuilder->setPosition(basicblock.get(), basicblock->end());
|
||||||
|
pBuilder->createUncondBrInst(thenBlock, {});
|
||||||
|
int phiindex = 0;
|
||||||
|
for (auto pred : elseBlock->getPredecessors()) {
|
||||||
|
phiindex++;
|
||||||
|
if (pred == basicblock.get()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &phiinst : elseBlock->getInstructions()) {
|
||||||
|
if (phiinst->getKind() != Instruction::kPhi) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
phiinst->removeOperand(phiindex);
|
||||||
|
}
|
||||||
|
basicblock->removeSuccessor(elseBlock);
|
||||||
|
elseBlock->removePredecessor(basicblock.get());
|
||||||
|
} else {
|
||||||
|
|
||||||
|
pBuilder->setPosition(basicblock.get(), basicblock->end());
|
||||||
|
pBuilder->createUncondBrInst(elseBlock, {});
|
||||||
|
int phiindex = 0;
|
||||||
|
for (auto pred : thenBlock->getPredecessors()) {
|
||||||
|
phiindex++;
|
||||||
|
if (pred == basicblock.get()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &phiinst : thenBlock->getInstructions()) {
|
||||||
|
if (phiinst->getKind() != Instruction::kPhi) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
phiinst->removeOperand(phiindex);
|
||||||
|
}
|
||||||
|
basicblock->removeSuccessor(thenBlock);
|
||||||
|
thenBlock->removePredecessor(basicblock.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace sysy
|
} // namespace sysy
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ enum class LatticeValue {
|
|||||||
//TODO: 下列数据结构考虑集成到类中,避免重命名问题
|
//TODO: 下列数据结构考虑集成到类中,避免重命名问题
|
||||||
static std::set<Instruction *> Worklist;
|
static std::set<Instruction *> Worklist;
|
||||||
static std::unordered_set<BasicBlock*> Executable_Blocks;
|
static std::unordered_set<BasicBlock*> Executable_Blocks;
|
||||||
static std::unordered_set<std::pair<BasicBlock *, BasicBlock *> > Executable_Edges;
|
static std::queue<std::pair<BasicBlock *, BasicBlock *> > Executable_Edges;
|
||||||
static std::map<Value*, LatticeValue> valueState;
|
static std::map<Value*, LatticeValue> valueState;
|
||||||
|
|
||||||
class SCCP {
|
class SCCP {
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ class SysYCFGOpt {
|
|||||||
for (auto &function : functions) {
|
for (auto &function : functions) {
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
while(changed){
|
while(changed){
|
||||||
|
changed = false;
|
||||||
|
changed |= SysYCondBr2Br(function.second.get(), pBuilder);
|
||||||
// 删除br后面的无用指令
|
// 删除br后面的无用指令
|
||||||
changed |= SysYDelInstAfterBr(function.second.get());
|
changed |= SysYDelInstAfterBr(function.second.get());
|
||||||
// 合并空基本块
|
// 合并空基本块
|
||||||
@@ -52,6 +54,7 @@ public:
|
|||||||
static bool SysYBlockMerge(Function *func); // 合并基本块(主要针对嵌套if while的exit块,
|
static bool SysYBlockMerge(Function *func); // 合并基本块(主要针对嵌套if while的exit块,
|
||||||
// 也可以修改IR生成实现回填机制
|
// 也可以修改IR生成实现回填机制
|
||||||
static bool SysYAddReturn(Function *func, IRBuilder* pBuilder); // 添加return指令(主要针对Void函数)
|
static bool SysYAddReturn(Function *func, IRBuilder* pBuilder); // 添加return指令(主要针对Void函数)
|
||||||
|
static bool SysYCondBr2Br(Function *func, IRBuilder* pBuilder); // 条件分支(已知cond的值)转换为无条件分支
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sysy
|
} // namespace sysy
|
||||||
|
|||||||
Reference in New Issue
Block a user