@@ -12,9 +12,10 @@ using LLD_jll: lld
12
12
using StaticTools
13
13
using StaticTools: @symbolcall , @c_str , println
14
14
using Core: MethodTable
15
+ using Base: BinaryPlatforms. Platform, BinaryPlatforms. HostPlatform, BinaryPlatforms. arch, BinaryPlatforms. os, BinaryPlatforms. libc_str
15
16
16
17
export load_function, compile_shlib, compile_executable
17
- export native_code_llvm, native_code_typed, native_llvm_module, native_code_native
18
+ export static_code_llvm, static_code_typed, static_llvm_module, static_code_native
18
19
export @device_override , @print_and_throw
19
20
20
21
include (" interpreter.jl" )
@@ -32,6 +33,7 @@ compile_executable(f::Function, types::Tuple, path::String, [name::String=string
32
33
filename::String=name,
33
34
cflags=``, # Specify libraries you would like to link against, and other compiler options here
34
35
also_expose=[],
36
+ target::StaticTarget=StaticTarget(),
35
37
method_table=StaticCompiler.method_table,
36
38
kwargs...
37
39
)
@@ -96,16 +98,16 @@ Hello, world!
96
98
```
97
99
"""
98
100
function compile_executable (f:: Function , types= (), path:: String = " ./" , name= fix_name (f);
99
- also_expose= Tuple{Function, Tuple{DataType}}[],
101
+ also_expose= Tuple{Function, Tuple{DataType}}[], target :: StaticTarget = StaticTarget (),
100
102
kwargs... )
101
-
102
- compile_executable (vcat ([(f, types)], also_expose), path, name; kwargs... )
103
+ compile_executable (vcat ([(f, types)], also_expose), path, name; target, kwargs... )
103
104
end
104
105
105
106
function compile_executable (funcs:: Union{Array,Tuple} , path:: String = " ./" , name= fix_name (first (first (funcs)));
106
107
filename = name,
107
108
demangle = true ,
108
109
cflags = ` ` ,
110
+ target:: StaticTarget = StaticTarget (),
109
111
kwargs...
110
112
)
111
113
@@ -114,12 +116,12 @@ function compile_executable(funcs::Union{Array,Tuple}, path::String="./", name=f
114
116
isexecutableargtype = tt == Tuple{} || tt == Tuple{Int, Ptr{Ptr{UInt8}}}
115
117
isexecutableargtype || @warn " input type signature $types should be either `()` or `(Int, Ptr{Ptr{UInt8}})` for standard executables"
116
118
117
- rt = last (only (native_code_typed (f, tt; kwargs... )))
119
+ rt = last (only (static_code_typed (f, tt; target, kwargs... )))
118
120
isconcretetype (rt) || error (" `$f$types ` did not infer to a concrete type. Got `$rt `" )
119
121
nativetype = isprimitivetype (rt) || isa (rt, Ptr)
120
122
nativetype || @warn " Return type `$rt ` of `$f$types ` does not appear to be a native type. Consider returning only a single value of a native machine type (i.e., a single float, int/uint, bool, or pointer). \n\n Ignoring this warning may result in Undefined Behavior!"
121
123
122
- generate_executable (funcs, path, name, filename; demangle, cflags, kwargs... )
124
+ generate_executable (funcs, path, name, filename; demangle, cflags, target, kwargs... )
123
125
joinpath (abspath (path), filename)
124
126
end
125
127
@@ -129,13 +131,15 @@ compile_shlib(f::Function, types::Tuple, [path::String="./"], [name::String=stri
129
131
filename::String=name,
130
132
cflags=``,
131
133
method_table=StaticCompiler.method_table,
134
+ target::StaticTarget=StaticTarget(),
132
135
kwargs...)
133
136
134
137
compile_shlib(funcs::Array, [path::String="./"];
135
138
filename="libfoo",
136
139
demangle=true,
137
140
cflags=``,
138
141
method_table=StaticCompiler.method_table,
142
+ target::StaticTarget=StaticTarget(),
139
143
kwargs...)
140
144
```
141
145
As `compile_executable`, but compiling to a standalone `.dylib`/`.so` shared library.
@@ -169,33 +173,35 @@ julia> ccall(("test", "test.dylib"), Float64, (Int64,), 100_000)
169
173
"""
170
174
function compile_shlib (f:: Function , types= (), path:: String = " ./" , name= fix_name (f);
171
175
filename= name,
176
+ target:: StaticTarget = StaticTarget (),
172
177
kwargs...
173
178
)
174
- compile_shlib (((f, types),), path; filename, kwargs... )
179
+ compile_shlib (((f, types),), path; filename, target, kwargs... )
175
180
end
176
181
# As above, but taking an array of functions and returning a single shlib
177
182
function compile_shlib (funcs:: Union{Array,Tuple} , path:: String = " ./" ;
178
183
filename = " libfoo" ,
179
184
demangle = true ,
180
185
cflags = ` ` ,
186
+ target:: StaticTarget = StaticTarget (),
181
187
kwargs...
182
188
)
183
189
for func in funcs
184
190
f, types = func
185
191
tt = Base. to_tuple_type (types)
186
192
isconcretetype (tt) || error (" input type signature `$types ` is not concrete" )
187
193
188
- rt = last (only (native_code_typed (f, tt)))
194
+ rt = last (only (static_code_typed (f, tt; target, kwargs ... )))
189
195
isconcretetype (rt) || error (" `$f$types ` did not infer to a concrete type. Got `$rt `" )
190
196
nativetype = isprimitivetype (rt) || isa (rt, Ptr)
191
197
nativetype || @warn " Return type `$rt ` of `$f$types ` does not appear to be a native type. Consider returning only a single value of a native machine type (i.e., a single float, int/uint, bool, or pointer). \n\n Ignoring this warning may result in Undefined Behavior!"
192
198
end
193
199
194
- generate_shlib (funcs, true , path, filename; demangle, cflags, kwargs... )
200
+ generate_shlib (funcs, path, filename; demangle, cflags, target , kwargs... )
195
201
196
202
joinpath (abspath (path), filename * " ." * Libdl. dlext)
197
203
end
198
-
204
+
199
205
200
206
"""
201
207
```julia
@@ -281,12 +287,11 @@ generate_executable(f, tt, args...; kwargs...) = generate_executable(((f, tt),),
281
287
function generate_executable (funcs:: Union{Array,Tuple} , path= tempname (), name= fix_name (first (first (funcs))), filename= name;
282
288
demangle = true ,
283
289
cflags = ` ` ,
290
+ target:: StaticTarget = StaticTarget (),
284
291
kwargs...
285
292
)
286
- lib_path = joinpath (path, " $filename .$(Libdl. dlext) " )
287
293
exec_path = joinpath (path, filename)
288
- external = true
289
- _, obj_path = generate_obj (funcs, external, path, filename; demangle, kwargs... )
294
+ _, obj_path = generate_obj (funcs, path, filename; demangle, target, kwargs... )
290
295
# Pick a compiler
291
296
cc = Sys. isapple () ? ` cc` : clang ()
292
297
# Compile!
318
323
319
324
"""
320
325
```julia
321
- generate_shlib(f::Function, tt, [external::Bool=true], [ path::String], [name], [filename]; kwargs...)
322
- generate_shlib(funcs::Array, [external::Bool=true], [ path::String], [filename::String]; demangle=true, kwargs...)
326
+ generate_shlib(f::Function, tt, [path::String], [name], [filename]; kwargs...)
327
+ generate_shlib(funcs::Array, [path::String], [filename::String]; demangle=true, target::StaticTarget=StaticTarget() , kwargs...)
323
328
```
324
329
Low level interface for compiling a shared object / dynamically loaded library
325
330
(`.so` / `.dylib`) for function `f` given a tuple type `tt` characterizing
@@ -356,19 +361,20 @@ julia> ccall(("test", "example/test.dylib"), Float64, (Int64,), 100_000)
356
361
5.2564961094956075
357
362
```
358
363
"""
359
- function generate_shlib (f:: Function , tt, external :: Bool = true , path:: String = tempname (), name= fix_name (f), filename= name; kwargs... )
360
- generate_shlib (((f, tt),), external, path, filename; kwargs... )
364
+ function generate_shlib (f:: Function , tt, path:: String = tempname (), name= fix_name (f), filename= name; target = StaticTarget (), kwargs... )
365
+ generate_shlib (((f, tt),), path, filename; target, kwargs... )
361
366
end
362
367
# As above, but taking an array of functions and returning a single shlib
363
- function generate_shlib (funcs:: Union{Array,Tuple} , external :: Bool = true , path:: String = tempname (), filename:: String = " libfoo" ;
368
+ function generate_shlib (funcs:: Union{Array,Tuple} , path:: String = tempname (), filename:: String = " libfoo" ;
364
369
demangle = true ,
365
370
cflags = ` ` ,
371
+ target:: StaticTarget = StaticTarget (),
366
372
kwargs...
367
373
)
368
374
369
375
lib_path = joinpath (path, " $filename .$(Libdl. dlext) " )
370
376
371
- _, obj_path = generate_obj (funcs, external, path, filename; demangle, kwargs... )
377
+ _, obj_path = generate_obj (funcs, path, filename; target, demangle, kwargs... )
372
378
# Pick a Clang
373
379
cc = Sys. isapple () ? ` cc` : clang ()
374
380
# Compile!
@@ -377,27 +383,27 @@ function generate_shlib(funcs::Union{Array,Tuple}, external::Bool=true, path::St
377
383
path, name
378
384
end
379
385
380
- function native_code_llvm (@nospecialize (func), @nospecialize (types); kwargs... )
381
- job, kwargs = native_job (func, types, true ; kwargs... )
386
+ function static_code_llvm (@nospecialize (func), @nospecialize (types); target :: StaticTarget = StaticTarget (), kwargs... )
387
+ job, kwargs = static_job (func, types; target, kwargs... )
382
388
GPUCompiler. code_llvm (stdout , job; kwargs... )
383
389
end
384
390
385
- function native_code_typed (@nospecialize (func), @nospecialize (types); kwargs... )
386
- job, kwargs = native_job (func, types, true ; kwargs... )
391
+ function static_code_typed (@nospecialize (func), @nospecialize (types); target :: StaticTarget = StaticTarget (), kwargs... )
392
+ job, kwargs = static_job (func, types; target, kwargs... )
387
393
GPUCompiler. code_typed (job; kwargs... )
388
394
end
389
395
390
- function native_code_native (@nospecialize (f), @nospecialize (tt), fname= fix_name (f); kwargs... )
391
- job, kwargs = native_job (f, tt, true ; fname, kwargs... )
396
+ function static_code_native (@nospecialize (f), @nospecialize (tt), fname= fix_name (f); target :: StaticTarget = StaticTarget (), kwargs... )
397
+ job, kwargs = static_job (f, tt; fname, target , kwargs... )
392
398
GPUCompiler. code_native (stdout , job; kwargs... )
393
399
end
394
400
395
401
# Return an LLVM module
396
- function native_llvm_module (f, tt, name= fix_name (f); demangle, kwargs... )
402
+ function static_llvm_module (f, tt, name= fix_name (f); demangle, target :: StaticTarget = StaticTarget () , kwargs... )
397
403
if ! demangle
398
404
name = " julia_" * name
399
405
end
400
- job, kwargs = native_job (f, tt, true ; name, kwargs... )
406
+ job, kwargs = static_job (f, tt; name, target , kwargs... )
401
407
m = GPUCompiler. JuliaContext () do context
402
408
m, _ = GPUCompiler. codegen (:llvm , job; strip= true , only_entry= false , validate= false )
403
409
locate_pointers_and_runtime_calls (m)
@@ -407,14 +413,14 @@ function native_llvm_module(f, tt, name=fix_name(f); demangle, kwargs...)
407
413
end
408
414
409
415
# Return an LLVM module for multiple functions
410
- function native_llvm_module (funcs:: Union{Array,Tuple} ; demangle= true , kwargs... )
416
+ function static_llvm_module (funcs:: Union{Array,Tuple} ; demangle= true , target :: StaticTarget = StaticTarget () , kwargs... )
411
417
f,tt = funcs[1 ]
412
418
mod = GPUCompiler. JuliaContext () do context
413
419
name_f = fix_name (f)
414
420
if ! demangle
415
421
name_f = " julia_" * name_f
416
422
end
417
- job, kwargs = native_job (f, tt, true ; name = name_f, kwargs... )
423
+ job, kwargs = static_job (f, tt; name = name_f, target , kwargs... )
418
424
mod,_ = GPUCompiler. codegen (:llvm , job; strip= true , only_entry= false , validate= false )
419
425
if length (funcs) > 1
420
426
for func in funcs[2 : end ]
@@ -423,7 +429,7 @@ function native_llvm_module(funcs::Union{Array,Tuple}; demangle=true, kwargs...)
423
429
if ! demangle
424
430
name_f = " julia_" * name_f
425
431
end
426
- job, kwargs = native_job (f, tt, true ; name = name_f, kwargs... )
432
+ job, kwargs = static_job (f, tt; name = name_f, target , kwargs... )
427
433
tmod,_ = GPUCompiler. codegen (:llvm , job; strip= true , only_entry= false , validate= false )
428
434
link! (mod,tmod)
429
435
end
458
464
459
465
"""
460
466
```julia
461
- generate_obj(f, tt, external::Bool, path::String = tempname(), filenamebase::String="obj";
467
+ generate_obj(f, tt, path::String = tempname(), filenamebase::String="obj";
462
468
target = (),
463
469
demangle = true,
464
470
strip_llvm = false,
498
504
499
505
"""
500
506
```julia
501
- generate_obj(funcs::Union{Array,Tuple}, external::Bool, path::String = tempname(), filenamebase::String="obj";
507
+ generate_obj(funcs::Union{Array,Tuple}, path::String = tempname(), filenamebase::String="obj";
502
508
target = (),
503
509
demangle =false,
504
510
strip_llvm = false,
@@ -514,18 +520,19 @@ which will be compiled.
514
520
This is a named tuple with fields `triple`, `cpu`, and `features` (each of these are strings).
515
521
The defaults compile to the native target.
516
522
"""
517
- function generate_obj (funcs:: Union{Array,Tuple} , external :: Bool , path:: String = tempname (), filenamebase:: String = " obj" ;
523
+ function generate_obj (funcs:: Union{Array,Tuple} , path:: String = tempname (), filenamebase:: String = " obj" ;
518
524
demangle = true ,
519
525
strip_llvm = false ,
520
526
strip_asm = true ,
521
527
opt_level = 3 ,
528
+ target:: StaticTarget = StaticTarget (),
522
529
kwargs... )
523
530
f, tt = funcs[1 ]
524
531
mkpath (path)
525
532
obj_path = joinpath (path, " $filenamebase .o" )
526
- mod = native_llvm_module (funcs; demangle, kwargs... )
533
+ mod = static_llvm_module (funcs; demangle, kwargs... )
527
534
obj = GPUCompiler. JuliaContext () do ctx
528
- fakejob, _ = native_job (f, tt, external; kwargs... )
535
+ fakejob, _ = static_job (f, tt; target, kwargs... )
529
536
obj, _ = GPUCompiler. emit_asm (fakejob, mod; strip= strip_asm, validate= false , format= LLVM. API. LLVMObjectFile)
530
537
obj
531
538
end
0 commit comments