Skip to content

Commit

Permalink
Implement the inverse normalization
Browse files Browse the repository at this point in the history
  • Loading branch information
Keno committed Apr 12, 2019
1 parent bf001f8 commit 05ae3a2
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -791,7 +791,7 @@ JL_CALLABLE(jl_f_nfields)
{
JL_NARGS(nfields, 1, 1);
jl_value_t *x = args[0];
return jl_box_long(jl_datatype_count_fields(jl_typeof(x)));
return jl_box_long(jl_datatype_count_fields((jl_datatype_t*)jl_typeof(x)));
}

JL_CALLABLE(jl_f_isdefined)
Expand Down
6 changes: 3 additions & 3 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5202,7 +5202,7 @@ static Function *gen_invoke_wrapper(jl_method_instance_t *lam, jl_value_t *jlret
idx++;
break;
}
for (size_t i = 0; i < jl_nparams(lam->specTypes) && idx < nfargs; ++i) {
for (size_t i = 0; i < jl_datatype_count_fields((jl_datatype_t*)lam->specTypes) && idx < nfargs; ++i) {
jl_value_t *ty = jl_nth_slot_type(lam->specTypes, i);
bool isboxed;
Type *lty = julia_type_to_llvm(ty, &isboxed);
Expand Down Expand Up @@ -5341,8 +5341,8 @@ static jl_returninfo_t get_specsig_function(Module *M, const std::string &name,
attributes = attributes.addAttribute(jl_LLVMContext, 1, Attribute::NoAlias);
attributes = attributes.addAttribute(jl_LLVMContext, 1, Attribute::NoCapture);
}
for (size_t i = 0; i < jl_nparams(sig); i++) {
jl_value_t *jt = jl_tparam(sig, i);
for (size_t i = 0; i < jl_datatype_count_fields((jl_datatype_t*)sig); i++) {
jl_value_t *jt = jl_field_type((jl_datatype_t*)sig, i);
bool isboxed;
Type *ty = julia_type_to_llvm(jt, &isboxed);
if (type_is_ghost(ty))
Expand Down
68 changes: 66 additions & 2 deletions src/jltypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -1123,12 +1123,12 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value
}

jl_datatype_t *ndt = NULL;
jl_value_t *last = iparams[ntp - 1];
jl_value_t *last = ntp == 0 ? NULL : iparams[ntp - 1];
JL_GC_PUSH3(&p, &ndt, &last);

//int isvatuple = istuple && ntp > 0 && jl_is_vararg_type(last);

int isvatuple = istuple && ntp > 0 && jl_is_vararg_type(last);
int isvatuple = istuple && last && jl_is_vararg_type(last);
#if 0 // NEW_NTUPLE_LAYOUT
if (isvatuple) {
// normalize Tuple{..., Vararg{Int, 3}} to Tuple{..., Int, Int, Int}
Expand Down Expand Up @@ -1180,8 +1180,72 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value
jl_svecset(p, ntp-1, last);
}
}
#else
jl_value_t *lastt = last;
size_t nva = 1;
if (isvatuple) {
jl_value_t *va = jl_unwrap_unionall(last);
jl_value_t *va0 = jl_tparam0(va), *va1 = jl_tparam1(va);
// return same `Tuple` object for types equal to it
if (ntp == 1 &&
(last == (jl_value_t*)jl_vararg_type || // Tuple{Vararg} == Tuple
(va0 == (jl_value_t*)jl_any_type &&
jl_is_unionall(last) && va1 == (jl_value_t*)((jl_unionall_t*)last)->var))) {
if (cacheable) JL_UNLOCK(&typecache_lock); // Might GC
JL_GC_POP();
return (jl_value_t*)jl_anytuple_type;
}
jl_value_t *last2 = normalize_vararg(last);
if (last2 != last) {
last = last2;
va = jl_unwrap_unionall(last);
va0 = jl_tparam0(va); va1 = jl_tparam1(va);
}
if (!jl_is_long(va1)) {
p = jl_alloc_svec(ntp);
for (size_t i = 0; i < ntp-1; i++)
jl_svecset(p, i, iparams[i]);
jl_svecset(p, ntp-1, last);
goto done_normalizing;
}
nva = jl_unbox_long(va1);
// Normalize Tuple{..., Vararg{T, 0}} to Tuple{...} and
// Tuple{..., Vararg{T, 1}} to Tuple{..., T}
if (nva == 0 || nva == 1) {
size_t i;
p = jl_alloc_svec(ntp - 1 + nva);
for (i = 0; i < ntp - 1; i++)
jl_svecset(p, i, iparams[i]);
if (nva == 1)
jl_svecset(p, ntp - 1, va0);
if (cacheable) JL_UNLOCK(&typecache_lock); // Might GC
jl_value_t *ndt = (jl_value_t*)jl_apply_tuple_type(p);
JL_GC_POP();
return ndt;
}
lastt = va0;
}
// normalize Tuple{..., Int, Int, Int} to Tuple{..., Vararg{Int, 3}}
int do_normalize = 0;
if (istuple && lastt && jl_is_concrete_type(lastt) && ntp >= 2) {
// Roll up any identical, trailing types into this type
for (size_t i = ntp - 1; i > 0; i--) {
jl_value_t *v = iparams[i - 1];
if (v != lastt)
break;
do_normalize = 1;
nva += 1;
}
}
if (do_normalize) {
p = jl_alloc_svec(ntp-nva+1);
for (size_t i = 0; i < ntp-nva; i++)
jl_svecset(p, i, iparams[i]);
jl_svecset(p, ntp-nva, jl_wrap_vararg(lastt, jl_box_long(nva)));
}
#endif

done_normalizing:
// move array of instantiated parameters to heap; we need to keep it
if (p == NULL) {
p = jl_alloc_svec_uninit(ntp);
Expand Down
4 changes: 2 additions & 2 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -879,7 +879,7 @@ STATIC_INLINE void jl_array_uint8_set(void *a, size_t i, uint8_t x) JL_NOTSAFEPO

#define jl_fieldref(s,i) jl_get_nth_field(((jl_value_t*)(s)),i)
#define jl_fieldref_noalloc(s,i) jl_get_nth_field_noalloc(((jl_value_t*)(s)),i)
#define jl_nfields(v) jl_datatype_nfields(jl_typeof(v))
#define jl_nfields(v) jl_datatype_count_fields((jl_datatype_t*)jl_typeof(v))

// Not using jl_fieldref to avoid allocations
#define jl_linenode_line(x) (((intptr_t*)(x))[0])
Expand Down Expand Up @@ -1367,7 +1367,7 @@ STATIC_INLINE jl_sym_t *jl_field_name(jl_datatype_t *st, size_t i) JL_NOTSAFEPOI
STATIC_INLINE jl_value_t *jl_field_type(jl_datatype_t *st, size_t i) JL_NOTSAFEPOINT
{
size_t len = jl_svec_len(st->types);
if (i + 2 < len) {
if (i + 2 <= len) {
return jl_tfield(st, i);
} else {
jl_value_t *vt = jl_tfield(st, len - 1);
Expand Down
7 changes: 5 additions & 2 deletions src/typemap.c
Original file line number Diff line number Diff line change
Expand Up @@ -588,14 +588,17 @@ int jl_typemap_intersection_visitor(jl_typemap_t *map, int offs,
static jl_typemap_entry_t *jl_typemap_assoc_by_type_(jl_typemap_entry_t *ml, jl_value_t *types,
jl_svec_t **penv, size_t world, size_t max_world_mask)
{
jl_value_t *unw = jl_unwrap_unionall((jl_value_t*)types);
jl_datatype_t *unw = (jl_datatype_t *)jl_unwrap_unionall((jl_value_t*)types);
int isua = jl_is_unionall(types);
size_t n = jl_field_count(unw);
int typesisva = n == 0 ? 0 : jl_is_vararg_type(jl_tparam(unw, n-1));
if (typesisva && jl_va_tuple_kind(unw) == JL_VARARG_INT)
n += jl_vararg_length(jl_tparam(unw, n-1)) - 1;
for (; ml != (void*)jl_nothing; ml = ml->next) {
if (world < ml->min_world || world > (ml->max_world | max_world_mask))
continue; // ignore replaced methods
size_t lensig = jl_field_count(jl_unwrap_unionall((jl_value_t*)ml->sig));
jl_datatype_t *sig_unw = (jl_datatype_t *)jl_unwrap_unionall((jl_value_t*)ml->sig);
size_t lensig = jl_va_tuple_kind(sig_unw) == JL_VARARG_INT ? jl_datatype_count_fields(sig_unw) : jl_field_count(sig_unw);
if (lensig == n || (ml->va && lensig <= n+1)) {
int resetenv = 0, ismatch = 1;
if (ml->simplesig != (void*)jl_nothing && !isua) {
Expand Down

0 comments on commit 05ae3a2

Please sign in to comment.