Skip to content
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

optimizer: support callsite annotations of @inline and @noinline #40754

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Generalize documentation and cleanup tests a bit
  • Loading branch information
dghosef committed Jun 19, 2021
commit 01b88ce4910c05e27e6ad05a7e24c10a878e7381
12 changes: 7 additions & 5 deletions base/expr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,10 @@ Give a hint to the compiler that this function is worth inlining.
Small functions typically do not need the `@inline` annotation,
as the compiler does it automatically. By using `@inline` on bigger functions,
an extra nudge can be given to the compiler to inline it.

`@inline` can be applied either in a function body or immediately before its definition.

This is shown in the following example:
This is shown in the following examples:

```julia
@inline function bigfunction(x)
Expand Down Expand Up @@ -222,11 +223,11 @@ Give a hint to the compiler that it should not inline a function.

Small functions are typically inlined automatically.
By using `@noinline` on small functions, auto-inlining can be
prevented. `@noinline` can be used at function definitions,
function calls, and in `do` blocks.
prevented.

`@noinline` can be applied either in a function body or
immediately before its definition.
`@noinline` can be applied in a function body,
immediately before its definition, or at a function
callsite.

This is shown in the following examples:

Expand Down Expand Up @@ -257,6 +258,7 @@ f() do
"""
dghosef marked this conversation as resolved.
Show resolved Hide resolved
macro noinline(ex)
if isa(ex, Expr)
ex = macroexpand(__module__, ex)
if ex.head === :function || is_short_function_def(ex) || ex.head === :->
aviatesk marked this conversation as resolved.
Show resolved Hide resolved
# function definition noinline
esc(pushmeta!(ex, :noinline))
Expand Down
8 changes: 4 additions & 4 deletions test/compiler/inline.jl
Original file line number Diff line number Diff line change
Expand Up @@ -323,14 +323,14 @@ end
# Ensure `@noinline` in caller overrides `@inline` in callee
@inline f18773(x) = x
g18773(x) = @noinline f18773(x)
let ci = code_typed(g18773, Tuple{Int})[1].first
let ci = first(code_typed(g18773, Tuple{Int})[1])
@test any(ci.code) do x
isexpr(x, :invoke) && x.args[1].def.name === :f18773
end
end
# Test that `@noinline` works across entire expression
h18773(x) = @noinline f18773(x) + f18773(x)
let ci = code_typed(h18773, Tuple{Int})[1].first
let ci = first(code_typed(h18773, Tuple{Int})[1])
@test count(ci.code) do x
isexpr(x, :invoke) && x.args[1].def.name === :f18773
end == 2
Expand All @@ -346,7 +346,7 @@ function do_inline(x)
return unresolved_call(x)
end
end
let ci = code_typed(do_inline, Tuple{Int})[1].first
let ci = first(code_typed(do_inline, Tuple{Int}))[1]
# what we test here is that both `simple_caller` and the anonymous function that the
# `do` block creates are inlined away, and as a result there is only the unresolved call
@test all(ci.code) do x
Expand All @@ -361,7 +361,7 @@ function do_noinline(x)
end
end

let ci = code_typed(do_noinline, Tuple{Int})[1].first
let ci = first(code_typed(do_noinline, Tuple{Int}))[1]
@test any(ci.code) do x
isexpr(x, :invoke) && startswith(string(x.args[1].def.name), '#')
end
Expand Down