@@ -166,68 +166,23 @@ const __llvm_initialized = Ref(false)
166
166
runtime_fns = LLVM. name .(defs (runtime))
167
167
end
168
168
169
- @timeit_debug to " LLVM middle-end" begin
170
- # target-specific libraries
169
+ @timeit_debug to " Library linking" begin
171
170
if libraries
171
+ # target-specific libraries
172
172
undefined_fns = LLVM. name .(decls (ir))
173
173
@timeit_debug to " target libraries" link_libraries! (job, ir, undefined_fns)
174
- end
175
-
176
- if optimize
177
- @timeit_debug to " optimization" optimize! (job, ir)
178
-
179
- # optimization may have replaced functions, so look the entry point up again
180
- entry = functions (ir)[entry_fn]
181
- end
182
174
183
- if libraries
184
- undefined_fns = LLVM. name .(decls (ir))
175
+ # GPU run-time library
185
176
if any (fn -> fn in runtime_fns, undefined_fns)
186
177
@timeit_debug to " runtime library" link_library! (ir, runtime)
187
178
end
188
179
end
189
-
190
- if ccall (:jl_is_debugbuild , Cint, ()) == 1
191
- @timeit_debug to " verification" verify (ir)
192
- end
193
-
194
- if only_entry
195
- # replace non-entry function definitions with a declaration
196
- for f in functions (ir)
197
- f == entry && continue
198
- isdeclaration (f) && continue
199
- LLVM. isintrinsic (f) && continue
200
- empty! (f)
201
- end
202
- end
203
-
204
- # remove everything except for the entry and any exported global variables
205
- @timeit_debug to " clean-up" begin
206
- exports = String[entry_fn]
207
- for gvar in globals (ir)
208
- push! (exports, LLVM. name (gvar))
209
- end
210
-
211
- ModulePassManager () do pm
212
- internalize! (pm, exports)
213
-
214
- # eliminate all unused internal functions
215
- global_optimizer! (pm)
216
- global_dce! (pm)
217
- strip_dead_prototypes! (pm)
218
-
219
- # merge constants (such as exception messages) from the runtime
220
- constant_merge! (pm)
221
-
222
- run! (pm, ir)
223
- end
224
- end
225
180
end
226
181
227
- entry = finish_module! (job, ir, entry)
228
-
229
182
# deferred code generation
230
- if ! only_entry && deferred_codegen && haskey (functions (ir), " deferred_codegen" )
183
+ do_deferred_codegen = ! only_entry && deferred_codegen &&
184
+ haskey (functions (ir), " deferred_codegen" )
185
+ if do_deferred_codegen
231
186
dyn_marker = functions (ir)[" deferred_codegen" ]
232
187
233
188
cache = Dict {CompilerJob, String} (job => entry_fn)
@@ -257,7 +212,7 @@ const __llvm_initialized = Ref(false)
257
212
for dyn_job in keys (worklist)
258
213
# cached compilation
259
214
dyn_entry_fn = get! (cache, dyn_job) do
260
- dyn_ir, dyn_meta = codegen (:llvm , dyn_job; optimize,
215
+ dyn_ir, dyn_meta = codegen (:llvm , dyn_job; optimize= false ,
261
216
deferred_codegen= false , parent_job= job)
262
217
dyn_entry_fn = LLVM. name (dyn_meta. entry)
263
218
merge! (compiled, dyn_meta. compiled)
@@ -281,28 +236,70 @@ const __llvm_initialized = Ref(false)
281
236
end
282
237
end
283
238
284
- ModulePassManager () do pm
285
- # inline and optimize the call to the deferred code. in particular we want to
286
- # remove unnecessary alloca's that are created by pass-by-ref semantics.
287
- instruction_combining! (pm)
288
- always_inliner! (pm)
289
- scalar_repl_aggregates_ssa! (pm)
290
- promote_memory_to_register! (pm)
291
- gvn! (pm)
239
+ # all deferred compilations should have been resolved
240
+ @compiler_assert isempty (uses (dyn_marker)) job
241
+ unsafe_delete! (ir, dyn_marker)
242
+ end
292
243
293
- # merge constants (such as exception messages) from each entry
294
- constant_merge! (pm )
244
+ @timeit_debug to " IR post-processing " begin
245
+ entry = finish_module! (job, ir, entry )
295
246
296
- # merge duplicate functions, since each compilation invocation emits everything
297
- # XXX : ideally we want to avoid emitting these in the first place
298
- merge_functions! (pm)
247
+ if optimize
248
+ @timeit_debug to " optimization" optimize! (job, ir)
299
249
300
- run! (pm, ir)
250
+ # optimization may have replaced functions, so look the entry point up again
251
+ entry = functions (ir)[entry_fn]
301
252
end
302
253
303
- # all deferred compilations should have been resolved
304
- @compiler_assert isempty (uses (dyn_marker)) job
305
- unsafe_delete! (ir, dyn_marker)
254
+ if ccall (:jl_is_debugbuild , Cint, ()) == 1
255
+ @timeit_debug to " verification" verify (ir)
256
+ end
257
+
258
+ @timeit_debug to " clean-up" begin
259
+ # replace non-entry function definitions with a declaration
260
+ if only_entry
261
+ for f in functions (ir)
262
+ f == entry && continue
263
+ isdeclaration (f) && continue
264
+ LLVM. isintrinsic (f) && continue
265
+ empty! (f)
266
+ end
267
+ end
268
+
269
+ # remove everything except for the entry and any exported global variables
270
+ exports = String[entry_fn]
271
+ for gvar in globals (ir)
272
+ push! (exports, LLVM. name (gvar))
273
+ end
274
+
275
+ ModulePassManager () do pm
276
+ internalize! (pm, exports)
277
+
278
+ # eliminate all unused internal functions
279
+ global_optimizer! (pm)
280
+ global_dce! (pm)
281
+ strip_dead_prototypes! (pm)
282
+
283
+ # merge constants (such as exception messages)
284
+ constant_merge! (pm)
285
+
286
+ if do_deferred_codegen
287
+ # inline and optimize the call to the deferred code. in particular we want to
288
+ # remove unnecessary alloca's that are created by pass-by-ref semantics.
289
+ instruction_combining! (pm)
290
+ always_inliner! (pm)
291
+ scalar_repl_aggregates_ssa! (pm)
292
+ promote_memory_to_register! (pm)
293
+ gvn! (pm)
294
+
295
+ # merge duplicate functions, since each compilation invocation emits everything
296
+ # XXX : ideally we want to avoid emitting these in the first place
297
+ merge_functions! (pm)
298
+ end
299
+
300
+ run! (pm, ir)
301
+ end
302
+ end
306
303
end
307
304
308
305
return ir, (; entry, compiled)
0 commit comments