From patchwork Thu Jul 9 20:47:35 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Martin_Li=C5=A1ka?= X-Patchwork-Id: 493567 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.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 477C8140273 for ; Fri, 10 Jul 2015 06:47:37 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=sfzGnvuY; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:subject:references :in-reply-to:content-type; q=dns; s=default; b=Ke3Y30CQ03kDUngXd uRokyeeMEdsjv09yZDpofxSascX5gTngPe/RstGdrYvplKNJ2qavIGlVgBxpLcgv 8aOA5XWoBUS6V8GZ+7vsjPf6LQ3ANO+uF5Q80fshE9QirV/vEzZXDTgBJTUP/vDg nT9TCNImguTNMjrmlLfJQ+QyEc= 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 :message-id:date:from:mime-version:to:subject:references :in-reply-to:content-type; s=default; bh=CTawB7E/vzSYst0V1P833BH zfhE=; b=sfzGnvuYR6238JUxKs2WlL87KPhYljcDg/PCwEjj8tbh3Xtq8G5LCB9 Wy74glNhhymB0l6GFgdMrFhogkScYlnSR4Vj000X0J+48D8ZLJHENC6HgCF79vAy SVQ5RdhBfUHx0FCtbU8RshtL5My8LgzPNg/bd7ymNXPE0DlRxFrQ= Received: (qmail 8492 invoked by alias); 9 Jul 2015 20:47:30 -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 8480 invoked by uid 89); 9 Jul 2015 20:47:29 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=0.9 required=5.0 tests=AWL, BAYES_50, KAM_LAZY_DOMAIN_SECURITY autolearn=no version=3.3.2 X-HELO: mx2.suse.de Received: from cantor2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (CAMELLIA256-SHA encrypted) ESMTPS; Thu, 09 Jul 2015 20:47:27 +0000 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 57D28AD40 for ; Thu, 9 Jul 2015 20:47:24 +0000 (UTC) Message-ID: <559EDDE7.3050604@suse.cz> Date: Thu, 09 Jul 2015 22:47:35 +0200 From: =?windows-1252?Q?Martin_Li=9Aka?= User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.7.0 MIME-Version: 1.0 To: gcc-patches@gcc.gnu.org Subject: Re: [PATCH 6/6] Migrate ipa-pure-const to function_summary. References: <33dfaf16d6b65e31edd08d8a588821ea6f8b3188.1436438929.git.mliska@suse.cz> <559EB306.6020103@redhat.com> In-Reply-To: <559EB306.6020103@redhat.com> X-IsSubscribed: yes On 07/09/2015 07:44 PM, Jeff Law wrote: > On 07/09/2015 03:13 AM, mliska wrote: >> gcc/ChangeLog: >> >> 2015-07-03 Martin Liska >> >> * ipa-pure-const.c (struct funct_state_d): New. >> (funct_state_d::default_p): Likewise. >> (has_function_state): Remove. >> (get_function_state): Likewise. >> (set_function_state): Likewise. >> (add_new_function): Rename and port to ::insert. >> (duplicate_node_data): Rename and port to ::duplicate. >> (funct_state_summary_t::duplicate): New function. >> (register_hooks): Remove hook registration. >> (pure_const_generate_summary): Use new data structure. >> (pure_const_write_summary): Likewise. >> (pure_const_read_summary): Likewise. >> (propagate_pure_const): Likewise. >> (propagate_nothrow): Likewise. >> (execute): Remove hook usage. >> (pass_ipa_pure_const::pass_ipa_pure_const): Likewise. >> --- >> @@ -84,6 +85,18 @@ const char *pure_const_names[3] = {"const", "pure", "neither"}; >> decl. */ >> struct funct_state_d >> { >> + funct_state_d (): pure_const_state (IPA_NEITHER), >> + state_previously_known (IPA_NEITHER), looping_previously_known (true), >> + looping (true), can_throw (true), can_free (true) {} >> + >> + funct_state_d (const funct_state_d &s): pure_const_state (s.pure_const_state), >> + state_previously_known (s.state_previously_known), >> + looping_previously_known (s.looping_previously_known), >> + looping (s.looping), can_throw (s.can_throw), can_free (s.can_free) {} >> + >> + /* Return true if the value is default. */ >> + bool default_p (); >> + >> /* See above. */ >> enum pure_const_state_e pure_const_state; >> /* What user set here; we can be always sure about this. */ > Doesn't this need to be a "class" rather then a "struct"? > > > OK with that change. > > jeff Yeah. 'class' will be more appropriate. As I'm going to be AFK for Friday and upcoming weekend, I will install these patches on Monday. Thanks, Martin From b20c6ceaf82210c564465be1ab92f6586fc706e4 Mon Sep 17 00:00:00 2001 From: mliska Date: Thu, 9 Jul 2015 11:13:55 +0200 Subject: [PATCH 6/6] Migrate ipa-pure-const to function_summary. gcc/ChangeLog: 2015-07-03 Martin Liska * ipa-pure-const.c (struct funct_state_d): New. (funct_state_d::default_p): Likewise. (has_function_state): Remove. (get_function_state): Likewise. (set_function_state): Likewise. (add_new_function): Rename and port to ::insert. (duplicate_node_data): Rename and port to ::duplicate. (funct_state_summary_t::duplicate): New function. (register_hooks): Remove hook registration. (pure_const_generate_summary): Use new data structure. (pure_const_write_summary): Likewise. (pure_const_read_summary): Likewise. (propagate_pure_const): Likewise. (propagate_nothrow): Likewise. (execute): Remove hook usage. (pass_ipa_pure_const::pass_ipa_pure_const): Likewise. --- gcc/ipa-pure-const.c | 180 +++++++++++++++++++-------------------------------- 1 file changed, 68 insertions(+), 112 deletions(-) diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c index f0373e6..f978950f 100644 --- a/gcc/ipa-pure-const.c +++ b/gcc/ipa-pure-const.c @@ -67,6 +67,7 @@ along with GCC; see the file COPYING3. If not see #include "intl.h" #include "opts.h" #include "varasm.h" +#include "symbol-summary.h" /* Lattice values for const and pure functions. Everything starts out being const, then may drop to pure and then neither depending on @@ -82,8 +83,21 @@ const char *pure_const_names[3] = {"const", "pure", "neither"}; /* Holder for the const_state. There is one of these per function decl. */ -struct funct_state_d +class funct_state_d { +public: + funct_state_d (): pure_const_state (IPA_NEITHER), + state_previously_known (IPA_NEITHER), looping_previously_known (true), + looping (true), can_throw (true), can_free (true) {} + + funct_state_d (const funct_state_d &s): pure_const_state (s.pure_const_state), + state_previously_known (s.state_previously_known), + looping_previously_known (s.looping_previously_known), + looping (s.looping), can_throw (s.can_throw), can_free (s.can_free) {} + + /* Return true if the value is default. */ + bool default_p (); + /* See above. */ enum pure_const_state_e pure_const_state; /* What user set here; we can be always sure about this. */ @@ -105,10 +119,16 @@ struct funct_state_d bool can_free; }; -/* State used when we know nothing about function. */ -static struct funct_state_d varying_state - = { IPA_NEITHER, IPA_NEITHER, true, true, true, true }; - +bool +funct_state_d::default_p () +{ + return pure_const_state == IPA_NEITHER + && state_previously_known == IPA_NEITHER + && looping_previously_known + && looping + && can_throw + && can_free; +} typedef struct funct_state_d * funct_state; @@ -116,9 +136,19 @@ typedef struct funct_state_d * funct_state; possibility that it may be desirable to move this to the cgraph local info. */ -/* Array, indexed by cgraph node uid, of function states. */ +class funct_state_summary_t: public function_summary +{ +public: + funct_state_summary_t (symbol_table *symtab): + function_summary (symtab) {} + + virtual void insert (cgraph_node *, funct_state_d *state); + virtual void duplicate (cgraph_node *src_node, cgraph_node *dst_node, + funct_state_d *src_data, + funct_state_d *dst_data); +}; -static vec funct_state_vec; +static funct_state_summary_t *funct_state_summaries = NULL; static bool gate_pure_const (void); @@ -150,12 +180,6 @@ public: private: bool init_p; - - /* Holders of ipa cgraph hooks: */ - struct cgraph_node_hook_list *function_insertion_hook_holder; - struct cgraph_2node_hook_list *node_duplication_hook_holder; - struct cgraph_node_hook_list *node_removal_hook_holder; - }; // class pass_ipa_pure_const } // anon namespace @@ -237,41 +261,6 @@ warn_function_noreturn (tree decl) true, warned_about, "noreturn"); } -/* Return true if we have a function state for NODE. */ - -static inline bool -has_function_state (struct cgraph_node *node) -{ - if (!funct_state_vec.exists () - || funct_state_vec.length () <= (unsigned int)node->uid) - return false; - return funct_state_vec[node->uid] != NULL; -} - -/* Return the function state from NODE. */ - -static inline funct_state -get_function_state (struct cgraph_node *node) -{ - if (!funct_state_vec.exists () - || funct_state_vec.length () <= (unsigned int)node->uid - || !funct_state_vec[node->uid]) - /* We might want to put correct previously_known state into varying. */ - return &varying_state; - return funct_state_vec[node->uid]; -} - -/* Set the function state S for NODE. */ - -static inline void -set_function_state (struct cgraph_node *node, funct_state s) -{ - if (!funct_state_vec.exists () - || funct_state_vec.length () <= (unsigned int)node->uid) - funct_state_vec.safe_grow_cleared (node->uid + 1); - funct_state_vec[node->uid] = s; -} - /* Check to see if the use (or definition when CHECKING_WRITE is true) variable T is legal in a function that is either pure or const. */ @@ -903,9 +892,8 @@ end: return l; } -/* Called when new function is inserted to callgraph late. */ -static void -add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED) +void +funct_state_summary_t::insert (cgraph_node *node, funct_state_d *state) { if (node->get_availability () < AVAIL_INTERPOSABLE) return; @@ -915,36 +903,21 @@ add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED) operations. */ if (node->get_availability () > AVAIL_INTERPOSABLE && opt_for_fn (node->decl, flag_ipa_pure_const)) - set_function_state (node, analyze_function (node, true)); -} - -/* Called when new clone is inserted to callgraph late. */ - -static void -duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst, - void *data ATTRIBUTE_UNUSED) -{ - if (has_function_state (src)) { - funct_state l = XNEW (struct funct_state_d); - gcc_assert (!has_function_state (dst)); - memcpy (l, get_function_state (src), sizeof (*l)); - set_function_state (dst, l); + funct_state_d *a = analyze_function (node, true); + new (state) funct_state_d (*a); + free (a); } } /* Called when new clone is inserted to callgraph late. */ -static void -remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED) +void +funct_state_summary_t::duplicate (cgraph_node *, cgraph_node *, + funct_state_d *src_data, + funct_state_d *dst_data) { - if (has_function_state (node)) - { - funct_state l = get_function_state (node); - if (l != &varying_state) - free (l); - set_function_state (node, NULL); - } + new (dst_data) funct_state_d (*src_data); } @@ -957,12 +930,7 @@ register_hooks (void) init_p = true; - node_removal_hook_holder = - symtab->add_cgraph_removal_hook (&remove_node_data, NULL); - node_duplication_hook_holder = - symtab->add_cgraph_duplication_hook (&duplicate_node_data, NULL); - function_insertion_hook_holder = - symtab->add_cgraph_insertion_hook (&add_new_function, NULL); + funct_state_summaries = new funct_state_summary_t (symtab); } @@ -986,7 +954,11 @@ pure_const_generate_summary (void) FOR_EACH_DEFINED_FUNCTION (node) if (node->get_availability () >= AVAIL_INTERPOSABLE && opt_for_fn (node->decl, flag_ipa_pure_const)) - set_function_state (node, analyze_function (node, true)); + { + funct_state_d *a = analyze_function (node, true); + new (funct_state_summaries->get (node)) funct_state_d (*a); + free (a); + } } @@ -1008,7 +980,8 @@ pure_const_write_summary (void) lsei_next_function_in_partition (&lsei)) { node = lsei_cgraph_node (lsei); - if (node->definition && has_function_state (node)) + if (node->definition + && !funct_state_summaries->get (node)->default_p ()) count++; } @@ -1019,15 +992,13 @@ pure_const_write_summary (void) lsei_next_function_in_partition (&lsei)) { node = lsei_cgraph_node (lsei); - if (node->definition && has_function_state (node)) + funct_state_d *fs = funct_state_summaries->get (node); + if (node->definition && !fs->default_p ()) { struct bitpack_d bp; - funct_state fs; int node_ref; lto_symtab_encoder_t encoder; - fs = get_function_state (node); - encoder = ob->decl_state->symtab_node_encoder; node_ref = lto_symtab_encoder_encode (encoder, node); streamer_write_uhwi_stream (ob->main_stream, node_ref); @@ -1082,13 +1053,12 @@ pure_const_read_summary (void) funct_state fs; lto_symtab_encoder_t encoder; - fs = XCNEW (struct funct_state_d); index = streamer_read_uhwi (ib); encoder = file_data->symtab_node_encoder; node = dyn_cast (lto_symtab_encoder_deref (encoder, index)); - set_function_state (node, fs); + fs = funct_state_summaries->get (node); /* Note that the flags must be read in the opposite order in which they were written (the bitflags were pushed into FLAGS). */ @@ -1216,7 +1186,7 @@ propagate_pure_const (void) int i; struct ipa_ref *ref = NULL; - funct_state w_l = get_function_state (w); + funct_state w_l = funct_state_summaries->get (w); if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, " Visiting %s/%i state:%s looping %i\n", w->name (), @@ -1272,7 +1242,7 @@ propagate_pure_const (void) } if (avail > AVAIL_INTERPOSABLE) { - funct_state y_l = get_function_state (y); + funct_state_d *y_l = funct_state_summaries->get (y); if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, @@ -1389,7 +1359,7 @@ propagate_pure_const (void) while (w && !can_free) { struct cgraph_edge *e; - funct_state w_l = get_function_state (w); + funct_state_d *w_l = funct_state_summaries->get (w); if (w_l->can_free || w->get_availability () == AVAIL_INTERPOSABLE @@ -1403,7 +1373,7 @@ propagate_pure_const (void) function_or_virtual_thunk_symbol (&avail); if (avail > AVAIL_INTERPOSABLE) - can_free = get_function_state (y)->can_free; + can_free = funct_state_summaries->get (y)->can_free; else can_free = true; } @@ -1416,7 +1386,7 @@ propagate_pure_const (void) w = node; while (w) { - funct_state w_l = get_function_state (w); + funct_state_d *w_l = funct_state_summaries->get (w); enum pure_const_state_e this_state = pure_const_state; bool this_looping = looping; @@ -1526,7 +1496,7 @@ propagate_nothrow (void) while (w && !can_throw) { struct cgraph_edge *e, *ie; - funct_state w_l = get_function_state (w); + funct_state_d *w_l = funct_state_summaries->get (w); if (w_l->can_throw || w->get_availability () == AVAIL_INTERPOSABLE) @@ -1540,7 +1510,7 @@ propagate_nothrow (void) if (avail > AVAIL_INTERPOSABLE) { - funct_state y_l = get_function_state (y); + funct_state_d *y_l = funct_state_summaries->get (y); if (y_l->can_throw && !TREE_NOTHROW (w->decl) && e->can_throw_external) @@ -1561,7 +1531,7 @@ propagate_nothrow (void) w = node; while (w) { - funct_state w_l = get_function_state (w); + funct_state_d *w_l = funct_state_summaries->get (w); if (!can_throw && !TREE_NOTHROW (w->decl)) { /* Inline clones share declaration with their offline copies; @@ -1594,23 +1564,14 @@ unsigned int pass_ipa_pure_const:: execute (function *) { - struct cgraph_node *node; bool remove_p; - symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder); - symtab->remove_cgraph_duplication_hook (node_duplication_hook_holder); - symtab->remove_cgraph_removal_hook (node_removal_hook_holder); - /* Nothrow makes more function to not lead to return and improve later analysis. */ propagate_nothrow (); remove_p = propagate_pure_const (); - /* Cleanup. */ - FOR_EACH_FUNCTION (node) - if (has_function_state (node)) - free (get_function_state (node)); - funct_state_vec.release (); + delete funct_state_summaries; return remove_p ? TODO_remove_functions : 0; } @@ -1631,12 +1592,7 @@ pass_ipa_pure_const::pass_ipa_pure_const(gcc::context *ctxt) 0, /* function_transform_todo_flags_start */ NULL, /* function_transform */ NULL), /* variable_transform */ - init_p(false), - function_insertion_hook_holder(NULL), - node_duplication_hook_holder(NULL), - node_removal_hook_holder(NULL) -{ -} + init_p (false) {} ipa_opt_pass_d * make_pass_ipa_pure_const (gcc::context *ctxt) -- 2.4.5