Commit 6fe906a3 by Martin Jambor Committed by Martin Jambor

Use call_summary in ipa-prop and ipa-cp

2017-05-03  Martin Jambor  <mjambor@suse.cz>

	* ipa-prop.h (ipa_edge_args): Make a class.  Mark with for_user GTY
	tag.  Added a default constructor and a destructor.
	(ipa_edge_args_sum_t): New class;
	(ipa_edge_args_sum): Declare.
	(ipa_edge_args_vector): Remove declaration.
	(IPA_EDGE_REF): Use ipa_edge_args_sum.
	(ipa_free_edge_args_substructures): Remove declaration.
	(ipa_check_create_edge_args): Use ipa_edge_args_sum.
	(ipa_edge_args_info_available_for_edge_p): Likewise.
	* ipa-prop.c (ipa_edge_args_vector): Removed.
	(edge_removal_hook_holder): Likewise.
	(edge_duplication_hook_holder): Likewise.
	(ipa_edge_args_sum): New variable.
	(ipa_propagate_indirect_call_infos): Test ipa_edge_args_sum instead of
	ipa_edge_args_vector.
	(ipa_free_edge_args_substructures): Likewise.
	(ipa_free_all_edge_args): Free ipa_edge_args_sum instead of
	ipa_edge_args_vector.
	(ipa_edge_removal_hook): Turned into method
	ipa_edge_args_sum_t::remove.
	(ipa_edge_duplication_hook): Turned into method
	ipa_edge_args_sum_t::duplicate.
	(ipa_register_cgraph_hooks): Create ipa_edge_args_sum instead of
	registering edge hooks.
	(ipa_unregister_cgraph_hooks): Do not unregister edge hooks.
	* ipa-inline-analysis.c (estimate_function_body_sizes): Test
	ipa_edge_args_sum instead of ipa_edge_args_vector.
	* ipa-profile.c (ipa_profile): Likewise.

