From c31577953d5041c82375c22d847c2eba06106c58 Mon Sep 17 00:00:00 2001 From: Yong He Date: Fri, 25 Feb 2022 20:49:31 -0800 Subject: Improved SCCP, inlining and resource specialization passes, legalize `ImageSubscript` for GLSL (#2146) --- source/slang/slang-ir-simplify-cfg.cpp | 82 ++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 source/slang/slang-ir-simplify-cfg.cpp (limited to 'source/slang/slang-ir-simplify-cfg.cpp') diff --git a/source/slang/slang-ir-simplify-cfg.cpp b/source/slang/slang-ir-simplify-cfg.cpp new file mode 100644 index 000000000..af0e7c0ce --- /dev/null +++ b/source/slang/slang-ir-simplify-cfg.cpp @@ -0,0 +1,82 @@ +#include "slang-ir-simplify-cfg.h" + +#include "slang-ir-insts.h" +#include "slang-ir.h" + +namespace Slang +{ + +bool processFunc(IRFunc* func) +{ + auto firstBlock = func->getFirstBlock(); + if (!firstBlock) + return false; + + bool changed = false; + + List workList; + HashSet processedBlock; + workList.add(func->getFirstBlock()); + while (workList.getCount()) + { + auto block = workList.getFirst(); + workList.fastRemoveAt(0); + while (block) + { + // If `block` does not end with an unconditional branch, bail. + if (block->getTerminator()->getOp() != kIROp_unconditionalBranch) + break; + auto branch = as(block->getTerminator()); + auto successor = branch->getTargetBlock(); + // Only perform the merge if `block` is the only predecessor of `successor`. + // We also need to make sure not to merge a block that serves as the + // merge point in CFG. Such blocks will have more than one use. + if (successor->hasMoreThanOneUse()) + break; + changed = true; + Index paramIndex = 0; + auto inst = successor->getFirstDecorationOrChild(); + while (inst) + { + auto next = inst->getNextInst(); + if (inst->getOp() == kIROp_Param) + { + inst->replaceUsesWith(branch->getArg(paramIndex)); + paramIndex++; + } + else + { + inst->removeFromParent(); + inst->insertAtEnd(block); + } + inst = next; + } + branch->removeAndDeallocate(); + assert(!successor->hasUses()); + successor->removeAndDeallocate(); + } + for (auto successor : block->getSuccessors()) + { + if (processedBlock.Add(successor)) + { + workList.add(successor); + } + } + } + return changed; +} + +bool simplifyCFG(IRModule* module) +{ + bool changed = false; + for (auto inst : module->getGlobalInsts()) + { + if (auto func = as(inst)) + { + changed |= processFunc(func); + } + } + return changed; +} + +} // namespace Slang -- cgit v1.2.3