summaryrefslogtreecommitdiff
path: root/source/val
diff options
context:
space:
mode:
authorGreg Fischer <greg@lunarg.com>2017-05-23 11:31:56 -0600
committerGregF <greg@LunarG.com>2017-05-25 11:43:24 -0600
commit3bea99d378af1dd2fc0baca3e0d38ec0d8169d1b (patch)
treed1fd08f5f65a0e626d8b49d32660bd75f96a4b61 /source/val
parentd6f29790687f697ee3cb0bf105e365dba5faf384 (diff)
CFA: Move TraversalRoots and ComputeAugmentedCFG into CFA
Diffstat (limited to 'source/val')
-rw-r--r--source/val/function.cpp94
1 files changed, 8 insertions, 86 deletions
diff --git a/source/val/function.cpp b/source/val/function.cpp
index 7b3caaa3..42f7ec15 100644
--- a/source/val/function.cpp
+++ b/source/val/function.cpp
@@ -33,56 +33,6 @@ using std::pair;
using std::tie;
using std::vector;
-namespace {
-
-using libspirv::BasicBlock;
-
-// Computes a minimal set of root nodes required to traverse, in the forward
-// direction, the CFG represented by the given vector of blocks, and successor
-// and predecessor functions. When considering adding two nodes, each having
-// predecessors, favour using the one that appears earlier on the input blocks
-// list.
-std::vector<BasicBlock*> TraversalRoots(const std::vector<BasicBlock*>& blocks,
- libspirv::get_blocks_func succ_func,
- libspirv::get_blocks_func pred_func) {
- // The set of nodes which have been visited from any of the roots so far.
- std::unordered_set<const BasicBlock*> visited;
-
- auto mark_visited = [&visited](const BasicBlock* b) { visited.insert(b); };
- auto ignore_block = [](const BasicBlock*) {};
- auto ignore_blocks = [](const BasicBlock*, const BasicBlock*) {};
-
-
- auto traverse_from_root = [&mark_visited, &succ_func, &ignore_block,
- &ignore_blocks](const BasicBlock* entry) {
- spvtools::CFA<libspirv::BasicBlock>::DepthFirstTraversal(
- entry, succ_func, mark_visited, ignore_block, ignore_blocks);
- };
-
- std::vector<BasicBlock*> result;
-
- // First collect nodes without predecessors.
- for (auto block : blocks) {
- if (pred_func(block)->empty()) {
- assert(visited.count(block) == 0 && "Malformed graph!");
- result.push_back(block);
- traverse_from_root(block);
- }
- }
-
- // Now collect other stranded nodes. These must be in unreachable cycles.
- for (auto block : blocks) {
- if (visited.count(block) == 0) {
- result.push_back(block);
- traverse_from_root(block);
- }
- }
-
- return result;
-}
-
-} // anonymous namespace
-
namespace libspirv {
// Universal Limit of ResultID + 1
@@ -324,42 +274,14 @@ void Function::ComputeAugmentedCFG() {
// the predecessors of the pseudo exit block.
auto succ_func = [](const BasicBlock* b) { return b->successors(); };
auto pred_func = [](const BasicBlock* b) { return b->predecessors(); };
- auto sources = TraversalRoots(ordered_blocks_, succ_func, pred_func);
-
- // For the predecessor traversals, reverse the order of blocks. This
- // will affect the post-dominance calculation as follows:
- // - Suppose you have blocks A and B, with A appearing before B in
- // the list of blocks.
- // - Also, A branches only to B, and B branches only to A.
- // - We want to compute A as dominating B, and B as post-dominating B.
- // By using reversed blocks for predecessor traversal roots discovery,
- // we'll add an edge from B to the pseudo-exit node, rather than from A.
- // All this is needed to correctly process the dominance/post-dominance
- // constraint when A is a loop header that points to itself as its
- // own continue target, and B is the latch block for the loop.
- std::vector<BasicBlock*> reversed_blocks(ordered_blocks_.rbegin(),
- ordered_blocks_.rend());
- auto sinks = TraversalRoots(reversed_blocks, pred_func, succ_func);
-
- // Wire up the pseudo entry block.
- augmented_successors_map_[&pseudo_entry_block_] = sources;
- for (auto block : sources) {
- auto& augmented_preds = augmented_predecessors_map_[block];
- const auto& preds = *block->predecessors();
- augmented_preds.reserve(1 + preds.size());
- augmented_preds.push_back(&pseudo_entry_block_);
- augmented_preds.insert(augmented_preds.end(), preds.begin(), preds.end());
- }
-
- // Wire up the pseudo exit block.
- augmented_predecessors_map_[&pseudo_exit_block_] = sinks;
- for (auto block : sinks) {
- auto& augmented_succ = augmented_successors_map_[block];
- const auto& succ = *block->successors();
- augmented_succ.reserve(1 + succ.size());
- augmented_succ.push_back(&pseudo_exit_block_);
- augmented_succ.insert(augmented_succ.end(), succ.begin(), succ.end());
- }
+ spvtools::CFA<BasicBlock>::ComputeAugmentedCFG(
+ ordered_blocks_,
+ &pseudo_entry_block_,
+ &pseudo_exit_block_,
+ &augmented_successors_map_,
+ &augmented_predecessors_map_,
+ succ_func,
+ pred_func);
};
Construct& Function::AddConstruct(const Construct& new_construct) {