Guards: Improve join-order for wrapper guards#20814
Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR improves the asymptotic performance of wrapper guards by applying a rank-iteration transformation to a recursive universal quantification. The optimization changes the complexity from O(n³) to O(n²) when evaluating O(n) results for methods with many return expressions (e.g., a switch statement with 1000 cases).
Key Changes
- Introduces dense ranking for return expressions based on their location to enable incremental processing
- Replaces a universal quantification (
forex) with a rank-based recursion that iterates through return expressions in order - Adds helper predicates to track relevance of return expressions and their values
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| validReturnInCustomGuard(_, _, m, ppos, retval, val) and rnk = 0 | ||
| or | ||
| validReturnInCustomGuardToRank(rnk - 1, m, ppos, retval, val) and | ||
| rnk <= maxRank(m) and |
There was a problem hiding this comment.
Yes. The condition for iterating to the next rank is otherwise vacuously true, and then we'll get "infinite" tuples.
| private predicate validReturnInCustomGuardToRank( | ||
| int rnk, NonOverridableMethod m, ParameterPosition ppos, GuardValue retval, GuardValue val | ||
| ) { | ||
| validReturnInCustomGuard(_, _, m, ppos, retval, val) and rnk = 0 |
There was a problem hiding this comment.
It's the validReturnInCustomGuard(_, _, m, ppos, retval, val) that ensures that this becomes a forex and not a forall, right? If so, that might deserve a comment.
There was a problem hiding this comment.
Yes. And the fact that we've pushed the constraint
not exists(GuardValue notRetval |
exprHasValue(ret, notRetval) and
disjointValues(notRetval, retval)
)
into it.
There was a problem hiding this comment.
I've added a commit with an elaborating comment.
Improves the asymptotic performance of wrapper guards by applying the usual rank-iteration tranformation to a recursive universal quantification.
An observed example of the form
goes from
O(n^3)toO(n^2)to evaluate theO(n)result (the set of implications from return value to parameter value seeded with return being zero or not-zero).