diff options
author | sayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-02-18 20:05:00 +0000 |
---|---|---|
committer | sayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-02-18 20:05:00 +0000 |
commit | eb744cd410c8916c74a6b6bcbac95bf56e9ff372 (patch) | |
tree | e0bd20d27931c0f092bc30265db72ff3f635d2eb /gcc | |
parent | d374ac2e2fc9cfdf28f6f2f1bf95874cc45b458d (diff) | |
download | gcc-eb744cd410c8916c74a6b6bcbac95bf56e9ff372.tar.gz |
* trans-array.c (gfc_build_constant_array_constructor): When the
shape of the constructor is known, use that to construct the
gfc_array_spec.
(gfc_trans_constant_array_constructor): Initialize the "info"
information for all of the dimensions of the array constructor.
(constant_array_constructor_loop_size): New function.
(gfc_trans_array_constructor): Use it to determine whether a
loop is suitable for "constant array constructor" optimization.
* trans-intrinsic.c (gfc_conv_intrinsic_anyall): Use fold_build2
instead of build2, to avoid conditions like "(a != b) != 0".
* gfortran.dg/array_constructor_15.f90: New test case.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@122103 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/fortran/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/fortran/trans-array.c | 78 | ||||
-rw-r--r-- | gcc/fortran/trans-intrinsic.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/array_constructor_15.f90 | 7 |
5 files changed, 90 insertions, 19 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 43c10ee7792..388bfd60cd8 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,4 +1,18 @@ 2007-02-18 Roger Sayle <roger@eyesopen.com> + + * trans-array.c (gfc_build_constant_array_constructor): When the + shape of the constructor is known, use that to construct the + gfc_array_spec. + (gfc_trans_constant_array_constructor): Initialize the "info" + information for all of the dimensions of the array constructor. + (constant_array_constructor_loop_size): New function. + (gfc_trans_array_constructor): Use it to determine whether a + loop is suitable for "constant array constructor" optimization. + + * trans-intrinsic.c (gfc_conv_intrinsic_anyall): Use fold_build2 + instead of build2, to avoid conditions like "(a != b) != 0". + +2007-02-18 Roger Sayle <roger@eyesopen.com> Paul Thomas <pault@gcc.gnu.org> PR fortran/30400 @@ -11,7 +25,7 @@ PR fortran/30793 * trans-decl.c (gfc_generate_function_code): Do not initialize - pointers to derived components. + pointers to derived components. 2007-02-15 Sandra Loosemore <sandra@codesourcery.com> Brooks Moses <brooks.moses@codesourcery.com> diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index 64ea9d6f436..683c8bdf6e1 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -1453,7 +1453,7 @@ gfc_build_constant_array_constructor (gfc_expr * expr, tree type) gfc_constructor *c; gfc_array_spec as; gfc_se se; - + int i; /* First traverse the constructor list, converting the constants to tree to build an initializer. */ @@ -1478,10 +1478,21 @@ gfc_build_constant_array_constructor (gfc_expr * expr, tree type) memset (&as, 0, sizeof (gfc_array_spec)); - as.rank = 1; + as.rank = expr->rank; as.type = AS_EXPLICIT; - as.lower[0] = gfc_int_expr (0); - as.upper[0] = gfc_int_expr (nelem - 1); + if (!expr->shape) + { + as.lower[0] = gfc_int_expr (0); + as.upper[0] = gfc_int_expr (nelem - 1); + } + else + for (i = 0; i < expr->rank; i++) + { + int tmp = (int) mpz_get_si (expr->shape[i]); + as.lower[i] = gfc_int_expr (0); + as.upper[i] = gfc_int_expr (tmp - 1); + } + tmptype = gfc_get_nodesc_array_type (type, &as, 3); init = build_constructor_from_list (tmptype, nreverse (list)); @@ -1512,6 +1523,7 @@ gfc_trans_constant_array_constructor (gfc_loopinfo * loop, { gfc_ss_info *info; tree tmp; + int i; tmp = gfc_build_constant_array_constructor (ss->expr, type); @@ -1522,16 +1534,54 @@ gfc_trans_constant_array_constructor (gfc_loopinfo * loop, info->offset = fold_build1 (NEGATE_EXPR, gfc_array_index_type, loop->from[0]); - info->delta[0] = gfc_index_zero_node; - info->start[0] = gfc_index_zero_node; - info->end[0] = gfc_index_zero_node; - info->stride[0] = gfc_index_one_node; - info->dim[0] = 0; + for (i = 0; i < info->dimen; i++) + { + info->delta[i] = gfc_index_zero_node; + info->start[i] = gfc_index_zero_node; + info->end[i] = gfc_index_zero_node; + info->stride[i] = gfc_index_one_node; + info->dim[i] = i; + } if (info->dimen > loop->temp_dim) loop->temp_dim = info->dimen; } +/* Helper routine of gfc_trans_array_constructor to determine if the + bounds of the loop specified by LOOP are constant and simple enough + to use with gfc_trans_constant_array_constructor. Returns the + the iteration count of the loop if suitable, and NULL_TREE otherwise. */ + +static tree +constant_array_constructor_loop_size (gfc_loopinfo * loop) +{ + tree size = gfc_index_one_node; + tree tmp; + int i; + + for (i = 0; i < loop->dimen; i++) + { + /* If the bounds aren't constant, return NULL_TREE. */ + if (!INTEGER_CST_P (loop->from[i]) || !INTEGER_CST_P (loop->to[i])) + return NULL_TREE; + if (!integer_zerop (loop->from[i])) + { + /* Only allow non-zero "from" in one-dimensional arrays. */ + if (loop->dimen != 1) + return NULL_TREE; + tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, + loop->to[i], loop->from[i]); + } + else + tmp = loop->to[i]; + tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, + tmp, gfc_index_one_node); + size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp); + } + + return size; +} + /* Array constructors are handled by constructing a temporary, then using that within the scalarization loop. This is not optimal, but seems by far the @@ -1584,17 +1634,13 @@ gfc_trans_array_constructor (gfc_loopinfo * loop, gfc_ss * ss) } /* Special case constant array constructors. */ - if (!dynamic - && loop->dimen == 1 - && INTEGER_CST_P (loop->from[0]) - && INTEGER_CST_P (loop->to[0])) + if (!dynamic) { unsigned HOST_WIDE_INT nelem = gfc_constant_array_constructor_p (c); if (nelem > 0) { - tree diff = fold_build2 (MINUS_EXPR, gfc_array_index_type, - loop->to[0], loop->from[0]); - if (compare_tree_int (diff, nelem - 1) == 0) + tree size = constant_array_constructor_loop_size (loop); + if (size && compare_tree_int (size, nelem) == 0) { gfc_trans_constant_array_constructor (loop, ss, type); return; diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c index e6bc46f228d..c041b630e77 100644 --- a/gcc/fortran/trans-intrinsic.c +++ b/gcc/fortran/trans-intrinsic.c @@ -1604,8 +1604,8 @@ gfc_conv_intrinsic_anyall (gfc_se * se, gfc_expr * expr, int op) gfc_conv_expr_val (&arrayse, actual->expr); gfc_add_block_to_block (&body, &arrayse.pre); - tmp = build2 (op, boolean_type_node, arrayse.expr, - build_int_cst (TREE_TYPE (arrayse.expr), 0)); + tmp = fold_build2 (op, boolean_type_node, arrayse.expr, + build_int_cst (TREE_TYPE (arrayse.expr), 0)); tmp = build3_v (COND_EXPR, tmp, found, build_empty_stmt ()); gfc_add_expr_to_block (&body, tmp); gfc_add_block_to_block (&body, &arrayse.post); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5870a68200c..3151a7dfba4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2007-02-18 Roger Sayle <roger@eyesopen.com> + * gfortran.dg/array_constructor_15.f90: New test case. + +2007-02-18 Roger Sayle <roger@eyesopen.com> + * gfortran.dg/forall_10.f90: New test case. 2007-02-18 Eric Botcazou <ebotcazou@adacore.com> diff --git a/gcc/testsuite/gfortran.dg/array_constructor_15.f90 b/gcc/testsuite/gfortran.dg/array_constructor_15.f90 new file mode 100644 index 00000000000..71260169d58 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/array_constructor_15.f90 @@ -0,0 +1,7 @@ +! { dg-do compile } +! { dg-options "-O2 -fdump-tree-original" } + integer :: x(2,2) + if (any(x(:,:) .ne. reshape ((/ 3, 1, 4, 1 /), (/ 2, 2 /)))) call abort () +end +! { dg-final { scan-tree-dump-times "atmp" 0 "original" } } +! { dg-final { cleanup-tree-dump "original" } } |