Optimizing generated termination checks to omit unfolds and condition…#879
Merged
Merged
Conversation
… evaluations where they are not needed
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.
For unfolding-expressions of the form
unfolding acc(P(args), p) in e, the termination plugin currently generates the following (simplified) termination check:If there are no conditions to check for
e, this code is currently still generated; in particular, the predicate is still unfolded inside a branch, and subsequently, we assume false. The unfold is completely unnecessary in this scenario though and could just be omitted.Even though the code generated by the plugin is subsequently run through the Simplifier, this block is not removed, because it's not empty (it unfolds a predicate and assumes false, after all).
While this is not a problem for individual unfolds, the effect can cascade into situations where we perform multiple unfolds inside branches after other unfolds only to not actually check anything in the end, as shown in viperproject/silicon#934.
So this PR modifies the termination plugin to generate some code blocks that exist to check termination conditions for some expressions only if there are actually termination conditions to check for those expressions, and omits them otherwise. In particular, we do this for unfoldings (omit the unfold, as explained above), implications, disjunctions, and some conjunctions (remove the need to evaluate the condition), let-expressions (remove the need to evaluate the bound expression).