From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20124 invoked by alias); 7 May 2015 16:35:48 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 20107 invoked by uid 89); 7 May 2015 16:35:48 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_NONE,SPF_PASS,T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-Spam-User: qpsmtpd, 2 recipients X-HELO: smtp25.services.sfr.fr Received: from smtp25.services.sfr.fr (HELO smtp25.services.sfr.fr) (93.17.128.119) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Thu, 07 May 2015 16:35:45 +0000 Received: from filter.sfr.fr (localhost [86.72.15.69]) by msfrf2514.sfr.fr (SMTP Server) with ESMTP id 4BF447000176; Thu, 7 May 2015 18:35:42 +0200 (CEST) Authentication-Results: sfrmc.priv.atos.fr; dkim=none (no signature); dkim-adsp=none (no policy) header.from=mikael.morin@sfr.fr Received: from tolstoi.localhost (69.15.72.86.rev.sfr.net [86.72.15.69]) (using TLSv1 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by msfrf2514.sfr.fr (SMTP Server) with ESMTP id B89F1700007E; Thu, 7 May 2015 18:35:41 +0200 (CEST) X-SFR-UUID: 20150507163541756.B89F1700007E@msfrf2514.sfr.fr Message-ID: <554B9447.9060701@sfr.fr> Date: Thu, 07 May 2015 16:35:00 -0000 From: Mikael Morin User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.6.0 MIME-Version: 1.0 To: Andre Vehreschild , GCC-Patches-ML , GCC-Fortran-ML Subject: Re: [Patch, fortran, pr65894, v1] [6 Regression] severe regression in gfortran 6.0.0 References: <20150507115242.10f4061c@gmx.de> In-Reply-To: <20150507115242.10f4061c@gmx.de> Content-Type: multipart/mixed; boundary=------------010706080708020604070203 X-IsSubscribed: yes X-SW-Source: 2015-05/txt/msg00569.txt.bz2 This is a multi-part message in MIME format. --------------010706080708020604070203 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Content-length: 1564 Le 07/05/2015 11:52, Andre Vehreschild a écrit : > Hi all, > > my work on pr60322 caused a regression on trunk. This patch fixes it. The > regression had two causes: > 1. Not taking the correct attribute for BT_CLASS objects with allocatable > components into account (chunk 1), and > 2. taking the address of an address (chunk 2). When a class or derived typed > scalar object is to be returned as a reference and a scalarizer is present, > then the address of the address of the object was returned. The former code > was meant to return the address of an array element for which taking the > address was ok. The patch now prevents taking the additional address when > the object is scalar. > Hello, The "chunk 2" fix should go in gfc_conv_expr, so that gfc_add_loop_ss_code's "can_be_null_ref" condition matches the one in gfc_conv_expr. Both functions work together, if references are generated in gfc_add_loop_ss_code, they should be used as reference in gfc_conv_expr. Same if values are generated. About the condition of the first chunk, I don't understand what it's good for. So I propose the attached patch instead. It creates a new function to decide between reference and value, so that gfc_add_loop_ss_code and gfc_conv_expr are kept in sync. As the new function needs information about the dummy argument, the dummy symbol is saved to a new field in gfc_ss_info. And the "chunk 1" condition is reverted to its previous state. The testcase is yours. regression tested on x86_64-unknown-linux-gnu. OK for trunk? Mikael --------------010706080708020604070203 Content-Type: text/plain; charset=UTF-8; name="pr65894_v2.CL" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="pr65894_v2.CL" Content-length: 830 MjAxNS0wNS0wNyAgQW5kcmUgVmVocmVzY2hpbGQgIDx2ZWhyZUBnbXguZGU+ CgkgICAgTWlrYWVsIE1vcmluICA8bWlrYWVsQGdjYy5nbnUub3JnPgoKCVBS IGZvcnRyYW4vNjU4OTQKCSogdHJhbnMtYXJyYXkuaCAoZ2ZjX3NjYWxhcl9l bGVtZW50YWxfYXJnX3NhdmVkX2FzX3JlZmVyZW5jZSk6CglOZXcgcHJvdG90 eXBlLgoJKiB0cmFucy1hcnJheS5jIChnZmNfc2NhbGFyX2VsZW1lbnRhbF9h cmdfc2F2ZWRfYXNfcmVmZXJlbmNlKToKCU5ldyBmdW5jdGlvbi4KCShnZmNf YWRkX2xvb3Bfc3NfY29kZSk6IFVzZSBnZmNfc2NhbGFyX2VsZW1lbnRhbF9h cmdfc2F2ZWRfYXNfcmVmZXJlbmNlCglhcyBjb25kaXRpb25hbC4KCShnZmNf d2Fsa19lbGVtZW50YWxfZnVuY3Rpb25fYXJncyk6IFNldCB0aGUgZHVtbXlf YXJnIGZpZWxkLgoJKiB0cmFucy5oIChnZmNfc3NfaW5mbyk6IE5ldyBzdWJm aWVsZCBkdW1teV9hcmcuCgkqIHRyYW5zLWV4cHIuYyAoZ2ZjX2NvbnZfcHJv Y2VkdXJlX2NhbGwpOiBSZXZlcnQgcjIyMjM2MS4KCShnZmNfY29udl9leHBy KTogVXNlIGdmY19zY2FsYXJfZWxlbWVudGFsX2FyZ19zYXZlZF9hc19yZWZl cmVuY2UKCWFzIGNvbmRpdGlvbmFsLgoJCgoK --------------010706080708020604070203 Content-Type: text/x-patch; name="pr65894_v2.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="pr65894_v2.diff" Content-length: 5574 diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index a17f431..fb9cbc4 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -2427,6 +2427,41 @@ set_vector_loop_bounds (gfc_ss * ss) } +/* Tells whether a scalar argument to an elemental procedure is saved out + of a scalarization loop as a value or as a reference. */ + +bool +gfc_scalar_elemental_arg_saved_as_reference (gfc_ss_info * ss_info) +{ + if (ss_info->type != GFC_SS_REFERENCE) + return false; + + /* If the actual argument can be absent (in other words, it can + be a NULL reference), don't try to evaluate it; pass instead + the reference directly. */ + if (ss_info->can_be_null_ref) + return true; + + /* If the expression is of polymorphic type, it's actual size is not known, + so we avoid copying it anywhere. */ + if (ss_info->data.scalar.dummy_arg + && ss_info->data.scalar.dummy_arg->ts.type == BT_CLASS + && ss_info->expr->ts.type == BT_CLASS) + return true; + + /* If the expression is a data reference of aggregate type, + avoid a copy by saving a reference to the content. */ + if (ss_info->expr->expr_type == EXPR_VARIABLE + && (ss_info->expr->ts.type == BT_DERIVED + || ss_info->expr->ts.type == BT_CLASS)) + return true; + + /* Otherwise the expression is evaluated to a temporary variable before the + scalarization loop. */ + return false; +} + + /* Add the pre and post chains for all the scalar expressions in a SS chain to loop. This is called after the loop parameters have been calculated, but before the actual scalarizing loops. */ @@ -2495,19 +2530,11 @@ gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, bool subscript, case GFC_SS_REFERENCE: /* Scalar argument to elemental procedure. */ gfc_init_se (&se, NULL); - if (ss_info->can_be_null_ref || (expr->symtree - && (expr->symtree->n.sym->ts.type == BT_DERIVED - || expr->symtree->n.sym->ts.type == BT_CLASS))) - { - /* If the actual argument can be absent (in other words, it can - be a NULL reference), don't try to evaluate it; pass instead - the reference directly. The reference is also needed when - expr is of type class or derived. */ - gfc_conv_expr_reference (&se, expr); - } + if (gfc_scalar_elemental_arg_saved_as_reference (ss_info)) + gfc_conv_expr_reference (&se, expr); else { - /* Otherwise, evaluate the argument outside the loop and pass + /* Evaluate the argument outside the loop and pass a reference to the value. */ gfc_conv_expr (&se, expr); } @@ -9101,7 +9128,8 @@ gfc_walk_elemental_function_args (gfc_ss * ss, gfc_actual_arglist *arg, gcc_assert (type == GFC_SS_SCALAR || type == GFC_SS_REFERENCE); newss = gfc_get_scalar_ss (head, arg->expr); newss->info->type = type; - + if (dummy_arg) + newss->info->data.scalar.dummy_arg = dummy_arg->sym; } else scalar = 0; diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h index 76bad2a..ad9a292 100644 --- a/gcc/fortran/trans-array.h +++ b/gcc/fortran/trans-array.h @@ -105,6 +105,8 @@ gfc_ss *gfc_get_temp_ss (tree, tree, int); /* Allocate a new scalar type ss. */ gfc_ss *gfc_get_scalar_ss (gfc_ss *, gfc_expr *); +bool gfc_scalar_elemental_arg_saved_as_reference (gfc_ss_info *); + /* Calculates the lower bound and stride of array sections. */ void gfc_conv_ss_startstride (gfc_loopinfo *); diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c index 9c5ce7d..c71037f 100644 --- a/gcc/fortran/trans-expr.c +++ b/gcc/fortran/trans-expr.c @@ -4735,19 +4735,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, gfc_init_se (&parmse, se); parm_kind = ELEMENTAL; - /* For all value functions or polymorphic scalar non-pointer - non-allocatable variables use the expression in e directly. This - ensures, that initializers of polymorphic entities are correctly - copied. */ - if (fsym && (fsym->attr.value - || (e->expr_type == EXPR_VARIABLE - && fsym->ts.type == BT_DERIVED - && e->ts.type == BT_DERIVED - && !e->ts.u.derived->attr.dimension - && !e->rank - && (!e->symtree - || (!e->symtree->n.sym->attr.allocatable - && !e->symtree->n.sym->attr.pointer))))) + if (fsym && fsym->attr.value) gfc_conv_expr (&parmse, e); else gfc_conv_expr_reference (&parmse, e); @@ -7310,11 +7298,9 @@ gfc_conv_expr (gfc_se * se, gfc_expr * expr) ss_info = ss->info; /* Substitute a scalar expression evaluated outside the scalarization - loop. */ + loop. */ se->expr = ss_info->data.scalar.value; - /* If the reference can be NULL, the value field contains the reference, - not the value the reference points to (see gfc_add_loop_ss_code). */ - if (ss_info->can_be_null_ref) + if (gfc_scalar_elemental_arg_saved_as_reference (ss_info)) se->expr = build_fold_indirect_ref_loc (input_location, se->expr); se->string_length = ss_info->string_length; diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h index e2a1fea..570b5b8 100644 --- a/gcc/fortran/trans.h +++ b/gcc/fortran/trans.h @@ -206,6 +206,9 @@ typedef struct gfc_ss_info /* If type is GFC_SS_SCALAR or GFC_SS_REFERENCE. */ struct { + /* If the scalar is passed as actual argument to an (elemental) procedure, + this is the symbol of the corresponding dummy argument. */ + gfc_symbol *dummy_arg; tree value; } scalar; --------------010706080708020604070203--