re PR tree-optimization/42108 (50% performance regression)

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
This commit is contained in:
Richard Biener 2014-12-11 15:52:47 +00:00 committed by Richard Biener
parent b214b73391
commit d17271de7f
4 changed files with 29 additions and 14 deletions

View 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

View 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));

View 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.

View 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" } }