From: tkoenig Date: Mon, 6 Sep 2010 21:40:15 +0000 (+0000) Subject: 2010-09-06 Thomas Koenig X-Git-Url: http://git.sourceforge.jp/view?a=commitdiff_plain;h=15474d415cb3ef03eafba229c674cf6b03223db0;p=pf3gnuchains%2Fgcc-fork.git 2010-09-06 Thomas Koenig PR fortran/36931 * frontend-passes.c (optimize_binop_array_assignment): New function. (optimize_assignment): Call it. 2010-09-06 Thomas Koenig PR fortran/36931 * gfortran.dg/dependency_35.f90: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@163934 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index d35cedca9d3..22810def8c2 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,5 +1,12 @@ 2010-09-06 Thomas Koenig + PR fortran/36931 + * frontend-passes.c (optimize_binop_array_assignment): New + function. + (optimize_assignment): Call it. + +2010-09-06 Thomas Koenig + PR fortran/34145 * trans-expr.c (gfc_conv_substring): If start and end of the string reference are equal, set the length to one. diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c index 14c5fe4e177..17b31fe5791 100644 --- a/gcc/fortran/frontend-passes.c +++ b/gcc/fortran/frontend-passes.c @@ -235,6 +235,77 @@ optimize_code_node (gfc_code *c) } } +/* Replace code like + a = matmul(b,c) + d + with + a = matmul(b,c) ; a = a + d + where the array function is not elemental and not allocatable + and does not depend on the left-hand side. +*/ + +static bool +optimize_binop_array_assignment (gfc_code *c, gfc_expr **rhs, bool seen_op) +{ + gfc_expr *e; + + e = *rhs; + if (e->expr_type == EXPR_OP) + { + switch (e->value.op.op) + { + /* Unary operators and exponentiation: Only look at a single + operand. */ + case INTRINSIC_NOT: + case INTRINSIC_UPLUS: + case INTRINSIC_UMINUS: + case INTRINSIC_PARENTHESES: + case INTRINSIC_POWER: + if (optimize_binop_array_assignment (c, &e->value.op.op1, seen_op)) + return true; + break; + + default: + /* Binary operators. */ + if (optimize_binop_array_assignment (c, &e->value.op.op1, true)) + return true; + + if (optimize_binop_array_assignment (c, &e->value.op.op2, true)) + return true; + + break; + } + } + else if (seen_op && e->expr_type == EXPR_FUNCTION && e->rank > 0 + && ! (e->value.function.esym + && (e->value.function.esym->attr.elemental + || e->value.function.esym->attr.allocatable)) + && ! (e->value.function.isym && e->value.function.isym->elemental)) + { + + gfc_code *n; + gfc_expr *new_expr; + + /* Insert a new assignment statement after the current one. */ + n = XCNEW (gfc_code); + n->op = EXEC_ASSIGN; + n->loc = c->loc; + n->next = c->next; + c->next = n; + + n->expr1 = gfc_copy_expr (c->expr1); + n->expr2 = c->expr2; + new_expr = gfc_copy_expr (c->expr1); + c->expr2 = e; + *rhs = new_expr; + + return true; + + } + + /* Nothing to optimize. */ + return false; +} + /* Optimizations for an assignment. */ static void @@ -259,6 +330,13 @@ optimize_assignment (gfc_code * c) } } + if (lhs->rank > 0 && gfc_check_dependency (lhs, rhs, true) == 0) + optimize_binop_array_assignment (c, &rhs, false); + + /* If we insert a statement after the current one, the surrounding loop in + optimize_code will call optimize_assignment on the inserted statement + anyway, so there is no need to call optimize_assignment again. */ + /* All direct optimizations have been done. Now it's time to optimize the rhs. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 362f5d1e2eb..cf07101cc0f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2010-09-06 Thomas Koenig + PR fortran/36931 + * gfortran.dg/dependency_35.f90: New test. + +2010-09-06 Thomas Koenig + PR fortran/34145 * gfortran.dg/char_length_17.f90: New test. diff --git a/gcc/testsuite/gfortran.dg/dependency_35.f90 b/gcc/testsuite/gfortran.dg/dependency_35.f90 new file mode 100644 index 00000000000..11b9e8b9449 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/dependency_35.f90 @@ -0,0 +1,24 @@ +! { dg-do compile } +! { dg-options "-Warray-temporaries -O" } +module foo + implicit none +contains + pure function bar(i,j) + integer, intent(in) :: i,j + integer, dimension(2,2) :: bar + bar = 33 + end function bar +end module foo + +program main + use foo + implicit none + integer a(2,2), b(2,2),c(2,2), d(2,2), e(2) + + read (*,*) b, c, d + a = matmul(b,c) + d + a = b + bar(3,4) + a = bar(3,4)*5 + b + e = sum(b,1) + 3 +end program main +! { dg-final { cleanup-modules "foo" } }