@@ -179,6 +179,25 @@ const __llvm_initialized = Ref(false)
179
179
end
180
180
end
181
181
182
+ # mark everything internal except for the entry and any exported global variables.
183
+ # this makes sure that the optimizer can, e.g., touch function signatures.
184
+ ModulePassManager () do pm
185
+ # NOTE: this needs to happen after linking libraries to remove unused functions,
186
+ # but before deferred codegen so that all kernels remain available.
187
+ exports = String[entry_fn]
188
+ for gvar in globals (ir)
189
+ if linkage (gvar) == LLVM. API. LLVMExternalLinkage
190
+ push! (exports, LLVM. name (gvar))
191
+ end
192
+ end
193
+ internalize! (pm, exports)
194
+ run! (pm, ir)
195
+ end
196
+
197
+ # finalize the current module. this needs to happen before linking deferred modules,
198
+ # since those modules have been finalized themselves, and we don't want to re-finalize.
199
+ entry = finish_module! (job, ir, entry)
200
+
182
201
# deferred code generation
183
202
do_deferred_codegen = ! only_entry && deferred_codegen &&
184
203
haskey (functions (ir), " deferred_codegen" )
@@ -242,39 +261,9 @@ const __llvm_initialized = Ref(false)
242
261
end
243
262
244
263
@timeit_debug to " IR post-processing" begin
245
- entry = finish_module! (job, ir, entry)
246
-
247
- if optimize
248
- @timeit_debug to " optimization" optimize! (job, ir)
249
-
250
- # optimization may have replaced functions, so look the entry point up again
251
- entry = functions (ir)[entry_fn]
252
- end
253
-
254
- if ccall (:jl_is_debugbuild , Cint, ()) == 1
255
- @timeit_debug to " verification" verify (ir)
256
- end
257
-
264
+ # some early clean-up to reduce the amount of code to optimize
258
265
@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
266
ModulePassManager () do pm
276
- internalize! (pm, exports)
277
-
278
267
# eliminate all unused internal functions
279
268
global_optimizer! (pm)
280
269
global_dce! (pm)
@@ -283,9 +272,20 @@ const __llvm_initialized = Ref(false)
283
272
# merge constants (such as exception messages)
284
273
constant_merge! (pm)
285
274
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.
275
+ run! (pm, ir)
276
+ end
277
+ end
278
+
279
+ if optimize
280
+ @timeit_debug to " optimization" begin
281
+ optimize! (job, ir)
282
+
283
+ # deferred codegen has some special optimization requirements,
284
+ # which also need to happen _after_ regular optimization.
285
+ # XXX : make these part of the optimizer pipeline?
286
+ do_deferred_codegen && ModulePassManager () do pm
287
+ # inline and optimize the call to e deferred code. in particular we want
288
+ # to remove unnecessary alloca's created by pass-by-ref semantics.
289
289
instruction_combining! (pm)
290
290
always_inliner! (pm)
291
291
scalar_repl_aggregates_ssa! (pm)
@@ -295,11 +295,30 @@ const __llvm_initialized = Ref(false)
295
295
# merge duplicate functions, since each compilation invocation emits everything
296
296
# XXX : ideally we want to avoid emitting these in the first place
297
297
merge_functions! (pm)
298
+
299
+ run! (pm, ir)
298
300
end
301
+ end
299
302
300
- run! (pm, ir)
303
+ # optimization may have replaced functions, so look the entry point up again
304
+ entry = functions (ir)[entry_fn]
305
+ end
306
+
307
+ # replace non-entry function definitions with a declaration
308
+ # NOTE: we can't do this before optimization, because the definitions of called
309
+ # functions may affect optimization.
310
+ if only_entry
311
+ for f in functions (ir)
312
+ f == entry && continue
313
+ isdeclaration (f) && continue
314
+ LLVM. isintrinsic (f) && continue
315
+ empty! (f)
301
316
end
302
317
end
318
+
319
+ if ccall (:jl_is_debugbuild , Cint, ()) == 1
320
+ @timeit_debug to " verification" verify (ir)
321
+ end
303
322
end
304
323
305
324
return ir, (; entry, compiled)
0 commit comments