-
Notifications
You must be signed in to change notification settings - Fork 11
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
Analysis of failures on Julia 1.10 #87
Comments
timholy
added a commit
that referenced
this issue
Dec 30, 2023
This uses a more sophisticated approach to analyzing control flow, asking which paths include execution of the required statements and ensuring we mark those statements that affect critical branching. Fixes #87
timholy
added a commit
that referenced
this issue
Dec 30, 2023
This uses a more sophisticated approach to analyzing control flow, asking which paths include execution of the required statements and ensuring we mark those statements that affect critical branching. Fixes #87
timholy
added a commit
to aviatesk/JET.jl
that referenced
this issue
Jan 10, 2024
Control-flow analysis changed considerably in LoweredCodeUtils 2.4 (xref JuliaDebug/LoweredCodeUtils.jl#87). This updates to the new version. The overall trend is less reliance on `norequire` as a way of blocking certain "bad" statements, instead attempting to discover minimal statements purely by their dependencies.
This was referenced Jan 10, 2024
aviatesk
pushed a commit
to aviatesk/JET.jl
that referenced
this issue
Jan 16, 2024
Control-flow analysis changed considerably in LoweredCodeUtils 2.4 (xref JuliaDebug/LoweredCodeUtils.jl#87). This updates to the new version. The overall trend is less reliance on `norequire` as a way of blocking certain "bad" statements, instead attempting to discover minimal statements purely by their dependencies.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This package's tests pass on Julia 1.9 and fail on Julia 1.10. Because the cause and likely resolutions are somewhat complex, I'm opening this issue to document the state of my analysis so far.
TL;DR summary
In Julia 1.10, changes to the lowering of
Core.get_binding_type
made control-flow graphs much more complicated, and the current way of ensuring correct propagation of flow is overly eager: it marks too many statements, breaking selective evaluation.In detail
Let's take a small modification of an example in the docs and tests:
This example is used to illustrate selective evaluation, identifying just the statements needed to evaluate
s11
but notk11
. (This capability is essential for Revise, which needs to be able to compute all the method signatures that will be generated without evaluating the method definition itself.)Here's an analysis script (the dependencies are obvious from the first line):
Julia 1.9
The output from
print_with_code
yieldsThe basic-block structure is quite simple:
with corresponding graph representation
Follow the direction of arrows (from successor to predecessor) to notice that basic blocks 2 and 3 form a cycle.
Currently, the way that we ensure full execution is that we mark the final line of each basic block as required, and then fill in any dependencies (e.g., evaluation of the conditional in a
GotoIfNot
). Specifically, here we mark the final statement of blocks 2 (statement %35) and 3 (statement %36), and marking these eventually leads to marking the entireiterate
loop. Note, however, thatk11
does not participate in the branching in any way, and thus this strategy does not force evaluation ofk11
(all statements associated withk11
are markedf
).Julia 1.10
The lowering affiliated with
get_binding_type
has changed significantly:You can see that almost all the lines (including ones for
k11
) are markedt
, unlike in Julia 1.9. This happens because we have a much more complicated graph of basic blocks:Basic blocks 8, 9, 11, 14, and 15 participate in the loop. This more complicated structure reveals that the old strategy of marking the exit of each "needed" basic block is too simple. Consider the case of block 11, for which the first statement (%36) is
s11 = _5
(assign from slot 5). Clearly this is a statement we must execute in order to evaluates11
. However, the remainder of block 11 deals withk11
, and in particular marking the exit statement (%41) forces analysis of the conditional which forces evaluation ofk11
itself.If we are to selectively evaluate
s11
, we have to "fall through" blocks like 11 without executing their control flow. Doing this in a way that doesn't risk omitting "necessary" control-flow like loops is not feasible with the current implementation of selective evaluation.The text was updated successfully, but these errors were encountered: