@@ -1985,7 +1985,7 @@ class jl_codectx_t {
19851985
19861986 Value *pgcstack = NULL ;
19871987 Instruction *topalloca = NULL ;
1988- Value *world_age_at_entry = NULL ; // Not valid to use in toplevel code
1988+ Value *world_age_at_entry = NULL ;
19891989
19901990 bool use_cache = false ;
19911991 bool external_linkage = false ;
@@ -2115,6 +2115,7 @@ static jl_cgval_t emit_sparam(jl_codectx_t &ctx, size_t i);
21152115static Value *emit_condition (jl_codectx_t &ctx, const jl_cgval_t &condV, const Twine &msg);
21162116static Value *get_current_task (jl_codectx_t &ctx);
21172117static Value *get_current_ptls (jl_codectx_t &ctx);
2118+ static Value *get_tls_world_age (jl_codectx_t &ctx);
21182119static Value *get_scope_field (jl_codectx_t &ctx);
21192120static Value *get_tls_world_age_field (jl_codectx_t &ctx);
21202121static void CreateTrap (IRBuilder<> &irbuilder, bool create_new_block = true );
@@ -7044,11 +7045,7 @@ static jl_cgval_t emit_expr(jl_codectx_t &ctx, jl_value_t *expr, ssize_t ssaidx_
70447045 std::tie (F, specF) = get_oc_function (ctx, (jl_method_t *)source.constant , (jl_tupletype_t *)env_t , argt_typ, ub.constant );
70457046 if (F) {
70467047 jl_cgval_t jlcall_ptr = mark_julia_type (ctx, F, false , jl_voidpointer_type);
7047- jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA (ctx, ctx.tbaa ().tbaa_gcframe );
7048- bool not_toplevel = (ctx.linfo && jl_is_method (ctx.linfo ->def .method ));
7049- Instruction *I = not_toplevel ? cast<Instruction>(ctx.world_age_at_entry ) :
7050- ctx.builder .CreateAlignedLoad (ctx.types ().T_size , get_tls_world_age_field (ctx), ctx.types ().alignof_ptr );
7051- jl_cgval_t world_age = mark_julia_type (ctx, ai.decorateInst (I), false , jl_long_type);
7048+ jl_cgval_t world_age = mark_julia_type (ctx, get_tls_world_age (ctx), false , jl_long_type);
70527049 jl_cgval_t fptr;
70537050 if (specF)
70547051 fptr = mark_julia_type (ctx, specF, false , jl_voidpointer_type);
@@ -7207,6 +7204,25 @@ static Value *get_tls_world_age_field(jl_codectx_t &ctx)
72077204 return emit_ptrgep (ctx, ct, offsetof (jl_task_t , world_age), " world_age" );
72087205}
72097206
7207+ // Get the value of the world age of the current task
7208+ static Value *get_tls_world_age (jl_codectx_t &ctx)
7209+ {
7210+ if (ctx.world_age_at_entry )
7211+ return ctx.world_age_at_entry ;
7212+ IRBuilderBase::InsertPointGuard IP (ctx.builder );
7213+ bool toplevel = !jl_is_method (ctx.linfo ->def .method );
7214+ if (!toplevel) {
7215+ ctx.builder .SetInsertPoint (ctx.topalloca ->getParent (), ++ctx.topalloca ->getIterator ());
7216+ ctx.builder .SetCurrentDebugLocation (ctx.topalloca ->getStableDebugLoc ());
7217+ }
7218+ jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA (ctx, ctx.tbaa ().tbaa_gcframe );
7219+ auto *world = ctx.builder .CreateAlignedLoad (ctx.types ().T_size , get_tls_world_age_field (ctx), ctx.types ().alignof_ptr );
7220+ ai.decorateInst (world);
7221+ if (!toplevel)
7222+ ctx.world_age_at_entry = world;
7223+ return world;
7224+ }
7225+
72107226static Value *get_scope_field (jl_codectx_t &ctx)
72117227{
72127228 Value *ct = get_current_task (ctx);
@@ -7524,9 +7540,8 @@ static Function* gen_cfun_wrapper(
75247540
75257541 auto world_age_field = get_tls_world_age_field (ctx);
75267542 jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA (ctx, ctx.tbaa ().tbaa_gcframe );
7527- Value *last_age = ai.decorateInst (
7543+ ctx. world_age_at_entry = ai.decorateInst (
75287544 ctx.builder .CreateAlignedLoad (ctx.types ().T_size , world_age_field, ctx.types ().alignof_ptr ));
7529- ctx.world_age_at_entry = last_age;
75307545 Value *world_v = ctx.builder .CreateAlignedLoad (ctx.types ().T_size ,
75317546 prepare_global_in (jl_Module, jlgetworld_global), ctx.types ().alignof_ptr );
75327547 cast<LoadInst>(world_v)->setOrdering (AtomicOrdering::Acquire);
@@ -7808,7 +7823,7 @@ static Function* gen_cfun_wrapper(
78087823 r = NULL ;
78097824 }
78107825
7811- ctx.builder .CreateStore (last_age , world_age_field);
7826+ ctx.builder .CreateStore (ctx. world_age_at_entry , world_age_field);
78127827 ctx.builder .CreateRet (r);
78137828
78147829 ctx.builder .SetCurrentDebugLocation (noDbg);
@@ -8418,7 +8433,6 @@ static jl_llvm_functions_t
84188433 ctx.source = src;
84198434
84208435 std::map<int , BasicBlock*> labels;
8421- bool toplevel = false ;
84228436 ctx.module = jl_is_method (lam->def .method ) ? lam->def .method ->module : lam->def .module ;
84238437 ctx.linfo = lam;
84248438 ctx.name = TSM.getModuleUnlocked ()->getModuleIdentifier ().data ();
@@ -8438,7 +8452,6 @@ static jl_llvm_functions_t
84388452 if (vn != jl_unused_sym)
84398453 ctx.vaSlot = ctx.nargs - 1 ;
84408454 }
8441- toplevel = !jl_is_method (lam->def .method );
84428455 ctx.rettype = jlrettype;
84438456 ctx.funcName = ctx.name ;
84448457 ctx.spvals_ptr = NULL ;
@@ -8776,12 +8789,12 @@ static jl_llvm_functions_t
87768789 // step 6. set up GC frame
87778790 allocate_gc_frame (ctx, b0);
87788791 Value *last_age = NULL ;
8779- auto world_age_field = get_tls_world_age_field (ctx);
8780- { // scope
8792+ Value *world_age_field = NULL ;
8793+ if (ctx.is_opaque_closure ) {
8794+ world_age_field = get_tls_world_age_field (ctx);
87818795 jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA (ctx, ctx.tbaa ().tbaa_gcframe );
87828796 last_age = ai.decorateInst (ctx.builder .CreateAlignedLoad (
87838797 ctx.types ().T_size , world_age_field, ctx.types ().alignof_ptr ));
8784- ctx.world_age_at_entry = last_age; // Load world age for use in get_tls_world_age
87858798 }
87868799
87878800 // step 7. allocate local variables slots
@@ -9005,6 +9018,7 @@ static jl_llvm_functions_t
90059018 Value *worldaddr = emit_ptrgep (ctx, oc_this, offsetof (jl_opaque_closure_t , world));
90069019 jl_cgval_t closure_world = typed_load (ctx, worldaddr, NULL , (jl_value_t *)jl_long_type,
90079020 nullptr , nullptr , false , AtomicOrdering::NotAtomic, false , ctx.types ().alignof_ptr .value ());
9021+ assert (ctx.world_age_at_entry == nullptr );
90089022 ctx.world_age_at_entry = closure_world.V ; // The tls world in a OC is the world of the closure
90099023 emit_unbox_store (ctx, closure_world, world_age_field, ctx.tbaa ().tbaa_gcframe , ctx.types ().alignof_ptr );
90109024
@@ -9282,19 +9296,11 @@ static jl_llvm_functions_t
92829296
92839297 Instruction &prologue_end = ctx.builder .GetInsertBlock ()->back ();
92849298
9285- // step 11a. For top-level code, load the world age
9286- if (toplevel && !ctx.is_opaque_closure ) {
9287- LoadInst *world = ctx.builder .CreateAlignedLoad (ctx.types ().T_size ,
9288- prepare_global_in (jl_Module, jlgetworld_global), ctx.types ().alignof_ptr );
9289- world->setOrdering (AtomicOrdering::Acquire);
9290- ctx.builder .CreateAlignedStore (world, world_age_field, ctx.types ().alignof_ptr );
9291- }
9292-
9293- // step 11b. Emit the entry safepoint
9299+ // step 11a. Emit the entry safepoint
92949300 if (JL_FEAT_TEST (ctx, safepoint_on_entry))
92959301 emit_gc_safepoint (ctx.builder , ctx.types ().T_size , get_current_ptls (ctx), ctx.tbaa ().tbaa_const );
92969302
9297- // step 11c . Do codegen in control flow order
9303+ // step 11b . Do codegen in control flow order
92989304 SmallVector<int , 0 > workstack;
92999305 std::map<int , BasicBlock*> BB;
93009306 std::map<size_t , BasicBlock*> come_from_bb;
@@ -9966,8 +9972,7 @@ static jl_llvm_functions_t
99669972 Instruction *root = cast_or_null<Instruction>(ctx.slots [ctx.vaSlot ].boxroot );
99679973 if (root) {
99689974 bool have_real_use = false ;
9969- for (Use &U : root->uses ()) {
9970- User *RU = U.getUser ();
9975+ for (User *RU : root->users ()) {
99719976 if (StoreInst *SRU = dyn_cast<StoreInst>(RU)) {
99729977 assert (isa<ConstantPointerNull>(SRU->getValueOperand ()) || SRU->getValueOperand () == restTuple);
99739978 (void )SRU;
@@ -9986,21 +9991,21 @@ static jl_llvm_functions_t
99869991 }
99879992 }
99889993 if (!have_real_use) {
9989- Instruction *use = NULL ;
9990- for (Use &U : root->uses ()) {
9991- if (use) // erase after the iterator moves on
9992- use->eraseFromParent ();
9993- User *RU = U.getUser ();
9994- use = cast<Instruction>(RU);
9994+ for (User *RU : make_early_inc_range (root->users ())) {
9995+ // This is safe because it checked above that each User is known and has at most one Use of root
9996+ cast<Instruction>(RU)->eraseFromParent ();
99959997 }
9996- if (use)
9997- use->eraseFromParent ();
99989998 root->eraseFromParent ();
99999999 restTuple->eraseFromParent ();
1000010000 }
1000110001 }
1000210002 }
1000310003
10004+ if (ctx.topalloca ->use_empty ()) {
10005+ ctx.topalloca ->eraseFromParent ();
10006+ ctx.topalloca = nullptr ;
10007+ }
10008+
1000410009 // link the dependent llvmcall modules, but switch their function's linkage to internal
1000510010 // so that they don't conflict when they show up in the execution engine.
1000610011 Linker L (*jl_Module);
0 commit comments