-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
performance: mark REPL and Doc code as non-specializeable #28065
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,8 @@ | |
# constants # | ||
############# | ||
|
||
@nospecialize | ||
|
||
const AbstractEvalConstant = Const | ||
|
||
const _NAMEDTUPLE_NAME = NamedTuple.body.body.name | ||
|
@@ -345,9 +347,9 @@ add_tfunc(nfields, 1, 1, | |
end | ||
return Int | ||
end, 0) | ||
add_tfunc(Core._expr, 1, INT_INF, (args...)->Expr, 100) | ||
add_tfunc(Core._expr, 1, INT_INF, (@nospecialize args...)->Expr, 100) | ||
add_tfunc(applicable, 1, INT_INF, (@nospecialize(f), args...)->Bool, 100) | ||
add_tfunc(Core.Intrinsics.arraylen, 1, 1, x->Int, 4) | ||
add_tfunc(Core.Intrinsics.arraylen, 1, 1, @nospecialize(x)->Int, 4) | ||
add_tfunc(arraysize, 2, 2, (@nospecialize(a), @nospecialize(d))->Int, 4) | ||
add_tfunc(pointerref, 3, 3, | ||
function (@nospecialize(a), @nospecialize(i), @nospecialize(align)) | ||
|
@@ -466,7 +468,7 @@ add_tfunc(<:, 2, 2, | |
return Bool | ||
end, 0) | ||
|
||
function const_datatype_getfield_tfunc(sv, fld) | ||
function const_datatype_getfield_tfunc(@nospecialize(sv), @nospecialize(fld)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
if (fld == DATATYPE_NAME_FIELDINDEX || | ||
fld == DATATYPE_PARAMETERS_FIELDINDEX || | ||
fld == DATATYPE_TYPES_FIELDINDEX || | ||
|
@@ -980,7 +982,7 @@ function tuple_tfunc(@nospecialize(argtype)) | |
return argtype | ||
end | ||
|
||
function array_builtin_common_nothrow(argtypes, first_idx_idx) | ||
function array_builtin_common_nothrow(argtypes::Array{Any,1}, first_idx_idx::Int) | ||
length(argtypes) >= 4 || return false | ||
(argtypes[1] ⊑ Bool && argtypes[2] ⊑ Array) || return false | ||
for i = first_idx_idx:length(argtypes) | ||
|
@@ -1052,7 +1054,7 @@ function builtin_tfunction(@nospecialize(f), argtypes::Array{Any,1}, | |
return tuple_tfunc(argtypes_to_type(argtypes)) | ||
end | ||
end | ||
return Const(tuple(anymap(a->a.val, argtypes)...)) | ||
return Const(tuple(anymap(a::Const -> a.val, argtypes)...)) | ||
elseif f === svec | ||
return SimpleVector | ||
elseif f === arrayset | ||
|
@@ -1111,7 +1113,7 @@ function builtin_tfunction(@nospecialize(f), argtypes::Array{Any,1}, | |
end | ||
if isa(f, IntrinsicFunction) | ||
if is_pure_intrinsic_infer(f) && _all(@nospecialize(a) -> isa(a, Const), argtypes) | ||
argvals = anymap(a -> a.val, argtypes) | ||
argvals = anymap(a::Const -> a.val, argtypes) | ||
try | ||
return Const(f(argvals...)) | ||
catch | ||
|
@@ -1193,3 +1195,5 @@ function typename_static(@nospecialize(t)) | |
t = unwrap_unionall(widenconst(t)) | ||
return isType(t) ? _typename(t.parameters[1]) : Core.TypeName | ||
end | ||
|
||
@specialize |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,15 +30,21 @@ end | |
@nospecialize | ||
|
||
Applied to a function argument name, hints to the compiler that the method | ||
should not be specialized for different types of that argument. | ||
should not be specialized for different types of that argument, | ||
but instead to use precisely the declared type for each argument. | ||
This is only a hint for avoiding excess code generation. | ||
Can be applied to an argument within a formal argument list, or in the | ||
function body. | ||
When applied to an argument, the macro must wrap the entire argument | ||
expression. | ||
Can be applied to an argument within a formal argument list, | ||
or in the function body. | ||
When applied to an argument, the macro must wrap the entire argument expression. | ||
When used in a function body, the macro must occur in statement position and | ||
before any code. | ||
|
||
When used without arguments, it applies to all arguments of the parent scope. | ||
In local scope, this means all arguments of the containing function. | ||
In global (top-level) scope, this means all methods subsequently defined in the current module. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems more natural to me to use a syntax like @nospecialize foo(...) = ... # applies to all arguments
@nospecialize begin ... end # applies to all methods defined in this block
@nospecialize module Foo ... end # applies to all methods in module Foo rather than acting like an imperative side-effect, and to have a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure, all of those can be added later to the macro. They'd just be syntax transforms to one of these forms, since this form – as an imperative side-effect – represents where that information needs to be present in the processing order (since method declaration is itself also imperative). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FWIW, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It does seem clearer for the low-level control to be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, for the module-level form There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about: @nospecialize [begin]
define() = functions
@nospecialize [end] There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can’t tell if you’re trolling |
||
|
||
Specialization can reset back to the default by using [`@specialize`](@ref). | ||
|
||
```julia | ||
function example_function(@nospecialize x) | ||
... | ||
|
@@ -52,21 +58,46 @@ function example_function(x, y, z) | |
@nospecialize x y | ||
... | ||
end | ||
|
||
@nospecialize | ||
f(y) = [x for x in y] | ||
@specialize | ||
``` | ||
""" | ||
macro nospecialize(var, vars...) | ||
if isa(var, Expr) && var.head === :(=) | ||
var.head = :kw | ||
macro nospecialize(vars...) | ||
if nfields(vars) === 1 | ||
# in argument position, need to fix `@nospecialize x=v` to `@nospecialize (kw x v)` | ||
var = getfield(vars, 1) | ||
if isa(var, Expr) && var.head === :(=) | ||
var.head = :kw | ||
end | ||
end | ||
return Expr(:meta, :nospecialize, vars...) | ||
end | ||
|
||
""" | ||
@specialize | ||
|
||
Reset the specialization hint for an argument back to the default. | ||
For details, see [`@specialize`](@ref). | ||
""" | ||
macro specialize(vars...) | ||
if nfields(vars) === 1 | ||
# in argument position, need to fix `@specialize x=v` to `@specialize (kw x v)` | ||
var = getfield(vars, 1) | ||
if isa(var, Expr) && var.head === :(=) | ||
var.head = :kw | ||
end | ||
end | ||
Expr(:meta, :nospecialize, var, vars...) | ||
return Expr(:meta, :specialize, vars...) | ||
end | ||
|
||
macro _pure_meta() | ||
Expr(:meta, :pure) | ||
return Expr(:meta, :pure) | ||
end | ||
# another version of inlining that propagates an inbounds context | ||
macro _propagate_inbounds_meta() | ||
Expr(:meta, :inline, :propagate_inbounds) | ||
return Expr(:meta, :inline, :propagate_inbounds) | ||
end | ||
|
||
""" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -970,6 +970,7 @@ export | |
@inline, | ||
@noinline, | ||
@nospecialize, | ||
@specialize, | ||
@polly, | ||
|
||
@assert, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can the
@nospecialize
be removed here since it is in a @nospecialize true block?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could, but I like the reminders that this code will run very slowly if you aren't careful