diff options
author | Richard Guenther <rguenther@suse.de> | 2011-08-04 12:22:42 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2011-08-04 12:22:42 +0000 |
commit | 428f80e65119aca0c7c03d5382d684dfdeaa7ac7 (patch) | |
tree | 1e961cfbf89e2f48a7457ac4fcac919d87391ec7 /gcc | |
parent | 9515740f004bf41a1a084285943cf73eb7316ef8 (diff) | |
download | gcc-428f80e65119aca0c7c03d5382d684dfdeaa7ac7.zip gcc-428f80e65119aca0c7c03d5382d684dfdeaa7ac7.tar.gz gcc-428f80e65119aca0c7c03d5382d684dfdeaa7ac7.tar.bz2 |
re PR tree-optimization/49957 (Fails to SLP in 410.bwaves)
2011-08-04 Richard Guenther <rguenther@suse.de>
PR fortran/49957
* trans-array.c (add_to_offset): New function.
(gfc_conv_array_ref): Build the array index expression in optimally
associated order.
(gfc_walk_variable_expr): Adjust for the backward walk.
* gfortran.dg/vect/O3-pr49957.f: New testcase.
From-SVN: r177368
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/fortran/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/fortran/trans-array.c | 40 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/vect/O3-pr49957.f | 16 |
4 files changed, 57 insertions, 12 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 912c011ba..d794d14a 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,11 @@ +2011-08-04 Richard Guenther <rguenther@suse.de> + + PR fortran/49957 + * trans-array.c (add_to_offset): New function. + (gfc_conv_array_ref): Build the array index expression in optimally + associated order. + (gfc_walk_variable_expr): Adjust for the backward walk. + 2011-08-02 Daniel Kraft <d@domob.eu> PR fortran/49885 diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index 85acf0c..3a75658 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -2622,6 +2622,22 @@ gfc_conv_tmp_array_ref (gfc_se * se) gfc_advance_se_ss_chain (se); } +/* Add T to the offset pair *OFFSET, *CST_OFFSET. */ + +static void +add_to_offset (tree *cst_offset, tree *offset, tree t) +{ + if (TREE_CODE (t) == INTEGER_CST) + *cst_offset = int_const_binop (PLUS_EXPR, *cst_offset, t); + else + { + if (!integer_zerop (*offset)) + *offset = fold_build2_loc (input_location, PLUS_EXPR, + gfc_array_index_type, *offset, t); + else + *offset = t; + } +} /* Build an array reference. se->expr already holds the array descriptor. This should be either a variable, indirect variable reference or component @@ -2634,7 +2650,7 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_symbol * sym, locus * where) { int n; - tree index; + tree offset, cst_offset; tree tmp; tree stride; gfc_se indexse; @@ -2669,10 +2685,12 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_symbol * sym, return; } - index = gfc_index_zero_node; + cst_offset = offset = gfc_index_zero_node; + add_to_offset (&cst_offset, &offset, gfc_conv_array_offset (se->expr)); - /* Calculate the offsets from all the dimensions. */ - for (n = 0; n < ar->dimen; n++) + /* Calculate the offsets from all the dimensions. Make sure to associate + the final offset so that we form a chain of loop invariant summands. */ + for (n = ar->dimen - 1; n >= 0; n--) { /* Calculate the index for this dimension. */ gfc_init_se (&indexse, se); @@ -2741,19 +2759,17 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_symbol * sym, indexse.expr, stride); /* And add it to the total. */ - index = fold_build2_loc (input_location, PLUS_EXPR, - gfc_array_index_type, index, tmp); + add_to_offset (&cst_offset, &offset, tmp); } - tmp = gfc_conv_array_offset (se->expr); - if (!integer_zerop (tmp)) - index = fold_build2_loc (input_location, PLUS_EXPR, - gfc_array_index_type, index, tmp); + if (!integer_zerop (cst_offset)) + offset = fold_build2_loc (input_location, PLUS_EXPR, + gfc_array_index_type, offset, cst_offset); /* Access the calculated element. */ tmp = gfc_conv_array_data (se->expr); tmp = build_fold_indirect_ref (tmp); - se->expr = gfc_build_array_ref (tmp, index, sym->backend_decl); + se->expr = gfc_build_array_ref (tmp, offset, sym->backend_decl); } @@ -7575,7 +7591,7 @@ gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr) switch (ar->type) { case AR_ELEMENT: - for (n = 0; n < ar->dimen + ar->codimen; n++) + for (n = ar->dimen + ar->codimen - 1; n >= 0; n--) { newss = gfc_get_ss (); newss->type = GFC_SS_SCALAR; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d1d4569..9145186 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-08-04 Richard Guenther <rguenther@suse.de> + + PR fortran/49957 + * gfortran.dg/vect/O3-pr49957.f: New testcase. + 2011-08-04 Ian Bolton <ian.bolton@arm.com> * gcc.target/arm/vfp-1.c: no large negative offsets on Thumb2. diff --git a/gcc/testsuite/gfortran.dg/vect/O3-pr49957.f b/gcc/testsuite/gfortran.dg/vect/O3-pr49957.f new file mode 100644 index 0000000..a973567 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vect/O3-pr49957.f @@ -0,0 +1,16 @@ +! { dg-do compile } +! { dg-require-effective-target vect_double } + subroutine shell(nx,ny,nz,q,dq) + implicit none + integer i,j,k,l,nx,ny,nz + real*8 q(5,nx,ny),dq(5,nx,ny) + do j=1,ny + do i=1,nx + do l=1,5 + q(l,i,j)=q(l,i,j)+dq(l,i,j) + enddo + enddo + enddo + return + end +! { dg-final { scan-tree-dump "vectorized 1 loops" "vect" { xfail vect_no_align } } } |