[CFG]增加分支优化,为SCCP调用做铺垫,预备修改phi定义

This commit is contained in:
rain2133
2025-07-17 16:50:09 +08:00
parent 009f54863e
commit 77fae4d662
3 changed files with 90 additions and 1 deletions

View File

@@ -476,4 +476,90 @@ bool SysYCFGOpt::SysYAddReturn(Function *func, IRBuilder* pBuilder) {
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