re PR tree-optimization/42108 (50% performance regression)
authorRichard Biener <rguenther@suse.de>
Thu, 11 Dec 2014 15:52:47 +0000 (15:52 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 11 Dec 2014 15:52:47 +0000 (15:52 +0000)
2014-12-11  Richard Biener  <rguenther@suse.de>

PR tree-optimization/42108
* trans-stmt.c (gfc_trans_do): Execute the division computing
countm1 before the loop entry check.

* gfortran.dg/pr42108.f90: Amend.

From-SVN: r218630

gcc/fortran/ChangeLog
gcc/fortran/trans-stmt.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/pr42108.f90

index 554474c3fc42bda819607ddfdbcc6fcc14321c70..3092e3cb4a25154bcaf5ccec95211a10b3060362 100644 (file)
@@ -1,3 +1,9 @@
+2014-12-11  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/42108
+       * trans-stmt.c (gfc_trans_do): Execute the division computing
+       countm1 before the loop entry check.
+
 2014-12-11  Manuel López-Ibáñez  <manu@gcc.gnu.org>
 
        PR fortran/44054
index d28d67bc82cc6e218838a20574a6db83b377cd44..1ba382ab1930a026d22033f264d28b10fefdf789 100644 (file)
@@ -1645,15 +1645,15 @@ gfc_trans_do (gfc_code * code, tree exit_cond)
      This code is executed before we enter the loop body. We generate:
      if (step > 0)
        {
+        countm1 = (to - from) / step;
         if (to < from)
           goto exit_label;
-        countm1 = (to - from) / step;
        }
      else
        {
+        countm1 = (from - to) / -step;
         if (to > from)
           goto exit_label;
-        countm1 = (from - to) / -step;
        }
    */
 
@@ -1675,11 +1675,12 @@ gfc_trans_do (gfc_code * code, tree exit_cond)
                              fold_build2_loc (loc, MINUS_EXPR, utype,
                                               tou, fromu),
                              stepu);
-      pos = fold_build3_loc (loc, COND_EXPR, void_type_node, tmp,
-                            fold_build1_loc (loc, GOTO_EXPR, void_type_node,
-                                             exit_label),
-                            fold_build2 (MODIFY_EXPR, void_type_node,
-                                         countm1, tmp2));
+      pos = build2 (COMPOUND_EXPR, void_type_node,
+                   fold_build2 (MODIFY_EXPR, void_type_node,
+                                countm1, tmp2),
+                   build3_loc (loc, COND_EXPR, void_type_node, tmp,
+                               build1_loc (loc, GOTO_EXPR, void_type_node,
+                                           exit_label), NULL_TREE));
 
       /* For a negative step, when to > from, exit, otherwise compute
          countm1 = ((unsigned)from - (unsigned)to) / -(unsigned)step  */
@@ -1688,11 +1689,12 @@ gfc_trans_do (gfc_code * code, tree exit_cond)
                              fold_build2_loc (loc, MINUS_EXPR, utype,
                                               fromu, tou),
                              fold_build1_loc (loc, NEGATE_EXPR, utype, stepu));
-      neg = fold_build3_loc (loc, COND_EXPR, void_type_node, tmp,
-                            fold_build1_loc (loc, GOTO_EXPR, void_type_node,
-                                             exit_label),
-                            fold_build2 (MODIFY_EXPR, void_type_node,
-                                         countm1, tmp2));
+      neg = build2 (COMPOUND_EXPR, void_type_node,
+                   fold_build2 (MODIFY_EXPR, void_type_node,
+                                countm1, tmp2),
+                   build3_loc (loc, COND_EXPR, void_type_node, tmp,
+                               build1_loc (loc, GOTO_EXPR, void_type_node,
+                                           exit_label), NULL_TREE));
 
       tmp = fold_build2_loc (loc, LT_EXPR, boolean_type_node, step,
                             build_int_cst (TREE_TYPE (step), 0));
index c6a1932746d189b8ed1dc3bea9c7a1008b38ac95..4507037087e121bff820b635610b5fbb9f749f41 100644 (file)
@@ -1,3 +1,8 @@
+2014-12-11  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/42108
+       * gfortran.dg/pr42108.f90: Amend.
+
 2014-12-11  Manuel López-Ibáñez  <manu@gcc.gnu.org>
 
         * gfortran.dg/do_iterator.f90: Remove bogus dg-warning.
index 9a0a2532a78764635c4cf400a3a2fa487e41f493..020a0a13ac4daa18a7cb8fff48212bd55c9f93d3 100644 (file)
@@ -1,5 +1,5 @@
 ! { dg-do compile }
-! { dg-options "-O2 -fdump-tree-fre1" }
+! { dg-options "-O2 -fdump-tree-fre1 -fdump-tree-pre-details" }
 
 subroutine  eval(foo1,foo2,foo3,foo4,x,n,nnd)
   implicit real*8 (a-h,o-z)
@@ -21,7 +21,9 @@ subroutine  eval(foo1,foo2,foo3,foo4,x,n,nnd)
   end do
 end subroutine eval
 
+! We should have hoisted the division
+! { dg-final { scan-tree-dump "in all uses of countm1\[^\n\]* / " "pre" } }
 ! There should be only one load from n left
-
 ! { dg-final { scan-tree-dump-times "\\*n_" 1 "fre1" } }
 ! { dg-final { cleanup-tree-dump "fre1" } }
+! { dg-final { cleanup-tree-dump "pre" } }