From d7d7912860ce7e1c423a1e3a16a6d56f8310ada5 Mon Sep 17 00:00:00 2001 From: d-netto Date: Tue, 16 Jan 2024 21:40:26 -0300 Subject: [PATCH] [late-gc-lowering] null-out GC frame slots for dead objects --- src/llvm-late-gc-lowering.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/llvm-late-gc-lowering.cpp b/src/llvm-late-gc-lowering.cpp index edb3aad8f23282..cbbf0251649ba4 100644 --- a/src/llvm-late-gc-lowering.cpp +++ b/src/llvm-late-gc-lowering.cpp @@ -348,6 +348,7 @@ struct LateLowerGCFrame: private JuliaPassContext { void ComputeLiveSets(State &S); SmallVector ColorRoots(const State &S); void PlaceGCFrameStore(State &S, unsigned R, unsigned MinColorRoot, ArrayRef Colors, Value *GCFrame, Instruction *InsertBefore); + void PlaceGCFrameReset(State &S, unsigned R, unsigned MinColorRoot, ArrayRef Colors, Value *GCFrame, Instruction *InsertBefore); void PlaceGCFrameStores(State &S, unsigned MinColorRoot, ArrayRef Colors, Value *GCFrame); void PlaceRootsAndUpdateCalls(SmallVectorImpl &Colors, State &S, std::map>); bool CleanupIR(Function &F, State *S, bool *CFGModified); @@ -2665,6 +2666,18 @@ void LateLowerGCFrame::PlaceGCFrameStore(State &S, unsigned R, unsigned MinColor } new StoreInst(Val, slotAddress, InsertBefore); } +void LateLowerGCFrame::PlaceGCFrameReset(State &S, unsigned R, unsigned MinColorRoot, + ArrayRef Colors, Value *GCFrame, + Instruction *InsertBefore) { + // Get the slot address. + auto slotAddress = CallInst::Create( + getOrDeclare(jl_intrinsics::getGCFrameSlot), + {GCFrame, ConstantInt::get(Type::getInt32Ty(InsertBefore->getContext()), Colors[R] + MinColorRoot)}, + "gc_slot_addr_" + StringRef(std::to_string(Colors[R] + MinColorRoot)), InsertBefore); + // Reset the slot to NULL. + Value *Val = ConstantPointerNull::get(T_prjlvalue); + new StoreInst(Val, slotAddress, InsertBefore); +} void LateLowerGCFrame::PlaceGCFrameStores(State &S, unsigned MinColorRoot, ArrayRef Colors, Value *GCFrame) @@ -2680,6 +2693,15 @@ void LateLowerGCFrame::PlaceGCFrameStores(State &S, unsigned MinColorRoot, for(auto rit = BBS.Safepoints.rbegin(); rit != BBS.Safepoints.rend(); ++rit ) { const LargeSparseBitVector &NowLive = S.LiveSets[*rit]; + // reset slots which are no longer alive + for (int Idx : *LastLive) { + if (!HasBitSet(NowLive, Idx)) { + PlaceGCFrameReset(S, Idx, MinColorRoot, Colors, GCFrame, + S.ReverseSafepointNumbering[*rit]); + } + } + // store values which are alive in this safepoint but + // haven't been stored in the GC frame before for (int Idx : NowLive) { if (!HasBitSet(*LastLive, Idx)) { PlaceGCFrameStore(S, Idx, MinColorRoot, Colors, GCFrame,