From 7fa26f011ec4fea616ad192eeaa8919f2cc17f97 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sat, 16 Nov 2024 14:20:39 -0500 Subject: [PATCH] Move Compiler <-> OpaqueClosure interface code to Compiler (#56576) After the excision, it is no longer permissable for Base to have `Compiler` data structures in arguments of methods it defines. To comply with this restriction, move the functions for creating OpaqueClosures from IRCode to `Compiler`. --- Compiler/src/Compiler.jl | 1 + Compiler/src/opaque_closure.jl | 56 +++++++++++++++++++++++++++++++++ base/opaque_closure.jl | 57 ---------------------------------- 3 files changed, 57 insertions(+), 57 deletions(-) create mode 100644 Compiler/src/opaque_closure.jl diff --git a/Compiler/src/Compiler.jl b/Compiler/src/Compiler.jl index 376721da46783..4104b71093f4d 100644 --- a/Compiler/src/Compiler.jl +++ b/Compiler/src/Compiler.jl @@ -179,6 +179,7 @@ include("optimize.jl") include("bootstrap.jl") include("reflection_interface.jl") +include("opaque_closure.jl") module IRShow end if !isdefined(Base, :end_base_include) diff --git a/Compiler/src/opaque_closure.jl b/Compiler/src/opaque_closure.jl new file mode 100644 index 0000000000000..d0a375c2a54b5 --- /dev/null +++ b/Compiler/src/opaque_closure.jl @@ -0,0 +1,56 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + +function compute_ir_rettype(ir::IRCode) + rt = Union{} + for i = 1:length(ir.stmts) + stmt = ir[SSAValue(i)][:stmt] + if isa(stmt, Core.ReturnNode) && isdefined(stmt, :val) + rt = Compiler.tmerge(Compiler.argextype(stmt.val, ir), rt) + end + end + return Compiler.widenconst(rt) +end + +function compute_oc_signature(ir::IRCode, nargs::Int, isva::Bool) + argtypes = Vector{Any}(undef, nargs) + for i = 1:nargs + argtypes[i] = Compiler.widenconst(ir.argtypes[i+1]) + end + if isva + lastarg = pop!(argtypes) + if lastarg <: Tuple + append!(argtypes, lastarg.parameters) + else + push!(argtypes, Vararg{Any}) + end + end + return Tuple{argtypes...} +end + +function Core.OpaqueClosure(ir::IRCode, @nospecialize env...; + isva::Bool = false, + slotnames::Union{Nothing,Vector{Symbol}}=nothing, + kwargs...) + # NOTE: we need ir.argtypes[1] == typeof(env) + ir = Core.Compiler.copy(ir) + # if the user didn't specify a definition MethodInstance or filename Symbol to use for the debuginfo, set a filename now + ir.debuginfo.def === nothing && (ir.debuginfo.def = :var"generated IR for OpaqueClosure") + nargtypes = length(ir.argtypes) + nargs = nargtypes-1 + sig = compute_oc_signature(ir, nargs, isva) + rt = compute_ir_rettype(ir) + src = ccall(:jl_new_code_info_uninit, Ref{CodeInfo}, ()) + if slotnames === nothing + src.slotnames = fill(:none, nargtypes) + else + length(slotnames) == nargtypes || error("mismatched `argtypes` and `slotnames`") + src.slotnames = slotnames + end + src.slotflags = fill(zero(UInt8), nargtypes) + src.slottypes = copy(ir.argtypes) + src.isva = isva + src.nargs = UInt(nargtypes) + src = ir_to_codeinf!(src, ir) + src.rettype = rt + return Base.Experimental.generate_opaque_closure(sig, Union{}, rt, src, nargs, isva, env...; kwargs...) +end diff --git a/base/opaque_closure.jl b/base/opaque_closure.jl index d7a91cff7d602..5e38c8523f4a8 100644 --- a/base/opaque_closure.jl +++ b/base/opaque_closure.jl @@ -39,63 +39,6 @@ end # OpaqueClosure construction from pre-inferred CodeInfo/IRCode using Core: CodeInfo, SSAValue -using Base: Compiler -using .Compiler: IRCode - -function compute_ir_rettype(ir::IRCode) - rt = Union{} - for i = 1:length(ir.stmts) - stmt = ir[SSAValue(i)][:stmt] - if isa(stmt, Core.ReturnNode) && isdefined(stmt, :val) - rt = Compiler.tmerge(Compiler.argextype(stmt.val, ir), rt) - end - end - return Compiler.widenconst(rt) -end - -function compute_oc_signature(ir::IRCode, nargs::Int, isva::Bool) - argtypes = Vector{Any}(undef, nargs) - for i = 1:nargs - argtypes[i] = Compiler.widenconst(ir.argtypes[i+1]) - end - if isva - lastarg = pop!(argtypes) - if lastarg <: Tuple - append!(argtypes, lastarg.parameters) - else - push!(argtypes, Vararg{Any}) - end - end - return Tuple{argtypes...} -end - -function Core.OpaqueClosure(ir::IRCode, @nospecialize env...; - isva::Bool = false, - slotnames::Union{Nothing,Vector{Symbol}}=nothing, - kwargs...) - # NOTE: we need ir.argtypes[1] == typeof(env) - ir = Core.Compiler.copy(ir) - # if the user didn't specify a definition MethodInstance or filename Symbol to use for the debuginfo, set a filename now - ir.debuginfo.def === nothing && (ir.debuginfo.def = :var"generated IR for OpaqueClosure") - nargtypes = length(ir.argtypes) - nargs = nargtypes-1 - sig = compute_oc_signature(ir, nargs, isva) - rt = compute_ir_rettype(ir) - src = ccall(:jl_new_code_info_uninit, Ref{CodeInfo}, ()) - if slotnames === nothing - src.slotnames = fill(:none, nargtypes) - else - length(slotnames) == nargtypes || error("mismatched `argtypes` and `slotnames`") - src.slotnames = slotnames - end - src.slotflags = fill(zero(UInt8), nargtypes) - src.slottypes = copy(ir.argtypes) - src.isva = isva - src.nargs = nargtypes - src = Core.Compiler.ir_to_codeinf!(src, ir) - src.rettype = rt - return generate_opaque_closure(sig, Union{}, rt, src, nargs, isva, env...; kwargs...) -end function Core.OpaqueClosure(src::CodeInfo, @nospecialize env...; rettype, sig, nargs, isva=false, kwargs...) return generate_opaque_closure(sig, Union{}, rettype, src, nargs, isva, env...; kwargs...)