|
1 | | -use std::collections::HashMap; |
| 1 | +use std::collections::{HashMap, HashSet}; |
2 | 2 | use std::fmt; |
3 | 3 | use std::mem::take; |
4 | 4 | use std::panic; |
@@ -2233,6 +2233,46 @@ impl Assembler |
2233 | 2233 | } |
2234 | 2234 | } |
2235 | 2235 | } |
| 2236 | + |
| 2237 | + /// Return a traversal of the block graph in reverse post-order. |
| 2238 | + pub fn rpo(&self) -> Vec<BlockId> { |
| 2239 | + let entry_blocks: Vec<BlockId> = self.basic_blocks.iter() |
| 2240 | + .filter(|block| block.entry) |
| 2241 | + .map(|block| block.id) |
| 2242 | + .collect(); |
| 2243 | + let mut result = self.po_from(entry_blocks); |
| 2244 | + result.reverse(); |
| 2245 | + result |
| 2246 | + } |
| 2247 | + |
| 2248 | + /// Compute postorder traversal starting from the given blocks. |
| 2249 | + /// Outbound edges are extracted from the last 0, 1, or 2 instructions (jumps). |
| 2250 | + fn po_from(&self, starts: Vec<BlockId>) -> Vec<BlockId> { |
| 2251 | + #[derive(PartialEq)] |
| 2252 | + enum Action { |
| 2253 | + VisitEdges, |
| 2254 | + VisitSelf, |
| 2255 | + } |
| 2256 | + let mut result = vec![]; |
| 2257 | + let mut seen = HashSet::with_capacity(self.basic_blocks.len()); |
| 2258 | + let mut stack: Vec<_> = starts.iter().map(|&start| (start, Action::VisitEdges)).collect(); |
| 2259 | + while let Some((block, action)) = stack.pop() { |
| 2260 | + if action == Action::VisitSelf { |
| 2261 | + result.push(block); |
| 2262 | + continue; |
| 2263 | + } |
| 2264 | + if !seen.insert(block) { continue; } |
| 2265 | + stack.push((block, Action::VisitSelf)); |
| 2266 | + let EdgePair(edge1, edge2) = self.basic_blocks[block.0].edges(); |
| 2267 | + if let Some(edge) = edge1 { |
| 2268 | + stack.push((edge.target, Action::VisitEdges)); |
| 2269 | + } |
| 2270 | + if let Some(edge) = edge2 { |
| 2271 | + stack.push((edge.target, Action::VisitEdges)); |
| 2272 | + } |
| 2273 | + } |
| 2274 | + result |
| 2275 | + } |
2236 | 2276 | } |
2237 | 2277 |
|
2238 | 2278 | /// Return a result of fmt::Display for Assembler without escape sequence |
|
0 commit comments