Commit 2c9561b5 by Martin Jambor Committed by Martin Jambor

re PR tree-optimization/53787 (Possible IPA-SRA / IPA-CP improvement)

2012-11-07  Martin Jambor  <mjambor@suse.cz>

	PR tree-optimization/53787
	* ipa-cp.c (ipcp_value_source): New field offset.
	(ipcp_agg_lattice): New type.
	(ipcp_param_lattices): Likewise, move virt_call from ipcp_lattice here.
	(ipcp_agg_lattice_pool): New variable.
	(ipa_get_parm_lattices): New function.
	(ipa_get_lattice): Turned into ipa_get_scalar_lat, use the above.
	Adjusted all callers.
	(print_lattice): New function.
	(print_all_lattices): Use the above, also print aggregate lattices.
	(set_agg_lats_to_bottom): New function.
	(set_agg_lats_contain_variable): Likewise.
	(set_all_contains_variable): Likewise.
	(initialize_node_lattices): Also handle aggregate lattices, set
	virt_call in ipcp_param_lattices.
	(add_value_source): Handle offsets.
	(add_value_to_lattice): Likewise.
	(add_scalar_value_to_lattice): New function.
	(propagate_vals_accross_pass_through): Use add_scalar_value_to_lattice.
	(propagate_vals_accross_ancestor): Likewise.
	(propagate_accross_jump_function): Renamed to
	propagate_scalar_accross_jump_function, use
	add_scalar_value_to_lattice.
	(set_check_aggs_by_ref): New function.
	(merge_agg_lats_step): Likewise.
	(set_chain_of_aglats_contains_variable): Likewise.
	(merge_aggregate_lattices): Likewise.
	(propagate_constants_accross_call): Also handle aggregate lattices.
	(hint_time_bonus): New function.
	(context_independent_aggregate_values): Likewise.
	(gather_context_independent_values): Also handle agggregate values.
	(agg_jmp_p_vec_for_t_vec): New function.
	(estimate_local_effects): Also handle agggregate values.
	(add_all_node_vals_to_toposort): Likewise.
	(ipcp_propagate_stage): Use struct ipcp_param_lattices.
	(get_clone_agg_value): New function.
	(cgraph_edge_brings_value_p): Also handle agggregate values.
	(create_specialized_node): Likewise.
	(find_more_values_for_callers_subset): Rename to
	find_more_scalar_values_for_callers_subset.  Modify dump.
	(copy_plats_to_inter): New function.
	(intersect_with_plats): Likewise.
	(agg_replacements_to_vector): Likewise.
	(intersect_with_agg_replacements): Likewise.
	(find_aggregate_values_for_callers_subset): Likewise.
	(known_aggs_to_agg_replacement_list): Likewise.
	(cgraph_edge_brings_all_scalars_for_node): Likewise.
	(cgraph_edge_brings_all_agg_vals_for_node): Likewise.
	(perhaps_add_new_callers): Old functionality moved to
	cgraph_edge_brings_all_scalars_for_node, call it and
	cgraph_edge_brings_all_agg_vals_for_node.
	(ipcp_val_in_agg_replacements_p): New function.
	(decide_about_value): New function.
	(decide_whether_version_node): A lot of functionality moved to
	decide_about_value.  Also handle agggregate values.
	(ipcp_driver): Also allocate ipcp_agg_lattice_pool.
	(pass_ipa_cp): Fill in new entries.
	* ipa-prop.c (ipa_node_agg_replacements): New variable.
	(free_parms_ainfo): New function.
	(ipa_analyze_node): Use free_parms_ainfo to free stuff.
	(ipa_find_agg_cst_for_param): Do not rely on offset ordering.
	(ipa_set_node_agg_value_chain): New function.
	(ipa_node_removal_hook): Also handle ipa_node_agg_replacements.
	(ipa_node_duplication_hook): Likewise.
	(ipa_free_all_structures_after_ipa_cp): Also free ipcp_agg_lattice_pool.
	(ipa_free_all_structures_after_iinln): Likewise.
	(ipa_dump_agg_replacement_values): New function.
	(write_agg_replacement_chain): Likewise.
	(read_agg_replacement_chain): Likewise.
	(ipa_prop_write_all_agg_replacement): Likewise.
	(read_replacements_section): Likewise.
	(ipa_prop_read_all_agg_replacement): Likewise.
	(adjust_agg_replacement_values): Likewise.
	(ipcp_transform_function): Likewise.
	* ipa-prop.h: Also define heap vector of ipa_agg_jf_item_t and of
	ipa_agg_jump_function_t.
	(ipa_node_params): Make lattices an array of ipcp_param_lattices.
	(ipa_agg_replacement_value): New type and its vector.
	(ipa_set_node_agg_value_chain) Declare.
	(ipa_node_agg_replacements): Likewise.
	(ipa_get_agg_replacements_for_node): New function.
	(ipcp_agg_lattice_pool): Declare.
	(ipa_dump_agg_replacement_values): Likewise.
	(ipa_prop_write_all_agg_replacement): Likewise.
	(ipa_prop_read_all_agg_replacement): Likewise.
	(ipcp_transform_function): Likewise.
	* ipa-inline-analysis.c (estimate_ipcp_clone_size_and_time): Pass around
	known aggregates and hints.
	* ipa-inline.h: include ipa-prop.h.
	(estimate_ipcp_clone_size_and_time): Adjust declaration.
	* lto-streamer.h (lto_section_type): New item
	LTO_section_ipcp_transform.
	* lto-section-in.c (lto_section_name): New element ipcp_trans.
	* params.def (PARAM_IPA_CP_LOOP_HINT_BONUS): New parameter.
	* Makefile.in (IPA_INLINE_H): New.  Use everywhee instead of
	ipa-inline.h.

	* testsuite/gcc.dg/ipa/ipa-5.c: Adjust.
	* testsuite/gcc.dg/ipa/ipcp-agg-1.c: New test.
	* testsuite/gcc.dg/ipa/ipcp-agg-2.c: Likewise.
	* testsuite/gcc.dg/ipa/ipcp-agg-3.c: Likewise.
	* testsuite/gcc.dg/ipa/ipcp-agg-4.c: Likewise.
	* testsuite/gcc.dg/ipa/ipcp-agg-5.c: Likewise.
	* testsuite/gcc.dg/ipa/ipcp-agg-6.c: Likewise.
	* testsuite/gfortran.dg/pr48636.f90: Add -fno-ipa-cp.
	* testsuite/gfortran.dg/pr48636-2.f90: New test.
	* testsuite/gfortran.dg/pr53787.f90: Likewise.

