Analysis that starts optimistically but is only correct at a fixed point. Will fail out to `analyse_pessimistic` if the lattice is missing, or `self.fuel` is exhausted. When successful, the result indicates whether new information was produced for `exprs.last()`.
(
&mut self,
exprs: &[&MirRelationExpr],
lower: usize,
upper: usize,
depends: &Derived,
lattice: &dyn crate::analysis::Lattice<A
| 424 | /// Will fail out to `analyse_pessimistic` if the lattice is missing, or `self.fuel` is exhausted. |
| 425 | /// When successful, the result indicates whether new information was produced for `exprs.last()`. |
| 426 | fn analyse_optimistic( |
| 427 | &mut self, |
| 428 | exprs: &[&MirRelationExpr], |
| 429 | lower: usize, |
| 430 | upper: usize, |
| 431 | depends: &Derived, |
| 432 | lattice: &dyn crate::analysis::Lattice<A::Value>, |
| 433 | ) -> Result<bool, ()> { |
| 434 | // Repeatedly re-evaluate the whole tree bottom up, until no changes of fuel spent. |
| 435 | let mut changed = true; |
| 436 | while changed { |
| 437 | changed = false; |
| 438 | |
| 439 | // Bail out if we have done too many `LetRec` passes in this analysis. |
| 440 | self.fuel -= 1; |
| 441 | if self.fuel == 0 { |
| 442 | return Err(()); |
| 443 | } |
| 444 | |
| 445 | // Track if repetitions may be required, to avoid iteration if they are not. |
| 446 | let mut is_recursive = false; |
| 447 | // Update each derived value and track if any have changed. |
| 448 | for index in lower..upper { |
| 449 | let value = self.derive(exprs[index], index, depends); |
| 450 | changed = lattice.meet_assign(&mut self.results[index], value) || changed; |
| 451 | if let MirRelationExpr::LetRec { .. } = &exprs[index] { |
| 452 | is_recursive = true; |
| 453 | } |
| 454 | } |
| 455 | |
| 456 | // Un-set the potential loop if there was no recursion. |
| 457 | if !is_recursive { |
| 458 | changed = false; |
| 459 | } |
| 460 | } |
| 461 | Ok(true) |
| 462 | } |
| 463 | |
| 464 | /// Analysis that starts conservatively and can be stopped at any point. |
| 465 | /// |
no test coverage detected