Skip to content

Commit

Permalink
typeintersect: allocation tuning for large UnionAll (#54745)
Browse files Browse the repository at this point in the history
This PR tries to reduce the allocation caused by `save_env` by
skipping `alloc_env` and truncating env size when possible.

(cherry picked from commit 99cc59c)
  • Loading branch information
N5N3 authored and KristofferC committed Oct 24, 2024
1 parent 8d07746 commit 716cf46
Showing 1 changed file with 39 additions and 5 deletions.
44 changes: 39 additions & 5 deletions src/subtype.c
Original file line number Diff line number Diff line change
Expand Up @@ -2412,24 +2412,47 @@ static jl_value_t *intersect_aside(jl_value_t *x, jl_value_t *y, jl_stenv_t *e,
if (obviously_egal(x, y))
return x;

jl_varbinding_t *vars = NULL;
jl_varbinding_t *bbprev = NULL;
jl_varbinding_t *xb = jl_is_typevar(x) ? lookup(e, (jl_tvar_t *)x) : NULL;
jl_varbinding_t *yb = jl_is_typevar(y) ? lookup(e, (jl_tvar_t *)y) : NULL;
int simple_x = !jl_has_free_typevars(!jl_is_typevar(x) ? x : xb ? xb->ub : ((jl_tvar_t *)x)->ub);
int simple_y = !jl_has_free_typevars(!jl_is_typevar(y) ? y : yb ? yb->ub : ((jl_tvar_t *)y)->ub);
if (simple_x && simple_y && !(xb && yb)) {
vars = e->vars;
e->vars = xb ? xb : yb;
if (e->vars != NULL) {
bbprev = e->vars->prev;
e->vars->prev = NULL;
}
}
jl_saved_unionstate_t oldRunions; push_unionstate(&oldRunions, &e->Runions);
int savedepth = e->invdepth;
e->invdepth = depth;
jl_value_t *res = intersect_all(x, y, e);
e->invdepth = savedepth;
pop_unionstate(&e->Runions, &oldRunions);
if (bbprev) e->vars->prev = bbprev;
if (vars) e->vars = vars;
return res;
}

static jl_value_t *intersect_union(jl_value_t *x, jl_uniontype_t *u, jl_stenv_t *e, int8_t R, int param)
{
if (param == 2 || (!jl_has_free_typevars(x) && !jl_has_free_typevars((jl_value_t*)u))) {
int no_free = !jl_has_free_typevars(x) && !jl_has_free_typevars((jl_value_t*)u);
if (param == 2 || no_free) {
jl_value_t *a=NULL, *b=NULL;
JL_GC_PUSH2(&a, &b);
jl_varbinding_t *vars = NULL;
if (no_free) {
vars = e->vars;
e->vars = NULL;
}
jl_saved_unionstate_t oldRunions; push_unionstate(&oldRunions, &e->Runions);
a = R ? intersect_all(x, u->a, e) : intersect_all(u->a, x, e);
b = R ? intersect_all(x, u->b, e) : intersect_all(u->b, x, e);
pop_unionstate(&e->Runions, &oldRunions);
if (vars) e->vars = vars;
jl_value_t *i = simple_join(a,b);
JL_GC_POP();
return i;
Expand Down Expand Up @@ -4127,19 +4150,30 @@ static jl_value_t *intersect_all(jl_value_t *x, jl_value_t *y, jl_stenv_t *e)
save_env(e, &se, 1);
int niter = 0, total_iter = 0;
is[0] = intersect(x, y, e, 0); // root
if (is[0] != jl_bottom_type)
if (is[0] == jl_bottom_type) {
restore_env(e, &se, 1);
}
else if (!e->emptiness_only && has_next_union_state(e, 1)) {
niter = merge_env(e, &me, &se, niter);
restore_env(e, &se, 1);
restore_env(e, &se, 1);
}
while (next_union_state(e, 1)) {
if (e->emptiness_only && is[0] != jl_bottom_type)
break;
e->Runions.depth = 0;
e->Runions.more = 0;

is[1] = intersect(x, y, e, 0);
if (is[1] != jl_bottom_type)
if (is[1] == jl_bottom_type) {
restore_env(e, &se, 1);
}
else if (niter > 0 || (!e->emptiness_only && has_next_union_state(e, 1))) {
niter = merge_env(e, &me, &se, niter);
restore_env(e, &se, 1);
restore_env(e, &se, 1);
}
else {
assert(is[0] == jl_bottom_type);
}
if (is[0] == jl_bottom_type)
is[0] = is[1];
else if (is[1] != jl_bottom_type) {
Expand Down

0 comments on commit 716cf46

Please sign in to comment.