From-SVN: r193298
parent a57d75dc
2012-11-07 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/53787
* ipa-cp.c (ipcp_value_source): New field offset.
(ipcp_agg_lattice): New type.
(ipcp_param_lattices): Likewise, move virt_call from ipcp_lattice here.
(ipcp_agg_lattice_pool): New variable.
(ipa_get_parm_lattices): New function.
(ipa_get_lattice): Turned into ipa_get_scalar_lat, use the above.
Adjusted all callers.
(print_lattice): New function.
(print_all_lattices): Use the above, also print aggregate lattices.
(set_agg_lats_to_bottom): New function.
(set_agg_lats_contain_variable): Likewise.
(set_all_contains_variable): Likewise.
(initialize_node_lattices): Also handle aggregate lattices, set
virt_call in ipcp_param_lattices.
(add_value_source): Handle offsets.
(add_value_to_lattice): Likewise.
(add_scalar_value_to_lattice): New function.
(propagate_vals_accross_pass_through): Use add_scalar_value_to_lattice.
(propagate_vals_accross_ancestor): Likewise.
(propagate_accross_jump_function): Renamed to
propagate_scalar_accross_jump_function, use
add_scalar_value_to_lattice.
(set_check_aggs_by_ref): New function.
(merge_agg_lats_step): Likewise.
(set_chain_of_aglats_contains_variable): Likewise.
(merge_aggregate_lattices): Likewise.
(propagate_constants_accross_call): Also handle aggregate lattices.
(hint_time_bonus): New function.
(context_independent_aggregate_values): Likewise.
(gather_context_independent_values): Also handle agggregate values.
(agg_jmp_p_vec_for_t_vec): New function.
(estimate_local_effects): Also handle agggregate values.
(add_all_node_vals_to_toposort): Likewise.
(ipcp_propagate_stage): Use struct ipcp_param_lattices.
(get_clone_agg_value): New function.
(cgraph_edge_brings_value_p): Also handle agggregate values.
(create_specialized_node): Likewise.
(find_more_values_for_callers_subset): Rename to
find_more_scalar_values_for_callers_subset. Modify dump.
(copy_plats_to_inter): New function.
(intersect_with_plats): Likewise.
(agg_replacements_to_vector): Likewise.
(intersect_with_agg_replacements): Likewise.
(find_aggregate_values_for_callers_subset): Likewise.
(known_aggs_to_agg_replacement_list): Likewise.
(cgraph_edge_brings_all_scalars_for_node): Likewise.
(cgraph_edge_brings_all_agg_vals_for_node): Likewise.
(perhaps_add_new_callers): Old functionality moved to
cgraph_edge_brings_all_scalars_for_node, call it and
cgraph_edge_brings_all_agg_vals_for_node.
(ipcp_val_in_agg_replacements_p): New function.
(decide_about_value): New function.
(decide_whether_version_node): A lot of functionality moved to
decide_about_value. Also handle agggregate values.
(ipcp_driver): Also allocate ipcp_agg_lattice_pool.
(pass_ipa_cp): Fill in new entries.
* ipa-prop.c (ipa_node_agg_replacements): New variable.
(free_parms_ainfo): New function.
(ipa_analyze_node): Use free_parms_ainfo to free stuff.
(ipa_find_agg_cst_for_param): Do not rely on offset ordering.
(ipa_set_node_agg_value_chain): New function.
(ipa_node_removal_hook): Also handle ipa_node_agg_replacements.
(ipa_node_duplication_hook): Likewise.
(ipa_free_all_structures_after_ipa_cp): Also free ipcp_agg_lattice_pool.
(ipa_free_all_structures_after_iinln): Likewise.
(ipa_dump_agg_replacement_values): New function.
(write_agg_replacement_chain): Likewise.
(read_agg_replacement_chain): Likewise.
(ipa_prop_write_all_agg_replacement): Likewise.
(read_replacements_section): Likewise.
(ipa_prop_read_all_agg_replacement): Likewise.
(adjust_agg_replacement_values): Likewise.
(ipcp_transform_function): Likewise.
* ipa-prop.h: Also define heap vector of ipa_agg_jf_item_t and of
ipa_agg_jump_function_t.
(ipa_node_params): Make lattices an array of ipcp_param_lattices.
(ipa_agg_replacement_value): New type and its vector.
(ipa_set_node_agg_value_chain) Declare.
(ipa_node_agg_replacements): Likewise.
(ipa_get_agg_replacements_for_node): New function.
(ipcp_agg_lattice_pool): Declare.
(ipa_dump_agg_replacement_values): Likewise.
(ipa_prop_write_all_agg_replacement): Likewise.
(ipa_prop_read_all_agg_replacement): Likewise.
(ipcp_transform_function): Likewise.
* ipa-inline-analysis.c (estimate_ipcp_clone_size_and_time): Pass around
known aggregates and hints.
* ipa-inline.h: include ipa-prop.h.
(estimate_ipcp_clone_size_and_time): Adjust declaration.
* lto-streamer.h (lto_section_type): New item
LTO_section_ipcp_transform.
* lto-section-in.c (lto_section_name): New element ipcp_trans.
* params.def (PARAM_IPA_CP_LOOP_HINT_BONUS): New parameter.
* Makefile.in (IPA_INLINE_H): New. Use everywhee instead of
ipa-inline.h.
2012-11-07 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.c (enum upper_128bits_state): Remove.
......@@ -953,6 +953,7 @@ TREE_STREAMER_H = tree-streamer.h $(TREE_H) $(LTO_STREAMER_H) \
STREAMER_HOOKS_H = streamer-hooks.h $(TREE_H)
TREE_VECTORIZER_H = tree-vectorizer.h $(TREE_DATA_REF_H) $(TARGET_H)
IPA_PROP_H = ipa-prop.h $(TREE_H) $(VEC_H) $(CGRAPH_H) $(GIMPLE_H) alloc-pool.h
IPA_INLINE_H = ipa-inline.h $(IPA_PROP_H)
GSTAB_H = gstab.h stab.def
BITMAP_H = bitmap.h $(HASHTAB_H) statistics.h
GCC_PLUGIN_H = gcc-plugin.h highlev-plugin-common.h plugin.def \
......@@ -2834,14 +2835,14 @@ cgraph.o : cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h dumpfile.h \
gt-cgraph.h intl.h $(BASIC_BLOCK_H) debug.h $(HASHTAB_H) \
$(TREE_INLINE_H) $(TREE_FLOW_H) cif-code.def \
value-prof.h $(EXCEPT_H) $(IPA_UTILS_H) $(DIAGNOSTIC_CORE_H) \
ipa-inline.h $(LTO_STREAMER_H) $(CFGLOOP_H) $(GIMPLE_PRETTY_PRINT_H)
$(IPA_INLINE_H) $(LTO_STREAMER_H) $(CFGLOOP_H) $(GIMPLE_PRETTY_PRINT_H)
cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) langhooks.h $(TREE_INLINE_H) toplev.h $(DIAGNOSTIC_CORE_H) $(FLAGS_H) $(GGC_H) \
$(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(GIMPLE_H) \
$(TREE_FLOW_H) $(TREE_PASS_H) debug.h $(DIAGNOSTIC_H) \
$(FIBHEAP_H) output.h $(PARAMS_H) $(RTL_H) $(IPA_PROP_H) \
gt-cgraphunit.h tree-iterator.h $(COVERAGE_H) $(TREE_DUMP_H) \
$(GIMPLE_PRETTY_PRINT_H) ipa-inline.h $(IPA_UTILS_H) \
$(GIMPLE_PRETTY_PRINT_H) $(IPA_INLINE_H) $(IPA_UTILS_H) \
$(LTO_STREAMER_H) output.h $(REGSET_H) $(EXCEPT_H) $(GCC_PLUGIN_H) plugin.h
cgraphclones.o : cgraphclones.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) langhooks.h $(TREE_INLINE_H) toplev.h $(DIAGNOSTIC_CORE_H) $(FLAGS_H) $(GGC_H) \
......@@ -2849,12 +2850,12 @@ cgraphclones.o : cgraphclones.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_FLOW_H) $(TREE_PASS_H) debug.h $(DIAGNOSTIC_H) $(TREE_DUMP_H) \
$(PARAMS_H) $(RTL_H) $(IPA_PROP_H) \
tree-iterator.h $(COVERAGE_H) \
$(GIMPLE_PRETTY_PRINT_H) ipa-inline.h $(IPA_UTILS_H) \
$(GIMPLE_PRETTY_PRINT_H) $(IPA_INLINE_H) $(IPA_UTILS_H) \
$(LTO_STREAMER_H) $(EXCEPT_H) $(GCC_PLUGIN_H) gt-cgraphclones.h
cgraphbuild.o : cgraphbuild.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) langhooks.h $(CGRAPH_H) intl.h pointer-set.h $(GIMPLE_H) \
$(TREE_FLOW_H) $(TREE_PASS_H) $(IPA_UTILS_H) $(EXCEPT_H) \
ipa-inline.h
$(IPA_INLINE_H)
varpool.o : varpool.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) $(CGRAPH_H) langhooks.h $(DIAGNOSTIC_CORE_H) $(HASHTAB_H) \
$(GGC_H) $(TIMEVAR_H) debug.h $(TARGET_H) output.h $(GIMPLE_H) \
......@@ -2874,21 +2875,22 @@ ipa-ref.o : ipa-ref.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
ipa-cp.o : ipa-cp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TREE_H) $(TARGET_H) $(GIMPLE_H) $(CGRAPH_H) $(IPA_PROP_H) $(TREE_FLOW_H) \
$(TREE_PASS_H) $(FLAGS_H) $(DIAGNOSTIC_H) \
$(TREE_INLINE_H) $(PARAMS_H) $(TREE_PRETTY_PRINT_H) ipa-inline.h
$(TREE_INLINE_H) $(PARAMS_H) $(TREE_PRETTY_PRINT_H) $(IPA_INLINE_H)
ipa-split.o : ipa-split.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TREE_H) $(TARGET_H) $(CGRAPH_H) $(IPA_PROP_H) $(TREE_FLOW_H) \
$(TREE_PASS_H) $(FLAGS_H) $(DIAGNOSTIC_H) $(TREE_DUMP_H) \
$(TREE_INLINE_H) $(PARAMS_H) $(GIMPLE_PRETTY_PRINT_H) ipa-inline.h
$(TREE_INLINE_H) $(PARAMS_H) $(GIMPLE_PRETTY_PRINT_H) $(IPA_INLINE_H)
ipa-inline.o : ipa-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) langhooks.h $(TREE_INLINE_H) $(FLAGS_H) $(CGRAPH_H) intl.h \
$(DIAGNOSTIC_H) $(FIBHEAP_H) $(PARAMS_H) $(TREE_PASS_H) \
$(COVERAGE_H) $(GGC_H) $(TREE_FLOW_H) $(RTL_H) $(IPA_PROP_H) \
$(EXCEPT_H) $(GIMPLE_PRETTY_PRINT_H) ipa-inline.h $(TARGET_H) $(IPA_UTILS_H)
$(EXCEPT_H) $(GIMPLE_PRETTY_PRINT_H) $(IPA_INLINE_H) $(TARGET_H) \
$(IPA_UTILS_H)
ipa-inline-analysis.o : ipa-inline-analysis.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) langhooks.h $(TREE_INLINE_H) $(FLAGS_H) $(CGRAPH_H) intl.h \
$(DIAGNOSTIC_H) $(PARAMS_H) $(TREE_PASS_H) $(CFGLOOP_H) \
$(HASHTAB_H) $(COVERAGE_H) $(GGC_H) $(TREE_FLOW_H) $(IPA_PROP_H) \
$(GIMPLE_PRETTY_PRINT_H) ipa-inline.h $(LTO_STREAMER_H) $(DATA_STREAMER_H) \
$(GIMPLE_PRETTY_PRINT_H) $(IPA_INLINE_H) $(LTO_STREAMER_H) $(DATA_STREAMER_H) \
$(TREE_STREAMER_H)
ipa-inline-transform.o : ipa-inline-transform.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) langhooks.h $(TREE_INLINE_H) $(FLAGS_H) $(CGRAPH_H) intl.h \
......
......@@ -2913,16 +2913,18 @@ estimate_node_size_and_time (struct cgraph_node *node,
void
estimate_ipcp_clone_size_and_time (struct cgraph_node *node,
VEC (tree, heap) *known_vals,
VEC (tree, heap) *known_binfos,
int *ret_size, int *ret_time)
VEC (tree, heap) *known_vals,
VEC (tree, heap) *known_binfos,
VEC (ipa_agg_jump_function_p, heap) *known_aggs,
int *ret_size, int *ret_time,
inline_hints *hints)
{
clause_t clause;
clause = evaluate_conditions_for_known_args (node, false, known_vals, NULL);
estimate_node_size_and_time (node, clause, known_vals, known_binfos, NULL,
ret_size, ret_time, NULL,
NULL);
clause = evaluate_conditions_for_known_args (node, false, known_vals,
known_aggs);
estimate_node_size_and_time (node, clause, known_vals, known_binfos,
known_aggs, ret_size, ret_time, hints, NULL);
}
/* Translate all conditions from callee representation into caller
......
......@@ -19,6 +19,8 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "ipa-prop.h"
/* Representation of inline parameters that do depend on context function is
inlined into (i.e. known constant values of function parameters.
......@@ -207,9 +209,9 @@ void initialize_inline_failed (struct cgraph_edge *);
int estimate_time_after_inlining (struct cgraph_node *, struct cgraph_edge *);
int estimate_size_after_inlining (struct cgraph_node *, struct cgraph_edge *);
void estimate_ipcp_clone_size_and_time (struct cgraph_node *,
VEC (tree, heap) *known_vals,
VEC (tree, heap) *known_binfos,
int *, int *);
VEC (tree, heap) *, VEC (tree, heap) *,
VEC (ipa_agg_jump_function_p, heap) *,
int *, int *, inline_hints *);
int do_estimate_growth (struct cgraph_node *);
void inline_merge_summary (struct cgraph_edge *edge);
void inline_update_overall_summary (struct cgraph_node *node);
......
......@@ -144,6 +144,7 @@ typedef struct GTY(()) ipa_agg_jf_item
DEF_VEC_O (ipa_agg_jf_item_t);
DEF_VEC_ALLOC_O (ipa_agg_jf_item_t, gc);
DEF_VEC_ALLOC_O (ipa_agg_jf_item_t, heap);
/* Aggregate jump function - i.e. description of contents of aggregates passed
either by reference or value. */
......@@ -159,6 +160,9 @@ struct GTY(()) ipa_agg_jump_function
typedef struct ipa_agg_jump_function *ipa_agg_jump_function_p;
DEF_VEC_P (ipa_agg_jump_function_p);
DEF_VEC_ALLOC_P (ipa_agg_jump_function_p, heap);
typedef struct ipa_agg_jump_function ipa_agg_jump_function_t;
DEF_VEC_P (ipa_agg_jump_function_t);
DEF_VEC_ALLOC_P (ipa_agg_jump_function_t, heap);
/* A jump function for a callsite represents the values passed as actual
arguments of the callsite. See enum jump_func_type for the various
......@@ -322,7 +326,7 @@ struct ipa_node_params
VEC (ipa_param_descriptor_t, heap) *descriptors;
/* Pointer to an array of structures describing individual formal
parameters. */
struct ipcp_lattice *lattices;
struct ipcp_param_lattices *lattices;
/* Only for versioned nodes this field would not be NULL,
it points to the node that IPA cp cloned from. */
struct cgraph_node *ipcp_orig_node;
......@@ -380,6 +384,27 @@ ipa_is_param_used (struct ipa_node_params *info, int i)
return VEC_index (ipa_param_descriptor_t, info->descriptors, i).used;
}
/* Information about replacements done in aggregates for a given node (each
node has its linked list). */
struct GTY(()) ipa_agg_replacement_value
{
/* Next item in the linked list. */
struct ipa_agg_replacement_value *next;
/* Offset within the aggregate. */
HOST_WIDE_INT offset;
/* The constant value. */
tree value;
/* The paramter index. */
int index;
};
typedef struct ipa_agg_replacement_value *ipa_agg_replacement_value_p;
DEF_VEC_P (ipa_agg_replacement_value_p);
DEF_VEC_ALLOC_P (ipa_agg_replacement_value_p, gc);
void ipa_set_node_agg_value_chain (struct cgraph_node *node,
struct ipa_agg_replacement_value *aggvals);
/* ipa_edge_args stores information related to a callsite and particularly its
arguments. It can be accessed by the IPA_EDGE_REF macro. */
typedef struct GTY(()) ipa_edge_args
......@@ -420,6 +445,8 @@ DEF_VEC_ALLOC_O (ipa_edge_args_t, gc);
/* Vector where the parameter infos are actually stored. */
extern VEC (ipa_node_params_t, heap) *ipa_node_params_vector;
/* Vector of known aggregate values in cloned nodes. */
extern GTY(()) VEC (ipa_agg_replacement_value_p, gc) *ipa_node_agg_replacements;
/* Vector where the parameter infos are actually stored. */
extern GTY(()) VEC (ipa_edge_args_t, gc) *ipa_edge_args_vector;
......@@ -487,6 +514,18 @@ ipa_edge_args_info_available_for_edge_p (struct cgraph_edge *edge)
ipa_edge_args_vector));
}
/* 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)
{
if ((unsigned) node->uid >= VEC_length (ipa_agg_replacement_value_p,
ipa_node_agg_replacements))
return NULL;
return VEC_index (ipa_agg_replacement_value_p, ipa_node_agg_replacements,
node->uid);
}
/* Function formal parameters related computations. */
void ipa_initialize_node_params (struct cgraph_node *node);
bool ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
......@@ -517,6 +556,7 @@ void ipcp_verify_propagated_values (void);
extern alloc_pool ipcp_values_pool;
extern alloc_pool ipcp_sources_pool;
extern alloc_pool ipcp_agg_lattice_pool;
/* Structure to describe transformations of formal parameters and actual
arguments. Each instance describes one new parameter and they are meant to
......@@ -589,13 +629,17 @@ void ipa_modify_call_arguments (struct cgraph_edge *, gimple,
ipa_parm_adjustment_vec ipa_combine_adjustments (ipa_parm_adjustment_vec,
ipa_parm_adjustment_vec);
void ipa_dump_param_adjustments (FILE *, ipa_parm_adjustment_vec, tree);
void ipa_dump_agg_replacement_values (FILE *f,
struct ipa_agg_replacement_value *av);
void ipa_prop_write_jump_functions (void);
void ipa_prop_read_jump_functions (void);
void ipa_prop_write_all_agg_replacement (void);
void ipa_prop_read_all_agg_replacement (void);
void ipa_update_after_lto_read (void);
int ipa_get_param_decl_index (struct ipa_node_params *, tree);
tree ipa_value_from_jfunc (struct ipa_node_params *info,
struct ipa_jump_func *jfunc);
unsigned int ipcp_transform_function (struct cgraph_node *node);
/* From tree-sra.c: */
......
......@@ -58,7 +58,8 @@ const char *lto_section_name[LTO_N_SECTION_TYPES] =
"symbol_nodes",
"opts",
"cgraphopt",
"inline"
"inline",
"ipcp_trans"
};
......
......@@ -248,6 +248,7 @@ enum lto_section_type
LTO_section_opts,
LTO_section_cgraph_opt_sum,
LTO_section_inline_summary,
LTO_section_ipcp_transform,
LTO_N_SECTION_TYPES /* Must be last. */
};
......
......@@ -901,6 +901,12 @@ DEFPARAM (PARAM_IPA_MAX_AGG_ITEMS,
"jump functions and lattices",
16, 0, 0)
DEFPARAM (PARAM_IPA_CP_LOOP_HINT_BONUS,
"ipa-cp-loop-hint-bonus",
"Compile-time bonus IPA-CP assigns to candidates which make loop "
"bounds or strides known.",
64, 0, 0)
/* WHOPR partitioning configuration. */
DEFPARAM (PARAM_LTO_PARTITIONS,
......
2012-11-07 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/53787
* gcc.dg/ipa/ipa-5.c: Adjust.
* gcc.dg/ipa/ipcp-agg-1.c: New test.
* gcc.dg/ipa/ipcp-agg-2.c: Likewise.
* gcc.dg/ipa/ipcp-agg-3.c: Likewise.
* gcc.dg/ipa/ipcp-agg-4.c: Likewise.
* gcc.dg/ipa/ipcp-agg-5.c: Likewise.
* gcc.dg/ipa/ipcp-agg-6.c: Likewise.
* gfortran.dg/pr48636.f90: Add -fno-ipa-cp.
* gfortran.dg/pr48636-2.f90: New test.
* gfortran.dg/pr53787.f90: Likewise.
2012-11-07 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/55226
......
......@@ -5,7 +5,7 @@
/* Float & short constants. */
#include <stdio.h>
void t(void);
int t(void);
int g (float b, short c)
{
t();
......@@ -13,10 +13,11 @@ int g (float b, short c)
}
int f (float a)
{
t();
int i, j = t();
/* a is modified. */
if (a++ > 0)
g (a, 3);
for (i = 0; i < j; i++)
g (a, 3);
}
int main ()
{
......@@ -26,7 +27,7 @@ int main ()
return 0;
}
/* { dg-final { scan-ipa-dump-times "Creating a specialized node" 2 "cp" } } */
/* { dg-final { scan-ipa-dump-times "Creating a specialized node" 3 "cp" } } */
/* { dg-final { scan-ipa-dump "replacing param c with const 3" "cp" } } */
/* { dg-final { scan-ipa-dump "replacing param a with const 7" "cp" } } */
/* { dg-final { cleanup-ipa-dump "cp" } } */
/* { dg-do compile } */
/* { dg-options "-O3 -fno-ipa-sra -fdump-ipa-cp-details -fdump-tree-optimized-slim" } */
/* { dg-add-options bind_pic_locally } */
struct S
{
int a, b, c;
};
void *blah(int, void *);
static void __attribute__ ((noinline))
foo (struct S *p)
{
int i, c = p->c;
int b = p->b;
void *v = (void *) p;
for (i= 0; i< c; i++)
v = blah(b + i, v);
}
void
entry (void)
{
struct S s;
s.a = 1;
s.b = 64;
s.c = 32;
foo (&s);
}
/* { dg-final { scan-ipa-dump "Creating a specialized node of foo.*for all known contexts" "cp" } } */
/* { dg-final { scan-ipa-dump-times "Aggregate replacements:" 2 "cp" } } */
/* { dg-final { cleanup-ipa-dump "cp" } } */
/* { dg-final { scan-tree-dump-not "->c;" "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
/* { dg-do compile } */
/* { dg-options "-O3 -fno-ipa-sra -fdump-ipa-cp-details -fdump-tree-optimized-slim" } */
/* { dg-add-options bind_pic_locally } */
struct S
{
int a, b, c;
};
void *blah(int, void *);
static void __attribute__ ((noinline))
foo (struct S *p)
{
int i, c = p->c;
int b = p->b;
void *v = (void *) p;
for (i= 0; i< c; i++)
v = blah(b + i, v);
}
void
entry (int c)
{
struct S s;
int i;
for (i = 0; i<c; i++)
{
s.a = 1;
s.b = 64;
s.c = 32;
foo (&s);
}
s.c = 2;
foo (&s);
}
/* { dg-final { scan-ipa-dump-times "Creating a specialized node of foo/\[0-9\]*\\." 2 "cp" } } */
/* { dg-final { scan-ipa-dump-times "Aggregate replacements:" 4 "cp" } } */
/* { dg-final { cleanup-ipa-dump "cp" } } */
/* { dg-final { scan-tree-dump-not "->c;" "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
/* { dg-do compile } */
/* { dg-options "-O3 -fno-ipa-sra -fdump-ipa-cp-details -fdump-tree-optimized-slim" } */
/* { dg-add-options bind_pic_locally } */
struct S
{
int a, b, c;
};
void *blah(int, void *);
static void __attribute__ ((noinline))
foo (int z, struct S *p)
{
int i, c = p->c;
int b = p->b;
void *v = (void *) p;
for (i= 0; i< c; i++)
v = blah(b + i, v);
}
void
entry (int c)
{
struct S s;
int i;
for (i = 0; i<c; i++)
{
s.a = 1;
s.b = 64;
s.c = 32;
foo (i, &s);
}
s.c = 2;
foo (0, &s);
}
/* { dg-final { scan-ipa-dump-times "Creating a specialized node of foo/\[0-9\]*\\." 2 "cp" } } */
/* { dg-final { scan-ipa-dump-times "Aggregate replacements: 1" 2 "cp" } } */
/* { dg-final { scan-ipa-dump-times "Aggregate replacements: 0" 2 "cp" } } */
/* { dg-final { cleanup-ipa-dump "cp" } } */
/* { dg-final { scan-tree-dump-not "->c;" "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
/* { dg-do compile } */
/* { dg-options "-O3 -fno-ipa-sra -fdump-ipa-cp-details -fdump-tree-optimized-slim" } */
/* { dg-add-options bind_pic_locally } */
struct S
{
int a, b, c;
};
void *blah(int, void *);
static void __attribute__ ((noinline))
foo (struct S *p)
{
int i, c = p->c;
int b = p->b;
void *v = (void *) p;
for (i= 0; i< c; i++)
v = blah(b + i, v);
}
void
entry1 (int c)
{
struct S s;
int i;
for (i = 0; i<c; i++)
{
s.a = 1;
s.b = 64;
s.c = 32;
foo (&s);
}
s.c = 2;
foo (&s);
}
void
entry2 (int c)
{
struct S s;
int i;
for (i = 0; i<c; i++)
{
s.a = 6;
s.b = 64;
s.c = 32;
foo (&s);
}
s.c = 2;
foo (&s);
}
/* { dg-final { scan-ipa-dump-times "Creating a specialized node of foo/\[0-9\]*\\." 2 "cp" } } */
/* { dg-final { scan-ipa-dump-times "Aggregate replacements:" 4 "cp" } } */
/* { dg-final { cleanup-ipa-dump "cp" } } */
/* { dg-final { scan-tree-dump-not "->c;" "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
/* { dg-do compile } */
/* { dg-options "-O3 -fno-ipa-sra -fdump-ipa-cp-details -fdump-tree-optimized-slim" } */
/* { dg-add-options bind_pic_locally } */
struct S
{
int a, b, c;
};
void *blah(int, void *);
static void __attribute__ ((noinline))
foo (struct S *p)
{
int i, c = p->c;
int b = p->b;
void *v = (void *) p;
for (i= 0; i< c; i++)
v = blah(b + i, v);
}
static void __attribute__ ((noinline))
bar (struct S *p)
{
foo (p);
}
void
entry1 (int c)
{
struct S s;
int i;
for (i = 0; i<c; i++)
{
s.a = 1;
s.b = 64;
s.c = 32;
bar (&s);
}
s.c = 2;
bar (&s);
}
void
entry2 (int c)
{
struct S s;
int i;
for (i = 0; i<c; i++)
{
s.a = 6;
s.b = 64;
s.c = 32;
foo (&s);
}
s.c = 2;
foo (&s);
}
/* { dg-final { scan-ipa-dump-times "Creating a specialized node of foo/\[0-9\]*\\." 2 "cp" } } */
/* { dg-final { scan-ipa-dump-times "Creating a specialized node of bar/\[0-9\]*\\." 2 "cp" } } */
/* { dg-final { scan-ipa-dump-times "Aggregate replacements:" 8 "cp" } } */
/* { dg-final { cleanup-ipa-dump "cp" } } */
/* { dg-final { scan-tree-dump-not "->c;" "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
/* { dg-do compile } */
/* { dg-options "-O3 -fno-ipa-sra -fdump-ipa-cp-details -fdump-tree-optimized-slim" } */
/* { dg-add-options bind_pic_locally } */
struct S
{
int a, b, c;
};
void *blah(int, void *);
static void __attribute__ ((noinline))
foo (struct S *p)
{
int i, c = p->c;
int b = p->b;
void *v = (void *) p;
for (i= 0; i< c; i++)
v = blah(b + i, v);
}
static void __attribute__ ((noinline))
bar (struct S *p)
{
foo (p);
}
static void __attribute__ ((noinline))
bar_2 (struct S *p)
{
foo (p);
}
void
entry1 (int c)
{
struct S s;
int i;
for (i = 0; i<c; i++)
{
s.a = 1;
s.b = 64;
s.c = 32;
bar (&s);
}
s.c = 2;
bar (&s);
}
void
entry2 (int c)
{
struct S s;
int i;
for (i = 0; i<c; i++)
{
s.a = 6;
s.b = 64;
s.c = 32;
bar_2 (&s);
}
s.c = 2;
foo (&s);
}
/* { dg-final { scan-ipa-dump-times "Creating a specialized node of foo/\[0-9\]*\\." 2 "cp" } } */
/* { dg-final { scan-ipa-dump-times "Creating a specialized node of bar/\[0-9\]*\\." 2 "cp" } } */
/* { dg-final { scan-ipa-dump "Creating a specialized node of bar_2.*for all known contexts" "cp" } } */
/* { dg-final { scan-ipa-dump-times "Aggregate replacements:" 10 "cp" } } */
/* { dg-final { cleanup-ipa-dump "cp" } } */
/* { dg-final { scan-tree-dump-not "->c;" "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
! { dg-do compile }
! { dg-options "-O3 -fdump-ipa-cp-details -fno-inline" }
module foo
implicit none
contains
subroutine bar(a,x)
real, dimension(:,:), intent(in) :: a
real, intent(out) :: x
integer :: i,j
x = 0
do j=1,ubound(a,2)
do i=1,ubound(a,1)
x = x + a(i,j)**2
end do
end do
end subroutine bar
end module foo
program main
use foo
implicit none
real, dimension(2,3) :: a
real :: x
integer :: i
data a /1.0, 2.0, 3.0, -1.0, -2.0, -3.0/
do i=1,2000000
call bar(a,x)
end do
print *,x
end program main
! { dg-final { scan-ipa-dump "Creating a specialized node of bar/\[0-9\]*\\." "cp" } }
! { dg-final { scan-ipa-dump-times "Aggregate replacements\[^=\]*=\[^=\]*=\[^=\]*=\[^=\]*=\[^=\]*=\[^=\]*=\[^=\]*=\[^=\]*=\[^=\]*=" 2 "cp" } }
! { dg-final { cleanup-ipa-dump "cp" } }
! { dg-do compile }
! { dg-options "-O3 -fdump-ipa-inline-details" }
! { dg-options "-O3 -fdump-ipa-inline-details -fno-ipa-cp" }
module foo
implicit none
......
! { dg-do compile }
! { dg-options "-O3 -fdump-ipa-cp-details -fno-inline -fwhole-program" }
real x(10)
n = 10
call init(x,n)
print *, x
end program
subroutine init(x, n)
real x(10)
do i=1,n
x(i) = i*i + 1
enddo
return
end subroutine init
! { dg-final { scan-ipa-dump "Creating a specialized node of init" "cp" } }
! { dg-final { scan-ipa-dump-times "Aggregate replacements" 2 "cp" } }
! { dg-final { cleanup-ipa-dump "cp" } }
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