Open zacky1972 opened 4 years ago
I wrote sample generated code:
static ERL_NIF_TERM
func(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
if (__builtin_expect((argc != 1), false)) {
return enif_make_badarg(env);
}
if (__builtin_expect(enif_is_empty_list(env, argv[0]), false)) {
// Write code here in the case that argv[0] is an empty list
...
return true;
}
ERL_NIF_TERM from, to;
if (__builtin_expect(enif_get_range(env, argv[0], &from, &to), false)) {
// Write code here in the case that argv[0] is an range
...
return true;
}
size_t n0 = INIT_SIZE_ERL_NIF;
size_t nn0 = cache_line_size;
ERL_NIF_TERM *t0 = (ERL_NIF_TERM *)enif_alloc(nn0);
if (__builtin_expect((t0 == NULL), false)) {
// In the case of an error of memory allocation
return false;
}
size_t l0 = 0;
// try to read argv[0] as a list
bool is_list0 = false;
ERL_NIF_TERM tail;
while (enif_get_list_cell(env, argv[0], &t0[l0++], &tail)) {
is_list0 = true;
if(__builtin_expect(i > n0, false)) {
// expand vector t0
...
}
}
if (__builtin_expect(is_list0, true)) {
// t0 is set to an vector of ERL_NIF_TERM, l0 is set to the length of t0
if (__builtin_expect(enif_is_number(env, t0[0]), true)) {
double double_0_1st;
if (__builtin_expect(enif_get_double(env, t0[0], &double_0_1st)), true) {
// In the case that the 1st element of t0 is a double number
double *double_0 = (double *)enif_alloc(l0 * sizeof(double))
if (__builtin_expect((double_0 == NULL), false)) {
// In the case of an error of memory allocation
return false;
}
double_0[0] = double_0_1st;
for(size_t i = 1; i < l0; i++) {
if(__builtin_expect(!enif_get_double(env, t0[i], &double_0[i]), false)) {
// In the case of poly-typed list
unsigned int b0[l0 >> PRECISION(UINT_MAX)] = {}; // bit vector for t0
size_t c0[T_NUM] = {}; // set to 0
c0[T_DOUBLE] += i;
do {
if(__builtin_expect(enif_is_number(env, t0[i]), true)) {
// In the case that t0[i] is a number
ErlNifSInt64 i64_i0;
ErlNIfUInt64 u64_i0;
if(__builtin_expect(enif_get_int64(env, t0[i], &i64_i0), true)) {
// In the case of t0[i] is int64
update_type_counters(c0, i64_i0);
BITSET(b0, i, 1);
} else if(__builtin_expect(enif_get_uint64(env, t0[i], &u64_i0), true)) {
// In the case of t0[i] is not int64 but uint64
c0[T_UINT64]++;
BITSET(b0, i, 1);
} else if(__builtin_expect(enif_get_double(env, t0[i], double_0[i]), true)) {
// In the case of t0[i] is double
c0[T_DOUBLE]++;
BITSET(b0, i, 0);
} else {
// In the case of out of range of INT64 and UINT64
return out_of_range;
}
} else {
// In the case that t0[i] is not a number
...
}
} while(i < l0);
// double_0 is set to a double array read from argv[0]
// t0 is set to an array of ERL_NIF_TERM
// b0 is set to an bit vector that a bit is set to 0 if the corresponding element is a double number
// c0 is set to counters for each type
// Write code here in the case that argv[0] is a poly-typed list of double.
return true;
}
}
// double_0 is set to a double array read from argv[0]
// l0 is set to the length of double_0
// Write code here in the case that argv[0] is a mono-typed list of double
return true;
}
ErlNifSInt64 int64_0_1st;
if (__builtin_expect(enif_get_int64(env, t0[0], &int64_0_1st), false)) {
// In the case that argv[0] is a list of an int64
...
return true;
}
ErlNIfUInt64 uint64_0_1st;
if (__builtin_expect(enif_get_uint64(env, t0[0], &uint64_0_1st), false)) {
// In the case that argv[0] is a list of an int64
...
return true;
}
// In the case of out of range of INT64 and UINT64
return out_of_range;
} else if ...
}
enif_free(t0);
if(__builtin_expect(enif_is_number(env, argv[0]), true)) {
// in the case that argv[0] is a number
...
return true;
}
...
if(__builtin_expect(enif_get_map_size(env, argv[0], &l0), true)) {
// in the case that argv[0] is a map
...
return true;
}
if(__builtin_expect(enif_get_tuple(env, argv[0], &l0, &t0), true)) {
// in the case that argv[0] is a tuple
...
return true;
}
}
Is your feature request related to a problem? Please describe. In SIMD calculation, optimized code is different according to which type of each element is required, 8, 16, 32, or 64 bit.
Describe the solution you'd like Type checking and inference system should investigate range of a value of each element and generate code using suitable type of array.
Describe alternatives you've considered None.
Additional context This issue is related to #75