Ref: https://github.com/JuliaLang/julia/pull/24362
Hi all, the above Ref is was to merge IPO constant propagation, but this still doesn't
seem to be working. The following code compiles conditionally with Val{B}
function myFun(::Type{Val{B}}, x::Int) where {B}
if B
println("B is true")
else
println("B is false")
end
return x
end
@code_warntype myFun(Val{true}, 2)
Variables:
x::Int64
Body:
begin
#= line 3 =#
$(Expr(:invoke, MethodInstance for println(::String), :(Main.println), "B is true"))::Nothing
goto 5
#= line 5 =#
5:
#= line 7 =#
return x::Int64
end::Int64
But not conditionally with B::Bool
function myFun(B::Bool, x::Int)
if B
println("B is true")
else
println("B is false")
end
return x
end
# Should optimise over B = true but does not.
@code_warntype myFun(true, 2)
Variables:
B::Bool
x::Int64
Body:
begin
unless B::Bool goto 5
#= line 3 =#
$(Expr(:invoke, MethodInstance for println(::String), :(Main.println), "B is true"))::Nothing
goto 8
5:
#= line 5 =#
$(Expr(:invoke, MethodInstance for println(::String), :(Main.println), "B is false"))::Nothing
8:
#= line 7 =#
return x::Int64
end::Int64
I used it with Julia 0.7.0-dev
downloaded today, so its the latest compiler.
Thank you.
That’s just the code_warntype behavior, IPO (inter-procedural) requires that you actually have an outer proceedure to infer between.
How do we verify that it is working?
Here's a test case showing the difference between 0.6.2 and 0.7.
julia> function test(x)
x ? 1 : 2
end
test (generic function with 1 method)
julia> function test2()
y = true
test(y)
end
test2 (generic function with 1 method)
julia> test2()
1
On 0.6, you get this:
julia> @code_warntype test2()
Variables:
#self# <optimized out>
y::Bool
#temp#::Int64
Body:
begin
y::Bool = true # line 3:
$(Expr(:inbounds, false))
# meta: location REPL[1] test 2
unless y::Bool goto 8
#temp#::Int64 = 1
goto 10
8:
#temp#::Int64 = 2
10:
# meta: pop location
$(Expr(:inbounds, :pop))
return #temp#::Int64
end::Int64
However, on 0.7 the constant is propagated into test
.
julia> @code_warntype test2()
Variables:
Body:
begin
return 1
end::Int64
I believe this is the IPO, but I'm not an expert.
Thanks @aaowens, I'm certainly no IPO expert either. Does this then not raise the need for some kind of const
identifier for function arguments to make full use of this feature?
Not necessarily. You know it’s working the same way you know any other optimization is working: trust, but verify, with @profile
.
Speaking with @keno in the Slack, it would make sense if @code_warntype myFun($true, $2)
handled the constants correctly. Could someone check if it does, and if it doesn't, I think that's a worthwhile feature request.
Reopen to implement the splicing syntax here.
As proposed here, this would introduce a bit of a strange disconnect with @benchmark
— it'd mean exactly the opposite thing. Not sure I have any good ideas here, but figured I'd update the title to represent the proposed action-item.
Not into @code_warntype
but at least in a replacement of Test.@inferred
:
https://discourse.julialang.org/t/pre-ann-rfc-testextras-jl/46487
Most helpful comment
Speaking with @keno in the Slack, it would make sense if
@code_warntype myFun($true, $2)
handled the constants correctly. Could someone check if it does, and if it doesn't, I think that's a worthwhile feature request.