diff options
author | Richard Sandiford <richard@codesourcery.com> | 2005-12-13 05:23:12 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2005-12-13 05:23:12 +0000 |
commit | 1524f80b1ceeda3c293142f4e370616be6dcf2cf (patch) | |
tree | 8b430f1a509f3fecd45aafac44d2707a38eb02d2 /gcc/fortran/trans-array.c | |
parent | 264c41eda5b1d3b073053da88f7e757635269cc3 (diff) | |
download | gcc-1524f80b1ceeda3c293142f4e370616be6dcf2cf.zip gcc-1524f80b1ceeda3c293142f4e370616be6dcf2cf.tar.gz gcc-1524f80b1ceeda3c293142f4e370616be6dcf2cf.tar.bz2 |
Make-lang.in (fortran/trans-resolve.o): Depend on fortran/dependency.h.
gcc/fortran/
* Make-lang.in (fortran/trans-resolve.o): Depend on
fortran/dependency.h.
* gfortran.h (gfc_expr): Add an "inline_noncopying_intrinsic" flag.
* dependency.h (gfc_get_noncopying_intrinsic_argument): Declare.
(gfc_check_fncall_dependency): Change prototype.
* dependency.c (gfc_get_noncopying_intrinsic_argument): New function.
(gfc_check_argument_var_dependency): New function, split from
gfc_check_fncall_dependency.
(gfc_check_argument_dependency): New function.
(gfc_check_fncall_dependency): Replace the expression parameter with
separate symbol and argument list parameters. Generalize the function
to handle dependencies for any type of expression, not just variables.
Accept a further argument giving the intent of the expression being
tested. Ignore intent(in) arguments if that expression is also
intent(in).
* resolve.c: Include dependency.h.
(find_noncopying_intrinsics): New function.
(resolve_function, resolve_call): Call it on success.
* trans-array.h (gfc_conv_array_transpose): Declare.
(gfc_check_fncall_dependency): Remove prototype.
* trans-array.c (gfc_conv_array_transpose): New function.
* trans-intrinsic.c (gfc_conv_intrinsic_function): Don't use the
libcall handling if the expression is to be evaluated inline.
Add a case for handling inline transpose()s.
* trans-expr.c (gfc_trans_arrayfunc_assign): Adjust for the new
interface provided by gfc_check_fncall_dependency.
libgfortran/
* m4/matmul.m4: Use a different order in the special case of a
transposed first argument.
* generated/matmul_c4.c, generated/matmul_c8.c, generated/matmul_c10.c,
* generated/matmul_c16.c, generated/matmul_i4.c, generated/matmul_i8.c,
* generated/matmul_i10.c, generated/matmul_r4.c, generated/matmul_r8.c
* generated/matmul_r10.c, generated/matmul_r16.c: Regenerated.
Co-Authored-By: Victor Leikehman <LEI@il.ibm.com>
From-SVN: r108459
Diffstat (limited to 'gcc/fortran/trans-array.c')
-rw-r--r-- | gcc/fortran/trans-array.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index a94d7e8..45c8351 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -673,6 +673,95 @@ gfc_trans_allocate_temp_array (stmtblock_t * pre, stmtblock_t * post, } +/* Generate code to tranpose array EXPR by creating a new descriptor + in which the dimension specifications have been reversed. */ + +void +gfc_conv_array_transpose (gfc_se * se, gfc_expr * expr) +{ + tree dest, src, dest_index, src_index; + gfc_loopinfo *loop; + gfc_ss_info *dest_info, *src_info; + gfc_ss *dest_ss, *src_ss; + gfc_se src_se; + int n; + + loop = se->loop; + + src_ss = gfc_walk_expr (expr); + dest_ss = se->ss; + + src_info = &src_ss->data.info; + dest_info = &dest_ss->data.info; + + /* Get a descriptor for EXPR. */ + gfc_init_se (&src_se, NULL); + gfc_conv_expr_descriptor (&src_se, expr, src_ss); + gfc_add_block_to_block (&se->pre, &src_se.pre); + gfc_add_block_to_block (&se->post, &src_se.post); + src = src_se.expr; + + /* Allocate a new descriptor for the return value. */ + dest = gfc_create_var (TREE_TYPE (src), "atmp"); + dest_info->descriptor = dest; + se->expr = dest; + + /* Copy across the dtype field. */ + gfc_add_modify_expr (&se->pre, + gfc_conv_descriptor_dtype (dest), + gfc_conv_descriptor_dtype (src)); + + /* Copy the dimension information, renumbering dimension 1 to 0 and + 0 to 1. */ + gcc_assert (dest_info->dimen == 2); + gcc_assert (src_info->dimen == 2); + for (n = 0; n < 2; n++) + { + dest_info->delta[n] = integer_zero_node; + dest_info->start[n] = integer_zero_node; + dest_info->stride[n] = integer_one_node; + dest_info->dim[n] = n; + + dest_index = gfc_rank_cst[n]; + src_index = gfc_rank_cst[1 - n]; + + gfc_add_modify_expr (&se->pre, + gfc_conv_descriptor_stride (dest, dest_index), + gfc_conv_descriptor_stride (src, src_index)); + + gfc_add_modify_expr (&se->pre, + gfc_conv_descriptor_lbound (dest, dest_index), + gfc_conv_descriptor_lbound (src, src_index)); + + gfc_add_modify_expr (&se->pre, + gfc_conv_descriptor_ubound (dest, dest_index), + gfc_conv_descriptor_ubound (src, src_index)); + + if (!loop->to[n]) + { + gcc_assert (integer_zerop (loop->from[n])); + loop->to[n] = build2 (MINUS_EXPR, gfc_array_index_type, + gfc_conv_descriptor_ubound (dest, dest_index), + gfc_conv_descriptor_lbound (dest, dest_index)); + } + } + + /* Copy the data pointer. */ + dest_info->data = gfc_conv_descriptor_data_get (src); + gfc_conv_descriptor_data_set (&se->pre, dest, dest_info->data); + + /* Copy the offset. This is not changed by transposition: the top-left + element is still at the same offset as before. */ + dest_info->offset = gfc_conv_descriptor_offset (src); + gfc_add_modify_expr (&se->pre, + gfc_conv_descriptor_offset (dest), + dest_info->offset); + + if (dest_info->dimen > loop->temp_dim) + loop->temp_dim = dest_info->dimen; +} + + /* Return the number of iterations in a loop that starts at START, ends at END, and has step STEP. */ |