From patchwork Fri Jul 26 15:04:36 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 262180 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 2A7BF2C00EB for ; Sat, 27 Jul 2013 01:06:30 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references; q=dns; s= default; b=y37mx+O4P28/dKMzA6iapA4L2BNgzNdgAenVoM3K/+gL1UIT0yzZx GgPulJvtRcsav4rcZXwoy37dAJu6lvuRNkrdOvbE8etdlGZQUBgyaZGbkSm56pKY Bz6xpvQPPjNCWdBz2ejmn1HuRiqB+NF6DbFSJ9lArKHkOOrm/uuqf0= 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:from :to:cc:subject:date:message-id:in-reply-to:references; s= default; bh=JZrcdwVL3pCuwdn+5wdiQcvpVvE=; b=hA02KzjNZ6pWfIzBsmRQ G3edlscO/n/TkrAkbf/sDNnVQEU3Tag7gKF93CrVFzaMKX0+4zOXh42oCNvEncLm chUaM5IxG4IjW3so2I2EGVUXh3wXjHC05wNQ/9yXUYfU6fT3sct0Kub2itmqTVEa zWrfGcZftx4hHFGI6t3kPJY= Received: (qmail 5013 invoked by alias); 26 Jul 2013 15:05:05 -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 4880 invoked by uid 89); 26 Jul 2013 15:05:05 -0000 X-Spam-SWARE-Status: No, score=-4.3 required=5.0 tests=AWL, BAYES_50, KHOP_THREADED, RCVD_IN_HOSTKARMA_W, RCVD_IN_HOSTKARMA_WL, RDNS_NONE, SPF_HELO_PASS, SPF_PASS, TW_CP autolearn=no version=3.3.1 Received: from Unknown (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Fri, 26 Jul 2013 15:05:04 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r6QF4v9t007378 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 26 Jul 2013 11:04:57 -0400 Received: from surprise.redhat.com (vpn-56-108.rdu2.redhat.com [10.10.56.108]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r6QF4ofR003451; Fri, 26 Jul 2013 11:04:56 -0400 From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [PATCH 06/11] Rewrite how instances of passes are cloned Date: Fri, 26 Jul 2013 11:04:36 -0400 Message-Id: <1374851081-32153-7-git-send-email-dmalcolm@redhat.com> In-Reply-To: <1374851081-32153-1-git-send-email-dmalcolm@redhat.com> References: <1374851081-32153-1-git-send-email-dmalcolm@redhat.com> gcc/ Rewrite how instances of passes are cloned to remove assumptions about their sizes (thus allowing pass subclasses to have additional data fields, albeit non-GC-managed ones at this point). * passes.c (make_pass_instance): Now that passes have clone methods, rewrite this function to eliminate XNEW and memcpy calls that used hardcoded sizes. Since this function no longer creates pass instances, rename it to... (add_pass_instance): ...this. Document the old way that passes were numbered and flagged, and rework this function to continue using it. (next_pass_1): Add an initial_pass argument for use by add_pass_instance. (position_pass): When adding multiple instances of a pass, use the pass's clone method, rather than relying on the XNEW/memcpy within the former make_pass_instance (now add_pass_instance). (pipeline::pipeline): When invoking next_pass_1, also supply the initial instance of the current pass within the pipeline. --- gcc/passes.c | 92 ++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 55 insertions(+), 37 deletions(-) diff --git a/gcc/passes.c b/gcc/passes.c index ead41a8..ce5cdeb 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -1167,68 +1167,77 @@ is_pass_explicitly_enabled_or_disabled (struct opt_pass *pass, return false; } -/* Look at the static_pass_number and duplicate the pass - if it is already added to a list. */ -static struct opt_pass * -make_pass_instance (struct opt_pass *pass, bool track_duplicates) -{ - /* A nonzero static_pass_number indicates that the - pass is already in the list. */ - if (pass->static_pass_number) - { - struct opt_pass *new_pass; +/* Update static_pass_number for passes (and the flag + TODO_mark_first_instance). - if (pass->type == GIMPLE_PASS - || pass->type == RTL_PASS - || pass->type == SIMPLE_IPA_PASS) - { - new_pass = XNEW (struct opt_pass); - memcpy (new_pass, pass, sizeof (struct opt_pass)); - } - else if (pass->type == IPA_PASS) - { - new_pass = (struct opt_pass *)XNEW (struct ipa_opt_pass_d); - memcpy (new_pass, pass, sizeof (struct ipa_opt_pass_d)); - } - else - gcc_unreachable (); + Passes are constructed with static_pass_number preinitialized to 0 + + This field is used in two different ways: initially as instance numbers + of their kind, and then as ids within the entire pipeline. + + Within pipeline::pipeline: + + * In add_pass_instance(), as called by next_pass_1 in + NEXT_PASS in init_optimization_passes - new_pass->next = NULL; + * When the initial instance of a pass within a pipeline is seen, + it is flagged, and its static_pass_number is set to -1 + * On subsequent times that it is seen, the static pass number + is decremented each time, so that if there are e.g. 4 dups, + they have static_pass_number -4, 2, 3, 4 respectively (note + how the initial one is negative and gives the count); these + can be thought of as instance numbers of the specific pass + + * Within the register_dump_files () traversal, set_pass_for_id() + is called on each pass, using these instance numbers to create + dumpfile switches, and then overwriting them with a pass id, + which are global to the whole pass pipeline (based on + (TDI_end + current value of extra_dump_files_in_use) ) */ + +static void +add_pass_instance (struct opt_pass *new_pass, bool track_duplicates, + opt_pass *initial_pass) +{ + /* Are we dealing with the first pass of its kind, or a clone? */ + if (new_pass != initial_pass) + { + /* We're dealing with a clone. */ new_pass->todo_flags_start &= ~TODO_mark_first_instance; /* Indicate to register_dump_files that this pass has duplicates, and so it should rename the dump file. The first instance will be -1, and be number of duplicates = -static_pass_number - 1. Subsequent instances will be > 0 and just the duplicate number. */ - if ((pass->name && pass->name[0] != '*') || track_duplicates) + if ((new_pass->name && new_pass->name[0] != '*') || track_duplicates) { - pass->static_pass_number -= 1; - new_pass->static_pass_number = -pass->static_pass_number; + initial_pass->static_pass_number -= 1; + new_pass->static_pass_number = -initial_pass->static_pass_number; } - return new_pass; } else { - pass->todo_flags_start |= TODO_mark_first_instance; - pass->static_pass_number = -1; + /* We're dealing with the first pass of its kind. */ + new_pass->todo_flags_start |= TODO_mark_first_instance; + new_pass->static_pass_number = -1; - invoke_plugin_callbacks (PLUGIN_NEW_PASS, pass); + invoke_plugin_callbacks (PLUGIN_NEW_PASS, new_pass); } - return pass; } /* Add a pass to the pass list. Duplicate the pass if it's already in the list. */ static struct opt_pass ** -next_pass_1 (struct opt_pass **list, struct opt_pass *pass) +next_pass_1 (struct opt_pass **list, struct opt_pass *pass, + struct opt_pass *initial_pass) { /* Every pass should have a name so that plugins can refer to them. */ gcc_assert (pass->name != NULL); - *list = make_pass_instance (pass, false); + add_pass_instance (pass, false, initial_pass); + *list = pass; return &(*list)->next; } @@ -1278,7 +1287,16 @@ position_pass (struct register_pass_info *new_pass_info, struct opt_pass *new_pass; struct pass_list_node *new_pass_node; - new_pass = make_pass_instance (new_pass_info->pass, true); + if (new_pass_info->ref_pass_instance_number == 0) + { + new_pass = new_pass_info->pass->clone (); + add_pass_instance (new_pass, true, new_pass_info->pass); + } + else + { + new_pass = new_pass_info->pass; + add_pass_instance (new_pass, true, new_pass); + } /* Insert the new pass instance based on the positioning op. */ switch (new_pass_info->pos_op) @@ -1477,7 +1495,7 @@ pipeline::pipeline (context *ctxt) gcc_assert (PASS ## _1); \ PASS ## _ ## NUM = PASS ## _1->clone (); \ } \ - p = next_pass_1 (p, PASS ## _ ## NUM); \ + p = next_pass_1 (p, PASS ## _ ## NUM, PASS ## _1); \ } while (0) #define TERMINATE_PASS_LIST() \