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
Revert "wip"
This reverts commit b1c742f.
  • Loading branch information
aviatesk committed Jun 18, 2021
commit 980ef45f5205d89492aa216c5d6f4eb734eb5354
3 changes: 1 addition & 2 deletions base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1806,8 +1806,7 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState)
if isa(fname, SlotNumber)
changes = StateUpdate(fname, VarState(Any, false), changes, false)
end
elseif hd === :code_coverage_effect ||
(hd !== :boundscheck && is_meta_expr_head(hd)) # :boundscheck can be narrowed to Bool
elseif hd === :inbounds || hd === :meta || hd === :loopinfo || hd === :code_coverage_effect || hd === :noinline
# these do not generate code
else
t = abstract_eval_statement(interp, stmt, changes, frame)
Expand Down
2 changes: 1 addition & 1 deletion base/compiler/utilities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ end
# Meta expression head, these generally can't be deleted even when they are
# in a dead branch but can be ignored when analyzing uses/liveness.
is_meta_expr_head(head::Symbol) = (head === :inbounds || head === :boundscheck || head === :meta ||
head === :loopinfo || head === :inline || head === :noinline)
head === :loopinfo || head === :noinline)

sym_isless(a::Symbol, b::Symbol) = ccall(:strcmp, Int32, (Ptr{UInt8}, Ptr{UInt8}), a, b) < 0

