Skip to content
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

Relax constprop recursion detection #39918

Closed
wants to merge 1 commit into from
Closed

Relax constprop recursion detection #39918

wants to merge 1 commit into from

Conversation

Keno
Copy link
Member

@Keno Keno commented Mar 5, 2021

At the moment, we restrict const prop whenever we see a cycle in
methods being called. However, I think this condition can be relaxed
slightly: In particular, if the type complexity limiting did not
decide to limit the growth of the type in question, I think it
should be fine to constant prop as long as there is no cycle in
method instances (rather than just methods).

Fixes #39915

At the moment, we restrict const prop whenever we see a cycle in
methods being called. However, I think this condition can be relaxed
slightly: In particular, if the type complexity limiting did not
decide to limit the growth of the type in question, I think it
should be fine to constant prop as long as there is no cycle in
*method instances* (rather than just methods).

Fixes #39915
@@ -456,7 +458,7 @@ function abstract_call_method_with_const_args(interp::AbstractInterpreter, @nosp
infstate = sv
cyclei = 0
while !(infstate === nothing)
if method === infstate.linfo.def && any(infstate.result.overridden_by_const)
if (edgelimited ? method === infstate.linfo.def : mi === infstate.linfo) && any(infstate.result.overridden_by_const)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to make sense in general, but I'd need to think hard through the specifics here to make sure it is good.

So, here we are checking with mi, which isn't normally a limited object, and thus would normally not be valid here for cycle detection (thus also why we don't use it originally in cycle detection). But I guess the concept is that abstract_call_gf_by_type is expected to deal with that possibility (via setting edgelimited when required), so we won't get here if this would be unrestricted in complexity, and making this === equivalent to <=?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct. Basically, the intuition is that the same logic that prevents infinite recursion over the type lattice should also restrict infinite recursion of the lattice that adjoins const elements, except that we can get additional recursion by calling the same method instance with different const elements (which is a cycle, but not infinite over the type lattice). There's an example that shows that case added in the tests (I verified the example stack overflows if you replace edgecycle by edgelimited above).

@bramtayl
Copy link
Contributor

bramtayl commented Mar 5, 2021

Huh. And here I was thinking this was a total impossibility. This opens up a lot of doors leading to doors leading to doors leading to doors.


# issue #39915
function f33915(a_tuple, which_ones)
rest = my_getindex(tail(a_tuple), tail(which_ones))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
rest = my_getindex(tail(a_tuple), tail(which_ones))
rest = f33915(tail(a_tuple), tail(which_ones))

@@ -542,7 +545,6 @@ function abstract_call_method(interp::AbstractInterpreter, method::Method, @nosp
parent_method2 isa Method || (parent_method2 = nothing) # Union{Method, Nothing}
if parent.linfo.def === sv.linfo.def && sv_method2 === parent_method2
topmost = infstate
edgecycle = true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reason to delete these edgecycle = true ?
In these cases there is a cycle, and we still need to try recursion detection in abstract_call_method_with_const_args ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you're right - these were deleted by accident (leftover from an earlier experiment) - thanks.

@vtjnash
Copy link
Member

vtjnash commented Apr 21, 2021

Needs an update after #39305

@aviatesk
Copy link
Member

I will try it.

aviatesk added a commit to aviatesk/julia that referenced this pull request Apr 22, 2021
At the moment, we restrict const prop whenever we see a cycle in
methods being called. However, I think this condition can be relaxed
slightly: In particular, if the type complexity limiting did not
decide to limit the growth of the type in question, I think it
should be fine to constant prop as long as there is no cycle in
*method instances* (rather than just methods).

Fixes JuliaLang#39915, replaces JuliaLang#39918

Co-Authored-By: Keno Fisher <[email protected]>
@vtjnash
Copy link
Member

vtjnash commented Apr 22, 2021

Continued in #40561

@vtjnash vtjnash closed this Apr 22, 2021
@vtjnash vtjnash deleted the kf/39915 branch April 22, 2021 13:36
aviatesk added a commit to aviatesk/julia that referenced this pull request Apr 24, 2021
At the moment, we restrict const prop whenever we see a cycle in
methods being called. However, I think this condition can be relaxed
slightly: In particular, if the type complexity limiting did not
decide to limit the growth of the type in question, I think it
should be fine to constant prop as long as there is no cycle in
*method instances* (rather than just methods).

Fixes JuliaLang#39915, replaces JuliaLang#39918

Co-Authored-By: Keno Fisher <[email protected]>
aviatesk added a commit to aviatesk/julia that referenced this pull request Apr 27, 2021
At the moment, we restrict const prop whenever we see a cycle in
methods being called. However, I think this condition can be relaxed
slightly: In particular, if the type complexity limiting did not
decide to limit the growth of the type in question, I think it
should be fine to constant prop as long as there is no cycle in
*method instances* (rather than just methods).

Fixes JuliaLang#39915, replaces JuliaLang#39918

Co-Authored-By: Keno Fisher <[email protected]>
aviatesk added a commit to aviatesk/julia that referenced this pull request May 6, 2021
At the moment, we restrict const prop whenever we see a cycle in
methods being called. However, I think this condition can be relaxed
slightly: In particular, if the type complexity limiting did not
decide to limit the growth of the type in question, I think it
should be fine to constant prop as long as there is no cycle in
*method instances* (rather than just methods).

Fixes JuliaLang#39915, replaces JuliaLang#39918

Co-Authored-By: Keno Fisher <[email protected]>
vtjnash pushed a commit that referenced this pull request May 26, 2021
At the moment, we restrict const prop whenever we see a cycle in
methods being called. However, I think this condition can be relaxed
slightly: In particular, if the type complexity limiting did not
decide to limit the growth of the type in question, I think it
should be fine to constant prop as long as there is no cycle in
*method instances* (rather than just methods).

Fixes #39915, replaces #39918

Co-authored-by: Keno Fisher <[email protected]>
shirodkara pushed a commit to shirodkara/julia that referenced this pull request Jun 9, 2021
At the moment, we restrict const prop whenever we see a cycle in
methods being called. However, I think this condition can be relaxed
slightly: In particular, if the type complexity limiting did not
decide to limit the growth of the type in question, I think it
should be fine to constant prop as long as there is no cycle in
*method instances* (rather than just methods).

Fixes JuliaLang#39915, replaces JuliaLang#39918

Co-authored-by: Keno Fisher <[email protected]>
johanmon pushed a commit to johanmon/julia that referenced this pull request Jul 5, 2021
At the moment, we restrict const prop whenever we see a cycle in
methods being called. However, I think this condition can be relaxed
slightly: In particular, if the type complexity limiting did not
decide to limit the growth of the type in question, I think it
should be fine to constant prop as long as there is no cycle in
*method instances* (rather than just methods).

Fixes JuliaLang#39915, replaces JuliaLang#39918

Co-authored-by: Keno Fisher <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Recursion disables constant propagation
4 participants