@@ -256,16 +256,24 @@ static inline void emit_gc_safepoint(llvm::IRBuilder<> &builder, llvm::Type *T_s
256
256
emit_signal_fence (builder);
257
257
}
258
258
259
- 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 )
259
+ 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 )
260
260
{
261
261
using namespace llvm ;
262
+ Value *ptls = get_current_ptls_from_task (builder, task, tbaa);
262
263
Type *T_int8 = state->getType ();
263
264
unsigned offset = offsetof (jl_tls_states_t , gc_state);
264
265
Value *gc_state = builder.CreateConstInBoundsGEP1_32 (T_int8, ptls, offset, " gc_state" );
265
266
if (old_state == nullptr ) {
266
267
old_state = builder.CreateLoad (T_int8, gc_state);
267
268
cast<LoadInst>(old_state)->setOrdering (AtomicOrdering::Monotonic);
268
269
}
270
+ if (isa<Constant>(state) ? state == builder.getInt8 (0 ) :
271
+ isa<Constant>(old_state) ? old_state == builder.getInt8 (0 ) : true ) {
272
+ unsigned offset = offsetof (jl_task_t , ctx.activefp );
273
+ Value *currentfp = builder.CreateConstInBoundsGEP1_32 (T_int8, task, offset, " gc_state" );
274
+ Value *fp = builder.CreateIntrinsic (Intrinsic::frameaddress, {builder.getPtrTy ()}, {builder.getInt32 (0 )});
275
+ builder.CreateAlignedStore (fp, currentfp, Align (sizeof (void *)));
276
+ }
269
277
builder.CreateAlignedStore (state, gc_state, Align (sizeof (void *)))->setOrdering (AtomicOrdering::Release);
270
278
if (auto *C = dyn_cast<ConstantInt>(old_state))
271
279
if (C->isZero ())
@@ -280,39 +288,38 @@ static inline llvm::Value *emit_gc_state_set(llvm::IRBuilder<> &builder, llvm::T
280
288
builder.CreateICmpEQ (state, zero8)),
281
289
passBB, exitBB);
282
290
builder.SetInsertPoint (passBB);
283
- MDNode *tbaa = get_tbaa_const (builder.getContext ());
284
- emit_gc_safepoint (builder, T_size, ptls, tbaa, final );
291
+ emit_gc_safepoint (builder, T_size, ptls, get_tbaa_const (builder.getContext ()), final );
285
292
builder.CreateBr (exitBB);
286
293
builder.SetInsertPoint (exitBB);
287
294
return old_state;
288
295
}
289
296
290
- static inline llvm::Value *emit_gc_unsafe_enter (llvm::IRBuilder<> &builder, llvm::Type *T_size, llvm::Value *ptls , bool final )
297
+ static inline llvm::Value *emit_gc_unsafe_enter (llvm::IRBuilder<> &builder, llvm::Type *T_size, llvm::Value *task, llvm::MDNode *tbaa , bool final )
291
298
{
292
299
using namespace llvm ;
293
300
Value *state = builder.getInt8 (0 );
294
- return emit_gc_state_set (builder, T_size, ptls , state, nullptr , final );
301
+ return emit_gc_state_set (builder, T_size, task, tbaa , state, nullptr , final );
295
302
}
296
303
297
- static inline llvm::Value *emit_gc_unsafe_leave (llvm::IRBuilder<> &builder, llvm::Type *T_size, llvm::Value *ptls , llvm::Value *state, bool final )
304
+ 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 )
298
305
{
299
306
using namespace llvm ;
300
307
Value *old_state = builder.getInt8 (JL_GC_STATE_UNSAFE);
301
- return emit_gc_state_set (builder, T_size, ptls , state, old_state, final );
308
+ return emit_gc_state_set (builder, T_size, task, tbaa , state, old_state, final );
302
309
}
303
310
304
- static inline llvm::Value *emit_gc_safe_enter (llvm::IRBuilder<> &builder, llvm::Type *T_size, llvm::Value *ptls , bool final )
311
+ static inline llvm::Value *emit_gc_safe_enter (llvm::IRBuilder<> &builder, llvm::Type *T_size, llvm::Value *task, llvm::MDNode *tbaa , bool final )
305
312
{
306
313
using namespace llvm ;
307
314
Value *state = builder.getInt8 (JL_GC_STATE_SAFE);
308
- return emit_gc_state_set (builder, T_size, ptls , state, nullptr , final );
315
+ return emit_gc_state_set (builder, T_size, task, tbaa , state, nullptr , final );
309
316
}
310
317
311
- static inline llvm::Value *emit_gc_safe_leave (llvm::IRBuilder<> &builder, llvm::Type *T_size, llvm::Value *ptls , llvm::Value *state, bool final )
318
+ 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 )
312
319
{
313
320
using namespace llvm ;
314
321
Value *old_state = builder.getInt8 (JL_GC_STATE_SAFE);
315
- return emit_gc_state_set (builder, T_size, ptls , state, old_state, final );
322
+ return emit_gc_state_set (builder, T_size, task, tbaa , state, old_state, final );
316
323
}
317
324
318
325
// Compatibility shims for LLVM attribute APIs that were renamed in LLVM 14.
0 commit comments