Skip to content

Commit 0945185

Browse files
authored
Merge branch 'master' into jishnub/copyto_subarray_linear
2 parents beea81c + ea42112 commit 0945185

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+634
-384
lines changed

Compiler/src/abstractinterpretation.jl

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -856,8 +856,7 @@ end
856856

857857
struct InvokeCall
858858
types # ::Type
859-
lookupsig # ::Type
860-
InvokeCall(@nospecialize(types), @nospecialize(lookupsig)) = new(types, lookupsig)
859+
InvokeCall(@nospecialize(types)) = new(types)
861860
end
862861

863862
struct ConstCallResult
@@ -2218,34 +2217,46 @@ function abstract_invoke(interp::AbstractInterpreter, arginfo::ArgInfo, si::Stmt
22182217
ft′ = argtype_by_index(argtypes, 2)
22192218
ft = widenconst(ft′)
22202219
ft === Bottom && return Future(CallMeta(Bottom, Any, EFFECTS_THROWS, NoCallInfo()))
2221-
(types, isexact, isconcrete, istype) = instanceof_tfunc(argtype_by_index(argtypes, 3), false)
2222-
isexact || return Future(CallMeta(Any, Any, Effects(), NoCallInfo()))
2223-
unwrapped = unwrap_unionall(types)
2224-
types === Bottom && return Future(CallMeta(Bottom, Any, EFFECTS_THROWS, NoCallInfo()))
2225-
if !(unwrapped isa DataType && unwrapped.name === Tuple.name)
2226-
return Future(CallMeta(Bottom, TypeError, EFFECTS_THROWS, NoCallInfo()))
2227-
end
2228-
argtype = argtypes_to_type(argtype_tail(argtypes, 4))
2229-
nargtype = typeintersect(types, argtype)
2230-
nargtype === Bottom && return Future(CallMeta(Bottom, TypeError, EFFECTS_THROWS, NoCallInfo()))
2231-
nargtype isa DataType || return Future(CallMeta(Any, Any, Effects(), NoCallInfo())) # other cases are not implemented below
2232-
isdispatchelem(ft) || return Future(CallMeta(Any, Any, Effects(), NoCallInfo())) # check that we might not have a subtype of `ft` at runtime, before doing supertype lookup below
2233-
ft = ft::DataType
2234-
lookupsig = rewrap_unionall(Tuple{ft, unwrapped.parameters...}, types)::Type
2235-
nargtype = Tuple{ft, nargtype.parameters...}
2236-
argtype = Tuple{ft, argtype.parameters...}
2237-
matched, valid_worlds = findsup(lookupsig, method_table(interp))
2238-
matched === nothing && return Future(CallMeta(Any, Any, Effects(), NoCallInfo()))
2239-
update_valid_age!(sv, valid_worlds)
2240-
method = matched.method
2220+
types = argtype_by_index(argtypes, 3)
2221+
if types isa Const && types.val isa Method
2222+
method = types.val::Method
2223+
types = method # argument value
2224+
lookupsig = method.sig # edge kind
2225+
argtype = argtypes_to_type(pushfirst!(argtype_tail(argtypes, 4), ft))
2226+
nargtype = typeintersect(lookupsig, argtype)
2227+
nargtype === Bottom && return Future(CallMeta(Bottom, TypeError, EFFECTS_THROWS, NoCallInfo()))
2228+
nargtype isa DataType || return Future(CallMeta(Any, Any, Effects(), NoCallInfo())) # other cases are not implemented below
2229+
else
2230+
widenconst(types) >: Method && return Future(CallMeta(Any, Any, Effects(), NoCallInfo()))
2231+
(types, isexact, isconcrete, istype) = instanceof_tfunc(argtype_by_index(argtypes, 3), false)
2232+
isexact || return Future(CallMeta(Any, Any, Effects(), NoCallInfo()))
2233+
unwrapped = unwrap_unionall(types)
2234+
types === Bottom && return Future(CallMeta(Bottom, Any, EFFECTS_THROWS, NoCallInfo()))
2235+
if !(unwrapped isa DataType && unwrapped.name === Tuple.name)
2236+
return Future(CallMeta(Bottom, TypeError, EFFECTS_THROWS, NoCallInfo()))
2237+
end
2238+
argtype = argtypes_to_type(argtype_tail(argtypes, 4))
2239+
nargtype = typeintersect(types, argtype)
2240+
nargtype === Bottom && return Future(CallMeta(Bottom, TypeError, EFFECTS_THROWS, NoCallInfo()))
2241+
nargtype isa DataType || return Future(CallMeta(Any, Any, Effects(), NoCallInfo())) # other cases are not implemented below
2242+
isdispatchelem(ft) || return Future(CallMeta(Any, Any, Effects(), NoCallInfo())) # check that we might not have a subtype of `ft` at runtime, before doing supertype lookup below
2243+
ft = ft::DataType
2244+
lookupsig = rewrap_unionall(Tuple{ft, unwrapped.parameters...}, types)::Type
2245+
nargtype = Tuple{ft, nargtype.parameters...}
2246+
argtype = Tuple{ft, argtype.parameters...}
2247+
matched, valid_worlds = findsup(lookupsig, method_table(interp))
2248+
matched === nothing && return Future(CallMeta(Any, Any, Effects(), NoCallInfo()))
2249+
update_valid_age!(sv, valid_worlds)
2250+
method = matched.method
2251+
end
22412252
tienv = ccall(:jl_type_intersection_with_env, Any, (Any, Any), nargtype, method.sig)::SimpleVector
22422253
ti = tienv[1]
22432254
env = tienv[2]::SimpleVector
22442255
mresult = abstract_call_method(interp, method, ti, env, false, si, sv)::Future
22452256
match = MethodMatch(ti, env, method, argtype <: method.sig)
22462257
ft′_box = Core.Box(ft′)
22472258
lookupsig_box = Core.Box(lookupsig)
2248-
invokecall = InvokeCall(types, lookupsig)
2259+
invokecall = InvokeCall(types)
22492260
return Future{CallMeta}(mresult, interp, sv) do result, interp, sv
22502261
(; rt, exct, effects, edge, volatile_inf_result) = result
22512262
local ft′ = ft′_box.contents

Compiler/src/abstractlattice.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ end
229229
if isa(t, Const)
230230
# don't consider mutable values useful constants
231231
val = t.val
232-
return isa(val, Symbol) || isa(val, Type) || !ismutable(val)
232+
return isa(val, Symbol) || isa(val, Type) || isa(val, Method) || !ismutable(val)
233233
end
234234
isa(t, PartialTypeVar) && return false # this isn't forwardable
235235
return is_const_prop_profitable_arg(widenlattice(𝕃), t)

Compiler/src/ssair/irinterp.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,10 @@ function process_terminator!(@nospecialize(stmt), bb::Int, bb_ip::BitSetBoundedM
249249
return backedge
250250
elseif isa(stmt, EnterNode)
251251
dest = stmt.catch_dest
252-
@assert dest > bb
253-
push!(bb_ip, dest)
252+
if dest 0
253+
@assert dest > bb
254+
push!(bb_ip, dest)
255+
end
254256
push!(bb_ip, bb+1)
255257
return false
256258
else

Compiler/src/ssair/passes.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2393,8 +2393,10 @@ function cfg_simplify!(ir::IRCode)
23932393
end
23942394
elseif isa(terminator, EnterNode)
23952395
catchbb = terminator.catch_dest
2396-
if bb_rename_succ[catchbb] == 0
2397-
push!(worklist, catchbb)
2396+
if catchbb 0
2397+
if bb_rename_succ[catchbb] == 0
2398+
push!(worklist, catchbb)
2399+
end
23982400
end
23992401
elseif isa(terminator, GotoNode) || isa(terminator, ReturnNode)
24002402
# No implicit fall through. Schedule from work list.

Compiler/src/utilities.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ function count_const_size(@nospecialize(x), count_self::Bool = true)
5454
# No definite size
5555
(isa(x, GenericMemory) || isa(x, String) || isa(x, SimpleVector)) &&
5656
return MAX_INLINE_CONST_SIZE + 1
57-
if isa(x, Module)
58-
# We allow modules, because we already assume they are externally
57+
if isa(x, Module) || isa(x, Method)
58+
# We allow modules and methods, because we already assume they are externally
5959
# rooted, so we count their contents as 0 size.
6060
return sizeof(Ptr{Cvoid})
6161
end

Compiler/test/irpasses.jl

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1816,7 +1816,34 @@ function f53521()
18161816
end
18171817
end
18181818
end
1819-
@test code_typed(f53521)[1][2] === Nothing
1819+
let (ir,rt) = only(Base.code_ircode(f53521, ()))
1820+
@test rt == Nothing
1821+
Compiler.verify_ir(ir)
1822+
Compiler.cfg_simplify!(ir)
1823+
Compiler.verify_ir(ir)
1824+
end
1825+
1826+
Base.@assume_effects :foldable Base.@constprop :aggressive function f53521(x::Int, ::Int)
1827+
VALUE = ScopedValue(x)
1828+
@with VALUE => 2 begin
1829+
for i = 1
1830+
@with VALUE => 3 begin
1831+
local v
1832+
try
1833+
v = sin(VALUE[])
1834+
catch
1835+
v = nothing
1836+
end
1837+
return v
1838+
end
1839+
end
1840+
end
1841+
end
1842+
let (ir,rt) = only(Base.code_ircode((Int,)) do y
1843+
f53521(1, y)
1844+
end)
1845+
@test rt == Union{Nothing,Float64}
1846+
end
18201847

18211848
# Test that adce_pass! sets Refined on PhiNode values
18221849
let code = Any[

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ New library features
119119
* `Base.require_one_based_indexing` and `Base.has_offset_axes` are now public ([#56196])
120120
* New `ltruncate`, `rtruncate` and `ctruncate` functions for truncating strings to text width, accounting for char widths ([#55351])
121121
* `isless` (and thus `cmp`, sorting, etc.) is now supported for zero-dimensional `AbstractArray`s ([#55772])
122+
* `invoke` now supports passing a Method instead of a type signature making this interface somewhat more flexible for certain uncommon use cases ([#56692]).
122123

123124
Standard library changes
124125
------------------------

base/cmd.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,7 @@ end
491491
"""
492492
@cmd str
493493
494-
Similar to `cmd`, generate a `Cmd` from the `str` string which represents the shell command(s) to be executed.
494+
Similar to ``` `str` ```, generate a `Cmd` from the `str` string which represents the shell command(s) to be executed.
495495
The [`Cmd`](@ref) object can be run as a process and can outlive the spawning julia process (see `Cmd` for more).
496496
497497
# Examples

base/docs/basedocs.jl

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2030,21 +2030,32 @@ applicable
20302030

20312031
"""
20322032
invoke(f, argtypes::Type, args...; kwargs...)
2033+
invoke(f, argtypes::Method, args...; kwargs...)
20332034
20342035
Invoke a method for the given generic function `f` matching the specified types `argtypes` on the
20352036
specified arguments `args` and passing the keyword arguments `kwargs`. The arguments `args` must
20362037
conform with the specified types in `argtypes`, i.e. conversion is not automatically performed.
20372038
This method allows invoking a method other than the most specific matching method, which is useful
20382039
when the behavior of a more general definition is explicitly needed (often as part of the
2039-
implementation of a more specific method of the same function).
2040+
implementation of a more specific method of the same function). However, because this means
2041+
the runtime must do more work, `invoke` is generally also slower--sometimes significantly
2042+
so--than doing normal dispatch with a regular call.
20402043
2041-
Be careful when using `invoke` for functions that you don't write. What definition is used
2044+
Be careful when using `invoke` for functions that you don't write. What definition is used
20422045
for given `argtypes` is an implementation detail unless the function is explicitly states
20432046
that calling with certain `argtypes` is a part of public API. For example, the change
20442047
between `f1` and `f2` in the example below is usually considered compatible because the
20452048
change is invisible by the caller with a normal (non-`invoke`) call. However, the change is
20462049
visible if you use `invoke`.
20472050
2051+
# Passing a `Method` instead of a signature
2052+
The `argtypes` argument may be a `Method`, in which case the ordinary method table lookup is
2053+
bypassed entirely and the given method is invoked directly. Needing this feature is uncommon.
2054+
Note in particular that the specified `Method` may be entirely unreachable from ordinary dispatch
2055+
(or ordinary invoke), e.g. because it was replaced or fully covered by more specific methods.
2056+
If the method is part of the ordinary method table, this call behaves similar
2057+
to `invoke(f, method.sig, args...)`.
2058+
20482059
# Examples
20492060
```jldoctest
20502061
julia> f(x::Real) = x^2;

base/experimental.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,4 +494,13 @@ function entrypoint(@nospecialize(argt::Type))
494494
nothing
495495
end
496496

497+
"""
498+
Base.Experimental.disable_new_worlds()
499+
500+
Mark that no new worlds (methods additions, deletions, etc) are permitted to be created at
501+
any future time, allowing for lower latencies for some operations and slightly lower memory
502+
usage, by eliminating the tracking of those possible invalidation.
503+
"""
504+
disable_new_worlds() = ccall(:jl_disable_new_worlds, Cvoid, ())
505+
497506
end

0 commit comments

Comments
 (0)