-
Notifications
You must be signed in to change notification settings - Fork 133
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix missed exploration of edges in constant propagation #1635
Conversation
99c1f78
to
dd62030
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but please add the reproducer or a derivative thereof as a regression test to our CI test suite. Make sure it fails (reproduces) without the fix and passes with it. Thanks!
I second @phschaad's comment about the test. I also think that there may be issues with this code concerning loop guards (which will have another incoming edge from the end/latch of a loop, thereby adding more Also, how do we know that this process works for multiple chained input edges going into the current node? This only propagates one step backwards. Ideally every state should traverse all the way back to a root node (or a dominator). |
This version ignores unvisited states but iterates until no change is made to the symbol definitions. Having more than one pass is the correct way of doing this. In general a loop body needs to be visited at least twice (it needs to propagate its definitions into itself). An optimization of my code would be to explicitly detect a loop (there is an edge with yet undefined result at its source) -> perform a sub-constant-propagation on the loop body only (going recursively if nested loops are found) and then continue with the normal propagation. This however would complicate the code a lot more (requiring changes into the topological sort function to start from arbitrary states). Do you think that is needed? |
Maybe the loop-specific behavior is not needed, especially when control flow blocks are raised from the code. Thanks for changing it! |
checking |
I have no idea what this means with relation to the existing code. How much longer is it than before? |
Testing a bit better. Before ~2.1s, now ~2.6s. I only change the |
There is a bug related to the missed exploration of interstate edges during constant propagation in case a loop body has a conditional assignment. The reverse DFS yields parent-node pairs and analyzes only the edge connecting the two. The DFS will yield a certain node only once, while the assumption in the code is that the uniqueness is enforced on the parent-node pair. This results in only one outgoing interstate edge per body state being visited, leading to mistakes in the common case of conditional assignments (which result in two outgoing edges performing different assignments). If the visited edge does not perform an assignment or assigns the initialization value, the symbol will be wrongly interpreted as a constant and replaced in downstream states.
A short reproducing example is:
The fix makes sure all interstate edges are visited at least once.