You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Here, the result of the length call is known at compile time, but the call to length is not elided. Even worse, it uses dynamic dispatch, resulting in relatively bad performance.
I've poked at his a bit, but I'm not 100% happy with what I've got so far. First attempt is
--- a/base/compiler/abstractinterpretation.jl+++ b/base/compiler/abstractinterpretation.jl@@ -982,7 +982,7 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
return CallMeta(abstract_call_known(interp, <:, fargs, argtypes, sv).rt, false)
elseif la == 2 && isa(argtypes[2], Const) && isa(argtypes[2].val, SimpleVector) && istopfunction(f, :length)
# mark length(::SimpleVector) as @pure
- return CallMeta(Const(length(argtypes[2].val)), false)+ return CallMeta(Const(length(argtypes[2].val)), nothing)
elseif la == 3 && isa(argtypes[2], Const) && isa(argtypes[3], Const) &&
isa(argtypes[2].val, SimpleVector) && isa(argtypes[3].val, Int) && istopfunction(f, :getindex)
# mark getindex(::SimpleVector, i::Int) as @pure
The false there tells the optimizer not to worry about this call. But apparently, it should. That gives:
So length is inlined and the dynamic dispatch is gone, but there is still unnecessary code left. Note, however, that the constant 2, although apparently lost, is still there ... somewhere:
So for bar(), further constant-propagting the result of length through the + 1 gets rid of its use by eliding the addition, allowing length to be elided as well. But for foo(), the return is a use of length's result, preventing its elision. But why can't it be replaced with its constant return value? Apparently I have not found the correct spot to patch here. @Keno to the rescue!
The text was updated successfully, but these errors were encountered:
Coming from discussion at #37230; related to #37303.
Here, the result of the length call is known at compile time, but the call to
length
is not elided. Even worse, it uses dynamic dispatch, resulting in relatively bad performance.I've poked at his a bit, but I'm not 100% happy with what I've got so far. First attempt is
The
false
there tells the optimizer not to worry about this call. But apparently, it should. That gives:So
length
is inlined and the dynamic dispatch is gone, but there is still unnecessary code left. Note, however, that the constant2
, although apparently lost, is still there ... somewhere:My second attempt was to completely elide the
length
call by declaring it effect-free with(And this is instead of, not in addition to, the diff above.)
Then I get:
Yay! But still:
So for
bar()
, further constant-propagting the result oflength
through the+ 1
gets rid of its use by eliding the addition, allowinglength
to be elided as well. But forfoo()
, thereturn
is a use oflength
's result, preventing its elision. But why can't it be replaced with its constant return value? Apparently I have not found the correct spot to patch here. @Keno to the rescue!The text was updated successfully, but these errors were encountered: