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; }
/*! \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; }