From patchwork Wed Oct 15 16:26:34 2014 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: 400027 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 5862714008C for ; Thu, 16 Oct 2014 03:26:51 +1100 (EST) 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:cc:subject:content-type; q=dns; s=default; b=xRNstut0ERPiA85+QJiGtA6Os9BIm5344THqUTOsnuo NCsFIxPZKQUBtT0dervBN2T7aAVVTDTs8ng28BifNRXkHuMAwWX4w4cH9bk2bEBh UV4tirKt1FB9HxvxNbnozZasJ8F2FDwZU+/OvLzNEB40KubJ+0Q58Zrjsfkhk50U = 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:cc:subject:content-type; s=default; bh=mm6FQIZ/HBuQQeCXMZxr7zWzwUk=; b=Rhxc89pSFIhsX/KjB PKktl8HcCPYMLLXr5kJlhp0glgWtN02oPW7ri/vhCnrz2oWQ9Z5/cwL0kzPJ79jF xkOZvrTp7JsnONglfFHvlV5Mvgg933UKlkL0r2vw0JkkYiolcfeU3ycFgEntKl4G NOBfQCa86udY66JKebsXfPDALA= Received: (qmail 4706 invoked by alias); 15 Oct 2014 16:26:43 -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 4695 invoked by uid 89); 15 Oct 2014 16:26:42 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=0.4 required=5.0 tests=AWL, BAYES_50 autolearn=ham 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; Wed, 15 Oct 2014 16:26:39 +0000 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id C16D8AB08; Wed, 15 Oct 2014 16:26:35 +0000 (UTC) Message-ID: <543EA03A.7000000@suse.cz> Date: Wed, 15 Oct 2014 18:26:34 +0200 From: =?UTF-8?B?TWFydGluIExpxaFrYQ==?= User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.1.0 MIME-Version: 1.0 To: GCC Patches CC: mjambor@suse.cz, Jan Hubicka Subject: [RFC, PATCH]: Introduction of callgraph annotation class X-IsSubscribed: yes Hello. Following patch introduces a new class called callgraph_annotation. Idea behind the patch is to provide a generic interface one can use to register custom info related to a cgraph_node. As you know, symbol_table provides hooks for creation, deletion and duplication of a cgraph_node. If you have a pass, you need to handle all these hooks and store custom data in your data structure. As an example, after discussion with Martin, I chose usage in ipa-prop.h: data structure: vec ipa_node_params_vector if the pass handles an event, following chunk is executed: if (ipa_node_params_vector.length () <= (unsigned) symtab->cgraph_max_uid) ipa_node_params_vector.safe_grow_cleared (symtab->cgraph_max_uid + 1); The problem is that you can have sparse UIDs of cgraph_nodes and every time you have to allocate a vector of size equal to cgraph_max_uid. As a replacement, I implemented first version of cgraph_annotation that internally uses hash_map. Every time a node is deleted, we remove corresponding data associated to the node. What do you think about it? Thank you, Martin diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 04ce0c0..bf34c96 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1171,6 +1171,7 @@ OBJS = \ cfgrtl.o \ symtab.o \ cgraph.o \ + annotation.o \ cgraphbuild.o \ cgraphunit.o \ cgraphclones.o \ diff --git a/gcc/annotation.c b/gcc/annotation.c new file mode 100644 index 0000000..a8b6053 --- /dev/null +++ b/gcc/annotation.c @@ -0,0 +1 @@ +#include "annotation.h" diff --git a/gcc/annotation.h b/gcc/annotation.h new file mode 100644 index 0000000..7520677 --- /dev/null +++ b/gcc/annotation.h @@ -0,0 +1,285 @@ +/* Annotations handling code. + Copyright (C) 2014 Free Software Foundation, Inc. + Contributed by Martin Liska + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_ANNOTATION_H +#define GCC_ANNOTATION_H + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "tree.h" +#include "varasm.h" +#include "calls.h" +#include "print-tree.h" +#include "tree-inline.h" +#include "langhooks.h" +#include "hashtab.h" +#include "toplev.h" +#include "flags.h" +#include "debug.h" +#include "target.h" +#include "cgraph.h" +#include "hash-map.h" + +#define ANNOTATION_DELETED_VALUE -1 +#define ANNOTATION_EMPTY_VALUE 0 + +struct annotation_hashmap_traits: default_hashmap_traits +{ + static inline + hashval_t hash (const int v) + { + return (hashval_t)v; + } + + template + static inline + bool is_deleted (T &e) + { + return e.m_key == ANNOTATION_DELETED_VALUE; + } + + template + static inline + bool is_empty (T &e) + { + return e.m_key == ANNOTATION_EMPTY_VALUE; + } + + template + static inline + void mark_deleted (T &e) + { + e.m_key = ANNOTATION_DELETED_VALUE; + } + + template + static inline + void mark_empty (T &e) + { + e.m_key = ANNOTATION_EMPTY_VALUE; + } +}; + +template +class cgraph_annotation +{ +public: + /* Default construction takes SYMTAB as an argument. */ + cgraph_annotation (symbol_table *symtab): m_symtab (symtab) + { + cgraph_node *node; + + FOR_EACH_FUNCTION (node) + { + gcc_assert (node->annotation_uid > 0); + m_reverse_map.put (node, node->annotation_uid); + } + + m_map = new hash_map(); + + m_symtab_insertion_hook = + symtab->add_cgraph_insertion_hook + (cgraph_annotation::symtab_insertion, this); + + m_symtab_removal_hook = + symtab->add_cgraph_removal_hook + (cgraph_annotation::symtab_removal, this); + m_symtab_duplication_hook = + symtab->add_cgraph_duplication_hook + (cgraph_annotation::symtab_duplication, this); + + } + + /* Destructor. */ + ~cgraph_annotation () + { + m_symtab->remove_cgraph_insertion_hook (m_symtab_insertion_hook); + m_symtab->remove_cgraph_removal_hook (m_symtab_removal_hook); + m_symtab->remove_cgraph_duplication_hook (m_symtab_duplication_hook); + + m_map->traverse (NULL); + } + + /* Traverses all annotations with a function F called with + ARG as argument. */ + template + void traverse (Arg a) const + { + m_map->traverse (a); + } + + /* Function for registering insertion hook. */ + template + inline void add_insertion_hook (void) + { + m_insertion_hooks.safe_push (f); + } + + /* Function for registering removal hook. */ + template + inline void add_removal_hook (void) + { + m_removal_hooks.safe_push (f); + } + + /* Function for registering duplication hook. */ + template + inline void add_duplication_hook (void) + { + m_duplication_hooks.safe_push (f); + } + + /* Getter for annotation callgraph ID. */ + inline T* get_or_add (int uid) + { + T **v = m_map->get (uid); + if (!v) + { + T *new_value = new T(); + m_map->put (uid, new_value); + + v = &new_value; + } + + return *v; + } + + /* Getter for annotation callgraph node pointer. */ + inline T *get_or_add (cgraph_node *node) + { + return get_or_add (node->annotation_uid); + } + + /* Symbol insertion hook that is registered to symbol table. */ + static void symtab_insertion (cgraph_node *node, void *data) + { + cgraph_annotation *annotation = (cgraph_annotation *) (data); + annotation->call_insertion_hooks (node); + } + + /* Symbol removal hook that is registered to symbol table. */ + static void symtab_removal (cgraph_node *node, void *data) + { + cgraph_annotation *annotation = (cgraph_annotation *) (data); + int *annotation_uid_ptr = annotation->m_reverse_map.get (node); + + if (!annotation_uid_ptr) + return; + + int annotation_uid = *annotation_uid_ptr; + + T **v = annotation->m_map->get (annotation_uid); + + if (v) + annotation->call_removal_hooks (node, *v); + + annotation->m_reverse_map.remove (node); + + if (annotation->m_map->get (annotation_uid)) + annotation->m_map->remove (annotation_uid); + + } + + /* Symbol duplication hook that is registered to symbol table. */ + static void symtab_duplication (cgraph_node *node, cgraph_node *node2, + void *data) + { + cgraph_annotation *annotation = (cgraph_annotation *) (data); + T **v = annotation->m_map->get (node->annotation_uid); + + gcc_assert (node2->annotation_uid > 0); + annotation->m_reverse_map.put (node2, node2->annotation_uid); + + if (v) + { + T *data = *v; + T *duplicate = new T(); + annotation->m_map->put (node2->annotation_uid, duplicate); + annotation->call_duplication_hooks (node, node2, data); + } + + } + + /* Main annotation store, where annotation ID is used as key. */ + hash_map *m_map; + + /* Inverse mapping structure used in cgraph deletion context. */ + hash_map m_reverse_map; + +private: + /* Remove annotation for annotation UID. */ + inline void remove (int uid) + { + T *v = m_map->get (uid); + + if (v) + m_map->erase (uid); + } + + /* Annotation class release function called by traverse method. */ + static bool release (int const &, T * const &v, void *) + { + delete (v); + return true; + } + + /* Call insertion hook for callgraph NODE. */ + inline void call_insertion_hooks (cgraph_node *node) + { + for (unsigned int i = 0; i < m_insertion_hooks.length (); i++) + m_insertion_hooks[i] (node, get_or_add (node)); + } + + /* Call removal hook for callgraph NODE. */ + inline void call_removal_hooks (cgraph_node *node, T *v) + { + for (unsigned int i = 0; i < m_removal_hooks.length (); i++) + m_removal_hooks[i] (node, v); + } + + /* Call duplication hook for callgraph NODE. */ + inline void call_duplication_hooks (cgraph_node *node, cgraph_node *node2, T *v) + { + for (unsigned int i = 0; i < m_duplication_hooks.length (); i++) + m_duplication_hooks[i] (node, node2, v, get_or_add (node2)); + } + + /* List of symbol insertion hooks. */ + auto_vec m_insertion_hooks; + /* List of symbol removal hooks. */ + auto_vec m_removal_hooks; + /* List of symbol duplication hooks. */ + auto_vec + m_duplication_hooks; + + /* Internal annotation insertion hook pointer. */ + cgraph_node_hook_list *m_symtab_insertion_hook; + /* Internal annotation removal hook pointer. */ + cgraph_node_hook_list *m_symtab_removal_hook; + /* Internal annotation duplication hook pointer. */ + cgraph_2node_hook_list *m_symtab_duplication_hook; + + /* Symbol table the annotation is registered to. */ + symbol_table *m_symtab; +}; + +#endif /* GCC_ANNOTATION_H */ diff --git a/gcc/cgraph.h b/gcc/cgraph.h index a5777c2..32a770a 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -1219,6 +1219,8 @@ public: int count_materialization_scale; /* Unique id of the node. */ int uid; + /* Annotation unique id of the node. */ + int annotation_uid; /* ID assigned by the profiling. */ unsigned int profile_id; /* Time profiler: first run of function. */ @@ -1771,6 +1773,10 @@ public: friend class cgraph_node; friend class cgraph_edge; + symbol_table (): cgraph_max_annotation_uid (1) + { + } + /* Initialize callgraph dump file. */ inline void initialize (void) @@ -1972,6 +1978,7 @@ public: int cgraph_count; int cgraph_max_uid; + int cgraph_max_annotation_uid; int edges_count; int edges_max_uid; @@ -2268,6 +2275,9 @@ symbol_table::create_empty (void) { cgraph_node *node = allocate_cgraph_symbol (); + gcc_assert (cgraph_max_annotation_uid); + node->annotation_uid = cgraph_max_annotation_uid++; + node->type = SYMTAB_FUNCTION; node->frequency = NODE_FREQUENCY_NORMAL; node->count_materialization_scale = REG_BR_PROB_BASE; diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c index 38f56d2..e2576b3 100644 --- a/gcc/ipa-inline-analysis.c +++ b/gcc/ipa-inline-analysis.c @@ -895,7 +895,7 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p, if (known_binfos_ptr) known_binfos_ptr->create (0); - if (ipa_node_params_vector.exists () + if (ipa_node_params_annotation && !e->call_stmt_cannot_inline_p && ((clause_ptr && info->conds) || known_vals_ptr || known_binfos_ptr)) { @@ -1115,7 +1115,7 @@ inline_node_duplication_hook (struct cgraph_node *src, /* When there are any replacements in the function body, see if we can figure out that something was optimized out. */ - if (ipa_node_params_vector.exists () && dst->clone.tree_map) + if (ipa_node_params_annotation && dst->clone.tree_map) { vec *entry = info->entry; /* Use SRC parm info since it may not be copied yet. */ @@ -2462,7 +2462,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early) calculate_dominance_info (CDI_DOMINATORS); loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS); - if (ipa_node_params_vector.exists ()) + if (ipa_node_params_annotation) { parms_info = IPA_NODE_REF (node); nonconstant_names.safe_grow_cleared @@ -2610,7 +2610,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early) nonconstant_names[SSA_NAME_VERSION (gimple_call_lhs (stmt))] = false_p; } - if (ipa_node_params_vector.exists ()) + if (ipa_node_params_annotation) { int count = gimple_call_num_args (stmt); int i; @@ -3353,7 +3353,7 @@ static void remap_edge_change_prob (struct cgraph_edge *inlined_edge, struct cgraph_edge *edge) { - if (ipa_node_params_vector.exists ()) + if (ipa_node_params_annotation) { int i; struct ipa_edge_args *args = IPA_EDGE_REF (edge); @@ -3509,7 +3509,7 @@ inline_merge_summary (struct cgraph_edge *edge) else toplev_predicate = true_predicate (); - if (ipa_node_params_vector.exists () && callee_info->conds) + if (ipa_node_params_annotation && callee_info->conds) { struct ipa_edge_args *args = IPA_EDGE_REF (edge); int count = ipa_get_cs_argument_count (args); diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 9ac1929..ad98467 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -2408,7 +2408,7 @@ pass_early_inline::execute (function *fun) it. This may confuse ourself when early inliner decide to inline call to function clone, because function clones don't have parameter list in ipa-prop matching their signature. */ - if (ipa_node_params_vector.exists ()) + if (ipa_node_params_annotation) return 0; #ifdef ENABLE_CHECKING diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 62db327..743d9ff 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -115,7 +115,8 @@ struct func_body_info unsigned int aa_walked; }; -/* Vector where the parameter infos are actually stored. */ +/* Callgraph annotation where the parameter infos are actually stored. */ +cgraph_annotation *ipa_node_params_annotation = NULL; vec ipa_node_params_vector; /* Vector of known aggregate values in cloned nodes. */ vec *ipa_node_agg_replacements; @@ -124,9 +125,7 @@ vec *ipa_edge_args_vector; /* Holders of ipa cgraph hooks: */ static struct cgraph_edge_hook_list *edge_removal_hook_holder; -static struct cgraph_node_hook_list *node_removal_hook_holder; static struct cgraph_2edge_hook_list *edge_duplication_hook_holder; -static struct cgraph_2node_hook_list *node_duplication_hook_holder; static struct cgraph_node_hook_list *function_insertion_hook_holder; /* Description of a reference to an IPA constant. */ @@ -3554,7 +3553,7 @@ ipa_propagate_indirect_call_infos (struct cgraph_edge *cs, bool changed; /* Do nothing if the preparation phase has not been carried out yet (i.e. during early inlining). */ - if (!ipa_node_params_vector.exists ()) + if (!ipa_node_params_annotation) return false; gcc_assert (ipa_edge_args_vector); @@ -3594,15 +3593,21 @@ ipa_free_all_edge_args (void) /* Frees all dynamically allocated structures that the param info points to. */ -void -ipa_free_node_params_substructures (struct ipa_node_params *info) +ipa_node_params::~ipa_node_params () { - info->descriptors.release (); - free (info->lattices); + descriptors.release (); + free (lattices); /* Lattice values and their sources are deallocated with their alocation pool. */ - info->known_vals.release (); - memset (info, 0, sizeof (*info)); + known_vals.release (); + + lattices = NULL; + ipcp_orig_node = NULL; + analysis_done = 0; + node_enqueued = 0; + do_clone_for_all_contexts = 0; + is_all_contexts_clone = 0; + node_dead = 0; } /* Free all ipa_node_params structures. */ @@ -3610,11 +3615,8 @@ ipa_free_node_params_substructures (struct ipa_node_params *info) void ipa_free_all_node_params (void) { - int i; - struct ipa_node_params *info; - - FOR_EACH_VEC_ELT (ipa_node_params_vector, i, info) - ipa_free_node_params_substructures (info); + delete ipa_node_params_annotation; + ipa_node_params_annotation = NULL; ipa_node_params_vector.release (); } @@ -3622,7 +3624,7 @@ ipa_free_all_node_params (void) /* Set the aggregate replacements of NODE to be AGGVALS. */ void -ipa_set_node_agg_value_chain (struct cgraph_node *node, +ipa_set_node_agg_value_chain (const struct cgraph_node *node, struct ipa_agg_replacement_value *aggvals) { if (vec_safe_length (ipa_node_agg_replacements) @@ -3663,18 +3665,6 @@ ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED) ipa_free_edge_args_substructures (IPA_EDGE_REF (cs)); } -/* Hook that is called by cgraph.c when a node is removed. */ - -static void -ipa_node_removal_hook (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED) -{ - /* During IPA-CP updating we can be called on not-yet analyze clones. */ - if (ipa_node_params_vector.length () > (unsigned)node->uid) - ipa_free_node_params_substructures (IPA_NODE_REF (node)); - if (vec_safe_length (ipa_node_agg_replacements) > (unsigned)node->uid) - (*ipa_node_agg_replacements)[(unsigned)node->uid] = NULL; -} - /* Hook that is called by cgraph.c when an edge is duplicated. */ static void @@ -3779,18 +3769,22 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst, } } -/* Hook that is called by cgraph.c when a node is duplicated. */ +/* Analyze newly added function into callgraph. */ static void -ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst, - ATTRIBUTE_UNUSED void *data) +ipa_add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED) { - struct ipa_node_params *old_info, *new_info; - struct ipa_agg_replacement_value *old_av, *new_av; + if (node->has_gimple_body_p ()) + ipa_analyze_node (node); +} - ipa_check_create_node_params (); - old_info = IPA_NODE_REF (src); - new_info = IPA_NODE_REF (dst); +/* Hook that is called by cgraph.c when a node is duplicated. */ + +void +ipa_node_duplication_hook (const struct cgraph_node *src, const struct cgraph_node *dst, + struct ipa_node_params *old_info, struct ipa_node_params *new_info) +{ + struct ipa_agg_replacement_value *old_av, *new_av; new_info->descriptors = old_info->descriptors.copy (); new_info->lattices = NULL; @@ -3817,33 +3811,19 @@ ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst, ipa_set_node_agg_value_chain (dst, new_av); } - -/* Analyze newly added function into callgraph. */ - -static void -ipa_add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED) -{ - if (node->has_gimple_body_p ()) - ipa_analyze_node (node); -} - /* Register our cgraph hooks if they are not already there. */ void ipa_register_cgraph_hooks (void) { + ipa_check_create_node_params (); + if (!edge_removal_hook_holder) edge_removal_hook_holder = symtab->add_edge_removal_hook (&ipa_edge_removal_hook, NULL); - if (!node_removal_hook_holder) - node_removal_hook_holder = - symtab->add_cgraph_removal_hook (&ipa_node_removal_hook, NULL); if (!edge_duplication_hook_holder) edge_duplication_hook_holder = symtab->add_edge_duplication_hook (&ipa_edge_duplication_hook, NULL); - if (!node_duplication_hook_holder) - node_duplication_hook_holder = - symtab->add_cgraph_duplication_hook (&ipa_node_duplication_hook, NULL); function_insertion_hook_holder = symtab->add_cgraph_insertion_hook (&ipa_add_new_function, NULL); } @@ -3855,12 +3835,8 @@ ipa_unregister_cgraph_hooks (void) { symtab->remove_edge_removal_hook (edge_removal_hook_holder); edge_removal_hook_holder = NULL; - symtab->remove_cgraph_removal_hook (node_removal_hook_holder); - node_removal_hook_holder = NULL; symtab->remove_edge_duplication_hook (edge_duplication_hook_holder); edge_duplication_hook_holder = NULL; - symtab->remove_cgraph_duplication_hook (node_duplication_hook_holder); - node_duplication_hook_holder = NULL; symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder); function_insertion_hook_holder = NULL; } @@ -5030,8 +5006,7 @@ ipa_prop_write_jump_functions (void) lto_symtab_encoder_iterator lsei; lto_symtab_encoder_t encoder; - - if (!ipa_node_params_vector.exists ()) + if (!ipa_node_params_annotation) return; ob = create_output_block (LTO_section_jump_functions); diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h index 7a06af9..6a3772d 100644 --- a/gcc/ipa-prop.h +++ b/gcc/ipa-prop.h @@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see #include "vec.h" #include "cgraph.h" #include "alloc-pool.h" +#include "annotation.h" /* The following definitions and interfaces are used by interprocedural analyses or parameters. */ @@ -359,6 +360,8 @@ struct ipcp_lattice; struct ipa_node_params { + ~ipa_node_params (); + /* Information about individual formal parameters that are gathered when summaries are generated. */ vec descriptors; @@ -473,7 +476,7 @@ struct GTY(()) ipa_agg_replacement_value typedef struct ipa_agg_replacement_value *ipa_agg_replacement_value_p; -void ipa_set_node_agg_value_chain (struct cgraph_node *node, +void ipa_set_node_agg_value_chain (const struct cgraph_node *node, struct ipa_agg_replacement_value *aggvals); /* ipa_edge_args stores information related to a callsite and particularly its @@ -519,7 +522,7 @@ ipa_get_ith_polymorhic_call_context (struct ipa_edge_args *args, int i) /* Types of vectors holding the infos. */ /* Vector where the parameter infos are actually stored. */ -extern vec ipa_node_params_vector; +extern cgraph_annotation *ipa_node_params_annotation; /* Vector of known aggregate values in cloned nodes. */ extern GTY(()) vec *ipa_node_agg_replacements; /* Vector where the parameter infos are actually stored. */ @@ -527,7 +530,7 @@ extern GTY(()) vec *ipa_edge_args_vector; /* Return the associated parameter/argument info corresponding to the given node/edge. */ -#define IPA_NODE_REF(NODE) (&ipa_node_params_vector[(NODE)->uid]) +#define IPA_NODE_REF(NODE) (ipa_node_params_annotation->get_or_add (NODE)) #define IPA_EDGE_REF(EDGE) (&(*ipa_edge_args_vector)[(EDGE)->uid]) /* This macro checks validity of index returned by ipa_get_param_decl_index function. */ @@ -537,11 +540,15 @@ extern GTY(()) vec *ipa_edge_args_vector; void ipa_create_all_node_params (void); void ipa_create_all_edge_args (void); void ipa_free_edge_args_substructures (struct ipa_edge_args *); -void ipa_free_node_params_substructures (struct ipa_node_params *); void ipa_free_all_node_params (void); void ipa_free_all_edge_args (void); void ipa_free_all_structures_after_ipa_cp (void); void ipa_free_all_structures_after_iinln (void); +void ipa_node_duplication_hook (const struct cgraph_node *src, + const struct cgraph_node *dst, + struct ipa_node_params *old_info, + struct ipa_node_params *new_info); + void ipa_register_cgraph_hooks (void); int count_formal_params (tree fndecl); @@ -551,11 +558,11 @@ int count_formal_params (tree fndecl); static inline void ipa_check_create_node_params (void) { - if (!ipa_node_params_vector.exists ()) - ipa_node_params_vector.create (symtab->cgraph_max_uid); - - if (ipa_node_params_vector.length () <= (unsigned) symtab->cgraph_max_uid) - ipa_node_params_vector.safe_grow_cleared (symtab->cgraph_max_uid + 1); + if (!ipa_node_params_annotation) + { + ipa_node_params_annotation = new cgraph_annotation (symtab); + ipa_node_params_annotation->add_duplication_hook (); + } } /* This function ensures the array of edge arguments infos is big enough to @@ -582,7 +589,7 @@ ipa_edge_args_info_available_for_edge_p (struct cgraph_edge *edge) /* Return the aggregate replacements for NODE, if there are any. */ static inline struct ipa_agg_replacement_value * -ipa_get_agg_replacements_for_node (struct cgraph_node *node) +ipa_get_agg_replacements_for_node (const struct cgraph_node *node) { if ((unsigned) node->uid >= vec_safe_length (ipa_node_agg_replacements)) return NULL; diff --git a/gcc/toplev.c b/gcc/toplev.c index f7a5035..5e31ec2 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1176,7 +1176,7 @@ general_init (const char *argv0) /* Create the singleton holder for global state. Doing so also creates the pass manager and with it the passes. */ g = new gcc::context (); - symtab = ggc_cleared_alloc (); + symtab = new (ggc_cleared_alloc ()) symbol_table (); statistics_early_init (); finish_params ();