summaryrefslogtreecommitdiff
path: root/source/slang/slang-ir-simplify-cfg.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2022-02-25 20:49:31 -0800
committerGitHub <noreply@github.com>2022-02-25 20:49:31 -0800
commitc31577953d5041c82375c22d847c2eba06106c58 (patch)
treebc685a8b63fc13cb85d160ae13df950056ca6e91 /source/slang/slang-ir-simplify-cfg.cpp
parent8990d270e3a0c01b1f7abbf4f79556c5ef82a096 (diff)
Improved SCCP, inlining and resource specialization passes, legalize `ImageSubscript` for GLSL (#2146)
Diffstat (limited to 'source/slang/slang-ir-simplify-cfg.cpp')
-rw-r--r--source/slang/slang-ir-simplify-cfg.cpp82
1 files changed, 82 insertions, 0 deletions
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<IRBlock*> workList;
+ HashSet<IRBlock*> 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<IRUnconditionalBranch>(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<IRFunc>(inst))
+ {
+ changed |= processFunc(func);
+ }
+ }
+ return changed;
+}
+
+} // namespace Slang