From patchwork Thu Apr 19 13:04:14 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Matz X-Patchwork-Id: 153749 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 0A93FB6ED0 for ; Thu, 19 Apr 2012 23:04:53 +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=1335445494; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Date: From:To:Cc:Subject:In-Reply-To:Message-ID:References: MIME-Version:Content-Type:Mailing-List:Precedence:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:Sender: Delivered-To; bh=Q0xHp70b2S8G2ZN7w38DX2LG0TA=; b=hWqDN0kuHzjTziI EXiJxeG/ZII/Wqe4CrYJX08x9BPVIuw/yM2Iuk4O2nigPazKtyubTIKWB8JlVQCC ComoWPNf6kKo0Q9oKT65gYPtytFQrJey7p5YIvR9iAC1CyDDgWt1MVfWn+Ul6sFV wKB8QEXWcFiv/v6uNE8jKCM6MN/g= 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:Date:From:To:Cc:Subject:In-Reply-To:Message-ID:References:MIME-Version:Content-Type:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=X0+bZLk8vLGdkcsDyJJQ7LvUhBBsBUCGejiC4QyqN6+SYVcv2PTBM2PZFEkV65 272S2a1X7OC1HxBPNOxeKIvfGV6Z2P0zXzjBXyVGeTUJLFJbSMbjkLFyjtgt84oq 4sFDNhHSPdt436OjfBUstem/r1HZeHovuXo0CZHne4REA=; Received: (qmail 18289 invoked by alias); 19 Apr 2012 13:04:49 -0000 Received: (qmail 18277 invoked by uid 22791); 19 Apr 2012 13:04:46 -0000 X-SWARE-Spam-Status: No, hits=-5.8 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, KHOP_THREADED, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from cantor2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 19 Apr 2012 13:04:15 +0000 Received: from relay1.suse.de (unknown [195.135.220.254]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx2.suse.de (Postfix) with ESMTP id A633995DCB for ; Thu, 19 Apr 2012 15:04:14 +0200 (CEST) Date: Thu, 19 Apr 2012 15:04:14 +0200 (CEST) From: Michael Matz To: Richard Guenther Cc: gcc-patches@gcc.gnu.org Subject: Re: [PATCH] Fix PR52977 In-Reply-To: Message-ID: References: MIME-Version: 1.0 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 Hi, On Mon, 16 Apr 2012, Richard Guenther wrote: > This fixes PR52977 - for PCH to work with its pointer relocation code we > have to avoid dereferencing pointers to compute array lengths in > structures. So we have to unfortunately keep duplicated info about > VECTOR_CST vector lengths. That's a pity and caused me to look a bit at gengtype. We can do better, and compute the lengths before all fields are accessed (and mangled in the PCH case). With the patch below we emit such code: case TS_VECTOR: { size_t l0 = (size_t)(TYPE_VECTOR_SUBPARTS (TREE_TYPE ((tree)&((*x).generic.vector)))); if ((void *)(x) == this_obj) op (&((*x).generic.vector.typed.type), cookie); { size_t i0; for (i0 = 0; i0 != l0; i0++) { if ((void *)(x) == this_obj) op (&((*x).generic.vector.elts[i0]), cookie); } } } Note how .generic.vector.typed.type is only mangled after TREE_TYPE is used to calculate the length. I regstrapped this on x86_64-linux, all languages, no regression. Okay for trunk (saving the all-important memory for vector constants again :) )? Ciao, Michael. ------------------ PR middle-end/52977 * tree.h (VECTOR_CST_NELTS): Use part number of types again. (struct tree_vector): Adjust GTY length. * tree.c (make_vector_stat): Don't set VECTOR_CST_NELTS. * gengtype.c (struct walk_type_data): Add in_record_p and loopcounter members. (walk_type, ): Handle case where our caller emitted the length calulation already. (walk_type, ): Emit length calculations before handling any of the fields for structs. Index: tree.h =================================================================== --- tree.h (revision 186580) +++ tree.h (working copy) @@ -1534,14 +1534,13 @@ struct GTY(()) tree_complex { }; /* In a VECTOR_CST node. */ -#define VECTOR_CST_NELTS(NODE) (VECTOR_CST_CHECK (NODE)->vector.length) +#define VECTOR_CST_NELTS(NODE) (TYPE_VECTOR_SUBPARTS (TREE_TYPE (NODE))) #define VECTOR_CST_ELTS(NODE) (VECTOR_CST_CHECK (NODE)->vector.elts) #define VECTOR_CST_ELT(NODE,IDX) (VECTOR_CST_CHECK (NODE)->vector.elts[IDX]) struct GTY(()) tree_vector { struct tree_typed typed; - unsigned length; - tree GTY ((length ("%h.length"))) elts[1]; + tree GTY ((length ("TYPE_VECTOR_SUBPARTS (TREE_TYPE ((tree)&%h))"))) elts[1]; }; #include "symtab.h" Index: tree.c =================================================================== --- tree.c (revision 186580) +++ tree.c (working copy) @@ -1329,7 +1329,6 @@ make_vector_stat (unsigned len MEM_STAT_ TREE_SET_CODE (t, VECTOR_CST); TREE_CONSTANT (t) = 1; - VECTOR_CST_NELTS (t) = len; return t; } Index: gengtype.c =================================================================== --- gengtype.c (revision 186580) +++ gengtype.c (working copy) @@ -2291,6 +2291,8 @@ struct walk_type_data const char *reorder_fn; bool needs_cast_p; bool fn_wants_lvalue; + bool in_record_p; + int loopcounter; }; /* Print a mangled name representing T to OF. */ @@ -2592,7 +2594,7 @@ walk_type (type_p t, struct walk_type_da } else { - int loopcounter = d->counter++; + int loopcounter = d->loopcounter; const char *oldval = d->val; const char *oldprevval3 = d->prev_val[3]; char *newval; @@ -2602,7 +2604,10 @@ walk_type (type_p t, struct walk_type_da oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter); oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent, "", loopcounter, loopcounter); - output_escaped_param (d, length, "length"); + if (!d->in_record_p) + output_escaped_param (d, length, "length"); + else + oprintf (d->of, "l%d", loopcounter); oprintf (d->of, "); i%d++) {\n", loopcounter); d->indent += 2; d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter); @@ -2624,7 +2629,7 @@ walk_type (type_p t, struct walk_type_da case TYPE_ARRAY: { - int loopcounter = d->counter++; + int loopcounter; const char *oldval = d->val; char *newval; @@ -2633,6 +2638,11 @@ walk_type (type_p t, struct walk_type_da if (t->u.a.p->kind == TYPE_SCALAR) break; + if (length) + loopcounter = d->loopcounter; + else + loopcounter = d->counter++; + /* When walking an array, compute the length and store it in a local variable before walking the array elements, instead of recomputing the length expression each time through the loop. @@ -2643,13 +2653,16 @@ walk_type (type_p t, struct walk_type_da oprintf (d->of, "%*s{\n", d->indent, ""); d->indent += 2; oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter); - oprintf (d->of, "%*ssize_t l%d = (size_t)(", - d->indent, "", loopcounter); - if (length) - output_escaped_param (d, length, "length"); - else - oprintf (d->of, "%s", t->u.a.len); - oprintf (d->of, ");\n"); + if (!d->in_record_p || !length) + { + oprintf (d->of, "%*ssize_t l%d = (size_t)(", + d->indent, "", loopcounter); + if (length) + output_escaped_param (d, length, "length"); + else + oprintf (d->of, "%s", t->u.a.len); + oprintf (d->of, ");\n"); + } oprintf (d->of, "%*sfor (i%d = 0; i%d != l%d; i%d++) {\n", d->indent, "", @@ -2678,6 +2691,9 @@ walk_type (type_p t, struct walk_type_da const int union_p = t->kind == TYPE_UNION; int seen_default_p = 0; options_p o; + int lengths_seen = 0; + int endcounter; + bool any_length_seen = false; if (!t->u.s.line.file) error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag); @@ -2713,6 +2729,45 @@ walk_type (type_p t, struct walk_type_da d->indent += 2; oprintf (d->of, "%*s{\n", d->indent, ""); } + + for (f = t->u.s.fields; f; f = f->next) + { + options_p oo; + int skip_p = 0; + const char *fieldlength = NULL; + + d->reorder_fn = NULL; + for (oo = f->opt; oo; oo = oo->next) + if (strcmp (oo->name, "skip") == 0) + skip_p = 1; + else if (strcmp (oo->name, "length") == 0 + && oo->kind == OPTION_STRING) + fieldlength = oo->info.string; + + if (skip_p) + continue; + if (fieldlength) + { + lengths_seen++; + d->counter++; + if (!union_p) + { + if (!any_length_seen) + { + oprintf (d->of, "%*s{\n", d->indent, ""); + d->indent += 2; + } + any_length_seen = true; + + oprintf (d->of, "%*ssize_t l%d = (size_t)(", + d->indent, "", d->counter - 1); + output_escaped_param (d, fieldlength, "length"); + oprintf (d->of, ");\n"); + } + } + } + endcounter = d->counter; + for (f = t->u.s.fields; f; f = f->next) { options_p oo; @@ -2721,6 +2776,7 @@ walk_type (type_p t, struct walk_type_da int skip_p = 0; int default_p = 0; int use_param_p = 0; + const char *fieldlength = NULL; char *newval; d->reorder_fn = NULL; @@ -2741,6 +2797,9 @@ walk_type (type_p t, struct walk_type_da else if (strncmp (oo->name, "use_param", 9) == 0 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9]))) use_param_p = 1; + else if (strcmp (oo->name, "length") == 0 + && oo->kind == OPTION_STRING) + fieldlength = oo->info.string; if (skip_p) continue; @@ -2774,16 +2833,24 @@ walk_type (type_p t, struct walk_type_da "field `%s' is missing `tag' or `default' option", f->name); + if (fieldlength) + { + d->loopcounter = endcounter - lengths_seen--; + } + d->line = &f->line; d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name); d->opt = f->opt; d->used_length = false; + d->in_record_p = !union_p; if (union_p && use_param_p && d->param == NULL) oprintf (d->of, "%*sgcc_unreachable ();\n", d->indent, ""); else walk_type (f->type, d); + d->in_record_p = false; + free (newval); if (union_p) @@ -2808,6 +2875,11 @@ walk_type (type_p t, struct walk_type_da oprintf (d->of, "%*s}\n", d->indent, ""); d->indent -= 2; } + if (any_length_seen) + { + d->indent -= 2; + oprintf (d->of, "%*s}\n", d->indent, ""); + } } break;