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-03-31 17:31:35 +0300
committerHans-Kristian Arntzen <post@arntzen-software.no>2022-03-31 17:52:59 +0300
commit00973cea25907124926db3d35d8cb8710a915b34 (patch)
tree99275ae210e1a899c3b3bf67217d1c64f29a4a7c
parent76b6e8a4e713124fd731710ccaa5e17f7bde5b7b (diff)
Do not attempt to rewrite loops if outer header does not dominate inner.
-rw-r--r--cfg_structurizer.cpp22
1 files changed, 16 insertions, 6 deletions
diff --git a/cfg_structurizer.cpp b/cfg_structurizer.cpp
index c7497ae..490fe65 100644
--- a/cfg_structurizer.cpp
+++ b/cfg_structurizer.cpp
@@ -3138,8 +3138,10 @@ void CFGStructurizer::find_loops()
CFGNode *CFGStructurizer::get_target_break_block_for_inner_header(const CFGNode *node, size_t header_index)
{
+ CFGNode *inner_header = node->headers[header_index];
CFGNode *target_header = nullptr;
- for (size_t j = header_index; j; j--)
+
+ for (size_t j = header_index; j && !target_header; j--)
{
if (node->headers[j - 1]->merge == MergeType::Loop)
{
@@ -3153,11 +3155,19 @@ CFGNode *CFGStructurizer::get_target_break_block_for_inner_header(const CFGNode
else if (candidate_header->loop_merge_block)
candidate_merge = candidate_header->loop_merge_block;
- if (candidate_merge && !query_reachability(*candidate_merge, *node->headers[header_index]))
- {
- target_header = candidate_header;
- break;
- }
+ if (!candidate_merge)
+ continue;
+
+ // Check for backwards branch.
+ if (query_reachability(*candidate_merge, *node->headers[header_index]))
+ continue;
+
+ // An outer header is expected to dominate the inner header. Otherwise, they live in
+ // separate scopes, and we should look for a header that is further out.
+ if (!candidate_header->dominates(inner_header))
+ continue;
+
+ target_header = candidate_header;
}
}