Eval-link procedure from the paper. For a predecessor V of node W returns V if V < W, otherwise the minimum of sdom(U), where U > W and U is on a semi-dominator path for W in CFG. Use path compression to bring complexity down to O(m*log(n)).
(&mut self, v: u32, last_linked: u32)
| 431 | /// where U > W and U is on a semi-dominator path for W in CFG. |
| 432 | /// Use path compression to bring complexity down to O(m*log(n)). |
| 433 | fn eval(&mut self, v: u32, last_linked: u32) -> u32 { |
| 434 | if self.stree[v].ancestor < last_linked { |
| 435 | return self.stree[v].label; |
| 436 | } |
| 437 | |
| 438 | // Follow semi-dominator path. |
| 439 | let mut root = v; |
| 440 | loop { |
| 441 | self.eval_worklist.push(root); |
| 442 | root = self.stree[root].ancestor; |
| 443 | |
| 444 | if self.stree[root].ancestor < last_linked { |
| 445 | break; |
| 446 | } |
| 447 | } |
| 448 | |
| 449 | let mut prev = root; |
| 450 | let root = self.stree[prev].ancestor; |
| 451 | |
| 452 | // Perform path compression. Point all ancestors to the root |
| 453 | // and propagate minimal sdom(U) value from ancestors to children. |
| 454 | while let Some(curr) = self.eval_worklist.pop() { |
| 455 | if self.stree[prev].label < self.stree[curr].label { |
| 456 | self.stree[curr].label = self.stree[prev].label; |
| 457 | } |
| 458 | |
| 459 | self.stree[curr].ancestor = root; |
| 460 | prev = curr; |
| 461 | } |
| 462 | |
| 463 | self.stree[v].label |
| 464 | } |
| 465 | |
| 466 | fn compute_domtree(&mut self, cfg: &ControlFlowGraph) { |
| 467 | // Compute semi-dominators. |
no test coverage detected