@@ -237,16 +237,24 @@ static inline void emit_gc_safepoint(llvm::IRBuilder<> &builder, llvm::Type *T_s
237237 emit_signal_fence (builder);
238238}
239239
240- static inline llvm::Value *emit_gc_state_set (llvm::IRBuilder<> &builder, llvm::Type *T_size, llvm::Value *ptls , llvm::Value *state, llvm::Value *old_state, bool final )
240+ static inline llvm::Value *emit_gc_state_set (llvm::IRBuilder<> &builder, llvm::Type *T_size, llvm::Value *task, llvm::MDNode *tbaa , llvm::Value *state, llvm::Value *old_state, bool final )
241241{
242242 using namespace llvm ;
243+ Value *ptls = get_current_ptls_from_task (builder, task, tbaa);
243244 Type *T_int8 = state->getType ();
244245 unsigned offset = offsetof (jl_tls_states_t , gc_state);
245246 Value *gc_state = builder.CreateConstInBoundsGEP1_32 (T_int8, ptls, offset, " gc_state" );
246247 if (old_state == nullptr ) {
247248 old_state = builder.CreateLoad (T_int8, gc_state);
248249 cast<LoadInst>(old_state)->setOrdering (AtomicOrdering::Monotonic);
249250 }
251+ if (isa<Constant>(state) ? state == builder.getInt8 (0 ) :
252+ isa<Constant>(old_state) ? old_state == builder.getInt8 (0 ) : true ) {
253+ unsigned offset = offsetof (jl_task_t , ctx.activefp );
254+ Value *currentfp = builder.CreateConstInBoundsGEP1_32 (T_int8, task, offset, " gc_state" );
255+ Value *fp = builder.CreateIntrinsic (Intrinsic::frameaddress, {builder.getPtrTy ()}, {builder.getInt32 (0 )});
256+ builder.CreateAlignedStore (fp, currentfp, Align (sizeof (void *)));
257+ }
250258 builder.CreateAlignedStore (state, gc_state, Align (sizeof (void *)))->setOrdering (AtomicOrdering::Release);
251259 if (auto *C = dyn_cast<ConstantInt>(old_state))
252260 if (C->isZero ())
@@ -261,39 +269,38 @@ static inline llvm::Value *emit_gc_state_set(llvm::IRBuilder<> &builder, llvm::T
261269 builder.CreateICmpEQ (state, zero8)),
262270 passBB, exitBB);
263271 builder.SetInsertPoint (passBB);
264- MDNode *tbaa = get_tbaa_const (builder.getContext ());
265- emit_gc_safepoint (builder, T_size, ptls, tbaa, final );
272+ emit_gc_safepoint (builder, T_size, ptls, get_tbaa_const (builder.getContext ()), final );
266273 builder.CreateBr (exitBB);
267274 builder.SetInsertPoint (exitBB);
268275 return old_state;
269276}
270277
271- static inline llvm::Value *emit_gc_unsafe_enter (llvm::IRBuilder<> &builder, llvm::Type *T_size, llvm::Value *ptls , bool final )
278+ static inline llvm::Value *emit_gc_unsafe_enter (llvm::IRBuilder<> &builder, llvm::Type *T_size, llvm::Value *task, llvm::MDNode *tbaa , bool final )
272279{
273280 using namespace llvm ;
274281 Value *state = builder.getInt8 (0 );
275- return emit_gc_state_set (builder, T_size, ptls , state, nullptr , final );
282+ return emit_gc_state_set (builder, T_size, task, tbaa , state, nullptr , final );
276283}
277284
278- static inline llvm::Value *emit_gc_unsafe_leave (llvm::IRBuilder<> &builder, llvm::Type *T_size, llvm::Value *ptls , llvm::Value *state, bool final )
285+ static inline llvm::Value *emit_gc_unsafe_leave (llvm::IRBuilder<> &builder, llvm::Type *T_size, llvm::Value *task, llvm::MDNode *tbaa , llvm::Value *state, bool final )
279286{
280287 using namespace llvm ;
281288 Value *old_state = builder.getInt8 (JL_GC_STATE_UNSAFE);
282- return emit_gc_state_set (builder, T_size, ptls , state, old_state, final );
289+ return emit_gc_state_set (builder, T_size, task, tbaa , state, old_state, final );
283290}
284291
285- static inline llvm::Value *emit_gc_safe_enter (llvm::IRBuilder<> &builder, llvm::Type *T_size, llvm::Value *ptls , bool final )
292+ static inline llvm::Value *emit_gc_safe_enter (llvm::IRBuilder<> &builder, llvm::Type *T_size, llvm::Value *task, llvm::MDNode *tbaa , bool final )
286293{
287294 using namespace llvm ;
288295 Value *state = builder.getInt8 (JL_GC_STATE_SAFE);
289- return emit_gc_state_set (builder, T_size, ptls , state, nullptr , final );
296+ return emit_gc_state_set (builder, T_size, task, tbaa , state, nullptr , final );
290297}
291298
292- static inline llvm::Value *emit_gc_safe_leave (llvm::IRBuilder<> &builder, llvm::Type *T_size, llvm::Value *ptls , llvm::Value *state, bool final )
299+ static inline llvm::Value *emit_gc_safe_leave (llvm::IRBuilder<> &builder, llvm::Type *T_size, llvm::Value *task, llvm::MDNode *tbaa , llvm::Value *state, bool final )
293300{
294301 using namespace llvm ;
295302 Value *old_state = builder.getInt8 (JL_GC_STATE_SAFE);
296- return emit_gc_state_set (builder, T_size, ptls , state, old_state, final );
303+ return emit_gc_state_set (builder, T_size, task, tbaa , state, old_state, final );
297304}
298305
299306// Compatibility shims for LLVM attribute APIs that were renamed in LLVM 14.
0 commit comments