From patchwork Sun Mar 24 21:46:37 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Koenig X-Patchwork-Id: 230495 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]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 313AE2C008A for ; Mon, 25 Mar 2013 08:47:38 +1100 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:subject:references :in-reply-to:content-type; q=dns; s=default; b=N32IlJQdGLrk1kkSk MhusjrX6FfkNDLytqxwNF8ypdkYKPmG5Do3kBxrZvReFvbLfemJ8DzNZj1TK1kw1 6nskRSGz7EZVID3GkrtrRKlubGmzCmz7ZpWqk/0jA/aLRFG0k8kEm6rREmxx6DYE Ae9MTD8FuY/iZXWlMK+a+N3Vgg= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:subject:references :in-reply-to:content-type; s=default; bh=+ElqoDoI4BYv9H3Bns0itdS NzOI=; b=YRfOCOFi6Qkpg88LTRjEi4bzJ8XA3qJu9Di7uY/tn3EJbTp5l1k4xID Dxii4aPXjT83ZQNS3I9Iw5txjk1LEqx9hOSLHs9Uo7VJASAvXoxlroV8XpneBKSy 3d0rqn4p2NFXzjxOLx77PfG6KUFpfnQyyxU5kCfTo++tIR6MT5yw= Received: (qmail 22898 invoked by alias); 24 Mar 2013 21:46:54 -0000 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 Received: (qmail 22517 invoked by uid 89); 24 Mar 2013 21:46:46 -0000 X-Spam-SWARE-Status: No, score=-3.1 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Spam-User: qpsmtpd, 2 recipients Received: from cc-smtpout3.netcologne.de (HELO cc-smtpout3.netcologne.de) (89.1.8.213) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Sun, 24 Mar 2013 21:46:42 +0000 Received: from cc-smtpin2.netcologne.de (cc-smtpin2.netcologne.de [89.1.8.202]) by cc-smtpout3.netcologne.de (Postfix) with ESMTP id 03BFE11F28; Sun, 24 Mar 2013 22:46:39 +0100 (CET) Received: from [192.168.0.107] (xdsl-87-79-195-40.netcologne.de [87.79.195.40]) by cc-smtpin2.netcologne.de (Postfix) with ESMTPSA id C881111D91; Sun, 24 Mar 2013 22:46:37 +0100 (CET) Message-ID: <514F743D.6020704@netcologne.de> Date: Sun, 24 Mar 2013 22:46:37 +0100 From: Thomas Koenig User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130307 Thunderbird/17.0.4 MIME-Version: 1.0 To: fortran@gcc.gnu.org, gcc-patches Subject: Re: [patch, fortran, 4.9] Improve efficiency of array constructor operators References: <51458DD6.8000200@netcologne.de> In-Reply-To: <51458DD6.8000200@netcologne.de> X-Virus-Found: No Hello world, this updated patch fixes a regression in my previous patch, with a test case for that regression also attached. Regression-tested. OK for trunk? Thomas 2013-03-24 Thomas Koenig PR fortran/55806 * frontend-passes.c (optimize_code): Keep track of current code to make code insertion possible. (combine_array_constructor): New function. (optimize_op): Call it. 2013-03-24 Thomas Koenig PR fortran/55806 * gfortran.dg/array_constructor_43.f90: New test. * gfortran.dg/random_seed_3.f90: New test. Index: frontend-passes.c =================================================================== --- frontend-passes.c (Revision 196748) +++ frontend-passes.c (Arbeitskopie) @@ -135,6 +135,10 @@ optimize_code (gfc_code **c, int *walk_subtrees AT else count_arglist = 0; + current_code = c; + inserted_block = NULL; + changed_statement = NULL; + if (op == EXEC_ASSIGN) optimize_assignment (*c); return 0; @@ -991,13 +995,97 @@ optimize_lexical_comparison (gfc_expr *e) return false; } +/* Combine stuff like [a]>b into [a>b], for easier optimization later. Do not + do CHARACTER because of possible pessimization involving character + lengths. */ + +static bool +combine_array_constructor (gfc_expr *e) +{ + + gfc_expr *op1, *op2; + gfc_expr *scalar; + gfc_expr *new_expr; + gfc_constructor *c, *new_c; + gfc_constructor_base oldbase, newbase; + bool scalar_first; + + /* Array constructors have rank one. */ + if (e->rank != 1) + return false; + + op1 = e->value.op.op1; + op2 = e->value.op.op2; + + if (op1->expr_type == EXPR_ARRAY && op2->rank == 0) + scalar_first = false; + else if (op2->expr_type == EXPR_ARRAY && op1->rank == 0) + { + scalar_first = true; + op1 = e->value.op.op2; + op2 = e->value.op.op1; + } + else + return false; + + if (op2->ts.type == BT_CHARACTER) + return false; + + if (op2->expr_type == EXPR_CONSTANT) + scalar = gfc_copy_expr (op2); + else + scalar = create_var (gfc_copy_expr (op2)); + + oldbase = op1->value.constructor; + newbase = NULL; + e->expr_type = EXPR_ARRAY; + + c = gfc_constructor_first (oldbase); + + for (c = gfc_constructor_first (oldbase); c; + c = gfc_constructor_next (c)) + { + new_expr = gfc_get_expr (); + new_expr->ts = e->ts; + new_expr->expr_type = EXPR_OP; + new_expr->rank = c->expr->rank; + new_expr->where = c->where; + new_expr->value.op.op = e->value.op.op; + + if (scalar_first) + { + new_expr->value.op.op1 = gfc_copy_expr (scalar); + new_expr->value.op.op2 = gfc_copy_expr (c->expr); + } + else + { + new_expr->value.op.op1 = gfc_copy_expr (c->expr); + new_expr->value.op.op2 = gfc_copy_expr (scalar); + } + + new_c = gfc_constructor_append_expr (&newbase, new_expr, &(e->where)); + new_c->iterator = c->iterator; + c->iterator = NULL; + } + + gfc_free_expr (op1); + gfc_free_expr (op2); + + e->value.constructor = newbase; + return true; +} + /* Recursive optimization of operators. */ static bool optimize_op (gfc_expr *e) { + bool changed; + gfc_intrinsic_op op = e->value.op.op; + changed = false; + /* Only use new-style comparisons. */ switch(op) { @@ -1037,8 +1125,16 @@ optimize_op (gfc_expr *e) case INTRINSIC_NE: case INTRINSIC_GT: case INTRINSIC_LT: - return optimize_comparison (e, op); + changed = optimize_comparison (e, op); + /* Fall through */ + /* Look at array constructors. */ + case INTRINSIC_PLUS: + case INTRINSIC_MINUS: + case INTRINSIC_TIMES: + case INTRINSIC_DIVIDE: + return combine_array_constructor (e) || changed; + default: break; }