-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
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
Missing Pi node after type assert (or, using the non type asserted SSA value leads to worse inference) #38274
Comments
Also compare to function f3(x::Dict{String, Any})
for (k, v) in x
v = v::String
return Base.UUID(v)
end
return nothing
end where julia> code_warntype(f3, Tuple{Dict{String, Any}})
Variables
v::Any
│ (v = Core.getfield(%11, 1))
│ Core.getfield(%6, 2)
│ (v = Core.typeassert(v, Main.String))
│ %15 = Base.UUID::Core.Const(Base.UUID)
│ %16 = (%15)(v::String)::Base.UUID With the assignment, |
Compare to:
Which inserts a
|
This seems to do the trick: --- a/base/compiler/abstractinterpretation.jl
+++ b/base/compiler/abstractinterpretation.jl
@@ -1390,6 +1390,17 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState)
else
frame.src.ssavaluetypes[pc] = t
end
+ if hd === :call
+ # give special treatment to typeasserts on variables as in
+ stmt::Expr
+ # which constrain the type of the variable in subsequent code
+ if length(stmt.args) == 3
+ f = abstract_eval_value(interp, stmt.args[1], changes, frame)
+ if isa(f, Const) && f.val === Core.typeassert && isa(stmt.args[2], Slot)
+ changes = StateUpdate(stmt.args[2], VarState(t, false), changes)
+ end
+ end
+ end
end
if frame.cur_hand !== nothing && isa(changes, StateUpdate)
# propagate new type info to exception handler It feels like a bit of hack though. We don't do this "if |
A different alternative would be to define Another option would be to expand |
So I think effectivly the change I would like to see is>
becomes
and
becomes
If we only change the the first we still lose some information and make two similar expressions quite distinct. This is hard to implement on the abstract interpretation level since we currently have the assumption of each statement leading to one state update. So probably the place to implement is during lowering. |
Add a subsection to the Performance tips. Updates JuliaLang#38274
Not sure if the title is 100% accurate. Anyway, here are two similar versions of a function:
However, the first one fails to infer while the second one does not:
Looking at the typed code, we can see why:
So julia here decided to pick the local variable
v
that was inferred toAny
in the call toUUID
instead of the one that is type asserted (%14
). In the inferred version:Here it is using
%15
which is the one where the type is known.Perhaps the optimizer can be taught how to pick the better one of the two possible SSA values.
The text was updated successfully, but these errors were encountered: