Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/HansKristian-Work/dxil-spirv.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans-Kristian Arntzen <post@arntzen-software.no>2022-04-08 13:47:01 +0300
committerGitHub <noreply@github.com>2022-04-08 13:47:01 +0300
commit2cb1e8c88b79fc59e70ef7c0287e7129bc3debc6 (patch)
tree55c402461b528ab5e6c7983bb1bf5f3f79254d92
parente33d7d5d010948a5cb3b98f50d7c9d0447122609 (diff)
parentd99c5722984fb04741582027eda719a1c0e0c5a4 (diff)
Merge pull request #109 from HansKristian-Work/post-dominates-any-work
Rewrite check for post_dominates_any_work() to work with ladder merges.
-rw-r--r--cfg_structurizer.cpp16
-rw-r--r--node.cpp39
-rw-r--r--node.hpp2
3 files changed, 42 insertions, 15 deletions
diff --git a/cfg_structurizer.cpp b/cfg_structurizer.cpp
index d181834..08ab20a 100644
--- a/cfg_structurizer.cpp
+++ b/cfg_structurizer.cpp
@@ -1845,20 +1845,6 @@ bool CFGStructurizer::control_flow_is_escaping(const CFGNode *node, const CFGNod
if (escaping_path && node->ir.operations.empty() && node->ir.phi.empty())
{
- bool post_dominates_nothing = true;
- for (auto *pred : node->pred)
- {
- // Skip completely useless ladder blocks when we consider this case.
- while (pred->pred.size() == 1 && pred->ir.operations.empty() && pred->ir.phi.empty())
- pred = pred->pred.front();
-
- if (node->post_dominates(pred))
- {
- post_dominates_nothing = false;
- break;
- }
- }
-
// If we post-dominate nothing useful or do nothing useful ourselves,
// this is a good indication we're a common escape edge ladder block.
// This can happen if we have a graph of:
@@ -1870,7 +1856,7 @@ bool CFGStructurizer::control_flow_is_escaping(const CFGNode *node, const CFGNod
// C -> node
// node -> merge
// This super jank diamond pattern will break the heuristics.
- if (post_dominates_nothing)
+ if (!node->post_dominates_any_work())
return true;
}
diff --git a/node.cpp b/node.cpp
index 8581532..d66f293 100644
--- a/node.cpp
+++ b/node.cpp
@@ -154,6 +154,45 @@ bool CFGNode::can_backtrace_to(const CFGNode *parent) const
return can_backtrace_to(parent, node_cache);
}
+bool CFGNode::post_dominates_any_work(const CFGNode *parent, UnorderedSet<const CFGNode *> &node_cache) const
+{
+ // If we reached this node before and didn't terminate, it must have returned false.
+ if (node_cache.count(parent))
+ return false;
+ node_cache.insert(parent);
+
+ // This is not a dummy block, we have an answer.
+ if (!parent->ir.operations.empty() || !parent->ir.phi.empty())
+ return post_dominates(parent);
+
+ for (auto *p : parent->pred)
+ if (post_dominates_any_work(p, node_cache))
+ return true;
+
+ return false;
+}
+
+bool CFGNode::post_dominates_any_work() const
+{
+ auto *start_node = this;
+ // Trivial back-trace as far as we can go.
+ while (start_node->pred.size() == 1 &&
+ start_node->ir.operations.empty() && start_node->ir.phi.empty() &&
+ start_node->post_dominates(start_node->pred.front()))
+ {
+ start_node = start_node->pred.front();
+ }
+
+ if (!start_node->ir.operations.empty() || !start_node->ir.phi.empty())
+ return true;
+
+ UnorderedSet<const CFGNode *> node_cache;
+ for (auto *p : start_node->pred)
+ if (start_node->post_dominates_any_work(p, node_cache))
+ return true;
+ return false;
+}
+
const CFGNode *CFGNode::get_innermost_loop_header_for(const CFGNode *other) const
{
while (this != other)
diff --git a/node.hpp b/node.hpp
index de729f3..34d4d9f 100644
--- a/node.hpp
+++ b/node.hpp
@@ -99,6 +99,8 @@ private:
CFGNode *get_immediate_dominator_loop_header();
bool can_backtrace_to(const CFGNode *parent) const;
bool can_backtrace_to(const CFGNode *parent, UnorderedSet<const CFGNode *> &node_cache) const;
+ bool post_dominates_any_work() const;
+ bool post_dominates_any_work(const CFGNode *parent, UnorderedSet<const CFGNode *> &node_cache) const;
void retarget_branch(CFGNode *to_prev, CFGNode *to_next);
void retarget_branch_with_intermediate_node(CFGNode *to_prev, CFGNode *to_next);