[patch, fortran] Implement constant-folding for TRANSFER intrinsic.
Tobias Schlüter
tobias.schlueter@physik.uni-muenchen.de
Sat May 12 15:03:00 GMT 2007
Hi Brooks,
this looks good for the most part. I have a few remarks, though.
Brooks Moses wrote:
> + /* Calculate the size of the source. */
> + if (source->expr_type == EXPR_ARRAY
> + && gfc_array_size (source, &tmp) == FAILURE)
> + gfc_internal_error ("Failure getting length of a constant array.");
I think we're standardizing on gcc_assert even in the frontend.
> + if (size)
^^^^
Above you checked size != NULL. I'd prefer if you omitted that in both
cases.
> + result_length = (size_t)mpz_get_ui (size->value.integer);
> + else
> + {
> + result_length = source_size / result_elt_size;
> + if (result_length * result_elt_size < source_size)
> + result_length += 1;
> + }
result_length = (source_size - 1) / result_elt_size + 1;
Don't know if that's harder to understand.
> + /* Allocate the buffer to store the binary version of the source. */
> + buffer_size = source_size > result_size ? source_size : result_size;
buffer_size = MAX (source_size, result_size);
> + buffer = gfc_getmem (buffer_size);
Maybe use alloca?
> +/* --------------------------------------------------------------- */
> +/* Calculate the size of an expression. */
> +
> +static size_t
> +size_array (gfc_expr *e)
> +{
> + mpz_t array_size;
> + size_t elt_size = gfc_target_expr_size (e->value.constructor->expr);
> +
> + gfc_array_size (e, &array_size);
> + return (size_t)mpz_get_ui (array_size) * elt_size;
> +}
> +
> +static size_t
> +size_integer (int kind)
> +{
> + return GET_MODE_SIZE (TYPE_MODE (gfc_get_int_type (kind)));;
> +}
> +
> +
> +static size_t
> +size_float (int kind)
> +{
> + return GET_MODE_SIZE (TYPE_MODE (gfc_get_real_type (kind)));;
> +}
> +
> +
> +static size_t
> +size_complex (int kind)
> +{
> + return kind * size_float (kind);
^^^^
Should be 2. You also lack testcases involving COMPLEX.
> + case BT_DERIVED:
> + ctr = e->value.constructor;
> + for (;ctr; ctr = ctr->next)
> + {
> + gcc_assert (ctr->expr != NULL);
> + expr_size += gfc_target_expr_size (ctr->expr);
> + }
> + return expr_size;
Is that so? What about alignment, say, of INTEGER*1 components? This
seems to call for the middle-end's size_for_type().
> +static int
> +encode_complex (int kind, mpfr_t real, mpfr_t imaginary, unsigned char *buffer,
> + size_t buffer_size)
> +{
> + int size;
> + size = encode_float (kind, real, &buffer[0], buffer_size);
> + size += encode_float (kind, imaginary, &buffer[size], buffer_size - size);
> + return size;
> +
> +static int
> +encode_character (int length, char *string, unsigned char *buffer,
> + size_t buffer_size)
> +{
> + gcc_assert (buffer_size >= size_character (length));
> + memcpy (buffer, string, length);
> + return length;
> +}
What about targets with different character sets?
> +static int
> +encode_derived (gfc_expr *source, unsigned char *buffer, size_t buffer_size)
> +{
> + gfc_constructor *ctr;
> + int ptr = 0;
> +
> + ctr = source->value.constructor;
> + for (;ctr; ctr = ctr->next)
> + {
> + gcc_assert (ctr->expr != NULL);
> + ptr += gfc_target_encode_expr (ctr->expr, &buffer[ptr],
> + buffer_size - ptr);
> + }
> + return ptr;
> +}
Again, alignment may interfere with this logic.
> + /* Calculate array size from its shape and rank. */
> + if (result->rank == 0 || result->shape == NULL)
> + gfc_error ("failure to obtain array size at %L", &result->where);
This should probably be caught in gfc_check_transfer, and at most
gcc_asserted here.
Cheers,
- Tobi
More information about the Fortran
mailing list