diff --git a/src/debug.jl b/src/debug.jl index 881bad94..382865a2 100644 --- a/src/debug.jl +++ b/src/debug.jl @@ -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 diff --git a/src/determinism.jl b/src/determinism.jl index 893e4307..cf39af62 100644 --- a/src/determinism.jl +++ b/src/determinism.jl @@ -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) diff --git a/src/driver.jl b/src/driver.jl index 13c3f81d..1065ca3c 100644 --- a/src/driver.jl +++ b/src/driver.jl @@ -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) diff --git a/src/irgen.jl b/src/irgen.jl index 87a5572e..7ded0af6 100644 --- a/src/irgen.jl +++ b/src/irgen.jl @@ -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) diff --git a/src/mangling.jl b/src/mangling.jl index 35a53df2..5f58e7a0 100644 --- a/src/mangling.jl +++ b/src/mangling.jl @@ -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 @@ -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)" diff --git a/src/metal.jl b/src/metal.jl index a7b63cad..06a019f7 100644 --- a/src/metal.jl +++ b/src/metal.jl @@ -2389,18 +2389,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 diff --git a/src/relocation.jl b/src/relocation.jl index 59da580f..31bfab2a 100644 --- a/src/relocation.jl +++ b/src/relocation.jl @@ -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) diff --git a/src/rtlib.jl b/src/rtlib.jl index 6c2d16a5..e38bd00c 100644 --- a/src/rtlib.jl +++ b/src/rtlib.jl @@ -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 diff --git a/src/utils.jl b/src/utils.jl index 3fc15d79..02758d79 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -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) diff --git a/src/validation.jl b/src/validation.jl index 87e144ed..2b0ea8d9 100644 --- a/src/validation.jl +++ b/src/validation.jl @@ -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)