MCPcopy Create free account
hub / github.com/KhronosGroup/SPIRV-Tools / OrderBlocks

Function OrderBlocks

source/disassemble.cpp:410–484  ·  view source on GitHub ↗

Given the control flow graph, calculates and returns the reverse post-order ordering of the blocks. The blocks are then disassembled in that order for readability.

Source from the content-addressed store, hash-verified

408// ordering of the blocks. The blocks are then disassembled in that order for
409// readability.
410std::vector<uint32_t> OrderBlocks(
411 ControlFlowGraph& cfg,
412 const std::unordered_map<uint32_t, uint32_t>& id_to_index) {
413 std::vector<uint32_t> post_order;
414
415 // Nest level of a function's first block is 0.
416 cfg.blocks[0].nest_level = 0;
417 cfg.blocks[0].nest_level_assigned = true;
418
419 // Stack of block indices as they are visited.
420 std::stack<StackEntry> dfs_stack;
421 dfs_stack.push({0, false});
422
423 std::set<uint32_t> visited;
424
425 while (!dfs_stack.empty()) {
426 const uint32_t block_index = dfs_stack.top().block_index;
427 const bool post_visit = dfs_stack.top().post_visit;
428 dfs_stack.pop();
429
430 // If this is the second time the block is visited, that's the post-order
431 // visit.
432 if (post_visit) {
433 post_order.push_back(block_index);
434 continue;
435 }
436
437 // If already visited, another path got to it first (like a case
438 // fallthrough), avoid reprocessing it.
439 if (visited.count(block_index) > 0) {
440 continue;
441 }
442 visited.insert(block_index);
443
444 // Push it back in the stack for post-order visit
445 dfs_stack.push({block_index, true});
446
447 SingleBlock& block = cfg.blocks[block_index];
448
449 // Assign nest levels of successors right away. The successors are either
450 // nested under this block, or are back or forward edges to blocks outside
451 // this nesting level (no farther than the merge block), whose nesting
452 // levels are already assigned before this block is visited.
453 NestSuccessors(cfg, block, id_to_index);
454 block.reachable = true;
455
456 // The post-order visit yields the order in which the blocks are naturally
457 // ordered _backwards_. So blocks to be ordered last should be visited
458 // first. In other words, they should be pushed to the DFS stack last.
459 VisitSuccesor(&dfs_stack, id_to_index, block.successors.true_block_id);
460 VisitSuccesor(&dfs_stack, id_to_index, block.successors.false_block_id);
461 VisitSuccesor(&dfs_stack, id_to_index, block.successors.body_block_id);
462 VisitSuccesor(&dfs_stack, id_to_index, block.successors.next_block_id);
463 for (uint32_t case_block_id : block.successors.case_block_ids) {
464 VisitSuccesor(&dfs_stack, id_to_index, case_block_id);
465 }
466 VisitSuccesor(&dfs_stack, id_to_index, block.successors.continue_block_id);
467 VisitSuccesor(&dfs_stack, id_to_index, block.successors.merge_block_id);

Callers 1

EmitCFGMethod · 0.85

Calls 9

NestSuccessorsFunction · 0.85
VisitSuccesorFunction · 0.85
rbeginMethod · 0.80
rendMethod · 0.80
emptyMethod · 0.45
push_backMethod · 0.45
countMethod · 0.45
insertMethod · 0.45
sizeMethod · 0.45

Tested by

no test coverage detected