Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/debug.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ function backtrace(inst::LLVM.Instruction, bt = StackTraces.StackFrame[])
name = replace(something(scope.name, ""), r";$"=>"")
isempty(name) && (name = "unknown")
file = scope.file
path = file === nothing ? "unknown" : joinpath(file.directory, file.filename)
path = file === nothing ? "unknown" :
joinpath(file.directory::Union{Nothing,String},
file.filename::Union{Nothing,String})
line = loc.line
push!(bt, StackTraces.StackFrame(name, path, line))
end
Expand Down
4 changes: 2 additions & 2 deletions src/determinism.jl
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,12 @@ function dedup_compile_units!(mod::LLVM.Module)
cus = mds["llvm.dbg.cu"].operands
length(cus) <= 1 && return false

canonical = Dict{Tuple,LLVM.Metadata}()
canonical = Dict{Vector{Union{Nothing,LLVM.Metadata}},LLVM.Metadata}()
canonical_cus = LLVM.Metadata[]
replacement = Dict{LLVM.Metadata,LLVM.Metadata}()
for cu in cus
cu === nothing && continue
key = Tuple(cu.operands)
key = Union{Nothing,LLVM.Metadata}[cu.operands...]
canon = get!(canonical, key, cu)
if canon == cu
push!(canonical_cus, cu)
Expand Down
8 changes: 7 additions & 1 deletion src/driver.jl
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,13 @@ const __llvm_initialized = Ref(false)
# which was loaded in a newer world.
dyn_ir, dyn_meta = @invokelatest deferred_codegen(dyn_job, job)
dyn_entry_fn = dyn_meta.entry.name
merge!(compiled, dyn_meta.compiled)
# the sibling compiler's result isn't inferred
dyn_compiled = dyn_meta.compiled
if dyn_compiled isa Dict{Any,Any}
merge!(compiled, dyn_compiled)
else
Base.inferencebarrier(merge!)(compiled, dyn_compiled)
end
@assert dyn_ir.context == ir.context
link_relocatable!(ir, relocations, dyn_ir,
dyn_meta.relocations)
Expand Down
2 changes: 1 addition & 1 deletion src/interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ llvm_targetinfo(@nospecialize(target::AbstractCompilerTarget)) = nothing
# the target's datalayout, with Julia's non-integral address spaces added to it, as a
# `DataLayout` the caller owns (or `nothing`)
function julia_datalayout(@nospecialize(target::AbstractCompilerTarget))
dl = llvm_datalayout(target)
dl = llvm_datalayout(target)::Union{Nothing,String}
dl === nothing && return nothing
LLVM.DataLayout(dl * "-ni:10:11:12:13")
end
Expand Down
17 changes: 7 additions & 10 deletions src/irgen.jl
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ end
# is not passed at the LLVM level.
function classify_arguments(@nospecialize(job::CompilerJob), codegen_ft::LLVM.FunctionType;
post_optimization::Bool=false)
source_sig = job.source.specTypes
source_sig = job.source.specTypes::DataType
source_types = collect(Any, source_sig.parameters)

source_argnames = Base.method_argnames(job.source.def)
Expand Down Expand Up @@ -979,7 +979,7 @@ function (self::AddKernelState)(mod::LLVM.Module)
position!(builder, LLVM.before(val))
state_arg = call!(builder, state_intr_ft, state_intr, Value[], "state")
new_val = if val isa LLVM.CallInst
call!(builder, ft, f, [state_arg, val.arguments...],
call!(builder, ft, f, Value[state_arg, val.arguments...],
val.operand_bundles)
else
# TODO: invoke and callbr
Expand All @@ -997,13 +997,10 @@ function (self::AddKernelState)(mod::LLVM.Module)
# XXX: we won't have to do this with opaque pointers.
position!(builder, LLVM.before(val))
target_ft = val.called_type
new_args = map(zip(target_ft.parameters,
val.arguments)) do (param_typ, arg)
if arg.value_type != param_typ
const_bitcast(arg, param_typ)
else
arg
end
new_args = Value[]
for (param_typ, arg) in zip(target_ft.parameters, val.arguments)
push!(new_args, arg.value_type != param_typ ?
const_bitcast(arg, param_typ) : arg)
end
new_val = call!(builder, val.called_type, val.called_operand, new_args,
val.operand_bundles)
Expand Down Expand Up @@ -1460,7 +1457,7 @@ function add_input_arguments!(@nospecialize(job::CompilerJob), mod::LLVM.Module,
position!(builder, LLVM.before(val))
new_val = if val isa LLVM.CallInst
call!(builder, new_f.function_type, new_f,
[val.arguments..., callee_f.parameters[end-nargs+1:end]...],
Value[val.arguments..., callee_f.parameters[end-nargs+1:end]...],
val.operand_bundles)
else
# TODO: invoke and callbr
Expand Down
8 changes: 4 additions & 4 deletions src/mangling.jl
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ function mangle_param(@nospecialize(t), substitutions = Any[], top = false)
# check if we already know this base type
str = find_substitution(t.name.wrapper)
if str === nothing
tn = safe_name(t)
tn = safe_name(t)::String
str = "$(length(tn))$tn"
push!(substitutions, t.name.wrapper)
end
Expand All @@ -82,7 +82,7 @@ function mangle_param(@nospecialize(t), substitutions = Any[], top = false)
else
# encode typevars as template parameters
if isempty(t.parameters)
w_types = t.name.wrapper.types
w_types = (t.name.wrapper::DataType).types
if !isempty(w_types) && !isempty(w_types[end] isa Core.TypeofVararg)
# If the type accepts a variable amount of parameters,
# e.g. `Tuple{}`, then we mark it as empty: "Tuple<>"
Expand Down Expand Up @@ -123,7 +123,7 @@ function mangle_param(@nospecialize(t), substitutions = Any[], top = false)
# `N` is a `TypeVar` when the length is still parametric, which is what unwrapping a
# `UnionAll` such as `NTuple{N,Int}` leaves behind. There is no count to repeat then,
# so the type is mangled like the unbounded `Vararg{T}` it is equal to.
N = isdefined(t, :N) && isa(t.N, Integer) ? t.N : nothing
N = isdefined(t, :N) && isa(t.N, Int) ? t.N::Int : nothing
if N !== nothing
# For NTuple, repeat the type as needed
str = ""
Expand Down Expand Up @@ -171,7 +171,7 @@ function mangle_param(@nospecialize(t), substitutions = Any[], top = false)
bits = string(reinterpret(UInt64, t); base=16)
"Ld$(bits)E"
else
tn = safe_name(t) # TODO: actually does support digits...
tn = safe_name(t)::String # TODO: actually does support digits...
if startswith(tn, r"\d")
# C++ classes cannot start with a digit, so mangling doesn't support it
tn = "_$(tn)"
Expand Down
9 changes: 5 additions & 4 deletions src/metal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2271,18 +2271,19 @@ function msl_identifier(@nospecialize(T))
str = String(strip(replace(julia_type_words(T), r"[^A-Za-z0-9_]+" => "_"), '_'))
return isempty(str) || isdigit(str[1]) ? "_" * str : str
end
function julia_type_words(@nospecialize(x))
# (recursive, so the result type is declared for inference)
function julia_type_words(@nospecialize(x))::String
if x isa DataType
join([String(nameof(x)); map(julia_type_words, x.parameters)], "_")
join([String(nameof(x)); String[julia_type_words(p) for p in x.parameters]], "_")
elseif x isa Union
# (sorted, as Julia orders union members by module name, which can be generated)
join(["Union"; sort!(map(julia_type_words, Base.uniontypes(x)))], "_")
join(["Union"; sort!(String[julia_type_words(T) for T in Base.uniontypes(x)])], "_")
elseif x isa UnionAll
julia_type_words(Base.unwrap_unionall(x))
elseif x isa TypeVar
String(x.name)
elseif x isa Tuple
join(map(julia_type_words, x), "_")
join(String[julia_type_words(y) for y in x], "_")
elseif x isa Union{Number,Symbol,AbstractChar,AbstractString}
string(x)
else
Expand Down
2 changes: 1 addition & 1 deletion src/relocation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ end
function resolve_relocation_target(target::CGlobalRef)
if target.library === nothing
# `jl_cglobal` accepts the symbol directly and does the process-wide `jl_dlfind`.
address = ccall(:jl_cglobal, Any, (Any, Any), target.symbol, UInt)
address = ccall(:jl_cglobal, Any, (Any, Any), target.symbol, UInt)::Ptr{UInt}
return unsafe_load(address + target.offset)
end
handle = Libdl.dlopen(target.library)
Expand Down
2 changes: 1 addition & 1 deletion src/rtlib.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ function LLVM.call!(builder, rt::Runtime.RuntimeMethodInstance, args=LLVM.Value[
runtime_function_type(job, rt)
end
LLVM.Function(mod, rt.llvm_name, ft)
end
end::LLVM.Function
ft = f.function_type
if !isdeclaration(f) && (rt.name !== :gc_pool_alloc && rt.name !== :report_exception)
# XXX: uses of the gc_pool_alloc intrinsic can be introduced _after_ the runtime
Expand Down
7 changes: 6 additions & 1 deletion src/runtime.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ using ..GPUCompiler
using LLVM, LLVM.IR, LLVM.Build
using LLVM.Interop

# imported explicitly, so that the binding exists before the generated functions below
# first use it. Julia 1.13 reports edges to a binding that a downstream package's
# precompilation created as invalidations (JuliaLang/julia#59135).
import Base: |


## representation of a runtime method instance

Expand Down Expand Up @@ -202,7 +207,7 @@ const gc_bits = 0x3 # FIXME
T_pjlvalue = convert(LLVMType, Any; allow_boxed=true)

# this isn't really a function, but we abuse it to get the JIT to resolve the address
typ = LLVM.Function(current_module(builder), "jl_" * String(type_name) * "_type",
typ = LLVM.Function(current_module(builder), "jl_" * String(type_name::Symbol) * "_type",
LLVM.FunctionType(T_pjlvalue))

typ_var = bitcast!(builder, typ, T_ptag)
Expand Down
3 changes: 3 additions & 0 deletions src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ end
struct ExternalBackend
library::String # path to the shared library, as exported by its JLL
prefix::String # e.g. "NVPTX" for `NVPTXCompile`

# JLLs are loaded lazily, so the type of their library paths isn't inferred
ExternalBackend(library, prefix) = new(library::String, prefix::String)
end

function api(backend::ExternalBackend, name::String)
Expand Down
7 changes: 5 additions & 2 deletions src/validation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ function explain_nonisbits(@nospecialize(dt), depth=1; maxdepth=10)
end

function check_invocation(@nospecialize(job::CompilerJob))
sig = job.source.specTypes
sig = job.source.specTypes::DataType
ft = sig.parameters[1]
tt = Tuple{sig.parameters[2:end]...}

Expand Down Expand Up @@ -656,6 +656,7 @@ function emitted_functions(mod::LLVM.Module, compiled)
for entry in values(compiled)
for name in (entry.func, entry.specfunc)
name === nothing && continue
name = name::String # `compiled` holds entries of any type
emitted[name] = entry
# functions may have been renamed since, but not their debug information
f = get(functions, name, nothing)
Expand Down Expand Up @@ -795,7 +796,9 @@ end
function describe_call(src::CodeInfo, mi::MethodInstance, pc::Int, @nospecialize(callee),
world::UInt; strict::Bool=false)
stmt = src.code[pc]
(stmt isa Expr && stmt.head === :call) || return nothing
# separate checks, so that inference narrows `stmt` to an `Expr`
stmt isa Expr || return nothing
stmt.head === :call || return nothing
f = constant_value(stmt.args[1], world)
if callee !== nothing
f === nothing && strict && return nothing
Expand Down
Loading