From-SVN: r247558
parent 57e563ac
2017-05-03 Martin Jambor <mjambor@suse.cz> 2017-05-03 Martin Jambor <mjambor@suse.cz>
* ipa-prop.h (ipa_edge_args): Make a class. Mark with for_user GTY
tag. Added a default constructor and a destructor.
(ipa_edge_args_sum_t): New class;
(ipa_edge_args_sum): Declare.
(ipa_edge_args_vector): Remove declaration.
(IPA_EDGE_REF): Use ipa_edge_args_sum.
(ipa_free_edge_args_substructures): Remove declaration.
(ipa_check_create_edge_args): Use ipa_edge_args_sum.
(ipa_edge_args_info_available_for_edge_p): Likewise.
* ipa-prop.c (ipa_edge_args_vector): Removed.
(edge_removal_hook_holder): Likewise.
(edge_duplication_hook_holder): Likewise.
(ipa_edge_args_sum): New variable.
(ipa_propagate_indirect_call_infos): Test ipa_edge_args_sum instead of
ipa_edge_args_vector.
(ipa_free_edge_args_substructures): Likewise.
(ipa_free_all_edge_args): Free ipa_edge_args_sum instead of
ipa_edge_args_vector.
(ipa_edge_removal_hook): Turned into method
ipa_edge_args_sum_t::remove.
(ipa_edge_duplication_hook): Turned into method
ipa_edge_args_sum_t::duplicate.
(ipa_register_cgraph_hooks): Create ipa_edge_args_sum instead of
registering edge hooks.
(ipa_unregister_cgraph_hooks): Do not unregister edge hooks.
* ipa-inline-analysis.c (estimate_function_body_sizes): Test
ipa_edge_args_sum instead of ipa_edge_args_vector.
* ipa-profile.c (ipa_profile): Likewise.
2017-05-03 Martin Jambor <mjambor@suse.cz>
* symbol-summary.h (function_summary): New method exists. * symbol-summary.h (function_summary): New method exists.
(function_summary::symtab_removal): Deallocate through release. (function_summary::symtab_removal): Deallocate through release.
(call_summary): New class. (call_summary): New class.
......
...@@ -2998,7 +2998,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early) ...@@ -2998,7 +2998,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
{ {
if (!early) if (!early)
loop_optimizer_finalize (); loop_optimizer_finalize ();
else if (!ipa_edge_args_vector) else if (!ipa_edge_args_sum)
ipa_free_all_node_params (); ipa_free_all_node_params ();
free_dominance_info (CDI_DOMINATORS); free_dominance_info (CDI_DOMINATORS);
} }
......
...@@ -620,7 +620,7 @@ ipa_profile (void) ...@@ -620,7 +620,7 @@ ipa_profile (void)
"Not speculating: target is overwritable " "Not speculating: target is overwritable "
"and can be discarded.\n"); "and can be discarded.\n");
} }
else if (ipa_node_params_sum && ipa_edge_args_vector else if (ipa_node_params_sum && ipa_edge_args_sum
&& (!vec_safe_is_empty && (!vec_safe_is_empty
(IPA_NODE_REF (n2)->descriptors)) (IPA_NODE_REF (n2)->descriptors))
&& ipa_get_param_count (IPA_NODE_REF (n2)) && ipa_get_param_count (IPA_NODE_REF (n2))
......
...@@ -57,8 +57,8 @@ along with GCC; see the file COPYING3. If not see ...@@ -57,8 +57,8 @@ along with GCC; see the file COPYING3. If not see
ipa_node_params_t *ipa_node_params_sum = NULL; ipa_node_params_t *ipa_node_params_sum = NULL;
/* Vector of IPA-CP transformation data for each clone. */ /* Vector of IPA-CP transformation data for each clone. */
vec<ipcp_transformation_summary, va_gc> *ipcp_transformations; vec<ipcp_transformation_summary, va_gc> *ipcp_transformations;
/* Vector where the parameter infos are actually stored. */ /* Edge summary for IPA-CP edge information. */
vec<ipa_edge_args, va_gc> *ipa_edge_args_vector; ipa_edge_args_sum_t *ipa_edge_args_sum;
/* Traits for a hash table for reusing already existing ipa_bits. */ /* Traits for a hash table for reusing already existing ipa_bits. */
...@@ -148,8 +148,6 @@ struct ipa_vr_ggc_hash_traits : public ggc_cache_remove <value_range *> ...@@ -148,8 +148,6 @@ struct ipa_vr_ggc_hash_traits : public ggc_cache_remove <value_range *>
static GTY ((cache)) hash_table<ipa_vr_ggc_hash_traits> *ipa_vr_hash_table; static GTY ((cache)) hash_table<ipa_vr_ggc_hash_traits> *ipa_vr_hash_table;
/* Holders of ipa cgraph hooks: */ /* Holders of ipa cgraph hooks: */
static struct cgraph_edge_hook_list *edge_removal_hook_holder;
static struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
static struct cgraph_node_hook_list *function_insertion_hook_holder; static struct cgraph_node_hook_list *function_insertion_hook_holder;
/* Description of a reference to an IPA constant. */ /* Description of a reference to an IPA constant. */
...@@ -3700,7 +3698,7 @@ ipa_propagate_indirect_call_infos (struct cgraph_edge *cs, ...@@ -3700,7 +3698,7 @@ ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
(i.e. during early inlining). */ (i.e. during early inlining). */
if (!ipa_node_params_sum) if (!ipa_node_params_sum)
return false; return false;
gcc_assert (ipa_edge_args_vector); gcc_assert (ipa_edge_args_sum);
propagate_controlled_uses (cs); propagate_controlled_uses (cs);
changed = propagate_info_to_inlined_callees (cs, cs->callee, new_edges); changed = propagate_info_to_inlined_callees (cs, cs->callee, new_edges);
...@@ -3715,9 +3713,10 @@ ipa_propagate_indirect_call_infos (struct cgraph_edge *cs, ...@@ -3715,9 +3713,10 @@ ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
void void
ipa_check_create_edge_args (void) ipa_check_create_edge_args (void)
{ {
if (vec_safe_length (ipa_edge_args_vector) if (!ipa_edge_args_sum)
<= (unsigned) symtab->edges_max_uid) ipa_edge_args_sum
vec_safe_grow_cleared (ipa_edge_args_vector, symtab->edges_max_uid + 1); = (new (ggc_cleared_alloc <ipa_edge_args_sum_t> ())
ipa_edge_args_sum_t (symtab, true));
if (!ipa_bits_hash_table) if (!ipa_bits_hash_table)
ipa_bits_hash_table = hash_table<ipa_bit_ggc_hash_traits>::create_ggc (37); ipa_bits_hash_table = hash_table<ipa_bit_ggc_hash_traits>::create_ggc (37);
if (!ipa_vr_hash_table) if (!ipa_vr_hash_table)
...@@ -3739,16 +3738,11 @@ ipa_free_edge_args_substructures (struct ipa_edge_args *args) ...@@ -3739,16 +3738,11 @@ ipa_free_edge_args_substructures (struct ipa_edge_args *args)
void void
ipa_free_all_edge_args (void) ipa_free_all_edge_args (void)
{ {
int i; if (!ipa_edge_args_sum)
struct ipa_edge_args *args;
if (!ipa_edge_args_vector)
return; return;
FOR_EACH_VEC_ELT (*ipa_edge_args_vector, i, args) ipa_edge_args_sum->release ();
ipa_free_edge_args_substructures (args); ipa_edge_args_sum = NULL;
vec_free (ipa_edge_args_vector);
} }
/* Free all ipa_node_params structures. */ /* Free all ipa_node_params structures. */
...@@ -3785,18 +3779,12 @@ ipa_set_node_agg_value_chain (struct cgraph_node *node, ...@@ -3785,18 +3779,12 @@ ipa_set_node_agg_value_chain (struct cgraph_node *node,
(*ipcp_transformations)[node->uid].agg_values = aggvals; (*ipcp_transformations)[node->uid].agg_values = aggvals;
} }
/* Hook that is called by cgraph.c when an edge is removed. */ /* Hook that is called by cgraph.c when an edge is removed. Adjust reference
count data structures accordingly. */
static void void
ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED) ipa_edge_args_sum_t::remove (cgraph_edge *cs, ipa_edge_args *args)
{ {
struct ipa_edge_args *args;
/* During IPA-CP updating we can be called on not-yet analyzed clones. */
if (vec_safe_length (ipa_edge_args_vector) <= (unsigned)cs->uid)
return;
args = IPA_EDGE_REF (cs);
if (args->jump_functions) if (args->jump_functions)
{ {
struct ipa_jump_func *jf; struct ipa_jump_func *jf;
...@@ -3811,24 +3799,17 @@ ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED) ...@@ -3811,24 +3799,17 @@ ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
rdesc->cs = NULL; rdesc->cs = NULL;
} }
} }
ipa_free_edge_args_substructures (IPA_EDGE_REF (cs));
} }
/* Hook that is called by cgraph.c when an edge is duplicated. */ /* Method invoked when an edge is duplicated. Copy ipa_edge_args and adjust
reference count data strucutres accordingly. */
static void void
ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst, ipa_edge_args_sum_t::duplicate (cgraph_edge *src, cgraph_edge *dst,
void *) ipa_edge_args *old_args, ipa_edge_args *new_args)
{ {
struct ipa_edge_args *old_args, *new_args;
unsigned int i; unsigned int i;
ipa_check_create_edge_args ();
old_args = IPA_EDGE_REF (src);
new_args = IPA_EDGE_REF (dst);
new_args->jump_functions = vec_safe_copy (old_args->jump_functions); new_args->jump_functions = vec_safe_copy (old_args->jump_functions);
if (old_args->polymorphic_call_contexts) if (old_args->polymorphic_call_contexts)
new_args->polymorphic_call_contexts new_args->polymorphic_call_contexts
...@@ -3989,13 +3970,8 @@ void ...@@ -3989,13 +3970,8 @@ void
ipa_register_cgraph_hooks (void) ipa_register_cgraph_hooks (void)
{ {
ipa_check_create_node_params (); ipa_check_create_node_params ();
ipa_check_create_edge_args ();
if (!edge_removal_hook_holder)
edge_removal_hook_holder =
symtab->add_edge_removal_hook (&ipa_edge_removal_hook, NULL);
if (!edge_duplication_hook_holder)
edge_duplication_hook_holder =
symtab->add_edge_duplication_hook (&ipa_edge_duplication_hook, NULL);
function_insertion_hook_holder = function_insertion_hook_holder =
symtab->add_cgraph_insertion_hook (&ipa_add_new_function, NULL); symtab->add_cgraph_insertion_hook (&ipa_add_new_function, NULL);
} }
...@@ -4005,10 +3981,6 @@ ipa_register_cgraph_hooks (void) ...@@ -4005,10 +3981,6 @@ ipa_register_cgraph_hooks (void)
static void static void
ipa_unregister_cgraph_hooks (void) ipa_unregister_cgraph_hooks (void)
{ {
symtab->remove_edge_removal_hook (edge_removal_hook_holder);
edge_removal_hook_holder = NULL;
symtab->remove_edge_duplication_hook (edge_duplication_hook_holder);
edge_duplication_hook_holder = NULL;
symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder); symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
function_insertion_hook_holder = NULL; function_insertion_hook_holder = NULL;
} }
...@@ -5218,7 +5190,7 @@ ipa_prop_write_jump_functions (void) ...@@ -5218,7 +5190,7 @@ ipa_prop_write_jump_functions (void)
lto_symtab_encoder_iterator lsei; lto_symtab_encoder_iterator lsei;
lto_symtab_encoder_t encoder; lto_symtab_encoder_t encoder;
if (!ipa_node_params_sum || !ipa_edge_args_vector) if (!ipa_node_params_sum || !ipa_edge_args_sum)
return; return;
ob = create_output_block (LTO_section_jump_functions); ob = create_output_block (LTO_section_jump_functions);
......
...@@ -559,9 +559,24 @@ void ipcp_grow_transformations_if_necessary (void); ...@@ -559,9 +559,24 @@ void ipcp_grow_transformations_if_necessary (void);
/* ipa_edge_args stores information related to a callsite and particularly its /* ipa_edge_args stores information related to a callsite and particularly its
arguments. It can be accessed by the IPA_EDGE_REF macro. */ arguments. It can be accessed by the IPA_EDGE_REF macro. */
struct GTY(()) ipa_edge_args
class GTY((for_user)) ipa_edge_args
{ {
/* Vector of the callsite's jump function of each parameter. */ public:
/* Default constructor. */
ipa_edge_args () : jump_functions (NULL), polymorphic_call_contexts (NULL)
{}
/* Destructor. */
~ipa_edge_args ()
{
vec_free (jump_functions);
vec_free (polymorphic_call_contexts);
}
/* Vectors of the callsite's jump function and polymorphic context
information of each parameter. */
vec<ipa_jump_func, va_gc> *jump_functions; vec<ipa_jump_func, va_gc> *jump_functions;
vec<ipa_polymorphic_call_context, va_gc> *polymorphic_call_contexts; vec<ipa_polymorphic_call_context, va_gc> *polymorphic_call_contexts;
}; };
...@@ -611,19 +626,35 @@ public: ...@@ -611,19 +626,35 @@ public:
ipa_node_params *data2); ipa_node_params *data2);
}; };
/* Summary to manange ipa_edge_args structures. */
class GTY((user)) ipa_edge_args_sum_t : public call_summary <ipa_edge_args *>
{
public:
ipa_edge_args_sum_t (symbol_table *table, bool ggc)
: call_summary<ipa_edge_args *> (table, ggc) { }
/* Hook that is called by summary when an edge is duplicated. */
virtual void remove (cgraph_edge *cs, ipa_edge_args *args);
/* Hook that is called by summary when an edge is duplicated. */
virtual void duplicate (cgraph_edge *src,
cgraph_edge *dst,
ipa_edge_args *old_args,
ipa_edge_args *new_args);
};
/* Function summary where the parameter infos are actually stored. */ /* Function summary where the parameter infos are actually stored. */
extern GTY(()) ipa_node_params_t * ipa_node_params_sum; extern GTY(()) ipa_node_params_t * ipa_node_params_sum;
/* Call summary to store information about edges such as jump functions. */
extern GTY(()) ipa_edge_args_sum_t *ipa_edge_args_sum;
/* Vector of IPA-CP transformation data for each clone. */ /* Vector of IPA-CP transformation data for each clone. */
extern GTY(()) vec<ipcp_transformation_summary, va_gc> *ipcp_transformations; extern GTY(()) vec<ipcp_transformation_summary, va_gc> *ipcp_transformations;
/* Vector where the parameter infos are actually stored. */
extern GTY(()) vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
/* Return the associated parameter/argument info corresponding to the given /* Return the associated parameter/argument info corresponding to the given
node/edge. */ node/edge. */
#define IPA_NODE_REF(NODE) (ipa_node_params_sum->get (NODE)) #define IPA_NODE_REF(NODE) (ipa_node_params_sum->get (NODE))
#define IPA_EDGE_REF(EDGE) (&(*ipa_edge_args_vector)[(EDGE)->uid]) #define IPA_EDGE_REF(EDGE) (ipa_edge_args_sum->get (EDGE))
/* This macro checks validity of index returned by /* This macro checks validity of index returned by
ipa_get_param_decl_index function. */ ipa_get_param_decl_index function. */
#define IS_VALID_JUMP_FUNC_INDEX(I) ((I) != -1) #define IS_VALID_JUMP_FUNC_INDEX(I) ((I) != -1)
...@@ -653,14 +684,14 @@ ipa_check_create_node_params (void) ...@@ -653,14 +684,14 @@ ipa_check_create_node_params (void)
ipa_node_params_t (symtab, true)); ipa_node_params_t (symtab, true));
} }
/* Returns true if the array of edge infos is large enough to accommodate an /* Returns true if edge summary contains a record for EDGE. The main purpose
info for EDGE. The main purpose of this function is that debug dumping of this function is that debug dumping function can check info availability
function can check info availability without causing reallocations. */ without causing allocations. */
static inline bool static inline bool
ipa_edge_args_info_available_for_edge_p (struct cgraph_edge *edge) ipa_edge_args_info_available_for_edge_p (struct cgraph_edge *edge)
{ {
return ((unsigned) edge->uid < vec_safe_length (ipa_edge_args_vector)); return ipa_edge_args_sum->exists (edge);
} }
static inline ipcp_transformation_summary * static inline ipcp_transformation_summary *
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment