From patchwork Fri Aug 24 15:12:43 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikael Morin X-Patchwork-Id: 179859 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 107A02C00C4 for ; Sat, 25 Aug 2012 01:13:46 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1346426027; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Content-Type:MIME-Version:From:To:Message-ID:In-Reply-To: References:Subject:Date:Mailing-List:Precedence:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:Sender: Delivered-To; bh=u6GlZLisUt0NnAmRiBcQgMBmHFk=; b=dpj+eny23Qzg1Uf IZWIxrWr3+wYYQZqKOa3h2oCDA8GeM7XlBLuMThlJjiWND2eNJAQ1/yu22TepR5t BZqZ9gNwhBipf9a3yd80XpFMZZ8rRMj4pdUNKMN4fGTNsH89ajDp/ACxLHRxkZvg 4pP9nLMnByU+FlG34QbvIHR3kTUE= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:X-SFR-UUID:Content-Type:MIME-Version:From:To:Message-ID:In-Reply-To:References:Subject:Date:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=RrFOy+g6ccFkjYAD/J/BAWCuzPlkWccINGK7JViA7Hle4rQFuXx2I0K9F3le5Z OR/bmUUA1yb8vFdYB5hE1qturR1Vk/7ZbOqtwixetAUk7imXisd2cbB1v/z3FNyx U8afirhfxoznQ3DesnFEQq0xI32DaRbdVfDURt0QqbaW0=; Received: (qmail 3737 invoked by alias); 24 Aug 2012 15:13:04 -0000 Received: (qmail 3394 invoked by uid 22791); 24 Aug 2012 15:12:58 -0000 X-SWARE-Spam-Status: No, hits=-1.1 required=5.0 tests=AWL, BAYES_50, KHOP_THREADED, RCVD_IN_DNSWL_NONE, RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from smtp24.services.sfr.fr (HELO smtp24.services.sfr.fr) (93.17.128.81) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 24 Aug 2012 15:12:44 +0000 Received: from filter.sfr.fr (localhost [127.0.0.1]) by msfrf2402.sfr.fr (SMTP Server) with ESMTP id 959A97000046; Fri, 24 Aug 2012 17:12:43 +0200 (CEST) Received: from [192.168.1.58] (37.15.72.86.rev.sfr.net [86.72.15.37]) by msfrf2402.sfr.fr (SMTP Server) with ESMTP id 2BAF67000086; Fri, 24 Aug 2012 17:12:43 +0200 (CEST) X-SFR-UUID: 20120824151243179.2BAF67000086@msfrf2402.sfr.fr MIME-Version: 1.0 From: Mikael Morin To: gfortran , GCC patches Message-ID: <20120824151014.6294.99503@marvin> In-Reply-To: <20120824150957.6294.56836@marvin> References: <20120824150957.6294.56836@marvin> Subject: [Patch, fortran] [3/5] PR 45586: Use the right type to build structure constructors. Date: Fri, 24 Aug 2012 17:12:43 +0200 (CEST) X-IsSubscribed: yes 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 This patch makes the LTO failures go away. It propagates the information that we want (non-)restrict types from gfc_trans_assignment_1 (where we have access to the LHS) down to gfc_conv_structure (where the type specialization happens). The call graph is roughly as follows (to be seen with a fixed font): gfc_trans_assignment_1 [set restricted] \ +-> gfc_conv_expr <------------------------------+-------+ \ \ \ +-> gfc_conv_structure [use restricted] <----+-|-----+ | \ \| \| +-> gfc_conv_initializer ----------------+ + \ | +-> gfc_conv_array_initializer -----------+ To avoid polluting every function (and every caller) with a restricted flag I have added it to gfc_se, which has already a good deal of request specification flags. Unfortunately, gfc_conv_initializer and gfc_conv_array_initializer don't have a gfc_se arg, so they don't avoid the restricted argument. To avoid changing all gfc_conv_initializer callers it is made a wrapper around the function with the restricted argument. I didn't do the same for gfc_conv_array_initializer as it has a single caller, so the interface change is harmless/non-invasive. As I had to update the declaration I moved it from gfortran.h to trans-array.h by the way. OK? 2012-08-22 Mikael Morin * trans.h (struct gfc_se): New flag want_restricted_types. * trans-expr.c (gfc_trans_assignment_1): Set the want_restricted_types field. (gfc_conv_structure): Use the new field to choose the variant type that is wanted. (gfc_conv_initializer): Make it a wrapper around the old function renamed to... (conv_initializer_1): ... this. Add the RESTRICTED argument. Pass it down. * gfortran.h (gfc_conv_array_initializer): Move declaration... * trans-array.h (gfc_conv_array_initializer): ... here. Add a boolean argument. * trans-array.c (gfc_conv_array_initializer): Add the RESTRICTED argument. Pass it down. diff --git a/gfortran.h b/gfortran.h index 4c8a856..c11cb12 100644 --- a/gfortran.h +++ b/gfortran.h @@ -2837,7 +2837,6 @@ gfc_try gfc_array_size (gfc_expr *, mpz_t *); gfc_try gfc_array_dimen_size (gfc_expr *, int, mpz_t *); gfc_try gfc_array_ref_shape (gfc_array_ref *, mpz_t *); gfc_array_ref *gfc_find_array_ref (gfc_expr *); -tree gfc_conv_array_initializer (tree type, gfc_expr *); gfc_try spec_size (gfc_array_spec *, mpz_t *); gfc_try spec_dimen_size (gfc_array_spec *, int, mpz_t *); int gfc_is_compile_time_shape (gfc_array_spec *); diff --git a/trans-array.c b/trans-array.c index c350c3b..217d7b8 100644 --- a/trans-array.c +++ b/trans-array.c @@ -5309,7 +5309,7 @@ gfc_array_deallocate (tree descriptor, tree pstat, tree errmsg, tree errlen, We assume the frontend already did any expansions and conversions. */ tree -gfc_conv_array_initializer (tree type, gfc_expr * expr) +gfc_conv_array_initializer (tree type, gfc_expr * expr, bool restricted) { gfc_constructor *c; tree tmp; @@ -5329,9 +5329,10 @@ gfc_conv_array_initializer (tree type, gfc_expr * expr) case EXPR_CONSTANT: case EXPR_STRUCTURE: /* A single scalar or derived type value. Create an array with all - elements equal to that value. */ + elements equal to that value. */ gfc_init_se (&se, NULL); - + se.want_restricted_types = restricted; + if (expr->expr_type == EXPR_CONSTANT) gfc_conv_constant (&se, expr); else @@ -5398,7 +5399,8 @@ gfc_conv_array_initializer (tree type, gfc_expr * expr) else range = NULL; - gfc_init_se (&se, NULL); + gfc_init_se (&se, NULL); + se.want_restricted_types = restricted; switch (c->expr->expr_type) { case EXPR_CONSTANT: diff --git a/trans-array.h b/trans-array.h index de03202..8d071b9 100644 --- a/trans-array.h +++ b/trans-array.h @@ -137,6 +137,8 @@ void gfc_conv_array_parameter (gfc_se *, gfc_expr *, bool, const gfc_symbol *, const char *, tree *); /* Evaluate and transpose a matrix expression. */ void gfc_conv_array_transpose (gfc_se *, gfc_expr *); +/* Creates a middle-end array constructor from a constant expression. */ +tree gfc_conv_array_initializer (tree, gfc_expr *, bool); /* These work with both descriptors and descriptorless arrays. */ tree gfc_conv_array_data (tree); diff --git a/trans-expr.c b/trans-expr.c index 9dab898..38c17a1 100644 --- a/trans-expr.c +++ b/trans-expr.c @@ -5166,12 +5166,13 @@ gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr) /* Build a static initializer. EXPR is the expression for the initial value. - The other parameters describe the variable of the component being - initialized. EXPR may be null. */ + The other parameters describe the variable of the component being + initialized. EXPR may be null. RESTRICTED asks for restrict-qualified + types. */ -tree -gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type, - bool array, bool pointer, bool procptr) +static tree +conv_initializer_1 (gfc_expr * expr, gfc_typespec * ts, tree type, + bool array, bool pointer, bool procptr, bool restricted) { gfc_se se; @@ -5206,9 +5207,9 @@ gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type, ctor = gfc_build_null_descriptor (type); /* Special case assigning an array to zero. */ else if (is_zero_initializer_p (expr)) - ctor = build_constructor (type, NULL); + ctor = build_constructor (type, NULL); else - ctor = gfc_conv_array_initializer (type, expr); + ctor = gfc_conv_array_initializer (type, expr, restricted); TREE_STATIC (ctor) = 1; return ctor; } @@ -5220,8 +5221,9 @@ gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type, { gfc_init_se (&se, NULL); se.want_pointer = 1; + se.want_restricted_types = restricted; gfc_conv_expr (&se, expr); - gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR); + gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR); return se.expr; } } @@ -5232,6 +5234,7 @@ gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type, case BT_DERIVED: case BT_CLASS: gfc_init_se (&se, NULL); + se.want_restricted_types = restricted; if (ts->type == BT_CLASS && expr->expr_type == EXPR_NULL) gfc_conv_structure (&se, gfc_class_null_initializer(ts), 1); else @@ -5255,7 +5258,18 @@ gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type, } } } - + + +/* Build a static initializer using default (i.e. restrict-qualified) types. */ + +tree +gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type, + bool array, bool pointer, bool procptr) +{ + return conv_initializer_1 (expr, ts, type, array, pointer, procptr, true); +} + + static tree gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr) { @@ -5653,6 +5667,8 @@ gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init) gcc_assert (se->ss == NULL); gcc_assert (expr->expr_type == EXPR_STRUCTURE); type = gfc_typenode_for_spec (&expr->ts); + if (!se->want_restricted_types) + type = gfc_nonrestricted_type (type); if (!init) { @@ -5691,10 +5707,14 @@ gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init) } else { - val = gfc_conv_initializer (c->expr, &cm->ts, - TREE_TYPE (cm->backend_decl), - cm->attr.dimension, cm->attr.pointer, - cm->attr.proc_pointer); + tree component_type = TREE_TYPE (cm->backend_decl); + + if (!se->want_restricted_types) + component_type = gfc_nonrestricted_type (component_type); + val = conv_initializer_1 (c->expr, &cm->ts, component_type, + cm->attr.dimension, cm->attr.pointer, + cm->attr.proc_pointer, + se->want_restricted_types); /* Append it to the constructor list. */ CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val); @@ -7286,6 +7306,7 @@ gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag, l_is_temp = (lss != gfc_ss_terminator && loop.temp_ss != NULL); /* Translate the expression. */ + rse.want_restricted_types = !(gfc_expr_attr (expr1).target); gfc_conv_expr (&rse, expr2); /* Stabilize a string length for temporaries. */ diff --git a/trans.h b/trans.h index 56b6c2f..7b67db9 100644 --- a/trans.h +++ b/trans.h @@ -89,6 +89,10 @@ typedef struct gfc_se unsigned want_coarray:1; + /* If set, we will use types with the restrict qualifier when building + structure and array constructors. */ + unsigned want_restricted_types:1; + /* Scalarization parameters. */ struct gfc_se *parent; struct gfc_ss *ss;