Skip to content

Commit 369660f

Browse files
authored
gf: accelerate adding backedges back to old performance (#48966)
Since it does not compute and branch on typeof, in my measurements, this implementation is up to 10x faster!
1 parent fd5b5e3 commit 369660f

File tree

1 file changed

+15
-13
lines changed

1 file changed

+15
-13
lines changed

src/gf.c

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1610,31 +1610,32 @@ JL_DLLEXPORT void jl_method_instance_add_backedge(jl_method_instance_t *callee,
16101610
JL_LOCK(&callee->def.method->writelock);
16111611
if (invokesig == jl_nothing)
16121612
invokesig = NULL; // julia uses `nothing` but C uses NULL (#undef)
1613+
int found = 0;
1614+
// TODO: use jl_cache_type_(invokesig) like cache_method does to save memory
16131615
if (!callee->backedges) {
16141616
// lazy-init the backedges array
16151617
callee->backedges = jl_alloc_vec_any(0);
16161618
jl_gc_wb(callee, callee->backedges);
1617-
push_edge(callee->backedges, invokesig, caller);
16181619
}
16191620
else {
16201621
size_t i = 0, l = jl_array_len(callee->backedges);
1621-
int found = 0;
1622-
jl_value_t *invokeTypes;
1623-
jl_method_instance_t *mi;
1624-
while (i < l) {
1625-
i = get_next_edge(callee->backedges, i, &invokeTypes, &mi);
1626-
// TODO: it would be better to canonicalize (how?) the Tuple-type so
1627-
// that we don't have to call `jl_egal`
1628-
if (mi == caller && ((invokesig == NULL && invokeTypes == NULL) ||
1629-
(invokesig && invokeTypes && jl_egal(invokesig, invokeTypes)))) {
1622+
for (i = 0; i < l; i++) {
1623+
// optimized version of while (i < l) i = get_next_edge(callee->backedges, i, &invokeTypes, &mi);
1624+
jl_value_t *mi = jl_array_ptr_ref(callee->backedges, i);
1625+
if (mi != (jl_value_t*)caller)
1626+
continue;
1627+
jl_value_t *invokeTypes = i > 0 ? jl_array_ptr_ref(callee->backedges, i - 1) : NULL;
1628+
if (invokeTypes && jl_is_method_instance(invokeTypes))
1629+
invokeTypes = NULL;
1630+
if ((invokesig == NULL && invokeTypes == NULL) ||
1631+
(invokesig && invokeTypes && jl_types_equal(invokesig, invokeTypes))) {
16301632
found = 1;
16311633
break;
16321634
}
16331635
}
1634-
if (!found) {
1635-
push_edge(callee->backedges, invokesig, caller);
1636-
}
16371636
}
1637+
if (!found)
1638+
push_edge(callee->backedges, invokesig, caller);
16381639
JL_UNLOCK(&callee->def.method->writelock);
16391640
}
16401641

@@ -1650,6 +1651,7 @@ JL_DLLEXPORT void jl_method_table_add_backedge(jl_methtable_t *mt, jl_value_t *t
16501651
jl_array_ptr_set(mt->backedges, 1, caller);
16511652
}
16521653
else {
1654+
// TODO: use jl_cache_type_(tt) like cache_method does, instead of a linear scan
16531655
size_t i, l = jl_array_len(mt->backedges);
16541656
for (i = 1; i < l; i += 2) {
16551657
if (jl_types_equal(jl_array_ptr_ref(mt->backedges, i - 1), typ)) {

0 commit comments

Comments
 (0)