@@ -96,7 +96,7 @@ typedef struct {
9696 std::vector<jl_code_instance_t *> jl_external_to_llvm;
9797} jl_native_code_desc_t ;
9898
99- extern " C" JL_DLLEXPORT
99+ extern " C" JL_DLLEXPORT_CODEGEN
100100void jl_get_function_id_impl (void *native_code, jl_code_instance_t *codeinst,
101101 int32_t *func_idx, int32_t *specfunc_idx)
102102{
@@ -110,7 +110,7 @@ void jl_get_function_id_impl(void *native_code, jl_code_instance_t *codeinst,
110110 }
111111}
112112
113- extern " C" JL_DLLEXPORT
113+ extern " C" JL_DLLEXPORT_CODEGEN
114114void jl_get_llvm_gvs_impl (void *native_code, arraylist_t *gvs)
115115{
116116 // map a memory location (jl_value_t or jl_binding_t) to a GlobalVariable
@@ -119,7 +119,7 @@ void jl_get_llvm_gvs_impl(void *native_code, arraylist_t *gvs)
119119 memcpy (gvs->items , data->jl_value_to_llvm .data (), gvs->len * sizeof (void *));
120120}
121121
122- extern " C" JL_DLLEXPORT
122+ extern " C" JL_DLLEXPORT_CODEGEN
123123void jl_get_llvm_external_fns_impl (void *native_code, arraylist_t *external_fns)
124124{
125125 jl_native_code_desc_t *data = (jl_native_code_desc_t *)native_code;
@@ -128,7 +128,7 @@ void jl_get_llvm_external_fns_impl(void *native_code, arraylist_t *external_fns)
128128 external_fns->len * sizeof (jl_code_instance_t *));
129129}
130130
131- extern " C" JL_DLLEXPORT
131+ extern " C" JL_DLLEXPORT_CODEGEN
132132LLVMOrcThreadSafeModuleRef jl_get_llvm_module_impl (void *native_code)
133133{
134134 jl_native_code_desc_t *data = (jl_native_code_desc_t *)native_code;
@@ -138,7 +138,7 @@ LLVMOrcThreadSafeModuleRef jl_get_llvm_module_impl(void *native_code)
138138 return NULL ;
139139}
140140
141- extern " C" JL_DLLEXPORT
141+ extern " C" JL_DLLEXPORT_CODEGEN
142142GlobalValue* jl_get_llvm_function_impl (void *native_code, uint32_t idx)
143143{
144144 jl_native_code_desc_t *data = (jl_native_code_desc_t *)native_code;
@@ -160,10 +160,12 @@ static void emit_offset_table(Module &mod, const std::vector<GlobalValue*> &vars
160160 addrs[i] = ConstantExpr::getBitCast (var, T_psize);
161161 }
162162 ArrayType *vars_type = ArrayType::get (T_psize, nvars);
163- new GlobalVariable (mod, vars_type, true ,
163+ auto GV = new GlobalVariable (mod, vars_type, true ,
164164 GlobalVariable::ExternalLinkage,
165165 ConstantArray::get (vars_type, addrs),
166166 name);
167+ GV->setVisibility (GlobalValue::HiddenVisibility);
168+ GV->setDSOLocal (true );
167169}
168170
169171static bool is_safe_char (unsigned char c)
@@ -241,7 +243,7 @@ static void jl_ci_cache_lookup(const jl_cgparams_t &cgparams, jl_method_instance
241243 *src_out = jl_uncompress_ir (def, codeinst, (jl_value_t *)*src_out);
242244 }
243245 if (*src_out == NULL || !jl_is_code_info (*src_out)) {
244- if (cgparams.lookup != jl_rettype_inferred ) {
246+ if (cgparams.lookup != jl_rettype_inferred_addr ) {
245247 jl_error (" Refusing to automatically run type inference with custom cache lookup." );
246248 }
247249 else {
@@ -265,7 +267,7 @@ static void jl_ci_cache_lookup(const jl_cgparams_t &cgparams, jl_method_instance
265267// The `policy` flag switches between the default mode `0` and the extern mode `1` used by GPUCompiler.
266268// `_imaging_mode` controls if raw pointers can be embedded (e.g. the code will be loaded into the same session).
267269// `_external_linkage` create linkages between pkgimages.
268- extern " C" JL_DLLEXPORT
270+ extern " C" JL_DLLEXPORT_CODEGEN
269271void *jl_create_native_impl (jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvmmod, const jl_cgparams_t *cgparams, int _policy, int _imaging_mode, int _external_linkage, size_t _world)
270272{
271273 JL_TIMING (NATIVE_AOT, NATIVE_Create);
@@ -432,6 +434,7 @@ void *jl_create_native_impl(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvm
432434 G->setInitializer (ConstantPointerNull::get (cast<PointerType>(G->getValueType ())));
433435 G->setLinkage (GlobalValue::ExternalLinkage);
434436 G->setVisibility (GlobalValue::HiddenVisibility);
437+ G->setDSOLocal (true );
435438 data->jl_sysimg_gvars .push_back (G);
436439 }
437440 CreateNativeGlobals += gvars.size ();
@@ -456,6 +459,7 @@ void *jl_create_native_impl(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvm
456459 if (!G.isDeclaration ()) {
457460 G.setLinkage (GlobalValue::ExternalLinkage);
458461 G.setVisibility (GlobalValue::HiddenVisibility);
462+ G.setDSOLocal (true );
459463 makeSafeName (G);
460464 if (TT.isOSWindows () && TT.getArch () == Triple::x86_64) {
461465 // Add unwind exception personalities to functions to handle async exceptions
@@ -523,6 +527,7 @@ static GlobalVariable *emit_shard_table(Module &M, Type *T_size, Type *T_psize,
523527 auto gv = new GlobalVariable (M, T_size, constant,
524528 GlobalValue::ExternalLinkage, nullptr , name + suffix);
525529 gv->setVisibility (GlobalValue::HiddenVisibility);
530+ gv->setDSOLocal (true );
526531 return gv;
527532 };
528533 auto table = tables.data () + i * sizeof (jl_image_shard_t ) / sizeof (void *);
@@ -540,6 +545,7 @@ static GlobalVariable *emit_shard_table(Module &M, Type *T_size, Type *T_psize,
540545 auto tables_gv = new GlobalVariable (M, tables_arr->getType (), false ,
541546 GlobalValue::ExternalLinkage, tables_arr, " jl_shard_tables" );
542547 tables_gv->setVisibility (GlobalValue::HiddenVisibility);
548+ tables_gv->setDSOLocal (true );
543549 return tables_gv;
544550}
545551
@@ -550,12 +556,15 @@ static GlobalVariable *emit_ptls_table(Module &M, Type *T_size, Type *T_psize) {
550556 new GlobalVariable (M, T_size, false , GlobalValue::ExternalLinkage, Constant::getNullValue (T_size), " jl_pgcstack_key_slot" ),
551557 new GlobalVariable (M, T_size, false , GlobalValue::ExternalLinkage, Constant::getNullValue (T_size), " jl_tls_offset" ),
552558 };
553- for (auto &gv : ptls_table)
559+ for (auto &gv : ptls_table) {
554560 cast<GlobalVariable>(gv)->setVisibility (GlobalValue::HiddenVisibility);
561+ cast<GlobalVariable>(gv)->setDSOLocal (true );
562+ }
555563 auto ptls_table_arr = ConstantArray::get (ArrayType::get (T_psize, ptls_table.size ()), ptls_table);
556564 auto ptls_table_gv = new GlobalVariable (M, ptls_table_arr->getType (), false ,
557565 GlobalValue::ExternalLinkage, ptls_table_arr, " jl_ptls_table" );
558566 ptls_table_gv->setVisibility (GlobalValue::HiddenVisibility);
567+ ptls_table_gv->setDSOLocal (true );
559568 return ptls_table_gv;
560569}
561570
@@ -1101,6 +1110,8 @@ static void materializePreserved(Module &M, Partition &partition) {
11011110 if (!Preserve.contains (&F)) {
11021111 F.deleteBody ();
11031112 F.setLinkage (GlobalValue::ExternalLinkage);
1113+ F.setVisibility (GlobalValue::HiddenVisibility);
1114+ F.setDSOLocal (true );
11041115 }
11051116 }
11061117 }
@@ -1109,6 +1120,8 @@ static void materializePreserved(Module &M, Partition &partition) {
11091120 if (!Preserve.contains (&GV)) {
11101121 GV.setInitializer (nullptr );
11111122 GV.setLinkage (GlobalValue::ExternalLinkage);
1123+ GV.setVisibility (GlobalValue::HiddenVisibility);
1124+ GV.setDSOLocal (true );
11121125 }
11131126 }
11141127 }
@@ -1130,7 +1143,8 @@ static void materializePreserved(Module &M, Partition &partition) {
11301143 GA.setAliasee (F);
11311144
11321145 DeletedAliases.push_back ({ &GA, F });
1133- } else {
1146+ }
1147+ else {
11341148 auto GV = new GlobalVariable (M, GA.getValueType (), false , GlobalValue::ExternalLinkage, Constant::getNullValue (GA.getValueType ()));
11351149 DeletedAliases.push_back ({ &GA, GV });
11361150 }
@@ -1197,26 +1211,24 @@ static void construct_vars(Module &M, Partition &partition) {
11971211 GlobalVariable::ExternalLinkage,
11981212 fidxs, " jl_fvar_idxs" );
11991213 fidxs_var->setVisibility (GlobalValue::HiddenVisibility);
1214+ fidxs_var->setDSOLocal (true );
12001215 auto gidxs = ConstantDataArray::get (M.getContext (), gvar_idxs);
12011216 auto gidxs_var = new GlobalVariable (M, gidxs->getType (), true ,
12021217 GlobalVariable::ExternalLinkage,
12031218 gidxs, " jl_gvar_idxs" );
12041219 gidxs_var->setVisibility (GlobalValue::HiddenVisibility);
1220+ gidxs_var->setDSOLocal (true );
12051221}
12061222
12071223// Materialization will leave many unused declarations, which multiversioning would otherwise clone.
12081224// This function removes them to avoid unnecessary cloning of declarations.
1209- static void dropUnusedDeclarations (Module &M) {
1210- SmallVector<GlobalValue *> unused;
1225+ // The GlobalDCEPass is much better at this, but we only care about removing unused
1226+ // declarations, not actually about seeing if code is dead (codegen knows it is live, by construction).
1227+ static void dropUnusedGlobals (Module &M) {
1228+ std::vector<GlobalValue *> unused;
12111229 for (auto &G : M.global_values ()) {
1212- if (G.isDeclaration ()) {
1213- if (G.use_empty ()) {
1214- unused.push_back (&G);
1215- } else {
1216- G.setDSOLocal (false ); // These are never going to be seen in the same module again
1217- G.setVisibility (GlobalValue::DefaultVisibility);
1218- }
1219- }
1230+ if (G.isDeclaration () && G.use_empty ())
1231+ unused.push_back (&G);
12201232 }
12211233 for (auto &G : unused)
12221234 G->eraseFromParent ();
@@ -1355,7 +1367,7 @@ static void add_output(Module &M, TargetMachine &TM, std::vector<std::string> &o
13551367 timers[i].construct .stopTimer ();
13561368
13571369 timers[i].deletion .startTimer ();
1358- dropUnusedDeclarations (*M);
1370+ dropUnusedGlobals (*M);
13591371 timers[i].deletion .stopTimer ();
13601372
13611373 add_output_impl (*M, TM, outputs_start + i * outcount, names_start + i * outcount,
@@ -1450,7 +1462,7 @@ static unsigned compute_image_thread_count(const ModuleInfo &info) {
14501462
14511463// takes the running content that has collected in the shadow module and dump it to disk
14521464// this builds the object file portion of the sysimage files for fast startup
1453- extern " C" JL_DLLEXPORT
1465+ extern " C" JL_DLLEXPORT_CODEGEN
14541466void jl_dump_native_impl (void *native_code,
14551467 const char *bc_fname, const char *unopt_bc_fname, const char *obj_fname,
14561468 const char *asm_fname,
@@ -1556,6 +1568,7 @@ void jl_dump_native_impl(void *native_code,
15561568 GlobalVariable::ExternalLinkage,
15571569 gidxs, " jl_gvar_idxs" );
15581570 gidxs_var->setVisibility (GlobalValue::HiddenVisibility);
1571+ gidxs_var->setDSOLocal (true );
15591572 idxs.clear ();
15601573 idxs.resize (data->jl_sysimg_fvars .size ());
15611574 std::iota (idxs.begin (), idxs.end (), 0 );
@@ -1564,6 +1577,7 @@ void jl_dump_native_impl(void *native_code,
15641577 GlobalVariable::ExternalLinkage,
15651578 fidxs, " jl_fvar_idxs" );
15661579 fidxs_var->setVisibility (GlobalValue::HiddenVisibility);
1580+ fidxs_var->setDSOLocal (true );
15671581 dataM->addModuleFlag (Module::Error, " julia.mv.suffix" , MDString::get (Context, " _0" ));
15681582
15691583 // reflect the address of the jl_RTLD_DEFAULT_handle variable
@@ -2004,7 +2018,7 @@ static RegisterPass<JuliaPipeline<0,true>> XS("juliaO0-sysimg", "Runs the entire
20042018static RegisterPass<JuliaPipeline<2 ,true >> YS (" julia-sysimg" , " Runs the entire julia pipeline (at -O2/sysimg mode)" , false , false );
20052019static RegisterPass<JuliaPipeline<3 ,true >> ZS (" juliaO3-sysimg" , " Runs the entire julia pipeline (at -O3/sysimg mode)" , false , false );
20062020
2007- extern " C" JL_DLLEXPORT
2021+ extern " C" JL_DLLEXPORT_CODEGEN
20082022void jl_add_optimization_passes_impl (LLVMPassManagerRef PM, int opt_level, int lower_intrinsics) {
20092023 addOptimizationPasses (unwrap (PM), opt_level, lower_intrinsics);
20102024}
@@ -2014,7 +2028,7 @@ void jl_add_optimization_passes_impl(LLVMPassManagerRef PM, int opt_level, int l
20142028// for use in reflection from Julia.
20152029// this is paired with jl_dump_function_ir, jl_dump_function_asm, jl_dump_method_asm in particular ways:
20162030// misuse will leak memory or cause read-after-free
2017- extern " C" JL_DLLEXPORT
2031+ extern " C" JL_DLLEXPORT_CODEGEN
20182032void jl_get_llvmf_defn_impl (jl_llvmf_dump_t * dump, jl_method_instance_t *mi, size_t world, char getwrapper, char optimize, const jl_cgparams_t params)
20192033{
20202034 if (jl_is_method (mi->def .method ) && mi->def .method ->source == NULL &&
@@ -2027,20 +2041,22 @@ void jl_get_llvmf_defn_impl(jl_llvmf_dump_t* dump, jl_method_instance_t *mi, siz
20272041 // get the source code for this function
20282042 jl_value_t *jlrettype = (jl_value_t *)jl_any_type;
20292043 jl_code_info_t *src = NULL ;
2030- JL_GC_PUSH2 (&src, &jlrettype);
2044+ jl_code_instance_t *codeinst = NULL ;
2045+ JL_GC_PUSH3 (&src, &jlrettype, &codeinst);
20312046 if (jl_is_method (mi->def .method ) && mi->def .method ->source != NULL && mi->def .method ->source != jl_nothing && jl_ir_flag_inferred (mi->def .method ->source )) {
20322047 src = (jl_code_info_t *)mi->def .method ->source ;
20332048 if (src && !jl_is_code_info (src))
20342049 src = jl_uncompress_ir (mi->def .method , NULL , (jl_value_t *)src);
20352050 }
20362051 else {
2037- jl_value_t *ci = jl_rettype_inferred (mi, world, world);
2052+ jl_value_t *ci = jl_rettype_inferred_addr (mi, world, world);
20382053 if (ci != jl_nothing) {
2039- jl_code_instance_t * codeinst = (jl_code_instance_t *)ci;
2054+ codeinst = (jl_code_instance_t *)ci;
20402055 src = (jl_code_info_t *)jl_atomic_load_relaxed (&codeinst->inferred );
20412056 if ((jl_value_t *)src != jl_nothing && !jl_is_code_info (src) && jl_is_method (mi->def .method ))
20422057 src = jl_uncompress_ir (mi->def .method , codeinst, (jl_value_t *)src);
20432058 jlrettype = codeinst->rettype ;
2059+ codeinst = NULL ; // not needed outside of this branch
20442060 }
20452061 if (!src || (jl_value_t *)src == jl_nothing) {
20462062 src = jl_type_infer (mi, world, 0 );
0 commit comments