-
-
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
Let tmerge form a Union more often #27843
Conversation
A non-monotonicity is pretty bad; I think it would be better to fix that and address the regression by improving the inlining logic (which I'm working on now). |
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.
Monotonicity is certainly very nice, but I assume v0.6 would have shown the same behavior? It’s only recently that I tried to push hard on these edge cases - they’re definitely very difficult to design.
@@ -331,8 +331,10 @@ function tmerge(@nospecialize(typea), @nospecialize(typeb)) | |||
# XXX: this should never happen | |||
return Any | |||
end | |||
# it's always ok to form a Union of two concrete types | |||
if (isconcretetype(typea) || isType(typea)) && (isconcretetype(typeb) || isType(typeb)) | |||
# it's always ok to form a Union of two Union-free types |
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 an alternate literal translation of this would be isa(unwrap_unionall(T), DataType)
I've looked a little bit into the non-montonicity. Union-splitting the
Then
These are Now interestingly, if the order of the |
d778622
to
af3c79e
Compare
Ok, this is now much more elegant. However, as the original issue is better tackled with #27857 (addressing the underlying problem instead of working around it), the need for this is much lower. It may still give slightly better inference results, but whether they give tangible benefits is another question. It does fix above-mentioned quirk, though, as now julia> code_typed(foo, atypes)
1-element Array{Any,1}:
CodeInfo(
1 1 ─ %1 = Main.SubArray(%%a, %%b, %%c, %%d)::Union{SubArray{_1,_2,_3,_4,false} where _4 where _3 where _2 where _1, SubArray{_1,_2,_3,_4,true} where _4 where _3 where _2 where _1}
└── return %1 │
) => Union{SubArray{_1,_2,_3,_4,false} where _4 where _3 where _2 where _1, SubArray{_1,_2,_3,_4,true} where _4 where _3 where _2 where _1}
julia> code_typed(foo, atypes2)
1-element Array{Any,1}:
CodeInfo(
1 1 ─ %1 = Main.SubArray(%%a, %%b, %%c, %%d)::Union{SubArray{_1,_2,_3,_4,false} where _4 where _3 where _2 where _1, SubArray{_1,_2,_3,_4,true} where _4 where _3 where _2 where _1}
└── return %1 │
) => Union{SubArray{_1,_2,_3,_4,false} where _4 where _3 where _2 where _1, SubArray{_1,_2,_3,_4,true} where _4 where _3 where _2 where _1} |
@nanosoldier |
Your benchmark job has completed - possible performance regressions were detected. A full report can be found here. cc @ararslan |
@nanosoldier |
1 similar comment
@nanosoldier |
@ararslan is the soldier down? I wanted to check how the recent changes, in particular wrt inlining, interact with this PR. |
Yeah there was a server error so I restarted it. @nanosoldier |
Your benchmark job has completed - possible performance regressions were detected. A full report can be found here. cc @ararslan |
Ok, this doesn't make much of a difference performance-wise now. Mostly that's a hint that the inlining heuristics are saner now. I still find this change esthetically pleasing, but there is little to no tangible benefit, so I leave it to others to make the call here. |
It does seem nicer to me as well in my very mildly informed opinion. @JeffBezanson? |
I would worry about compiler performance here; using more Union types will cause us to infer more signatures. |
I think this seems good |
If we're going to merge this it would be good to add some sort of test related to #27843 (comment) (the example from the OP basically). |
af3c79e
to
f72bb13
Compare
Not sure how good a benchmark of compiler performance building the sysmimg is, but:
this PR:
So, yes, might cost us a few percent. Test to the same effect as OP, but not relying on the specifics of the |
They both give |
Let tmerge decide whether to directly form a Union based on unioncomplexity, not concreteness.
f72bb13
to
2c45fc2
Compare
Rebased. Let's see whether CI still likes it. |
Added a test to address #27843 (comment). CI had been all green, now there is a fail in SHA on tester_linux64 which I don't understand but assume unrelated. If someone can confirm it's unrelated to this PR, I'll go ahead and merge unless anyone objects. |
It is an AMD cpu bug |
This reverts commit 6c1824d.
This reverts commit 6c1824d.
Let tmerge decide whether to directly form a Union based on unioncomplexity, not concreteness.
…ang#39406) This reverts commit 6c1824d. Fixes JuliaLang#39349. The extra inference precision is nice, but seems to carry too much risk of blowup.
…ang#39406) This reverts commit 6c1824d. Fixes JuliaLang#39349. The extra inference precision is nice, but seems to carry too much risk of blowup.
This addresses the performance regression of
mapslices
introduced by #27417 and noticed in #27828. I think replacingisconcretetype(typea) || isType(typea)
withunioncomplexity(typea) == 0
makes a lot of sense and is in the same spirit as the original PR.However, I had to introduce another condition due to this quirk (which happens both before #27417 and with this PR):
Note that the wider
atypes2
gives the narrower inference result. Hence the additionalTuple
condition to turnUnion{Tuple{}, Tuple{Any,Vararg{Any,N} where N}}
intoTuple
. (They should probably be type-equal anyway, but that's a different issue.) This leaves me a bit unsatisfied, but seems to be necessary to fix the regression.