Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 28 additions & 10 deletions src/gf.c
Original file line number Diff line number Diff line change
Expand Up @@ -724,13 +724,14 @@ static void jl_compilation_sig(
jl_tupletype_t *const tt, // the original tupletype of the call (or DataType from precompile)
jl_svec_t *sparams,
jl_method_t *definition,
intptr_t nspec,
intptr_t max_varargs,
// output:
jl_svec_t **const newparams JL_REQUIRE_ROOTED_SLOT)
{
assert(jl_is_tuple_type(tt));
jl_value_t *decl = definition->sig;
size_t nargs = definition->nargs; // == jl_nparams(jl_unwrap_unionall(decl));
size_t nspec = max_varargs + nargs;

if (definition->generator) {
// staged functions aren't optimized
Expand Down Expand Up @@ -766,7 +767,8 @@ static void jl_compilation_sig(
case JL_VARARG_UNBOUND:
if (np < nspec && jl_is_va_tuple(tt))
// there are insufficient given parameters for jl_isa_compileable_sig now to like this type
// (there were probably fewer methods defined when we first selected this signature)
// (there were probably fewer methods defined when we first selected this signature, or
// the max varargs limit was not reached indicating the type is already fully-specialized)
return;
break;
}
Expand Down Expand Up @@ -919,7 +921,13 @@ static void jl_compilation_sig(
// and the types we find should be bigger.
if (np >= nspec && jl_va_tuple_kind((jl_datatype_t*)decl) == JL_VARARG_UNBOUND) {
if (!*newparams) *newparams = tt->parameters;
type_i = jl_svecref(*newparams, nspec - 2);
if (max_varargs > 0) {
type_i = jl_svecref(*newparams, nspec - 2);
} else {
// If max varargs is zero, always specialize to (Any...) since
// there is no preceding parameter to use for `type_i`
type_i = jl_bottom_type;
}
// if all subsequent arguments are subtypes of type_i, specialize
// on that instead of decl. for example, if decl is
// (Any...)
Expand Down Expand Up @@ -988,13 +996,15 @@ JL_DLLEXPORT int jl_isa_compileable_sig(
// supertype of any other method signatures. so far we are conservative
// and the types we find should be bigger.
if (definition->isva) {
unsigned nspec_min = nargs + 1; // min number of non-vararg values before vararg
unsigned nspec_max = INT32_MAX; // max number of non-vararg values before vararg
unsigned nspec_min = nargs + 1; // min number of arg values (including tail vararg)
unsigned nspec_max = INT32_MAX; // max number of arg values (including tail vararg)
jl_methtable_t *mt = jl_method_table_for(decl);
jl_methtable_t *kwmt = mt == jl_kwcall_mt ? jl_kwmethod_table_for(decl) : mt;
if ((jl_value_t*)mt != jl_nothing) {
// try to refine estimate of min and max
if (kwmt != NULL && kwmt != jl_type_type_mt && kwmt != jl_nonfunction_mt && kwmt != jl_kwcall_mt)
if (definition->max_varargs != UINT8_MAX)
nspec_max = nspec_min = nargs + definition->max_varargs;
else if (kwmt != NULL && kwmt != jl_type_type_mt && kwmt != jl_nonfunction_mt && kwmt != jl_kwcall_mt)
// new methods may be added, increasing nspec_min later
nspec_min = jl_atomic_load_relaxed(&kwmt->max_args) + 2 + 2 * (mt == jl_kwcall_mt);
else
Expand Down Expand Up @@ -1224,8 +1234,12 @@ static jl_method_instance_t *cache_method(
int cache_with_orig = 1;
jl_tupletype_t *compilationsig = tt;
jl_methtable_t *kwmt = mt == jl_kwcall_mt ? jl_kwmethod_table_for(definition->sig) : mt;
intptr_t nspec = (kwmt == NULL || kwmt == jl_type_type_mt || kwmt == jl_nonfunction_mt || kwmt == jl_kwcall_mt ? definition->nargs + 1 : jl_atomic_load_relaxed(&kwmt->max_args) + 2 + 2 * (mt == jl_kwcall_mt));
jl_compilation_sig(tt, sparams, definition, nspec, &newparams);
intptr_t max_varargs = 1;
if (definition->max_varargs != UINT8_MAX)
max_varargs = definition->max_varargs;
else if (kwmt != NULL && kwmt != jl_type_type_mt && kwmt != jl_nonfunction_mt && kwmt != jl_kwcall_mt)
max_varargs = (jl_atomic_load_relaxed(&kwmt->max_args) + 2 + 2 * (mt == jl_kwcall_mt)) - definition->nargs;
jl_compilation_sig(tt, sparams, definition, max_varargs, &newparams);
if (newparams) {
temp2 = jl_apply_tuple_type(newparams);
// Now there may be a problem: the widened signature is more general
Expand Down Expand Up @@ -2509,8 +2523,12 @@ JL_DLLEXPORT jl_value_t *jl_normalize_to_compilable_sig(jl_methtable_t *mt, jl_t
jl_svec_t *newparams = NULL;
JL_GC_PUSH2(&tt, &newparams);
jl_methtable_t *kwmt = mt == jl_kwcall_mt ? jl_kwmethod_table_for(m->sig) : mt;
intptr_t nspec = (kwmt == NULL || kwmt == jl_type_type_mt || kwmt == jl_nonfunction_mt || kwmt == jl_kwcall_mt ? m->nargs + 1 : jl_atomic_load_relaxed(&kwmt->max_args) + 2 + 2 * (mt == jl_kwcall_mt));
jl_compilation_sig(ti, env, m, nspec, &newparams);
intptr_t max_varargs = 1;
if (m->max_varargs != UINT8_MAX)
max_varargs = m->max_varargs;
else if (kwmt != NULL && kwmt != jl_type_type_mt && kwmt != jl_nonfunction_mt && kwmt != jl_kwcall_mt)
max_varargs = (jl_atomic_load_relaxed(&kwmt->max_args) + 2 + 2 * (mt == jl_kwcall_mt)) - m->nargs;
jl_compilation_sig(ti, env, m, max_varargs, &newparams);
int is_compileable = ((jl_datatype_t*)ti)->isdispatchtuple;
if (newparams) {
tt = (jl_datatype_t*)jl_apply_tuple_type(newparams);
Expand Down
6 changes: 4 additions & 2 deletions src/jltypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -2731,7 +2731,7 @@ void jl_init_types(void) JL_GC_DISABLED
jl_method_type =
jl_new_datatype(jl_symbol("Method"), core,
jl_any_type, jl_emptysvec,
jl_perm_symsvec(28,
jl_perm_symsvec(29,
"name",
"module",
"file",
Expand Down Expand Up @@ -2759,8 +2759,9 @@ void jl_init_types(void) JL_GC_DISABLED
"isva",
"is_for_opaque_closure",
"constprop",
"max_varargs",
"purity"),
jl_svec(28,
jl_svec(29,
jl_symbol_type,
jl_module_type,
jl_symbol_type,
Expand Down Expand Up @@ -2788,6 +2789,7 @@ void jl_init_types(void) JL_GC_DISABLED
jl_bool_type,
jl_bool_type,
jl_uint8_type,
jl_uint8_type,
jl_uint8_type),
jl_emptysvec,
0, 1, 10);
Expand Down
4 changes: 3 additions & 1 deletion src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,9 @@ typedef struct _jl_method_t {
uint8_t isva;
uint8_t is_for_opaque_closure;
// uint8 settings
uint8_t constprop; // 0x00 = use heuristic; 0x01 = aggressive; 0x02 = none
uint8_t constprop; // 0x00 = use heuristic; 0x01 = aggressive; 0x02 = none
uint8_t max_varargs; // 0xFF = use heuristic; otherwise, max # of args to expand
// varargs when specializing.

// Override the conclusions of inter-procedural effect analysis,
// forcing the conclusion to always true.
Expand Down
2 changes: 2 additions & 0 deletions src/method.c
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,8 @@ JL_DLLEXPORT jl_method_t *jl_new_method_uninit(jl_module_t *module)
m->deleted_world = ~(size_t)0;
m->is_for_opaque_closure = 0;
m->constprop = 0;
m->purity.bits = 0;
m->max_varargs = UINT8_MAX;
JL_MUTEX_INIT(&m->writelock);
return m;
}
Expand Down