@@ -52,40 +52,37 @@ export compile
52
52
const compile_hook = Ref {Union{Nothing,Function}} (nothing )
53
53
54
54
"""
55
- compile(target::Symbol, job::CompilerJob;
56
- libraries=true, optimize=true, strip=false, ...)
55
+ compile(target::Symbol, job::CompilerJob; kwargs...)
57
56
58
57
Compile a function `f` invoked with types `tt` for device capability `cap` to one of the
59
58
following formats as specified by the `target` argument: `:julia` for Julia IR, `:llvm` for
60
59
LLVM IR and `:asm` for machine code.
61
60
62
61
The following keyword arguments are supported:
63
- - `libraries`: link the GPU runtime and `libdevice` libraries (if required)
64
- - `optimize`: optimize the code (default: true)
65
- - `cleanup`: run cleanup passes on the code (default: true)
62
+ - `toplevel`: indicates that this compilation is the outermost invocation of the compiler
63
+ (default: true)
64
+ - `libraries`: link the GPU runtime and `libdevice` libraries (default: true, if toplevel)
65
+ - `optimize`: optimize the code (default: true, if toplevel)
66
+ - `cleanup`: run cleanup passes on the code (default: true, if toplevel)
67
+ - `validate`: enable optional validation of input and outputs (default: true, if toplevel)
66
68
- `strip`: strip non-functional metadata and debug information (default: false)
67
- - `validate`: enable optional validation of input and outputs (default: true)
68
69
- `only_entry`: only keep the entry function, remove all others (default: false).
69
70
This option is only for internal use, to implement reflection's `dump_module`.
70
71
71
72
Other keyword arguments can be found in the documentation of [`cufunction`](@ref).
72
73
"""
73
- function compile (target:: Symbol , @nospecialize (job:: CompilerJob );
74
- libraries:: Bool = true , toplevel:: Bool = true ,
75
- optimize:: Bool = true , cleanup:: Bool = true , strip:: Bool = false ,
76
- validate:: Bool = true , only_entry:: Bool = false )
74
+ function compile (target:: Symbol , @nospecialize (job:: CompilerJob ); kwargs... )
77
75
if compile_hook[] != = nothing
78
76
compile_hook[](job)
79
77
end
80
78
81
- return codegen (target, job;
82
- libraries, toplevel, optimize, cleanup, strip, validate, only_entry)
79
+ return codegen (target, job; kwargs... )
83
80
end
84
81
85
- function codegen (output:: Symbol , @nospecialize (job:: CompilerJob );
86
- libraries:: Bool = true , toplevel :: Bool = true , optimize :: Bool = true ,
87
- cleanup :: Bool = true , strip:: Bool = false , validate :: Bool = true ,
88
- only_entry :: Bool = false , parent_job:: Union{Nothing, CompilerJob} = nothing )
82
+ function codegen (output:: Symbol , @nospecialize (job:: CompilerJob ); toplevel :: Bool = true ,
83
+ libraries:: Bool = toplevel, optimize :: Bool = toplevel, cleanup :: Bool = toplevel ,
84
+ validate :: Bool = toplevel , strip:: Bool = false , only_entry :: Bool = false ,
85
+ parent_job:: Union{Nothing, CompilerJob} = nothing )
89
86
if context (; throw_error= false ) === nothing
90
87
error (" No active LLVM context. Use `JuliaContext()` do-block syntax to create one." )
91
88
end
159
156
160
157
const __llvm_initialized = Ref (false )
161
158
162
- @locked function emit_llvm (@nospecialize (job:: CompilerJob );
163
- libraries:: Bool = true , toplevel :: Bool = true , optimize :: Bool = true ,
164
- cleanup :: Bool = true , only_entry:: Bool = false , validate :: Bool = true )
159
+ @locked function emit_llvm (@nospecialize (job:: CompilerJob ); toplevel :: Bool ,
160
+ libraries:: Bool , optimize :: Bool , cleanup :: Bool ,
161
+ validate :: Bool , only_entry:: Bool )
165
162
if ! __llvm_initialized[]
166
163
InitializeAllTargets ()
167
164
InitializeAllTargetInfos ()
@@ -186,8 +183,7 @@ const __llvm_initialized = Ref(false)
186
183
entry = finish_module! (job, ir, entry)
187
184
188
185
# deferred code generation
189
- has_deferred_jobs = ! only_entry && toplevel &&
190
- haskey (functions (ir), " deferred_codegen" )
186
+ has_deferred_jobs = toplevel && ! only_entry && haskey (functions (ir), " deferred_codegen" )
191
187
jobs = Dict {CompilerJob, String} (job => entry_fn)
192
188
if has_deferred_jobs
193
189
dyn_marker = functions (ir)[" deferred_codegen" ]
@@ -225,10 +221,8 @@ const __llvm_initialized = Ref(false)
225
221
for dyn_job in keys (worklist)
226
222
# cached compilation
227
223
dyn_entry_fn = get! (jobs, dyn_job) do
228
- dyn_ir, dyn_meta = codegen (:llvm , dyn_job; validate= false ,
229
- optimize= false ,
230
- toplevel= false ,
231
- parent_job= job)
224
+ dyn_ir, dyn_meta = codegen (:llvm , dyn_job; toplevel= false ,
225
+ parent_job= job)
232
226
dyn_entry_fn = LLVM. name (dyn_meta. entry)
233
227
merge! (compiled, dyn_meta. compiled)
234
228
@assert context (dyn_ir) == context (ir)
@@ -264,27 +258,24 @@ const __llvm_initialized = Ref(false)
264
258
unsafe_delete! (ir, dyn_marker)
265
259
end
266
260
267
- if toplevel
268
- # always preload the runtime, and do so early; it cannot be part of any
269
- # timing block because it recurses into the compiler
270
- if ! uses_julia_runtime (job) && libraries
261
+ if libraries
262
+ # load the runtime outside of a timing block (because it recurses into the compiler)
263
+ if ! uses_julia_runtime (job)
271
264
runtime = load_runtime (job)
272
265
runtime_fns = LLVM. name .(defs (runtime))
273
266
runtime_intrinsics = [" julia.gc_alloc_obj" ]
274
267
end
275
268
276
269
@timeit_debug to " Library linking" begin
277
- if libraries
278
- # target-specific libraries
279
- undefined_fns = LLVM. name .(decls (ir))
280
- @timeit_debug to " target libraries" link_libraries! (job, ir, undefined_fns)
281
-
282
- # GPU run-time library
283
- if ! uses_julia_runtime (job) && any (fn -> fn in runtime_fns ||
284
- fn in runtime_intrinsics,
285
- undefined_fns)
286
- @timeit_debug to " runtime library" link_library! (ir, runtime)
287
- end
270
+ # target-specific libraries
271
+ undefined_fns = LLVM. name .(decls (ir))
272
+ @timeit_debug to " target libraries" link_libraries! (job, ir, undefined_fns)
273
+
274
+ # GPU run-time library
275
+ if ! uses_julia_runtime (job) && any (fn -> fn in runtime_fns ||
276
+ fn in runtime_intrinsics,
277
+ undefined_fns)
278
+ @timeit_debug to " runtime library" link_library! (ir, runtime)
288
279
end
289
280
end
290
281
end
@@ -434,7 +425,7 @@ const __llvm_initialized = Ref(false)
434
425
end
435
426
436
427
@locked function emit_asm (@nospecialize (job:: CompilerJob ), ir:: LLVM.Module ;
437
- strip:: Bool = false , validate:: Bool = true , format:: LLVM.API.LLVMCodeGenFileType )
428
+ strip:: Bool , validate:: Bool , format:: LLVM.API.LLVMCodeGenFileType )
438
429
# NOTE: strip after validation to get better errors
439
430
if strip
440
431
@timeit_debug to " Debug info removal" strip_debuginfo! (ir)
0 commit comments