diff --git a/src/interface.jl b/src/interface.jl index d04c1ded..6a51f1a5 100644 --- a/src/interface.jl +++ b/src/interface.jl @@ -158,3 +158,6 @@ link_libraries!(::CompilerJob, mod::LLVM.Module, undefined_fns::Vector{String}) # whether pointer is a valid call target valid_function_pointer(::CompilerJob, ptr::Ptr{Cvoid}) = false + +# whether we should compile in imaging mode +extern_policy(::CompilerJob) = false diff --git a/src/jlgen.jl b/src/jlgen.jl index d55d527f..f6a21d3c 100644 --- a/src/jlgen.jl +++ b/src/jlgen.jl @@ -213,7 +213,7 @@ function compile_method_instance(@nospecialize(job::CompilerJob), method_instanc # generate IR native_code = ccall(:jl_create_native, Ptr{Cvoid}, (Vector{MethodInstance}, Base.CodegenParams, Cint), - [method_instance], params, #=extern policy=# 1) + [method_instance], params, extern_policy(job) ? 2 : 1) @assert native_code != C_NULL llvm_mod_ref = ccall(:jl_get_llvm_module, LLVM.API.LLVMModuleRef, (Ptr{Cvoid},), native_code) diff --git a/src/native.jl b/src/native.jl index 58543c63..85fb3a46 100644 --- a/src/native.jl +++ b/src/native.jl @@ -7,6 +7,7 @@ export NativeCompilerTarget Base.@kwdef struct NativeCompilerTarget <: AbstractCompilerTarget cpu::String=(LLVM.version() < v"8") ? "" : unsafe_string(LLVM.API.LLVMGetHostCPUName()) features::String=(LLVM.version() < v"8") ? "" : unsafe_string(LLVM.API.LLVMGetHostCPUFeatures()) + reloc::LLVM.API.LLVMRelocMode=LLVM.API.LLVMRelocDefault end llvm_triple(::NativeCompilerTarget) = Sys.MACHINE @@ -16,12 +17,17 @@ function llvm_machine(target::NativeCompilerTarget) t = Target(triple=triple) - tm = TargetMachine(t, triple, target.cpu, target.features) + optlevel = LLVM.API.LLVMCodeGenLevelDefault + reloc = target.reloc + tm = TargetMachine(t, triple, target.cpu, target.features, optlevel, reloc) asm_verbosity!(tm, true) return tm end +GPUCompiler.extern_policy(job::CompilerJob{NativeCompilerTarget,P} where P) = + job.target.reloc == LLVM.API.LLVMRelocPIC + ## job diff --git a/test/native.jl b/test/native.jl index c044c0c8..8a8ae589 100644 --- a/test/native.jl +++ b/test/native.jl @@ -307,6 +307,70 @@ end end end +using Libdl + +function generate_shlib_fptr(f, tt, name=GPUCompiler.safe_name(repr(f))) + mktemp() do path, io + source = FunctionSpec(f, Base.to_tuple_type(tt), false, name) + target = NativeCompilerTarget(;reloc=LLVM.API.LLVMRelocPIC) + params = TestCompilerParams() + job = CompilerJob(target, source, params) + obj, _ = GPUCompiler.codegen(:obj, job; strip=true, only_entry=false, validate=false) + write(io, obj) + flush(io) + # FIXME: Be more portable + run(`ld -shared -o $path.$dlext $path`) + ptr = dlopen("$path.$dlext", Libdl.RTLD_LOCAL) + fptr = dlsym(ptr, "julia_$name") + @assert fptr != C_NULL + atexit(()->rm("$path.$dlext")) + fptr + end +end + +@static if VERSION >= v"1.7.0-DEV.600" +@testset "shared library emission" begin + f1(x) = x+1 + @test ccall(generate_shlib_fptr(f1, (Int,)), Int, (Int,), 1) == 2 + f2(x,y) = x+y + @test ccall(generate_shlib_fptr(f2, (Int,Int)), Int, (Int,Int), 1, 2) == 3 + f3(str) = str*"!" + @test_skip ccall(generate_shlib_fptr(f3, (String,)), String, (String,), "Hello") == "Hello!" + function f4() + # Something reasonably complicated + if isdir(homedir()) + true + else + false + end + end + @test ccall(generate_shlib_fptr(f4, ()), Bool, ()) + f5() = :asymbol + @test_skip ccall(generate_shlib_fptr(f5, ()), Symbol, ()) == :asymbol + f6(x) = x == :asymbol ? true : false + @test_skip ccall(generate_shlib_fptr(f6, (Symbol,)), Bool, (Symbol,), :asymbol) + @test_skip !ccall(generate_shlib_fptr(f6, (Symbol,)), Bool, (Symbol,), :bsymbol) + #= FIXME + function f7(A, sym) + if sym != :asymbol + A[] = true + else + A[] = false + end + return nothing + end + A = Ref(false) + ccall(generate_shlib_fptr(f7, (Base.RefValue{Bool}, Symbol)), Nothing, (Base.RefValue{Bool}, Symbol), A, :asymbol); @test A[] + ccall(generate_shlib_fptr(f7, (Base.RefValue{Bool}, Symbol)), Nothing, (Base.RefValue{Bool}, Symbol), A, :bsymbol); @test !A[] + =# + y = [42.0] + function cf1(x) + x + y[1] + end + @test ccall(generate_shlib_fptr(cf1, (Float64,)), Float64, (Any, Float64,), cf1, 1.0) == 43.0 +end +end + end ############################################################################################