-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
improve effect_free
to fix regressions from #20726
#20843
Conversation
@nanosoldier |
base/inference.jl
Outdated
# fall-through | ||
else | ||
return false | ||
end |
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.
Couldn't you write this as
if !isa(ft, Const) || !contains_is(_pure_builtins, ft.val)
return false
end
or am I missing something?
base/inference.jl
Outdated
@@ -3405,13 +3408,20 @@ function effect_free(e::ANY, src::CodeInfo, mod::Module, allow_volatile::Bool) | |||
# first argument must be immutable to ensure e is affect_free | |||
a = ea[2] | |||
typ = widenconst(exprtype(a, src, mod)) | |||
if !isa(typ, DataType) || typ.mutable || typ.abstract | |||
if !isa(typ, DataType) || typ.mutable || (typ.abstract && !isconstType(typ)) |
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.
some of the fields of DataType aren't affect_free (uid
isn't constant)
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.
Is it possible for code to actually observe that change though? I have trouble believing this is a real issue.
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.
Precompile could. But I have trouble believing we should add that bug. Can you actually observe the benefit of this change for well-written code?
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.
Yes, this is needed here; the code in question does something like Tuple{...}.types
. Would it be sufficient just to exclude anything that might access uid
?
base/inference.jl
Outdated
elseif is_known_call(e, _apply, src, mod) && length(ea) > 1 | ||
ft = exprtype(ea[2], src, mod) | ||
if isa(ft, Const) && contains_is(_pure_builtins, ft.val) | ||
# fall-through |
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.
need to duplicate the rest of the logic from :call
here (well, DRY it in a helper function probably)
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.
That's why I only allowed _pure_builtins
; looking into apply's arguments is difficult.
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.
That's why I only allowed _pure_builtins
ah, right. So this won't handle return_type
either, but is still needed for this PR?
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.
Yes. Nothing here was splatting into return_type
itself (the code is _return_type(f, eltypestuple(A, Bs...))
), but in theory that could need to be added.
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.
It's marked @pure
though; that should already express that it can be considered effect-free. Couldn't we just ccall arg_type_tuple
(or write a proper O(n) Julia function) instead of this crazy O(n^2 * log(n))
implementation though?
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.
I think there are cases of splatting args to a @pure
function where we do not end up calling pure_eval_call
. That could be fixed as well.
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.
Line 3400 has an isa
test. That's from an old bug where we were passing in the wrong sv
object. I think that's fixed now that we're passing in the right src
object. Is that not true somewhere?
(https://github.com/JuliaLang/julia/pull/20843/files#diff-c0d983631c937ee5acfd0137cd7332deR3400)
base/inference.jl
Outdated
@@ -3405,13 +3408,20 @@ function effect_free(e::ANY, src::CodeInfo, mod::Module, allow_volatile::Bool) | |||
# first argument must be immutable to ensure e is affect_free | |||
a = ea[2] | |||
typ = widenconst(exprtype(a, src, mod)) | |||
if !isa(typ, DataType) || typ.mutable || typ.abstract | |||
if !isa(typ, DataType) || typ.mutable || (typ.abstract && !isconstType(typ)) |
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.
Precompile could. But I have trouble believing we should add that bug. Can you actually observe the benefit of this change for well-written code?
base/inference.jl
Outdated
elseif is_known_call(e, _apply, src, mod) && length(ea) > 1 | ||
ft = exprtype(ea[2], src, mod) | ||
if isa(ft, Const) && contains_is(_pure_builtins, ft.val) | ||
# fall-through |
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.
That's why I only allowed _pure_builtins
ah, right. So this won't handle return_type
either, but is still needed for this PR?
Yes, I believe all |
741ec6a
to
3475b6c
Compare
Your benchmark job has completed - possible performance regressions were detected. A full report can be found here. cc @jrevels |
Let's do this again for the most recent changes @nanosoldier |
Your benchmark job has completed - possible performance regressions were detected. A full report can be found here. cc @jrevels |
So, what do we make of those results? I'm not sure what to conclude. |
I'd rebase the branch and run it again. |
3475b6c
to
33dac60
Compare
@nanosoldier |
Your benchmark job has completed - possible performance regressions were detected. A full report can be found here. cc @jrevels |
where's travis here? attempting to re trigger it |
Should we merge this? It does seem to fix the vector arithmetic issue. The code for |
et = exprtype(e, src, mod) | ||
if !isa(et,Const) && !(isType(et) && isleaftype(et)) | ||
# first argument must be immutable to ensure e is affect_free | ||
a = ea[2] | ||
typ = widenconst(exprtype(a, src, mod)) | ||
if !isa(typ, DataType) || typ.mutable || typ.abstract | ||
if isconstType(typ) | ||
if Const(:uid) ⊑ exprtype(ea[3], src, mod) |
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.
that's quite optimistic :P
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.
as in incorrect? can't tell if this is an objection to the change or not
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.
yes, it's blacklist of one bad case but doesn't actually handle the general case
although it's possible we should just be more nuanced here. the uid
field is probably the only observable value that can change, and it only can change when loading pre-compiled code – so we really only need to be concerned about constant folding it during then. for all other purposes, it's effect-free.
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.
For constant folding, getfield_tfunc
uses a whitelist of DataType
fields (name, parameters, types, super), so I don't think there's any risk of constant folding the value of type.uid
.
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.
so I guess this effect-free
test is basically equivalent to tbaa_const
, for all current usages? (which all fields of DataType should be)
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.
Yes that sounds right.
33dac60
to
2f800a5
Compare
No description provided.