@@ -2485,8 +2485,24 @@ bool LateLowerGCFrame::CleanupIR(Function &F, State *S, bool *CFGModified) {
2485
2485
CI->replaceAllUsesWith (NewCall);
2486
2486
UpdatePtrNumbering (CI, NewCall, S);
2487
2487
} else {
2488
- if (CI->getFnAttr (" julia.gc_safe" ).isValid ())
2489
- dbgs () << " Found julia.gc_safe attribute on" << *CI;
2488
+ if (CI->getFnAttr (" julia.gc_safe" ).isValid ()) {
2489
+ // Insert the operations to switch to gc_safe if necessary.
2490
+ IRBuilder<> builder (CI);
2491
+ Value *pgcstack = getPGCstack (F);
2492
+ assert (pgcstack);
2493
+ Value *ptls = get_current_ptls_from_task (builder, T_size, get_current_task_from_pgcstack (builder, T_size, pgcstack), tbaa_gcframe);
2494
+ Value *last_gc_state = emit_gc_safe_enter (builder, T_size, ptls, false );
2495
+ builder.SetInsertPoint (CI->getNextNode ());
2496
+ // Can't use `emit_gc_safe_exit` since that wan'ts to emit some branches...
2497
+ // Value *old_state = builder.getInt8(JL_GC_STATE_SAFE);
2498
+ llvm::Value *ptls_i8 = emit_bitcast_with_builder (builder, ptls, builder.getInt8PtrTy ());
2499
+ Constant *offset = ConstantInt::getSigned (builder.getInt32Ty (), offsetof (jl_tls_states_t , gc_state));
2500
+ Value *gc_state = builder.CreateInBoundsGEP (builder.getInt8Ty (), ptls_i8, ArrayRef<Value*>(offset), " gc_state" );
2501
+ builder.CreateAlignedStore (last_gc_state, gc_state, Align (sizeof (void *)))->setOrdering (AtomicOrdering::Release);
2502
+ MDNode *tbaa = get_tbaa_const (builder.getContext ());
2503
+ // unconditional safepoint due to branches
2504
+ emit_gc_safepoint (builder, T_size, ptls, tbaa, false );
2505
+ }
2490
2506
if (CI->arg_size () == CI->getNumOperands ()) {
2491
2507
/* No operand bundle to lower */
2492
2508
++it;
0 commit comments