summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>2007-02-18 20:05:00 +0000
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>2007-02-18 20:05:00 +0000
commiteb744cd410c8916c74a6b6bcbac95bf56e9ff372 (patch)
treee0bd20d27931c0f092bc30265db72ff3f635d2eb /gcc
parentd374ac2e2fc9cfdf28f6f2f1bf95874cc45b458d (diff)
downloadgcc-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/ChangeLog16
-rw-r--r--gcc/fortran/trans-array.c78
-rw-r--r--gcc/fortran/trans-intrinsic.c4
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gfortran.dg/array_constructor_15.f907
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" } }