Static Fork Analysis#275
Merged
Merged
Conversation
ce03667 to
595ca84
Compare
595ca84 to
5a1093e
Compare
5a1093e to
a167cd9
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Do not merge until #271The analysis:
ForkFactForkFactis ano_fork_guard: ExprRefand afork_guard: ExprRef.no_fork_guardmeans "if this is true, there is some path ending at this node where no fork is triggered".fork_guardmeans "if this is true, there is some path ending at this node where a fork is triggered."no_fork_guardfor all in neighbors, and same for thefork_guards. The catch is that we know which edges must've been taken, so we can do a similar trick as in the assignment analysis and say "if the predecessor forks underpand only transitions to this node underp, it definitely forked: simplify to true". We then simplify/canonicalize the expressions.pin this node, the transfer function is just OR-ing withpon thefork_guardand OR-ing with!pon thenot_fork_guard.Using the analysis:
Once we have the in_fact and out_fact for each node at the fixpoint, we can make the following inferences for some node
n:fork_guardtonisDefinitelyUnsat(the expression simplifies to false), we definitely didn't fork before thisnot_fork_guardtonisDefinitelyUnsatand thefork_guardtonisAlwaysSat(the expression simplifies to true), we definitely did fork before thisMaybeForkedAssertions:
in_factfork_guardto this node isDefinitelyNotForked. i.e. if we hit a fork, we haven't forked prior. This is maybe too strong an assertion, but for now everything satisfies this.DefinitelyNotForkedorDefinitelyForked. If weMaybeForkedwe need internal state, so we panic for now. If weDefinitelyNotForked, then we graft the next protocol onto the done node. If weDefinitelyForked, we do not.Testing:
All the tests pass without tripping those assertions. Also I wrote very targeted unit tests that test different important cases for the analysis.
While it's not in the rust suite because it needs extra flags and some modifications, for a sanity check I also was able to test that the following protocol, run with
--skip-static-step-fork-checkspanics after the analysis becausefork node node6 can be reached after a prior forkOther Minor stuff:
DefinitelySattoAlwaysSatbecause I think that is more descriptive.AlwaysSatis just if the expression tautologically simplifies to true.propogate_assigns.rsandreaching_defs.rshave some small changes which are just generalizing helpers so I can use them in the fork analysis as well