@@ -8,6 +8,8 @@ using Libdl: Libdl, dlsym, dlopen
88using Base: RefValue
99using Serialization: serialize, deserialize
1010using Clang_jll: clang
11+ using StaticTools
12+ using StaticTools: @symbolcall , @c_str , println
1113
1214export compile, load_function, compile_shlib, compile_executable
1315export native_code_llvm, native_code_typed, native_llvm_module, native_code_native
@@ -16,6 +18,7 @@ include("target.jl")
1618include (" pointer_patching.jl" )
1719include (" code_loading.jl" )
1820include (" optimize.jl" )
21+ include (" quirks.jl" )
1922
2023
2124"""
@@ -95,7 +98,7 @@ function compile(f, _tt, path::String = tempname(); name = GPUCompiler.safe_nam
9598 isconcretetype (rt) || error (" $f on $_tt did not infer to a concrete type. Got $rt " )
9699
97100 f_wrap! (out:: Ref , args:: Ref{<:Tuple} ) = (out[] = f (args[]. .. ); nothing )
98- _, _, table = generate_obj (f_wrap!, Tuple{RefValue{rt}, RefValue{tt}}, path, name; opt_level, strip_llvm, strip_asm, filename, kwargs... )
101+ _, _, table = generate_obj (f_wrap!, Tuple{RefValue{rt}, RefValue{tt}}, false , path, name; opt_level, strip_llvm, strip_asm, filename, kwargs... )
99102
100103 lf = LazyStaticCompiledFunction {rt, tt} (Symbol (f), path, name, filename, table)
101104 cjl_path = joinpath (path, " $filename .cjl" )
@@ -131,15 +134,15 @@ shell> tree \$path
1311340 directories, 1 file
132135```
133136"""
134- function generate_obj (f, tt, path:: String = tempname (), name = GPUCompiler. safe_name (repr (f)), filenamebase:: String = " obj" ;
137+ function generate_obj (f, tt, external = true , path:: String = tempname (), name = GPUCompiler. safe_name (repr (f)), filenamebase:: String = " obj" ;
135138 strip_llvm = false ,
136139 strip_asm = true ,
137140 opt_level= 3 ,
138141 kwargs... )
139142 mkpath (path)
140143 obj_path = joinpath (path, " $filenamebase .o" )
141- tm = GPUCompiler. llvm_machine (NativeCompilerTarget ())
142- job, kwargs = native_job (f, tt; name, kwargs... )
144+ tm = GPUCompiler. llvm_machine (external ? ExternalNativeCompilerTarget () : NativeCompilerTarget ())
145+ job, kwargs = native_job (f, tt, external ; name, kwargs... )
143146 # Get LLVM to generated a module of code for us. We don't want GPUCompiler's optimization passes.
144147 mod, meta = GPUCompiler. JuliaContext () do context
145148 GPUCompiler. codegen (:llvm , job; strip= strip_llvm, only_entry= false , validate= false , optimize= false , ctx= context)
@@ -267,7 +270,7 @@ function compile_shlib(f, types=(), path::String="./", name=GPUCompiler.safe_nam
267270
268271 # Would be nice to use a compiler pass or something to check if there are any heap allocations or references to globals
269272 # Keep an eye on https://github.com/JuliaLang/julia/pull/43747 for this
270- generate_shlib (f, tt, path, name, filename; cflags= cflags, kwargs... )
273+ generate_shlib (f, tt, true , path, name, filename; cflags= cflags, kwargs... )
271274
272275 joinpath (abspath (path), filename * " ." * Libdl. dlext)
273276end
@@ -276,7 +279,7 @@ function generate_shlib_fptr(f, tt, path::String=tempname(), name = GPUCompiler.
276279 temp:: Bool = true ,
277280 kwargs... )
278281
279- generate_shlib (f, tt, path, name; kwargs... )
282+ generate_shlib (f, tt, false , path, name; kwargs... )
280283 lib_path = joinpath (abspath (path), " $filename .$(Libdl. dlext) " )
281284 ptr = Libdl. dlopen (lib_path, Libdl. RTLD_LOCAL)
282285 fptr = Libdl. dlsym (ptr, " julia_$name " )
@@ -358,7 +361,7 @@ function generate_executable(f, tt, path=tempname(), name=GPUCompiler.safe_name(
358361 mkpath (path)
359362 obj_path = joinpath (path, " $filename .o" )
360363 exec_path = joinpath (path, filename)
361- job, kwargs = native_job (f, tt; name, kwargs... )
364+ job, kwargs = native_job (f, tt, true ; name, kwargs... )
362365 obj, _ = GPUCompiler. codegen (:obj , job; strip= true , only_entry= false , validate= false )
363366
364367 # Write to file
@@ -425,15 +428,15 @@ julia> ccall(StaticCompiler.generate_shlib_fptr(path, name), Float64, (Int64,),
4254285.256496109495593
426429```
427430"""
428- function generate_shlib (f, tt, path= tempname (), name= GPUCompiler. safe_name (repr (f)), filename= name;
431+ function generate_shlib (f, tt, external = true , path= tempname (), name= GPUCompiler. safe_name (repr (f)), filename= name;
429432 cflags= ` ` ,
430433 kwargs...
431434 )
432435
433436 mkpath (path)
434437 obj_path = joinpath (path, " $filename .o" )
435438 lib_path = joinpath (path, " $filename .$(Libdl. dlext) " )
436- job, kwargs = native_job (f, tt; name, kwargs... )
439+ job, kwargs = native_job (f, tt, external ; name, kwargs... )
437440 obj, _ = GPUCompiler. codegen (:obj , job; strip= true , only_entry= false , validate= false )
438441
439442 open (obj_path, " w" ) do io
@@ -449,26 +452,26 @@ function generate_shlib(f, tt, path=tempname(), name=GPUCompiler.safe_name(repr(
449452end
450453
451454function native_code_llvm (@nospecialize (func), @nospecialize (types); kwargs... )
452- job, kwargs = native_job (func, types; kwargs... )
455+ job, kwargs = native_job (func, types, true ; kwargs... )
453456 GPUCompiler. code_llvm (stdout , job; kwargs... )
454457end
455458
456459function native_code_typed (@nospecialize (func), @nospecialize (types); kwargs... )
457- job, kwargs = native_job (func, types; kwargs... )
460+ job, kwargs = native_job (func, types, true ; kwargs... )
458461 GPUCompiler. code_typed (job; kwargs... )
459462end
460463
461464# Return an LLVM module
462465function native_llvm_module (f, tt, name = GPUCompiler. safe_name (repr (f)); kwargs... )
463- job, kwargs = native_job (f, tt; name, kwargs... )
466+ job, kwargs = native_job (f, tt, true ; name, kwargs... )
464467 m, _ = GPUCompiler. JuliaContext () do context
465468 GPUCompiler. codegen (:llvm , job; strip= true , only_entry= false , validate= false , ctx= context)
466469 end
467470 return m
468471end
469472
470473function native_code_native (@nospecialize (f), @nospecialize (tt), name = GPUCompiler. safe_name (repr (f)); kwargs... )
471- job, kwargs = native_job (f, tt; name, kwargs... )
474+ job, kwargs = native_job (f, tt, true ; name, kwargs... )
472475 GPUCompiler. code_native (stdout , job; kwargs... )
473476end
474477
@@ -498,7 +501,7 @@ function native_llvm_module(funcs::Array; demangle = false, kwargs...)
498501 return mod
499502end
500503
501- function generate_obj (funcs:: Array , path:: String = tempname (), filenamebase:: String = " obj" ;
504+ function generate_obj (funcs:: Array , external, path:: String = tempname (), filenamebase:: String = " obj" ;
502505 demangle = false ,
503506 strip_llvm = false ,
504507 strip_asm = true ,
@@ -507,7 +510,7 @@ function generate_obj(funcs::Array, path::String = tempname(), filenamebase::Str
507510 f,tt = funcs[1 ]
508511 mkpath (path)
509512 obj_path = joinpath (path, " $filenamebase .o" )
510- fakejob, kwargs = native_job (f,tt, kwargs... )
513+ fakejob, kwargs = native_job (f,tt, external, kwargs... )
511514 mod = native_llvm_module (funcs; demangle = demangle, kwargs... )
512515 obj, _ = GPUCompiler. emit_asm (fakejob, mod; strip= strip_asm, validate= false , format= LLVM. API. LLVMObjectFile)
513516 open (obj_path, " w" ) do io
@@ -516,15 +519,15 @@ function generate_obj(funcs::Array, path::String = tempname(), filenamebase::Str
516519 path, obj_path
517520end
518521
519- function generate_shlib (funcs:: Array , path:: String = tempname (), filename:: String = " libfoo" ;
522+ function generate_shlib (funcs:: Array , external = true , path:: String = tempname (), filename:: String = " libfoo" ;
520523 demangle= false ,
521524 cflags= ` ` ,
522525 kwargs...
523526 )
524527
525528 lib_path = joinpath (path, " $filename .$(Libdl. dlext) " )
526529
527- _,obj_path = generate_obj (funcs, path, filename; demangle= demangle, kwargs... )
530+ _,obj_path = generate_obj (funcs, external, path, filename; demangle= demangle, kwargs... )
528531 # Pick a Clang
529532 cc = Sys. isapple () ? ` cc` : clang ()
530533 # Compile!
@@ -550,7 +553,7 @@ function compile_shlib(funcs::Array, path::String="./";
550553# Would be nice to use a compiler pass or something to check if there are any heap allocations or references to globals
551554# Keep an eye on https://github.com/JuliaLang/julia/pull/43747 for this
552555
553- generate_shlib (funcs, path, filename; demangle= demangle, cflags= cflags, kwargs... )
556+ generate_shlib (funcs, true , path, filename; demangle= demangle, cflags= cflags, kwargs... )
554557
555558 joinpath (abspath (path), filename * " ." * Libdl. dlext)
556559end
0 commit comments