ControlFlowGraph::BlockPointerVector ControlFlowGraph::reverse_topological_sequence() { typedef std::set<iterator, BlockSetCompare> BlockSet; typedef std::queue<iterator> Queue; report("Creating reverse topological order traversal"); BlockSet visited; BlockPointerVector sequence; Queue queue; queue.push(get_exit_block()); while (sequence.size() != size()) { if(queue.empty()) { for (pointer_iterator block = sequence.begin(); block != sequence.end(); ++block) { for (pointer_iterator pred = (*block)->predecessors.begin(); pred != (*block)->predecessors.end(); ++pred) { if (visited.count(*pred) == 0) { queue.push(*pred); break; } } if(!queue.empty()) { break; } } if(queue.empty()) break; // The remaining blocks are unreachable } iterator current = queue.front(); queue.pop(); if(!visited.insert(current).second) continue; sequence.push_back(current); report(" Adding block " << current->label()); for (pointer_iterator block = current->predecessors.begin(); block != current->predecessors.end(); ++block) { bool noDependencies = true; for (pointer_iterator successor = (*block)->successors.begin(); successor != (*block)->successors.end(); ++successor) { if (visited.count(*successor) == 0) { noDependencies = false; break; } } if(noDependencies) { queue.push(*block); } } } return sequence; }
PostdominatorTree::BlockPointerVector PostdominatorTree::getPostDominanceFrontier(block_iterator block) { BlockPointerVector frontierBlocks; auto& frontier = frontiers[blocksToIndex[block]]; for(auto blockId : frontier) { frontierBlocks.push_back(blocks[blockId]); } return frontierBlocks; }
ControlFlowGraph::BlockPointerVector ControlFlowGraph::pre_order_sequence() { typedef std::unordered_set<iterator> BlockSet; typedef std::stack<iterator> Stack; BlockSet visited; BlockPointerVector sequence; Stack stack; if (!empty()) { stack.push(get_entry_block()); visited.insert(get_entry_block()); } while (!stack.empty()) { iterator current = stack.top(); stack.pop(); sequence.push_back(current); // favor the fallthrough iterator fallthrough = end(); if (current->has_fallthrough_edge()) { edge_iterator fallthroughEdge = sequence.back()->get_fallthrough_edge(); if (visited.insert(fallthroughEdge->tail).second) { fallthrough = fallthroughEdge->tail; } } for (pointer_iterator block = current->successors.begin(); block != current->successors.end(); ++block) { if (visited.insert(*block).second) { stack.push(*block); } } if (fallthrough != end()) { stack.push(fallthrough); } } return sequence; }
ControlFlowGraph::BlockPointerVector ControlFlowGraph::post_order_sequence() { typedef std::unordered_set<iterator> BlockSet; typedef std::stack<iterator> Stack; report("Creating post order traversal"); BlockSet visited; BlockPointerVector sequence; Stack stack; if (!empty()) { for (pointer_iterator block = get_entry_block()->successors.begin(); block != get_entry_block()->successors.end(); ++block) { if (visited.insert(*block).second) { stack.push(*block); } } } while (!stack.empty()) { iterator current = stack.top(); bool one = false; for (pointer_iterator block = current->successors.begin(); block != current->successors.end(); ++block) { if (visited.insert(*block).second) { stack.push(*block); one = true; } } if(!one) { stack.pop(); sequence.push_back(current); report(" Adding block " << current->label()); } } report(" Adding block " << get_entry_block()->label()); sequence.push_back(get_entry_block()); return sequence; }
/*! \brief performs a topological sort to maximize reconvergence opportunities and ensure forward progress */ ir::ControlFlowGraph::BlockPointerVector ir::HammockGraph::topological_sequence() { typedef ir::ControlFlowGraph::BlockPointerVector BlockPointerVector; std::set< int > scheduled; BlockPointerVector sequence; schedule_hammock(sequence, scheduled, domTree.blocksToIndex[ domTree.blocks[0] ], domTree.blocksToIndex[ pdomTree.blocks[0] ]); // tests: // are all blocks scheduled exactly once? // is the entry node the first block? // are hammocks scheduled correctly? report("schedule:"); for (BlockPointerVector::iterator bb_it = sequence.begin(); bb_it != sequence.end(); ++bb_it) { report(" " << (*bb_it)->label); } return sequence; }
ControlFlowGraph::BlockPointerVector ControlFlowGraph::executable_sequence() { typedef std::unordered_set<iterator> BlockSet; BlockPointerVector sequence; BlockSet unscheduled; for(iterator i = begin(); i != end(); ++i) { unscheduled.insert(i); } report("Getting executable sequence."); sequence.push_back(get_entry_block()); unscheduled.erase(get_entry_block()); report(" added " << get_entry_block()->label()); while (!unscheduled.empty()) { if (sequence.back()->has_fallthrough_edge()) { edge_iterator fallthroughEdge = sequence.back()->get_fallthrough_edge(); if (unscheduled.count(fallthroughEdge->tail) != 0) { sequence.push_back(fallthroughEdge->tail); unscheduled.erase(fallthroughEdge->tail); } } else { // find a new block, favor branch targets over random blocks iterator next = *unscheduled.begin(); for(edge_pointer_iterator edge = sequence.back()->out_edges.begin(); edge != sequence.back()->out_edges.end(); ++edge) { if(unscheduled.count((*edge)->tail) != 0) { next = (*edge)->tail; } } // rewind through fallthrough edges to find the beginning of the // next chain of fall throughs report(" restarting at " << next->label()); bool rewinding = true; while (rewinding) { rewinding = false; for (edge_pointer_iterator edge = next->in_edges.begin(); edge != next->in_edges.end(); ++edge) { if ((*edge)->type == Edge::FallThrough) { assertM(unscheduled.count((*edge)->head) != 0, (*edge)->head->label() << " has multiple fallthrough branches."); next = (*edge)->head; report(" rewinding to " << next->label() ); rewinding = true; break; } } } sequence.push_back(next); unscheduled.erase(next); } report(" added " << sequence.back()->label()); } return sequence; }