Skip to content

Commit 222cde9

Browse files
authored
Split reflection into compiler-dependent and compiler-independent pieces (#56185)
The `reflection.jl` file provides a large amount of functionality covering everything from helpers for access to core runtime data structures to setting up particular inference problems. It is included by both Base and Core.Compiler, but the functions that use the compiler, don't really make sense in the latter. In preparation for #56128, and stop including the compiler-dependent pieces in Core.Compiler. While we're here, also move a few generically useful reflection functions out of Core.Compiler, so users that access them don't have to load the compiler. Split out from #56128, but doesn't make any semantic changes by itself, so should be quick/easy to merge.
1 parent e252877 commit 222cde9

File tree

8 files changed

+1601
-1600
lines changed

8 files changed

+1601
-1600
lines changed

base/Base.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ include("essentials.jl")
173173
include("ctypes.jl")
174174
include("gcutils.jl")
175175
include("generator.jl")
176+
include("runtime_internals.jl")
176177
include("reflection.jl")
177178
include("options.jl")
178179

base/compiler/compiler.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ const NUM_EFFECTS_OVERRIDES = 11 # sync with julia.h
8484
include("essentials.jl")
8585
include("ctypes.jl")
8686
include("generator.jl")
87-
include("reflection.jl")
87+
include("runtime_internals.jl")
8888
include("options.jl")
8989

9090
ntuple(f, ::Val{0}) = ()

base/compiler/typeutils.jl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,8 +202,6 @@ function typesubtract(@nospecialize(a), @nospecialize(b), max_union_splitting::I
202202
return a # TODO: improve this bound?
203203
end
204204

205-
hasintersect(@nospecialize(a), @nospecialize(b)) = typeintersect(a, b) !== Bottom
206-
207205
_typename(@nospecialize a) = Union{}
208206
_typename(a::TypeVar) = Core.TypeName
209207
function _typename(a::Union)

base/compiler/utilities.jl

Lines changed: 0 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -48,24 +48,6 @@ anymap(f::Function, a::Array{Any,1}) = Any[ f(a[i]) for i in 1:length(a) ]
4848

4949
_topmod(m::Module) = ccall(:jl_base_relative_to, Any, (Any,), m)::Module
5050

51-
#######
52-
# AST #
53-
#######
54-
55-
# Meta expression head, these generally can't be deleted even when they are
56-
# in a dead branch but can be ignored when analyzing uses/liveness.
57-
is_meta_expr_head(head::Symbol) = head === :boundscheck || head === :meta || head === :loopinfo
58-
is_meta_expr(@nospecialize x) = isa(x, Expr) && is_meta_expr_head(x.head)
59-
60-
function is_self_quoting(@nospecialize(x))
61-
return isa(x,Number) || isa(x,AbstractString) || isa(x,Tuple) || isa(x,Type) ||
62-
isa(x,Char) || x === nothing || isa(x,Function)
63-
end
64-
65-
function quoted(@nospecialize(x))
66-
return is_self_quoting(x) ? x : QuoteNode(x)
67-
end
68-
6951
############
7052
# inlining #
7153
############
@@ -116,10 +98,6 @@ function is_inlineable_constant(@nospecialize(x))
11698
return count_const_size(x) <= MAX_INLINE_CONST_SIZE
11799
end
118100

119-
is_nospecialized(method::Method) = method.nospecialize 0
120-
121-
is_nospecializeinfer(method::Method) = method.nospecializeinfer && is_nospecialized(method)
122-
123101
###########################
124102
# MethodInstance/CodeInfo #
125103
###########################
@@ -192,74 +170,12 @@ function get_compileable_sig(method::Method, @nospecialize(atype), sparams::Simp
192170
mt, atype, sparams, method, #=int return_if_compileable=#1)
193171
end
194172

195-
function get_nospecializeinfer_sig(method::Method, @nospecialize(atype), sparams::SimpleVector)
196-
isa(atype, DataType) || return method.sig
197-
mt = ccall(:jl_method_get_table, Any, (Any,), method)
198-
mt === nothing && return method.sig
199-
return ccall(:jl_normalize_to_compilable_sig, Any, (Any, Any, Any, Any, Cint),
200-
mt, atype, sparams, method, #=int return_if_compileable=#0)
201-
end
202173

203174
isa_compileable_sig(@nospecialize(atype), sparams::SimpleVector, method::Method) =
204175
!iszero(ccall(:jl_isa_compileable_sig, Int32, (Any, Any, Any), atype, sparams, method))
205176

206-
# eliminate UnionAll vars that might be degenerate due to having identical bounds,
207-
# or a concrete upper bound and appearing covariantly.
208-
function subst_trivial_bounds(@nospecialize(atype))
209-
if !isa(atype, UnionAll)
210-
return atype
211-
end
212-
v = atype.var
213-
if isconcretetype(v.ub) || v.lb === v.ub
214-
subst = try
215-
atype{v.ub}
216-
catch
217-
# Note in rare cases a var bound might not be valid to substitute.
218-
nothing
219-
end
220-
if subst !== nothing
221-
return subst_trivial_bounds(subst)
222-
end
223-
end
224-
return UnionAll(v, subst_trivial_bounds(atype.body))
225-
end
226-
227177
has_typevar(@nospecialize(t), v::TypeVar) = ccall(:jl_has_typevar, Cint, (Any, Any), t, v) != 0
228178

229-
# If removing trivial vars from atype results in an equivalent type, use that
230-
# instead. Otherwise we can get a case like issue #38888, where a signature like
231-
# f(x::S) where S<:Int
232-
# gets cached and matches a concrete dispatch case.
233-
function normalize_typevars(method::Method, @nospecialize(atype), sparams::SimpleVector)
234-
at2 = subst_trivial_bounds(atype)
235-
if at2 !== atype && at2 == atype
236-
atype = at2
237-
sp_ = ccall(:jl_type_intersection_with_env, Any, (Any, Any), at2, method.sig)::SimpleVector
238-
sparams = sp_[2]::SimpleVector
239-
end
240-
return Pair{Any,SimpleVector}(atype, sparams)
241-
end
242-
243-
# get a handle to the unique specialization object representing a particular instantiation of a call
244-
@inline function specialize_method(method::Method, @nospecialize(atype), sparams::SimpleVector; preexisting::Bool=false)
245-
if isa(atype, UnionAll)
246-
atype, sparams = normalize_typevars(method, atype, sparams)
247-
end
248-
if is_nospecializeinfer(method)
249-
atype = get_nospecializeinfer_sig(method, atype, sparams)
250-
end
251-
if preexisting
252-
# check cached specializations
253-
# for an existing result stored there
254-
return ccall(:jl_specializations_lookup, Any, (Any, Any), method, atype)::Union{Nothing,MethodInstance}
255-
end
256-
return ccall(:jl_specializations_get_linfo, Ref{MethodInstance}, (Any, Any, Any), method, atype, sparams)
257-
end
258-
259-
function specialize_method(match::MethodMatch; kwargs...)
260-
return specialize_method(match.method, match.spec_types, match.sparams; kwargs...)
261-
end
262-
263179
"""
264180
is_declared_inline(method::Method) -> Bool
265181

base/expr.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1560,3 +1560,17 @@ function make_atomiconce(success_order, fail_order, ex)
15601560
end
15611561
error("@atomiconce expression missing field access or indexing")
15621562
end
1563+
1564+
# Meta expression head, these generally can't be deleted even when they are
1565+
# in a dead branch but can be ignored when analyzing uses/liveness.
1566+
is_meta_expr_head(head::Symbol) = head === :boundscheck || head === :meta || head === :loopinfo
1567+
is_meta_expr(@nospecialize x) = isa(x, Expr) && is_meta_expr_head(x.head)
1568+
1569+
function is_self_quoting(@nospecialize(x))
1570+
return isa(x,Number) || isa(x,AbstractString) || isa(x,Tuple) || isa(x,Type) ||
1571+
isa(x,Char) || x === nothing || isa(x,Function)
1572+
end
1573+
1574+
function quoted(@nospecialize(x))
1575+
return is_self_quoting(x) ? x : QuoteNode(x)
1576+
end

0 commit comments

Comments
 (0)