diff options
author | Hans-Kristian Arntzen <hans-kristian.arntzen@arm.com> | 2016-11-18 11:59:54 +0300 |
---|---|---|
committer | Hans-Kristian Arntzen <hans-kristian.arntzen@arm.com> | 2016-11-18 11:59:54 +0300 |
commit | 0c9683cd850f792d54dacc11621e3ba344a30f7f (patch) | |
tree | ac4ec4e742d8ba28af015e0b926fbf7830dad10b /spirv_cfg.cpp | |
parent | edbe867b7474f6ebf859e3289fd7398c67f5b6f3 (diff) |
Distinguish between cross edges and back edges.
Handle the weird opcodes CopyMemory/CopyObject.
Diffstat (limited to 'spirv_cfg.cpp')
-rw-r--r-- | spirv_cfg.cpp | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/spirv_cfg.cpp b/spirv_cfg.cpp index 8ecadc09..5900bfbd 100644 --- a/spirv_cfg.cpp +++ b/spirv_cfg.cpp @@ -70,22 +70,31 @@ void CFG::build_immediate_dominators() for (auto &edge : pred) { - if (!immediate_dominators[block]) - immediate_dominators[block] = edge; - else + if (immediate_dominators[block]) { assert(immediate_dominators[edge]); immediate_dominators[block] = update_common_dominator(block, edge); } + else + immediate_dominators[block] = edge; } } } +bool CFG::is_back_edge(uint32_t to) const +{ + // We have a back edge if the visit order is set with the temporary magic value 0. + // Crossing edges will have already been recorded with a visit order. + return visit_order[to] == 0; +} + bool CFG::post_order_visit(uint32_t block_id) { // If we have already branched to this block (back edge), stop recursion. + // If our branches are back-edges, we do not record them. + // We have to record crossing edges however. if (visit_order[block_id] >= 0) - return false; + return !is_back_edge(block_id); // Block back-edges from recursively revisiting ourselves. visit_order[block_id] = 0; @@ -120,8 +129,8 @@ bool CFG::post_order_visit(uint32_t block_id) break; } - // Then visit ourselves. - visit_order[block_id] = visit_count++; + // Then visit ourselves. Start counting at one, to let 0 be a magic value for testing back vs. crossing edges. + visit_order[block_id] = ++visit_count; post_order.push_back(block_id); return true; } |