Skip to content

Commit 91be2f9

Browse files
committed
Merge branch 'master' into teh/juliac_headerlogs
2 parents 93a0557 + a776445 commit 91be2f9

File tree

244 files changed

+5094
-2792
lines changed

Some content is hidden

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

244 files changed

+5094
-2792
lines changed

AGENTS.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,11 @@ If you made changes to the runtime (any files in `src/`), you will need to rebui
2727
julia. Run `make -j` to rebuild julia. This process may take up to 10 minutes
2828
depending on your changes.
2929

30-
After `make` run these static analysis checks:
31-
- `make -C src clang-sa-<filename>` (replace `<filename>` with the basename of the file you modified)
32-
- `make -C src clang-sagc-<filename>` which may require adding JL_GC_PUSH arguments, or JL_GC_PROMISE_ROOTED statements., or require fixing locks. Remember arguments are assumed rooted, so check the callers to make sure that is handled. If the value is being temporarily moved around in a struct or arraylist, `JL_GC_PROMISE_ROOTED(struct->field)` may be needed as a statement (it return void) immediately after reloading the struct before any use of struct. Put the promise as early in the code as is legal.
33-
- `make -C src clang-tidy-<filename>`
30+
After making changes, run static analysis checks:
31+
- First run `make -C src install-analysis-deps` to initialize dependencies (only needed once the first time).
32+
- Run `make -C src analyze-<filename> --output-sync -j8` (replace `<filename>` with the basename of any C or C++ file you modified, excluding headers).
33+
- Tests can also be rerun individually with `clang-sa-<filename>`, `clang-sagc-<filename>` or `clang-tidy-<filename>`.
34+
- If `clang-sagc-<filename>` fails, it may require adding `JL_GC_PUSH` statements, or `JL_GC_PROMISE_ROOTED` statements., or require fixing locks. Remember arguments are assumed rooted, so check the callers to make sure that is handled. If the value is being temporarily moved around in a struct or arraylist, `JL_GC_PROMISE_ROOTED(struct->field)` may be needed as a statement (it return void) immediately after reloading the struct before any use of struct. Put that promise as early in the code as is legal, near the definition not the use.
3435

3536
## Using Revise
3637

@@ -97,7 +98,7 @@ make sure to take them into account.
9798
- Do not `ccall` runtime C functions directly if there are existing wrappers for the function.
9899
- Do not explicitly add a module prefix if the code you're adding is in the same module. E.g. do not use `Base.` for code in Base unless required.
99100

100-
## Commit message formatting
101+
## Commit messages and pull requests
101102

102103
When writing commit messages, follow the format "component: Brief summary" for
103104
the title. In the body of the commit message, provide a brief prose summary
@@ -109,7 +110,7 @@ If your change fixes one or more issues, use the syntax "Fixes #" at the end of
109110
When referencing external GitHub PRs or issues, use proper GitHub interlinking format (e.g., `owner/repo#123` for PRs/issues).
110111
When fixing CI failures, include the link to the specific CI failure in the commit message.
111112

112-
When creating pull requests, if the pull request consists of one commit only,
113-
use the body of the commit for the body of the pull request. If there are multiple
114-
commits in the pull request, follow the same guidelines for the pull request
115-
as for the commit body.
113+
When creating pull requests:
114+
1. If the pull request consists of one commit only, use the body of the commit for the body of the pull request.
115+
2. If there are multiple commits in the pull request, follow the same guidelines for the pull request as for the commit body.
116+
3. Make sure that the base commit of the pull request is recent (within the past two days) - if not rebase your changes first.

