Skip to content

Commit c59cede

Browse files
committed
Add a white list of known non-safepoint functions
These are functions we emit in codegen directly that are known to not contain any safepoint
1 parent df63db6 commit c59cede

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

src/llvm-late-gc-lowering.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,12 @@ State LateLowerGCFrame::LocalScan(Function &F) {
729729
if (CI->canReturnTwice()) {
730730
S.ReturnsTwice.push_back(CI);
731731
}
732+
if (auto callee = CI->getCalledFunction()) {
733+
// Known functions emitted in codegen that are not safepoints
734+
if (callee == pointer_from_objref_func || callee->getName() == "memcmp") {
735+
continue;
736+
}
737+
}
732738
int SafepointNumber = NoteSafepoint(S, BBS, CI);
733739
BBS.HasSafepoint = true;
734740
BBS.TopmostSafepoint = SafepointNumber;

test/codegen.jl

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,35 @@ if opt_level > 0
6161
test_loads_no_call(get_llvm(core_sizeof, Tuple{Vector}), [Iptr, "i16"])
6262
end
6363

64-
@test !contains(get_llvm(isequal, Tuple{Nullable{BigFloat}, Nullable{BigFloat}}), "%gcframe")
64+
# Make sure we will not elide the allocation
65+
@noinline create_ref1() = Ref(1)
66+
function pointer_not_safepoint()
67+
a = create_ref1()
68+
unsafe_store!(Ptr{Int}(pointer_from_objref(a)), 3)
69+
return a[]
70+
end
71+
@test pointer_not_safepoint() == 3
72+
73+
struct LargeStruct
74+
x::NTuple{100,Int}
75+
LargeStruct() = new()
76+
end
77+
78+
const large_struct = LargeStruct()
79+
@noinline create_ref_struct() = Ref(large_struct)
80+
function compare_large_struct(a)
81+
b = create_ref_struct()
82+
if a[] === b[]
83+
b[].x[1]
84+
else
85+
a[].x[2]
86+
end
87+
end
88+
89+
if opt_level > 0
90+
@test !contains(get_llvm(isequal, Tuple{Nullable{BigFloat}, Nullable{BigFloat}}), "%gcframe")
91+
@test !contains(get_llvm(pointer_not_safepoint, Tuple{}), "%gcframe")
92+
compare_large_struct_ir = get_llvm(compare_large_struct, Tuple{typeof(create_ref_struct())})
93+
@test contains(compare_large_struct_ir, "call i32 @memcmp")
94+
@test !contains(compare_large_struct_ir, "%gcframe")
95+
end

0 commit comments

Comments
 (0)