/** * Sort the m_blocks vector in reverse post order. This enforces that * m_blocks will be a topological order in case the region is acyclic. * All region arcs are taken into account, including retranslation arcs. */ void RegionDesc::sortBlocks() { RegionDesc::BlockIdSet visited; RegionDesc::BlockIdVec reverse; postOrderSort(entry()->id(), visited, reverse); assertx(m_blocks.size() == reverse.size()); // Update `m_blocks' vector. m_blocks.clear(); auto size = reverse.size(); for (size_t i = 0; i < size; i++) { m_blocks.push_back(block(reverse[size - i - 1])); } }
/* * Perform a DFS starting at block `bid', storing the post-order in * `outVec'. */ void RegionDesc::postOrderSort(RegionDesc::BlockId bid, RegionDesc::BlockIdSet& visited, RegionDesc::BlockIdVec& outVec) { if (visited.count(bid)) return; visited.insert(bid); if (auto nextRetr = nextRetrans(bid)) { postOrderSort(nextRetr.value(), visited, outVec); } for (auto succ : succs(bid)) { postOrderSort(succ, visited, outVec); } outVec.push_back(bid); }
/** * Sort the m_blocks vector in reverse post order. This enforces that * m_blocks will be a topological order in case the region is acyclic. * All region arcs are taken into account, including retranslation arcs. */ void RegionDesc::sortBlocks() { RegionDesc::BlockIdSet visited; RegionDesc::BlockIdVec reverse; postOrderSort(entry()->id(), visited, reverse); assertx(m_blocks.size() >= reverse.size()); // Remove unreachable blocks from `m_data'. for (auto it = m_blocks.begin(); it != m_blocks.end();) { auto bid = (*it)->id(); if (visited.count(bid) == 0) { it = deleteBlock(it); } else { it++; } } // Update `m_blocks' vector. m_blocks.clear(); auto size = reverse.size(); for (size_t i = 0; i < size; i++) { m_blocks.push_back(block(reverse[size - i - 1])); } }