Compiler/src/Compiler.jl

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,12 @@ using Base: @_foldable_meta, @_gc_preserve_begin, @_gc_preserve_end, @nospeciali
4848
PARTITION_KIND_GLOBAL, PARTITION_KIND_UNDEF_CONST, PARTITION_KIND_BACKDATED_CONST, PARTITION_KIND_DECLARED,
4949
PARTITION_FLAG_DEPWARN,
5050
Base, BitVector, Bottom, Callable, DataTypeFieldDesc,
51-
EffectsOverride, Filter, Generator, IteratorSize, JLOptions, NUM_EFFECTS_OVERRIDES,
52-
OneTo, Ordering, RefValue, SizeUnknown, _NAMEDTUPLE_NAME,
51+
EffectsOverride, Filter, Generator, NUM_EFFECTS_OVERRIDES,
52+
OneTo, Ordering, RefValue, _NAMEDTUPLE_NAME,
5353
_array_for, _bits_findnext, _methods_by_ftype, _uniontypes, all, allocatedinline, any,
5454
argument_datatype, binding_kind, cconvert, copy_exprargs, datatype_arrayelem,
5555
datatype_fieldcount, datatype_fieldtypes, datatype_layoutsize, datatype_nfields,
56-
datatype_pointerfree, decode_effects_override, diff_names, fieldindex,
56+
datatype_pointerfree, decode_effects_override, diff_names, fieldindex, visit,
5757
generating_output, get_nospecializeinfer_sig, get_world_counter, has_free_typevars,
5858
hasgenerator, hasintersect, indexed_iterate, isType, is_file_tracked, is_function_def,
5959
is_meta_expr, is_meta_expr_head, is_nospecialized, is_nospecializeinfer, is_defined_const_binding,
@@ -64,9 +64,11 @@ using Base: @_foldable_meta, @_gc_preserve_begin, @_gc_preserve_end, @nospeciali
6464
partition_restriction, quoted, rename_unionall, rewrap_unionall, specialize_method,
6565
structdiff, tls_world_age, unconstrain_vararg_length, unionlen, uniontype_layout,
6666
uniontypes, unsafe_convert, unwrap_unionall, unwrapva, vect, widen_diagonal,
67-
_uncompressed_ir, maybe_add_binding_backedge!, datatype_min_ninitialized,
67+
_uncompressed_ir, datatype_min_ninitialized,
6868
partialstruct_init_undefs, fieldcount_noerror, _eval_import, _eval_using,
69-
get_ci_mi
69+
get_ci_mi, get_methodtable, morespecific, specializations, has_image_globalref,
70+
PARTITION_MASK_KIND, PARTITION_KIND_GUARD, PARTITION_FLAG_EXPORTED, PARTITION_FLAG_DEPRECATED,
71+
BINDING_FLAG_ANY_IMPLICIT_EDGES, is_some_implicit, IteratorSize, SizeUnknown, get_require_world, JLOptions
7072

7173
using Base.Order
7274

@@ -185,9 +187,14 @@ include("typeinfer.jl")
185187
include("optimize.jl")
186188

187189
include("bootstrap.jl")
190+
include("precompile.jl")
188191
include("reflection_interface.jl")
189192
include("opaque_closure.jl")
190193

194+
baremodule ReinferUtils end
195+
include(ReinferUtils, "reinfer.jl")
196+
include(ReinferUtils, "bindinginvalidations.jl")
197+
191198
macro __SOURCE_FILE__()
192199
__source__.file === nothing && return nothing
193200
return QuoteNode(__source__.file::Symbol)

