@@ -219,8 +219,12 @@ const __llvm_initialized = Ref(false)
219219 internalize! (pm, exports)
220220
221221 # eliminate all unused internal functions
222+ add! (pm, ModulePass (" ExternalizeJuliaGlobals" ,
223+ externalize_julia_globals!))
222224 global_optimizer! (pm)
223225 global_dce! (pm)
226+ add! (pm, ModulePass (" InternalizeJuliaGlobals" ,
227+ internalize_julia_globals!))
224228 strip_dead_prototypes! (pm)
225229
226230 # merge constants (such as exception messages) from the runtime
@@ -309,6 +313,39 @@ const __llvm_initialized = Ref(false)
309313 return ir, (; entry, compiled)
310314end
311315
316+ # Protect null globals from being killed and inlined
317+ function externalize_julia_globals! (mod:: LLVM.Module )
318+ changed = false
319+ for gbl in LLVM. globals (mod)
320+ if LLVM. linkage (gbl) == LLVM. API. LLVMInternalLinkage &&
321+ typeof (LLVM. initializer (gbl)) <: LLVM.PointerNull &&
322+ (startswith (LLVM. name (gbl), " jl_global" ) ||
323+ startswith (LLVM. name (gbl), " jl_sym" ))
324+ LLVM. linkage! (gbl, LLVM. API. LLVMExternalLinkage)
325+ LLVM. initializer! (gbl, nothing )
326+ LLVM. extinit! (gbl, true )
327+ changed = true
328+ end
329+ end
330+ changed
331+ end
332+ # And reset the back later
333+ function internalize_julia_globals! (mod:: LLVM.Module )
334+ changed = false
335+ for gbl in LLVM. globals (mod)
336+ if LLVM. linkage (gbl) == LLVM. API. LLVMExternalLinkage &&
337+ LLVM. initializer (gbl) === nothing &&
338+ (startswith (LLVM. name (gbl), " jl_global" ) ||
339+ startswith (LLVM. name (gbl), " jl_sym" ))
340+ LLVM. extinit! (gbl, false )
341+ LLVM. initializer! (gbl, null (eltype (llvmtype (gbl))))
342+ LLVM. linkage! (gbl, LLVM. API. LLVMInternalLinkage)
343+ changed = true
344+ end
345+ end
346+ changed
347+ end
348+
312349@locked function emit_asm (@nospecialize (job:: CompilerJob ), ir:: LLVM.Module ;
313350 strip:: Bool = false , validate:: Bool = true , format:: LLVM.API.LLVMCodeGenFileType )
314351 finish_module! (job, ir)
0 commit comments