Skip to content

Commit

Permalink
add supports for new @inline and @noinline features
Browse files Browse the repository at this point in the history
xrefs:
- <JuliaLang/julia#41312>
- <JuliaLang/julia#41328>

Built on top of <#752>.
  • Loading branch information
aviatesk committed Sep 11, 2021
1 parent 12ffcdc commit cfe0078
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 0 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ changes in `julia`.

## Supported features

* `Compat.@inline` and `Compat.@noinline` can be used at function callsites to encourage the compiler to (not) inline the function calls on Julia versions that support these features, and otherwise do not have any effects ([#41312]) (since Compat 3.36)

* `Compat.@inline` and `Compat.@noinline` can be used within function body to hint to the compiler the inlineability of the defined function ([#41312]) (since Compat 3.36)

* `Compat.@constprop :aggressive ex` and `Compat.@constprop :none ex` allow control over constant-propagation during inference on Julia versions that support this feature, and otherwise just pass back `ex`. ([#42125]) (since Compat 3.36)

* `Returns(value)` returns `value` for any arguments ([#39794]) (since Compat 3.35)
Expand Down Expand Up @@ -276,3 +280,5 @@ Note that you should specify the correct minimum version for `Compat` in the
[#34331]: https://github.com/JuliaLang/julia/pull/34331
[#39794]: https://github.com/JuliaLang/julia/pull/39794
[#42125]: https://github.com/JuliaLang/julia/pull/42125
[#41312]: https://github.com/JuliaLang/julia/pull/41312
[#41328]: https://github.com/JuliaLang/julia/pull/41328
44 changes: 44 additions & 0 deletions src/Compat.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,50 @@ using LinearAlgebra: Adjoint, Diagonal, Transpose, UniformScaling, RealHermSymCo

include("compatmacro.jl")

# NOTE these `@inline` and `@noinline` definitions overwrite the definitions implicitly
# imported from Base and so should happen before any usages of them within this module

# https://github.com/JuliaLang/julia/pull/41312: `@inline`/`@noinline` annotations within a function body
@static if !hasmethod(getfield(Base, Symbol("@inline")), (LineNumberNode,Module))
macro inline() Expr(:meta, :inline) end
macro noinline() Expr(:meta, :noinline) end
end

# https://github.com/JuliaLang/julia/pull/41328: callsite annotations of inlining
@static if !isdefined(Base, :annotate_meta_def_or_block)
macro inline(ex) annotate_meta_def_or_nothing(ex, :inline) end
macro noinline(ex) annotate_meta_def_or_nothing(ex, :noinline) end
function annotate_meta_def_or_nothing(@nospecialize(ex), meta::Symbol)
inner = unwrap_macrocalls(ex)
if is_function_def(inner)
# annotation on a definition
return esc(Base.pushmeta!(ex, meta))
else
# do nothing
return esc(ex)
end
end
unwrap_macrocalls(@nospecialize(x)) = x
function unwrap_macrocalls(ex::Expr)
inner = ex
while inner.head === :macrocall
inner = inner.args[end]::Expr
end
return inner
end
is_function_def(@nospecialize(ex)) =
return Meta.isexpr(ex, :function) || is_short_function_def(ex) || Meta.isexpr(ex, :->)
function is_short_function_def(@nospecialize(ex))
Meta.isexpr(ex, :(=)) || return false
while length(ex.args) >= 1 && isa(ex.args[1], Expr)
(ex.args[1].head === :call) && return true
(ex.args[1].head === :where || ex.args[1].head === :(::)) || return false
ex = ex.args[1]
end
return false
end
end

# https://github.com/JuliaLang/julia/pull/29440
if VERSION < v"1.1.0-DEV.389"
Base.:(:)(I::CartesianIndex{N}, J::CartesianIndex{N}) where N =
Expand Down
41 changes: 41 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1171,3 +1171,44 @@ end
)
@test aggf("hi") == nonef("hi") == :hi
end

# https://github.com/JuliaLang/julia/pull/41312
@testset "`@inline`/`@noinline` annotations within a function body" begin
callf(f, args...) = f(args...)
function foo1(a)
Compat.@inline
sum(sincos(a))
end
foo2(a) = (Compat.@inline; sum(sincos(a)))
foo3(a) = callf(a) do a
Compat.@inline
sum(sincos(a))
end
function foo4(a)
Compat.@noinline
sum(sincos(a))
end
foo5(a) = (Compat.@noinline; sum(sincos(a)))
foo6(a) = callf(a) do a
Compat.@noinline
sum(sincos(a))
end

@test foo1(42) == foo2(42) == foo3(42) == foo4(42) == foo5(42) == foo6(42)
end

# https://github.com/JuliaLang/julia/pull/41328
@testset "callsite annotations of inlining" begin
function foo1(a)
Compat.@inline begin
return sum(sincos(a))
end
end
function foo2(a)
Compat.@noinline begin
return sum(sincos(a))
end
end

@test foo1(42) == foo2(42)
end

0 comments on commit cfe0078

Please sign in to comment.