Skip to content

Commit cfe0078

Browse files
committed
add supports for new @inline and @noinline features
xrefs: - <JuliaLang/julia#41312> - <JuliaLang/julia#41328> Built on top of <#752>.
1 parent 12ffcdc commit cfe0078

File tree

3 files changed

+91
-0
lines changed

3 files changed

+91
-0
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ changes in `julia`.
5454

5555
## Supported features
5656

57+
* `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)
58+
59+
* `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)
60+
5761
* `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)
5862

5963
* `Returns(value)` returns `value` for any arguments ([#39794]) (since Compat 3.35)
@@ -276,3 +280,5 @@ Note that you should specify the correct minimum version for `Compat` in the
276280
[#34331]: https://github.com/JuliaLang/julia/pull/34331
277281
[#39794]: https://github.com/JuliaLang/julia/pull/39794
278282
[#42125]: https://github.com/JuliaLang/julia/pull/42125
283+
[#41312]: https://github.com/JuliaLang/julia/pull/41312
284+
[#41328]: https://github.com/JuliaLang/julia/pull/41328

src/Compat.jl

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,50 @@ using LinearAlgebra: Adjoint, Diagonal, Transpose, UniformScaling, RealHermSymCo
88

99
include("compatmacro.jl")
1010

11+
# NOTE these `@inline` and `@noinline` definitions overwrite the definitions implicitly
12+
# imported from Base and so should happen before any usages of them within this module
13+
14+
# https://github.com/JuliaLang/julia/pull/41312: `@inline`/`@noinline` annotations within a function body
15+
@static if !hasmethod(getfield(Base, Symbol("@inline")), (LineNumberNode,Module))
16+
macro inline() Expr(:meta, :inline) end
17+
macro noinline() Expr(:meta, :noinline) end
18+
end
19+
20+
# https://github.com/JuliaLang/julia/pull/41328: callsite annotations of inlining
21+
@static if !isdefined(Base, :annotate_meta_def_or_block)
22+
macro inline(ex) annotate_meta_def_or_nothing(ex, :inline) end
23+
macro noinline(ex) annotate_meta_def_or_nothing(ex, :noinline) end
24+
function annotate_meta_def_or_nothing(@nospecialize(ex), meta::Symbol)
25+
inner = unwrap_macrocalls(ex)
26+
if is_function_def(inner)
27+
# annotation on a definition
28+
return esc(Base.pushmeta!(ex, meta))
29+
else
30+
# do nothing
31+
return esc(ex)
32+
end
33+
end
34+
unwrap_macrocalls(@nospecialize(x)) = x
35+
function unwrap_macrocalls(ex::Expr)
36+
inner = ex
37+
while inner.head === :macrocall
38+
inner = inner.args[end]::Expr
39+
end
40+
return inner
41+
end
42+
is_function_def(@nospecialize(ex)) =
43+
return Meta.isexpr(ex, :function) || is_short_function_def(ex) || Meta.isexpr(ex, :->)
44+
function is_short_function_def(@nospecialize(ex))
45+
Meta.isexpr(ex, :(=)) || return false
46+
while length(ex.args) >= 1 && isa(ex.args[1], Expr)
47+
(ex.args[1].head === :call) && return true
48+
(ex.args[1].head === :where || ex.args[1].head === :(::)) || return false
49+
ex = ex.args[1]
50+
end
51+
return false
52+
end
53+
end
54+
1155
# https://github.com/JuliaLang/julia/pull/29440
1256
if VERSION < v"1.1.0-DEV.389"
1357
Base.:(:)(I::CartesianIndex{N}, J::CartesianIndex{N}) where N =

test/runtests.jl

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1171,3 +1171,44 @@ end
11711171
)
11721172
@test aggf("hi") == nonef("hi") == :hi
11731173
end
1174+
1175+
# https://github.com/JuliaLang/julia/pull/41312
1176+
@testset "`@inline`/`@noinline` annotations within a function body" begin
1177+
callf(f, args...) = f(args...)
1178+
function foo1(a)
1179+
Compat.@inline
1180+
sum(sincos(a))
1181+
end
1182+
foo2(a) = (Compat.@inline; sum(sincos(a)))
1183+
foo3(a) = callf(a) do a
1184+
Compat.@inline
1185+
sum(sincos(a))
1186+
end
1187+
function foo4(a)
1188+
Compat.@noinline
1189+
sum(sincos(a))
1190+
end
1191+
foo5(a) = (Compat.@noinline; sum(sincos(a)))
1192+
foo6(a) = callf(a) do a
1193+
Compat.@noinline
1194+
sum(sincos(a))
1195+
end
1196+
1197+
@test foo1(42) == foo2(42) == foo3(42) == foo4(42) == foo5(42) == foo6(42)
1198+
end
1199+
1200+
# https://github.com/JuliaLang/julia/pull/41328
1201+
@testset "callsite annotations of inlining" begin
1202+
function foo1(a)
1203+
Compat.@inline begin
1204+
return sum(sincos(a))
1205+
end
1206+
end
1207+
function foo2(a)
1208+
Compat.@noinline begin
1209+
return sum(sincos(a))
1210+
end
1211+
end
1212+
1213+
@test foo1(42) == foo2(42)
1214+
end

0 commit comments

Comments
 (0)