Expand Down
3 changes: 1 addition & 2 deletions base/compiler/validation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ const VALID_EXPR_HEADS = IdDict{Symbol,UnitRange}(
:leave => 1:1,
:pop_exception => 1:1,
:inbounds => 1:1,
:inline => 1:1,
:noinline => 1:1,
:boundscheck => 0:0,
:copyast => 1:1,
Expand Down Expand Up @@ -143,7 +142,7 @@ function validate_code!(errors::Vector{>:InvalidCodeError}, c::CodeInfo, is_top_
head === :const || head === :enter || head === :leave || head === :pop_exception ||
head === :method || head === :global || head === :static_parameter ||
head === :new || head === :splatnew || head === :thunk || head === :loopinfo ||
head === :throw_undef_if_not || head === :code_coverage_effect || head === :inline || head === :noinline
head === :throw_undef_if_not || head === :code_coverage_effect || head === :noinline
validate_val!(x)
else
# TODO: nothing is actually in statement position anymore
Expand Down
49 changes: 22 additions & 27 deletions base/expr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -213,14 +213,13 @@ bigfunction2() do
Usage in `do` blocks requires at least Julia 1.7
"""
macro inline(ex)
if isa(ex, Expr)
ex = macroexpand(__module__, ex) # expand inner macros which may include other meta annotations
annotate_meta_def_or_block(ex, :inline)
else
return ex
end
esc(isa(ex, Expr) ? pushmeta!(ex, :inline) : ex)
end

macro inline()
Expr(:meta, :inline)
end
macro inline() Expr(:meta, :inline) end


"""
@noinline
Expand Down Expand Up @@ -267,26 +266,24 @@ f() do
"""
dghosef marked this conversation as resolved.
Show resolved Hide resolved
macro noinline(ex)
if isa(ex, Expr)
ex = macroexpand(__module__, ex) # expand inner macros which may include other meta annotations
annotate_meta_def_or_block(ex, :noinline)
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))
else
# callsite noinline
return Expr(:block,
Expr(:noinline, true),
Expr(:local, Expr(:(=), :val, esc(ex))),
Expr(:noinline, false),
:val)
end
else
return ex
esc(ex)
end
end
macro noinline() Expr(:meta, :noinline) end

function annotate_meta_def_or_block(ex::Expr, meta::Symbol)
if is_function_def(ex)
# annotation on a definition
return esc(pushmeta!(ex, :noinline))
else
# annotation on a block
return Expr(:block,
Expr(:noinline, true),
Expr(:local, Expr(:(=), :val, esc(ex))),
Expr(:noinline, false),
:val)
end
macro noinline()
Expr(:meta, :noinline)
end

"""
Expand Down Expand Up @@ -399,7 +396,7 @@ function findmetaarg(metaargs, sym)
return 0
end

function is_short_function_def(ex::Expr)
function is_short_function_def(ex)
ex.head === :(=) || return false
while length(ex.args) >= 1 && isa(ex.args[1], Expr)
(ex.args[1].head === :call) && return true
Expand All @@ -408,11 +405,9 @@ function is_short_function_def(ex::Expr)
end
return false
end
is_function_def(ex::Expr) =
return ex.head === :function || is_short_function_def(ex) || ex.head === :->

function findmeta(ex::Expr)
if is_function_def(ex)
if ex.head === :function || is_short_function_def(ex) || ex.head === :->
body = ex.args[2]::Expr
body.head === :block || error(body, " is not a block expression")
return findmeta_block(ex.args)
Expand Down
2 changes: 1 addition & 1 deletion base/meta.jl
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,6 @@ end
_instantiate_type_in_env(x, spsig, spvals) = ccall(:jl_instantiate_type_in_env, Any, (Any, Any, Ptr{Any}), x, spsig, spvals)

is_meta_expr_head(head::Symbol) = (head === :inbounds || head === :boundscheck || head === :meta
|| head === :loopinfo || head === :inline || head === :noinline)
|| head === :loopinfo || head === :noinline)

end # module
2 changes: 1 addition & 1 deletion src/ast.scm
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@
;; predicates and accessors

(define (quoted? e)
(memq (car e) '(quote top core globalref outerref line break inert meta inbounds inline noinline loopinfo)))
(memq (car e) '(quote top core globalref outerref line break inert meta inbounds noinline loopinfo)))
(define (quotify e) `',e)
(define (unquote e)
(if (and (pair? e) (memq (car e) '(quote inert)))
Expand Down
4 changes: 2 additions & 2 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4375,7 +4375,7 @@ static void emit_stmtpos(jl_codectx_t &ctx, jl_value_t *expr, int ssaval_result)
jl_value_t **args = (jl_value_t**)jl_array_data(ex->args);
jl_sym_t *head = ex->head;
if (head == meta_sym || head == inbounds_sym || head == coverageeffect_sym
|| head == aliasscope_sym || head == popaliasscope_sym || head == inline_sym || head == noinline_sym) {
|| head == aliasscope_sym || head == popaliasscope_sym || head == noinline_sym) {
// some expression types are metadata and can be ignored
// in statement position
return;
Expand Down Expand Up @@ -4810,7 +4810,7 @@ static jl_cgval_t emit_expr(jl_codectx_t &ctx, jl_value_t *expr, ssize_t ssaval)
}
else if (head == leave_sym || head == coverageeffect_sym
|| head == pop_exception_sym || head == enter_sym || head == inbounds_sym
|| head == aliasscope_sym || head == popaliasscope_sym || head == inline_sym || head == noinline_sym) {
|| head == aliasscope_sym || head == popaliasscope_sym || head == noinline_sym) {
jl_errorf("Expr(:%s) in value position", jl_symbol_name(head));
}
else if (head == boundscheck_sym) {
Expand Down
2 changes: 1 addition & 1 deletion src/interpreter.c
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ static jl_value_t *eval_value(jl_value_t *e, interpreter_state *s)
return jl_true;
}
else if (head == meta_sym || head == coverageeffect_sym || head == inbounds_sym || head == loopinfo_sym ||
head == aliasscope_sym || head == popaliasscope_sym || head == inline_sym || head == noinline_sym) {
head == aliasscope_sym || head == popaliasscope_sym || head == noinline_sym) {
return jl_nothing;
}
else if (head == gc_preserve_begin_sym || head == gc_preserve_end_sym) {
Expand Down
6 changes: 3 additions & 3 deletions src/julia-syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -3495,7 +3495,7 @@ f(x) = yt(x)
thunk with-static-parameters toplevel-only
global globalref outerref const-if-global thismodule
const atomic null true false ssavalue isdefined toplevel module lambda
error gc_preserve_begin gc_preserve_end import using export inline noinline)))
error gc_preserve_begin gc_preserve_end import using export noinline)))

(define (local-in? s lam)
(or (assq s (car (lam:vinfo lam)))
Expand Down Expand Up @@ -4589,7 +4589,7 @@ f(x) = yt(x)
(cons (car e) args)))

;; metadata expressions
((line meta inbounds loopinfo gc_preserve_end aliasscope popaliasscope inline noinline)
((line meta inbounds loopinfo gc_preserve_end aliasscope popaliasscope noinline)
(let ((have-ret? (and (pair? code) (pair? (car code)) (eq? (caar code) 'return))))
(cond ((eq? (car e) 'line)
(set! current-loc e)
Expand Down Expand Up @@ -4734,7 +4734,7 @@ f(x) = yt(x)
(begin (set! linetable (cons (make-lineinfo name file line) linetable))
(set! current-loc 1)))
(if (or reachable
(and (pair? e) (memq (car e) '(meta inbounds gc_preserve_begin gc_preserve_end aliasscope popaliasscope inline noinline))))
(and (pair? e) (memq (car e) '(meta inbounds gc_preserve_begin gc_preserve_end aliasscope popaliasscope noinline))))
(begin (set! code (cons e code))
(set! i (+ i 1))
(set! locs (cons current-loc locs)))))
Expand Down
2 changes: 1 addition & 1 deletion src/macroexpand.scm
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@
,(resolve-expansion-vars-with-new-env (caddr arg) env m parent-scope inarg))))
(else
`(global ,(resolve-expansion-vars-with-new-env arg env m parent-scope inarg))))))
((using import export meta line inbounds boundscheck loopinfo inline noinline) (map unescape e))
((using import export meta line noinline inbounds boundscheck loopinfo) (map unescape e))
((macrocall) e) ; invalid syntax anyways, so just act like it's quoted.
((symboliclabel) e)
((symbolicgoto) e)
Expand Down
2 changes: 1 addition & 1 deletion src/method.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ static jl_value_t *resolve_globals(jl_value_t *expr, jl_module_t *module, jl_sve
e->head == meta_sym || e->head == inbounds_sym ||
e->head == boundscheck_sym || e->head == loopinfo_sym ||
e->head == aliasscope_sym || e->head == popaliasscope_sym ||
e->head == inline_sym || e->head == noinline_sym) {
e->head == noinline_sym) {
// ignore these
}
else {
Expand Down