From patchwork Fri Sep 3 22:58:41 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Koenig X-Patchwork-Id: 63732 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 3C127B7160 for ; Sat, 4 Sep 2010 08:58:55 +1000 (EST) Received: (qmail 10833 invoked by alias); 3 Sep 2010 22:58:52 -0000 Received: (qmail 10817 invoked by uid 22791); 3 Sep 2010 22:58:51 -0000 X-SWARE-Spam-Status: No, hits=1.3 required=5.0 tests=AWL, BAYES_50, RCVD_IN_DNSWL_NONE, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from smtp6.netcologne.de (HELO smtp6.netcologne.de) (194.8.194.26) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 03 Sep 2010 22:58:44 +0000 Received: from [192.168.0.196] (xdsl-84-44-251-154.netcologne.de [84.44.251.154]) by smtp6.netcologne.de (Postfix) with ESMTP id CC0972A1196; Sat, 4 Sep 2010 00:58:41 +0200 (CEST) Subject: [patch, fortran] Fix PR 36931, more array dependencies From: Thomas Koenig To: fortran@gcc.gnu.org Cc: gcc-patches@gcc.gnu.org Date: Sat, 04 Sep 2010 00:58:41 +0200 Message-ID: <1283554721.4759.23.camel@linux-fd1f.site> Mime-Version: 1.0 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hello world, here a few more temporary eliminations, for code like a = f() + b After unsuccessfully trying to understand how to do this in trans-*, I used a transformation of the front end trees, in the front end optimization pass. Regression-tested. OK for trunk? Thomas 2010-09-04 Thomas Koenig PR fortran/36931 * frontend-passes.c (optimize_binop_array_assignment): New function. (optimize_assignment): Call it. 2010-09-04 Thomas Koenig PR fortran/36931 * gfortran.dg/dependency_35.f90: New test. Index: frontend-passes.c =================================================================== --- frontend-passes.c (Revision 163846) +++ frontend-passes.c (Arbeitskopie) @@ -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. */