Skip to content

Commit

Permalink
Merge branch 'master' into eschnett/openssl
Browse files Browse the repository at this point in the history
  • Loading branch information
eschnett committed Dec 19, 2024
2 parents f7af55f + 6e04a0b commit ba14e00
Show file tree
Hide file tree
Showing 206 changed files with 2,894 additions and 3,110 deletions.
8 changes: 4 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,8 @@ Be sure to change the UUID value back before making the pull request.

The process of [creating a patch release](https://docs.julialang.org/en/v1/devdocs/build/distributing/#Point-releasing-101) is roughly as follows:

1. Create a new branch (e.g. `backports-release-1.6`) against the relevant minor release
branch (e.g. `release-1.6`). Usually a corresponding pull request is created as well.
1. Create a new branch (e.g. `backports-release-1.10`) against the relevant minor release
branch (e.g. `release-1.10`). Usually a corresponding pull request is created as well.

2. Add commits, nominally from `master` (hence "backports"), to that branch.
See below for more information on this process.
Expand All @@ -291,8 +291,8 @@ The process of [creating a patch release](https://docs.julialang.org/en/v1/devdo
the pull request associated with the backports branch. Fix any issues.

4. Once all test and benchmark reports look good, merge the backports branch into
the corresponding release branch (e.g. merge `backports-release-1.6` into
`release-1.6`).
the corresponding release branch (e.g. merge `backports-release-1.10` into
`release-1.10`).

5. Open a pull request that bumps the version of the relevant minor release to the
next patch version, e.g. as in [this pull request](https://github.com/JuliaLang/julia/pull/37718).
Expand Down
15 changes: 15 additions & 0 deletions Compiler/extras/CompilerDevTools/Manifest.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# This file is machine-generated - editing it directly is not advised

julia_version = "1.12.0-DEV"
manifest_format = "2.0"
project_hash = "84f495a1bf065c95f732a48af36dd0cd2cefb9d5"

[[deps.Compiler]]
path = "../.."
uuid = "807dbc54-b67e-4c79-8afb-eafe4df6f2e1"
version = "0.0.2"

[[deps.CompilerDevTools]]
path = "."
uuid = "92b2d91f-d2bd-4c05-9214-4609ac33433f"
version = "0.0.0"
5 changes: 5 additions & 0 deletions Compiler/extras/CompilerDevTools/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name = "CompilerDevTools"
uuid = "92b2d91f-d2bd-4c05-9214-4609ac33433f"

[deps]
Compiler = "807dbc54-b67e-4c79-8afb-eafe4df6f2e1"
48 changes: 48 additions & 0 deletions Compiler/extras/CompilerDevTools/src/CompilerDevTools.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
module CompilerDevTools

using Compiler
using Core.IR

struct SplitCacheOwner; end
struct SplitCacheInterp <: Compiler.AbstractInterpreter
world::UInt
inf_params::Compiler.InferenceParams
opt_params::Compiler.OptimizationParams
inf_cache::Vector{Compiler.InferenceResult}
function SplitCacheInterp(;
world::UInt = Base.get_world_counter(),
inf_params::Compiler.InferenceParams = Compiler.InferenceParams(),
opt_params::Compiler.OptimizationParams = Compiler.OptimizationParams(),
inf_cache::Vector{Compiler.InferenceResult} = Compiler.InferenceResult[])
new(world, inf_params, opt_params, inf_cache)
end
end

Compiler.InferenceParams(interp::SplitCacheInterp) = interp.inf_params
Compiler.OptimizationParams(interp::SplitCacheInterp) = interp.opt_params
Compiler.get_inference_world(interp::SplitCacheInterp) = interp.world
Compiler.get_inference_cache(interp::SplitCacheInterp) = interp.inf_cache
Compiler.cache_owner(::SplitCacheInterp) = SplitCacheOwner()

import Core.OptimizedGenerics.CompilerPlugins: typeinf, typeinf_edge
@eval @noinline typeinf(::SplitCacheOwner, mi::MethodInstance, source_mode::UInt8) =
Base.invoke_in_world(which(typeinf, Tuple{SplitCacheOwner, MethodInstance, UInt8}).primary_world, Compiler.typeinf_ext, SplitCacheInterp(; world=Base.tls_world_age()), mi, source_mode)

@eval @noinline function typeinf_edge(::SplitCacheOwner, mi::MethodInstance, parent_frame::Compiler.InferenceState, world::UInt, source_mode::UInt8)
# TODO: This isn't quite right, we're just sketching things for now
interp = SplitCacheInterp(; world)
Compiler.typeinf_edge(interp, mi.def, mi.specTypes, Core.svec(), parent_frame, false, false)
end

function with_new_compiler(f, args...)
mi = @ccall jl_method_lookup(Any[f, args...]::Ptr{Any}, (1+length(args))::Csize_t, Base.tls_world_age()::Csize_t)::Ref{Core.MethodInstance}
world = Base.tls_world_age()
new_compiler_ci = Core.OptimizedGenerics.CompilerPlugins.typeinf(
SplitCacheOwner(), mi, Compiler.SOURCE_MODE_ABI
)
invoke(f, new_compiler_ci, args...)
end

export with_new_compiler

end
70 changes: 42 additions & 28 deletions Compiler/src/Compiler.jl
Original file line number Diff line number Diff line change
Expand Up @@ -41,36 +41,36 @@ ccall(:jl_set_module_uuid, Cvoid, (Any, NTuple{2, UInt64}), Compiler,

using Core.Intrinsics, Core.IR

import Core: print, println, show, write, unsafe_write,
_apply_iterate, svec, apply_type, Builtin, IntrinsicFunction,
MethodInstance, CodeInstance, MethodTable, MethodMatch, PartialOpaque,
TypeofVararg, Core, SimpleVector, donotdelete, compilerbarrier,
memoryref_isassigned, memoryrefnew, memoryrefoffset, memoryrefget,
memoryrefset!, typename
using Core: Builtin, CodeInstance, IntrinsicFunction, MethodInstance, MethodMatch,
MethodTable, PartialOpaque, SimpleVector, TypeofVararg,
_apply_iterate, apply_type, compilerbarrier, donotdelete, memoryref_isassigned,
memoryrefget, memoryrefnew, memoryrefoffset, memoryrefset!, print, println, show, svec,
typename, unsafe_write, write

using Base
using Base: Ordering, vect, EffectsOverride, BitVector, @_gc_preserve_begin, @_gc_preserve_end, RefValue,
@nospecializeinfer, @_foldable_meta, fieldindex, is_function_def, indexed_iterate, isexpr, methods,
get_world_counter, JLOptions, _methods_by_ftype, unwrap_unionall, cconvert, unsafe_convert,
issingletontype, isType, rewrap_unionall, has_free_typevars, isvarargtype, hasgenerator,
IteratorSize, SizeUnknown, _array_for, Bottom, generating_output, diff_names,
ismutationfree, NUM_EFFECTS_OVERRIDES, _NAMEDTUPLE_NAME, datatype_fieldtypes,
argument_datatype, isfieldatomic, unwrapva, iskindtype, _bits_findnext, copy_exprargs,
Generator, Filter, ismutabletypename, isvatuple, datatype_fieldcount,
isconcretedispatch, isdispatchelem, datatype_layoutsize,
datatype_arrayelem, unionlen, isidentityfree, _uniontypes, uniontypes, OneTo, Callable,
DataTypeFieldDesc, datatype_nfields, datatype_pointerfree, midpoint, is_valid_intrinsic_elptr,
allocatedinline, isbitsunion, widen_diagonal, unconstrain_vararg_length,
rename_unionall, may_invoke_generator, is_meta_expr_head, is_meta_expr, quoted,
specialize_method, hasintersect, is_nospecializeinfer, is_nospecialized,
get_nospecializeinfer_sig, tls_world_age, uniontype_layout, kwerr,
moduleroot, is_file_tracked, decode_effects_override, lookup_binding_partition,
is_some_imported, binding_kind, is_some_guard, is_some_const_binding, partition_restriction,
BINDING_KIND_GLOBAL, structdiff
using Base: @_foldable_meta, @_gc_preserve_begin, @_gc_preserve_end, @nospecializeinfer,
BINDING_KIND_GLOBAL, Base, BitVector, Bottom, Callable, DataTypeFieldDesc,
EffectsOverride, Filter, Generator, IteratorSize, JLOptions, NUM_EFFECTS_OVERRIDES,
OneTo, Ordering, RefValue, SizeUnknown, _NAMEDTUPLE_NAME,
_array_for, _bits_findnext, _methods_by_ftype, _uniontypes, all, allocatedinline, any,
argument_datatype, binding_kind, cconvert, copy_exprargs, datatype_arrayelem,
datatype_fieldcount, datatype_fieldtypes, datatype_layoutsize, datatype_nfields,
datatype_pointerfree, decode_effects_override, diff_names, fieldindex,
generating_output, get_nospecializeinfer_sig, get_world_counter, has_free_typevars,
hasgenerator, hasintersect, indexed_iterate, isType, is_file_tracked, is_function_def,
is_meta_expr, is_meta_expr_head, is_nospecialized, is_nospecializeinfer,
is_some_const_binding, is_some_guard, is_some_imported, is_valid_intrinsic_elptr,
isbitsunion, isconcretedispatch, isdispatchelem, isexpr, isfieldatomic, isidentityfree,
iskindtype, ismutabletypename, ismutationfree, issingletontype, isvarargtype, isvatuple,
kwerr, lookup_binding_partition, may_invoke_generator, methods, midpoint, moduleroot,
partition_restriction, quoted, rename_unionall, rewrap_unionall, specialize_method,
structdiff, tls_world_age, unconstrain_vararg_length, unionlen, uniontype_layout,
uniontypes, unsafe_convert, unwrap_unionall, unwrapva, vect, widen_diagonal
using Base.Order
import Base: getindex, setindex!, length, iterate, push!, isempty, first, convert, ==,
copy, popfirst!, in, haskey, resize!, copy!, append!, last, get!, size,
get, iterate, findall, min_world, max_world, _topmod, isready

import Base: ==, _topmod, append!, convert, copy, copy!, findall, first, get, get!,
getindex, haskey, in, isempty, isready, iterate, iterate, last, length, max_world,
min_world, popfirst!, push!, resize!, setindex!, size

const getproperty = Core.getfield
const setproperty! = Core.setfield!
Expand Down Expand Up @@ -181,12 +181,26 @@ include("bootstrap.jl")
include("reflection_interface.jl")
include("opaque_closure.jl")

macro __SOURCE_FILE__()
__source__.file === nothing && return nothing
return QuoteNode(__source__.file::Symbol)
end

module IRShow end
function load_irshow!()
if isdefined(Base, :end_base_include)
# This code path is exclusively for Revise, which may want to re-run this
# after bootstrap.
include(IRShow, Base.joinpath(Base.dirname(Base.String(@__SOURCE_FILE__)), "ssair/show.jl"))
else
include(IRShow, "ssair/show.jl")
end
end
if !isdefined(Base, :end_base_include)
# During bootstrap, skip including this file and defer it to base/show.jl to include later
else
# When this module is loaded as the standard library, include this file as usual
include(IRShow, "ssair/show.jl")
load_irshow!()
end

end # baremodule Compiler
Expand Down
80 changes: 57 additions & 23 deletions Compiler/src/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2218,16 +2218,47 @@ function abstract_invoke(interp::AbstractInterpreter, arginfo::ArgInfo, si::Stmt
ft = widenconst(ft′)
ft === Bottom && return Future(CallMeta(Bottom, Any, EFFECTS_THROWS, NoCallInfo()))
types = argtype_by_index(argtypes, 3)
if types isa Const && types.val isa Method
method = types.val::Method
types = method # argument value
lookupsig = method.sig # edge kind
argtype = argtypes_to_type(pushfirst!(argtype_tail(argtypes, 4), ft))
nargtype = typeintersect(lookupsig, argtype)
nargtype === Bottom && return Future(CallMeta(Bottom, TypeError, EFFECTS_THROWS, NoCallInfo()))
nargtype isa DataType || return Future(CallMeta(Any, Any, Effects(), NoCallInfo())) # other cases are not implemented below
if types isa Const && types.val isa Union{Method, CodeInstance}
method_or_ci = types.val
if isa(method_or_ci, CodeInstance)
our_world = sv.world.this
argtype = argtypes_to_type(pushfirst!(argtype_tail(argtypes, 4), ft))
specsig = method_or_ci.def.specTypes
defdef = method_or_ci.def.def
exct = method_or_ci.exctype
if !hasintersect(argtype, specsig)
return Future(CallMeta(Bottom, TypeError, EFFECTS_THROWS, NoCallInfo()))
elseif !(argtype <: specsig) || (isa(defdef, Method) && !(argtype <: defdef.sig))
exct = Union{exct, TypeError}
end
callee_valid_range = WorldRange(method_or_ci.min_world, method_or_ci.max_world)
if !(our_world in callee_valid_range)
if our_world < first(callee_valid_range)
update_valid_age!(sv, WorldRange(first(sv.world.valid_worlds), first(callee_valid_range)-1))
else
update_valid_age!(sv, WorldRange(last(callee_valid_range)+1, last(sv.world.valid_worlds)))
end
return Future(CallMeta(Bottom, ErrorException, EFFECTS_THROWS, NoCallInfo()))
end
# TODO: When we add curing, we may want to assume this is nothrow
if (method_or_ci.owner === Nothing && method_ir_ci.def.def isa Method)
exct = Union{exct, ErrorException}
end
update_valid_age!(sv, callee_valid_range)
return Future(CallMeta(method_or_ci.rettype, exct, Effects(decode_effects(method_or_ci.ipo_purity_bits), nothrow=(exct===Bottom)),
InvokeCICallInfo(method_or_ci)))
else
method = method_or_ci::Method
types = method # argument value
lookupsig = method.sig # edge kind
argtype = argtypes_to_type(pushfirst!(argtype_tail(argtypes, 4), ft))
nargtype = typeintersect(lookupsig, argtype)
nargtype === Bottom && return Future(CallMeta(Bottom, TypeError, EFFECTS_THROWS, NoCallInfo()))
nargtype isa DataType || return Future(CallMeta(Any, Any, Effects(), NoCallInfo())) # other cases are not implemented below
# Fall through to generic invoke handling
end
else
widenconst(types) >: Method && return Future(CallMeta(Any, Any, Effects(), NoCallInfo()))
hasintersect(widenconst(types), Union{Method, CodeInstance}) && return Future(CallMeta(Any, Any, Effects(), NoCallInfo()))
(types, isexact, isconcrete, istype) = instanceof_tfunc(argtype_by_index(argtypes, 3), false)
isexact || return Future(CallMeta(Any, Any, Effects(), NoCallInfo()))
unwrapped = unwrap_unionall(types)
Expand Down Expand Up @@ -2625,7 +2656,7 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
if sv isa InferenceState && f === typeassert
# perform very limited back-propagation of invariants after this type assertion
if rt !== Bottom && isa(fargs, Vector{Any})
farg2 = fargs[2]
farg2 = ssa_def_slot(fargs[2], sv)
if farg2 isa SlotNumber
refinements = SlotRefinement(farg2, rt)
end
Expand Down Expand Up @@ -2863,20 +2894,21 @@ end

function abstract_eval_cfunction(interp::AbstractInterpreter, e::Expr, sstate::StatementState, sv::AbsIntState)
f = abstract_eval_value(interp, e.args[2], sstate, sv)
# rt = sp_type_rewrap(e.args[3], sv.linfo, true)
# rt = sp_type_rewrap(e.args[3], sv.linfo, true) # verify that the result type make sense?
# rt === Bottom && return RTEffects(Union{}, Any, EFFECTS_UNKNOWN)
atv = e.args[4]::SimpleVector
at = Vector{Any}(undef, length(atv) + 1)
at[1] = f
for i = 1:length(atv)
at[i + 1] = sp_type_rewrap(at[i], frame_instance(sv), false)
at[i + 1] === Bottom && return
atᵢ = at[i + 1] = sp_type_rewrap(atv[i], frame_instance(sv), false)
atᵢ === Bottom && return RTEffects(Union{}, Any, EFFECTS_UNKNOWN)
end
# this may be the wrong world for the call,
# but some of the result is likely to be valid anyways
# and that may help generate better codegen
abstract_call(interp, ArgInfo(nothing, at), StmtInfo(false, false), sv)::Future
rt = e.args[1]
isa(rt, Type) || (rt = Any)
isconcretetype(rt) || (rt = Any)
return RTEffects(rt, Any, EFFECTS_UNKNOWN)
end

Expand Down Expand Up @@ -3209,8 +3241,16 @@ function abstract_eval_throw_undef_if_not(interp::AbstractInterpreter, e::Expr,
end

function abstract_eval_the_exception(::AbstractInterpreter, sv::InferenceState)
(;handlers, handler_at) = sv.handler_info::HandlerInfo
return the_exception_info(handlers[handler_at[sv.currpc][2]].exct)
(;handler_info) = sv
if handler_info === nothing
return the_exception_info(Any)
end
(;handlers, handler_at) = handler_info
handler_id = handler_at[sv.currpc][2]
if handler_id === 0
return the_exception_info(Any)
end
return the_exception_info(handlers[handler_id].exct)
end
abstract_eval_the_exception(::AbstractInterpreter, ::IRInterpretationState) = the_exception_info(Any)
the_exception_info(@nospecialize t) = RTEffects(t, Union{}, Effects(EFFECTS_TOTAL; consistent=ALWAYS_FALSE))
Expand Down Expand Up @@ -4020,13 +4060,7 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState, nextr
end
effects === nothing || merge_override_effects!(interp, effects, frame)
if lhs !== nothing && rt !== Bottom
if isa(lhs, SlotNumber)
changes = StateUpdate(lhs, VarState(rt, false))
elseif isa(lhs, GlobalRef)
handle_global_assignment!(interp, frame, currsaw_latestworld, lhs, rt)
else
merge_effects!(interp, frame, EFFECTS_UNKNOWN)
end
changes = StateUpdate(lhs::SlotNumber, VarState(rt, false))
end
end
if !has_curr_ssaflag(frame, IR_FLAG_NOTHROW)
Expand Down
2 changes: 1 addition & 1 deletion Compiler/src/abstractlattice.jl
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ end
if isa(t, Const)
# don't consider mutable values useful constants
val = t.val
return isa(val, Symbol) || isa(val, Type) || isa(val, Method) || !ismutable(val)
return isa(val, Symbol) || isa(val, Type) || isa(val, Method) || isa(val, CodeInstance) || !ismutable(val)
end
isa(t, PartialTypeVar) && return false # this isn't forwardable
return is_const_prop_profitable_arg(widenlattice(𝕃), t)
Expand Down
10 changes: 9 additions & 1 deletion Compiler/src/bootstrap.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,15 @@
# especially try to make sure any recursive and leaf functions have concrete signatures,
# since we won't be able to specialize & infer them at runtime

activate_codegen!() = ccall(:jl_set_typeinf_func, Cvoid, (Any,), typeinf_ext_toplevel)
function activate_codegen!()
ccall(:jl_set_typeinf_func, Cvoid, (Any,), typeinf_ext_toplevel)
Core.eval(Compiler, quote
let typeinf_world_age = Base.tls_world_age()
@eval Core.OptimizedGenerics.CompilerPlugins.typeinf(::Nothing, mi::MethodInstance, source_mode::UInt8) =
Base.invoke_in_world($(Expr(:$, :typeinf_world_age)), typeinf_ext_toplevel, mi, Base.tls_world_age(), source_mode)
end
end)
end

function bootstrap!()
let time() = ccall(:jl_clock_now, Float64, ())
Expand Down
1 change: 1 addition & 0 deletions Compiler/src/effects.jl
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ is_inaccessiblemem_or_argmemonly(effects::Effects) = effects.inaccessiblememonly

is_consistent_overlay(effects::Effects) = effects.nonoverlayed === CONSISTENT_OVERLAY

# (sync this with codegen.cpp and staticdata.c effects_foldable functions)
function encode_effects(e::Effects)
return ((e.consistent % UInt32) << 0) |
((e.effect_free % UInt32) << 3) |
Expand Down
Loading

0 comments on commit ba14e00

Please sign in to comment.