Compiler/src/abstractinterpretation.jl

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1245,7 +1245,7 @@ function const_prop_methodinstance_heuristic(interp::AbstractInterpreter,
12451245
if isa(code, CodeInstance)
12461246
inferred = @atomic :monotonic code.inferred
12471247
# TODO propagate a specific `CallInfo` that conveys information about this call
1248-
if src_inlining_policy(interp, inferred, NoCallInfo(), IR_FLAG_NULL)
1248+
if src_inlining_policy(interp, mi, inferred, NoCallInfo(), IR_FLAG_NULL)
12491249
return true
12501250
end
12511251
end
@@ -3485,7 +3485,59 @@ function refine_partial_type(@nospecialize t)
34853485
return t
34863486
end
34873487

3488+
abstract_eval_nonlinearized_foreigncall_name(interp::AbstractInterpreter, e, sstate::StatementState, sv::IRInterpretationState) = nothing
3489+
3490+
function abstract_eval_nonlinearized_foreigncall_name(interp::AbstractInterpreter, e, sstate::StatementState, sv::AbsIntState)
3491+
if isexpr(e, :call)
3492+
n = length(e.args)
3493+
argtypes = Vector{Any}(undef, n)
3494+
callresult = Future{CallMeta}()
3495+
i::Int = 1
3496+
nextstate::UInt8 = 0x0
3497+
local ai, res
3498+
function evalargs(interp, sv)
3499+
if nextstate === 0x1
3500+
@goto state1
3501+
elseif nextstate === 0x2
3502+
@goto state2
3503+
end
3504+
while i <= n
3505+
ai = abstract_eval_nonlinearized_foreigncall_name(interp, e.args[i], sstate, sv)
3506+
if !isready(ai)
3507+
nextstate = 0x1
3508+
return false
3509+
@label state1
3510+
end
3511+
argtypes[i] = ai[].rt
3512+
i += 1
3513+
end
3514+
res = abstract_call(interp, ArgInfo(e.args, argtypes), sstate, sv)
3515+
if !isready(res)
3516+
nextstate = 0x2
3517+
return false
3518+
@label state2
3519+
end
3520+
callresult[] = res[]
3521+
return true
3522+
end
3523+
evalargs(interp, sv) || push!(sv.tasks, evalargs)
3524+
return callresult
3525+
else
3526+
return Future(abstract_eval_basic_statement(interp, e, sstate, sv))
3527+
end
3528+
end
3529+
34883530
function abstract_eval_foreigncall(interp::AbstractInterpreter, e::Expr, sstate::StatementState, sv::AbsIntState)
3531+
callee = e.args[1]
3532+
if isexpr(callee, :call) && length(callee.args) > 1 && callee.args[1] == GlobalRef(Core, :tuple)
3533+
# NOTE these expressions are not properly linearized
3534+
abstract_eval_nonlinearized_foreigncall_name(interp, callee.args[2], sstate, sv)
3535+
if length(callee.args) > 2
3536+
abstract_eval_nonlinearized_foreigncall_name(interp, callee.args[3], sstate, sv)
3537+
end
3538+
else
3539+
abstract_eval_value(interp, callee, sstate, sv)
3540+
end
34893541
mi = frame_instance(sv)
34903542
t = sp_type_rewrap(e.args[2], mi, true)
34913543
for i = 3:length(e.args)

base/invalidation.jl renamed to Compiler/src/bindinginvalidations.jl

Lines changed: 14 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,17 @@
11
# This file is a part of Julia. License is MIT: https://julialang.org/license
22

3-
struct GlobalRefIterator
4-
mod::Module
5-
end
6-
IteratorSize(::Type{GlobalRefIterator}) = SizeUnknown()
7-
globalrefs(mod::Module) = GlobalRefIterator(mod)
8-
9-
function iterate(gri::GlobalRefIterator, i = 1)
10-
m = gri.mod
11-
table = ccall(:jl_module_get_bindings, Ref{SimpleVector}, (Any,), m)
12-
i > length(table) && return nothing
13-
b = table[i]
14-
b === nothing && return iterate(gri, i+1)
15-
return ((b::Core.Binding).globalref, i+1)
16-
end
3+
using ..Compiler: _uncompressed_ir, specializations, get_ci_mi, convert, unsafe_load, cglobal, generating_output, has_image_globalref,
4+
PARTITION_MASK_KIND, PARTITION_KIND_GUARD, PARTITION_FLAG_EXPORTED, PARTITION_FLAG_DEPRECATED,
5+
BINDING_FLAG_ANY_IMPLICIT_EDGES, binding_kind, partition_restriction, is_some_imported,
6+
is_some_binding_imported, is_some_implicit, SizeUnknown, maybe_add_binding_backedge!, walk_binding_partition, abstract_eval_partition_load, userefs
7+
using .Core: SimpleVector, CodeInfo
178

189
function foreachgr(visit, src::CodeInfo)
1910
stmts = src.code
2011
for i = 1:length(stmts)
2112
stmt = stmts[i]
2213
isa(stmt, GlobalRef) && visit(stmt)
23-
for ur in Compiler.userefs(stmt)
14+
for ur in userefs(stmt)
2415
arg = ur[]
2516
isa(arg, GlobalRef) && visit(arg)
2617
end
@@ -35,7 +26,7 @@ function anygr(visit, src::CodeInfo)
3526
visit(stmt) && return true
3627
continue
3728
end
38-
for ur in Compiler.userefs(stmt)
29+
for ur in userefs(stmt)
3930
arg = ur[]
4031
isa(arg, GlobalRef) && visit(arg) && return true
4132
end
@@ -69,7 +60,7 @@ function invalidate_method_for_globalref!(gr::GlobalRef, method::Method, invalid
6960
src = _uncompressed_ir(method)
7061
invalidate_all = should_invalidate_code_for_globalref(gr, src)
7162
end
72-
if invalidate_all && !Base.generating_output()
63+
if invalidate_all && !generating_output()
7364
@atomic method.did_scan_source |= 0x4
7465
end
7566
invalidated_any = false
@@ -99,15 +90,15 @@ export_affecting_partition_flags(bpart::Core.BindingPartition) =
9990
function invalidate_code_for_globalref!(b::Core.Binding, invalidated_bpart::Core.BindingPartition, new_bpart::Core.BindingPartition, new_max_world::UInt)
10091
gr = b.globalref
10192

102-
(_, (ib, ibpart)) = Compiler.walk_binding_partition(b, invalidated_bpart, new_max_world)
103-
(_, (nb, nbpart)) = Compiler.walk_binding_partition(b, new_bpart, new_max_world+1)
93+
(_, (ib, ibpart)) = walk_binding_partition(b, invalidated_bpart, new_max_world)
94+
(_, (nb, nbpart)) = walk_binding_partition(b, new_bpart, new_max_world+1)
10495

10596
# `abstract_eval_partition_load` is the maximum amount of information that inference
10697
# reads from a binding partition. If this information does not change - we do not need to
10798
# invalidate any code that inference created, because we know that the result will not change.
10899
need_to_invalidate_code =
109-
Compiler.abstract_eval_partition_load(nothing, ib, ibpart) !==
110-
Compiler.abstract_eval_partition_load(nothing, nb, nbpart)
100+
abstract_eval_partition_load(nothing, ib, ibpart) !==
101+
abstract_eval_partition_load(nothing, nb, nbpart)
111102

112103
need_to_invalidate_export = export_affecting_partition_flags(invalidated_bpart) !==
113104
export_affecting_partition_flags(new_bpart)
@@ -155,9 +146,7 @@ function invalidate_code_for_globalref!(b::Core.Binding, invalidated_bpart::Core
155146
latest_bpart = user_binding.partitions
156147
latest_bpart.max_world == typemax(UInt) || continue
157148
is_some_implicit(binding_kind(latest_bpart)) || continue
158-
new_bpart = need_to_invalidate_export ?
159-
ccall(:jl_maybe_reresolve_implicit, Any, (Any, Csize_t), user_binding, new_max_world) :
160-
latest_bpart
149+
new_bpart = ccall(:jl_maybe_reresolve_implicit, Any, (Any, Csize_t), user_binding, new_max_world)
161150
if need_to_invalidate_code || new_bpart !== latest_bpart
162151
push!(queued_bindings, (convert(Core.Binding, user_binding), latest_bpart, new_bpart))
163152
end
@@ -173,12 +162,6 @@ end
173162
invalidate_code_for_globalref!(gr::GlobalRef, invalidated_bpart::Core.BindingPartition, new_bpart::Core.BindingPartition, new_max_world::UInt) =
174163
invalidate_code_for_globalref!(convert(Core.Binding, gr), invalidated_bpart, new_bpart, new_max_world)
175164

176-
function maybe_add_binding_backedge!(b::Core.Binding, edge::Union{Method, CodeInstance})
177-
meth = isa(edge, Method) ? edge : get_ci_mi(edge).def
178-
ccall(:jl_maybe_add_binding_backedge, Cint, (Any, Any, Any), b, edge, meth)
179-
return nothing
180-
end
181-
182165
function binding_was_invalidated(b::Core.Binding)
183166
# At least one partition is required for invalidation
184167
!isdefined(b, :partitions) && return false
@@ -206,7 +189,7 @@ function scan_new_method!(method::Method, image_backedges_only::Bool)
206189
end
207190

208191
function scan_new_methods!(extext_methods::Vector{Any}, internal_methods::Vector{Any}, image_backedges_only::Bool)
209-
if image_backedges_only && Base.generating_output(true)
192+
if image_backedges_only && generating_output(true)
210193
# Replacing image bindings is forbidden during incremental precompilation - skip backedge insertion
211194
return
212195
end

Compiler/src/bootstrap.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
function activate_codegen!()
99
ccall(:jl_set_typeinf_func, Cvoid, (Any,), typeinf_ext_toplevel)
10+
# Register the new unified compile and emit function
11+
ccall(:jl_set_compile_and_emit_func, Cvoid, (Any,), compile_and_emit_native)
1012
Core.eval(Compiler, quote
1113
let typeinf_world_age = Base.tls_world_age()
1214
@eval Core.OptimizedGenerics.CompilerPlugins.typeinf(::Nothing, mi::MethodInstance, source_mode::UInt8) =

Compiler/src/inferencestate.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,8 @@ end
587587
_should_instrument(loc::Symbol) = is_file_tracked(loc)
588588
_should_instrument(loc::Method) = _should_instrument(loc.file)
589589
_should_instrument(loc::MethodInstance) = _should_instrument(loc.def)
590-
_should_instrument(loc::Module) = false
590+
_should_instrument(::Module) = false
591+
_should_instrument(::Nothing) = false
591592
function _should_instrument(info::DebugInfo)
592593
linetable = info.linetable
593594
linetable === nothing || (_should_instrument(linetable) && return true)

Compiler/src/optimize.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,17 @@ is_declared_noinline(@nospecialize src::MaybeCompressed) =
132132
#####################
133133

134134
# return whether this src should be inlined. If so, retrieve_ir_for_inlining must return an IRCode from it
135+
136+
function src_inlining_policy(interp::AbstractInterpreter, mi::MethodInstance,
137+
@nospecialize(src), @nospecialize(info::CallInfo), stmt_flag::UInt32)
138+
# If we have a generator, but we can't invoke it (because argument type information is lacking),
139+
# don't inline so we defer its invocation to runtime where we'll have precise type information.
140+
if isa(mi.def, Method) && hasgenerator(mi)
141+
may_invoke_generator(mi) || return false
142+
end
143+
return src_inlining_policy(interp, src, info, stmt_flag)
144+
end
145+
135146
function src_inlining_policy(interp::AbstractInterpreter,
136147
@nospecialize(src), @nospecialize(info::CallInfo), stmt_flag::UInt32)
137148
isa(src, OptimizationState) && (src = src.src)

0 commit comments

Comments
 (0)