From patchwork Sat Jul 3 17:25:39 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 57817 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 C4324B6F1B for ; Sun, 4 Jul 2010 03:25:52 +1000 (EST) Received: (qmail 10317 invoked by alias); 3 Jul 2010 17:25:51 -0000 Received: (qmail 10306 invoked by uid 22791); 3 Jul 2010 17:25:50 -0000 X-SWARE-Spam-Status: No, hits=-1.7 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, T_TO_NO_BRKTS_FREEMAIL X-Spam-Check-By: sourceware.org Received: from mail-wy0-f175.google.com (HELO mail-wy0-f175.google.com) (74.125.82.175) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 03 Jul 2010 17:25:44 +0000 Received: by wye20 with SMTP id 20so2348313wye.20 for ; Sat, 03 Jul 2010 10:25:42 -0700 (PDT) Received: by 10.227.37.140 with SMTP id x12mr586288wbd.98.1278177942171; Sat, 03 Jul 2010 10:25:42 -0700 (PDT) Received: from localhost (rsandifo.gotadsl.co.uk [82.133.89.107]) by mx.google.com with ESMTPS id g37sm15469808wbg.3.2010.07.03.10.25.40 (version=TLSv1/SSLv3 cipher=RC4-MD5); Sat, 03 Jul 2010 10:25:41 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, rdsandiford@googlemail.com Subject: Allow gc roots to be structures with array fields Date: Sat, 03 Jul 2010 18:25:39 +0100 Message-ID: <87vd8w4gvg.fsf@firetop.home> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) 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 This is a prerequisite for the upcoming "speed up target_reinit" patches. gengtype supports roots that are arrays of structures, but not roots that contain array fields. E.g.: struct GTY(()) foo { rtx a[4]; struct { rtx b[4]; } sub; }; struct GTY(()) bar { rtx a; int b; }; extern GTY(()) struct foo foo_var; extern GTY(()) struct bar bar_var[4]; generates the roots: { &bar_var[0].a, 1 * (4), sizeof (bar_var[0]), >_ggc_mx_rtx_def, >_pch_nx_rtx_def }, { &foo_var.a[0], 1, sizeof (foo_var), >_ggc_mx_rtx_def, >_pch_nx_rtx_def }, { &foo_var.sub.b[0], 1, sizeof (foo_var), >_ggc_mx_rtx_def, >_pch_nx_rtx_def }, The first one is fine (count = 4, stride = sizeof (rtx)), but the last two are wrong (count = 1, stride = sizeof (whole of foo)). Only the foo_var.a[0] and foo_var.sub.b[0] parts of foo get garbage-collected. The patch adds support for foo-like roots too. The idea is to treat top-level fields of structure roots in the same way as separate variables. The patch also errors for array fields in an array of structures, which are in general too complex to handle with a single count and stride. Bootstrapped & regression-tested on x86_64-linux-gnu. OK to install? Richard gcc/ * gengtype.c (write_field_root): New function. (write_root): Use it. Index: gcc/gengtype.c =================================================================== --- gcc/gengtype.c 2010-07-03 11:25:24.000000000 +0100 +++ gcc/gengtype.c 2010-07-03 11:49:36.000000000 +0100 @@ -3174,6 +3174,37 @@ finish_root_table (struct flist *flp, co } } +/* A subroutine of write_root for writing the roots for field FIELD_NAME, + which has type FIELD_TYPE. Parameters F to EMIT_PCH are the parameters + of the caller. */ + +static void +write_field_root (outf_p f, pair_p v, type_p type, const char *name, + int has_length, struct fileloc *line, const char *if_marked, + bool emit_pch, type_p field_type, const char *field_name) +{ + /* If the field reference is relative to V, rather than to some + subcomponent of V, we can mark any subarrays with a single stride. + We're effectively treating the field as a global variable in its + own right. */ + if (type == v->type) + { + struct pair newv; + + newv = *v; + newv.type = field_type; + newv.name = ACONCAT ((v->name, ".", field_name, NULL)); + v = &newv; + } + /* Otherwise, any arrays nested in the structure are too complex to + handle. */ + else if (field_type->kind == TYPE_ARRAY) + error_at_line (line, "nested array `%s.%s' is too complex to be a root", + name, field_name); + write_root (f, v, field_type, ACONCAT ((name, ".", field_name, NULL)), + has_length, line, if_marked, emit_pch); +} + /* Write out to F the table entry and any marker routines needed to mark NAME as TYPE. The original variable is V, at LINE. HAS_LENGTH is nonzero iff V was a variable-length array. IF_MARKED @@ -3232,27 +3263,18 @@ write_root (outf_p f, pair_p v, type_p t validf = ufld; } if (validf != NULL) - { - char *newname; - newname = xasprintf ("%s.%s.%s", - name, fld->name, validf->name); - write_root (f, v, validf->type, newname, 0, line, - if_marked, emit_pch); - free (newname); - } + write_field_root (f, v, type, name, 0, line, if_marked, + emit_pch, validf->type, + ACONCAT ((fld->name, ".", + validf->name, NULL))); } else if (desc) error_at_line (line, "global `%s.%s' has `desc' option but is not union", name, fld->name); else - { - char *newname; - newname = xasprintf ("%s.%s", name, fld->name); - write_root (f, v, fld->type, newname, 0, line, if_marked, - emit_pch); - free (newname); - } + write_field_root (f, v, type, name, 0, line, if_marked, + emit_pch, fld->type, fld->name); } } break;