diff --git a/src/SysYIRCFGOpt.cpp b/src/SysYIRCFGOpt.cpp index 4098008..4a84497 100644 --- a/src/SysYIRCFGOpt.cpp +++ b/src/SysYIRCFGOpt.cpp @@ -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(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(thelast->get()->getOperand(1)); + auto elseBlock = dynamic_cast(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 diff --git a/src/include/SCCP.h b/src/include/SCCP.h index da6452e..7db0a7b 100644 --- a/src/include/SCCP.h +++ b/src/include/SCCP.h @@ -172,7 +172,7 @@ enum class LatticeValue { //TODO: 下列数据结构考虑集成到类中,避免重命名问题 static std::set Worklist; static std::unordered_set Executable_Blocks; -static std::unordered_set > Executable_Edges; +static std::queue > Executable_Edges; static std::map valueState; class SCCP { diff --git a/src/include/SysYIRCFGOpt.h b/src/include/SysYIRCFGOpt.h index bf0e524..6b13a3f 100644 --- a/src/include/SysYIRCFGOpt.h +++ b/src/include/SysYIRCFGOpt.h @@ -31,6 +31,8 @@ class SysYCFGOpt { for (auto &function : functions) { bool changed = false; while(changed){ + changed = false; + changed |= SysYCondBr2Br(function.second.get(), pBuilder); // 删除br后面的无用指令 changed |= SysYDelInstAfterBr(function.second.get()); // 合并空基本块 @@ -52,6 +54,7 @@ public: static bool SysYBlockMerge(Function *func); // 合并基本块(主要针对嵌套if while的exit块, // 也可以修改IR生成实现回填机制 static bool SysYAddReturn(Function *func, IRBuilder* pBuilder); // 添加return指令(主要针对Void函数) + static bool SysYCondBr2Br(Function *func, IRBuilder* pBuilder); // 条件分支(已知cond的值)转换为无条件分支 }; } // namespace sysy