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> 2012-11-07 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.c (enum upper_128bits_state): Remove. * config/i386/i386.c (enum upper_128bits_state): Remove.
...@@ -953,6 +953,7 @@ TREE_STREAMER_H = tree-streamer.h $(TREE_H) $(LTO_STREAMER_H) \ ...@@ -953,6 +953,7 @@ TREE_STREAMER_H = tree-streamer.h $(TREE_H) $(LTO_STREAMER_H) \
STREAMER_HOOKS_H = streamer-hooks.h $(TREE_H) STREAMER_HOOKS_H = streamer-hooks.h $(TREE_H)
TREE_VECTORIZER_H = tree-vectorizer.h $(TREE_DATA_REF_H) $(TARGET_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_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 GSTAB_H = gstab.h stab.def
BITMAP_H = bitmap.h $(HASHTAB_H) statistics.h BITMAP_H = bitmap.h $(HASHTAB_H) statistics.h
GCC_PLUGIN_H = gcc-plugin.h highlev-plugin-common.h plugin.def \ 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 \ ...@@ -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) \ gt-cgraph.h intl.h $(BASIC_BLOCK_H) debug.h $(HASHTAB_H) \
$(TREE_INLINE_H) $(TREE_FLOW_H) cif-code.def \ $(TREE_INLINE_H) $(TREE_FLOW_H) cif-code.def \
value-prof.h $(EXCEPT_H) $(IPA_UTILS_H) $(DIAGNOSTIC_CORE_H) \ 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) \ 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) \ $(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) \ $(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(GIMPLE_H) \
$(TREE_FLOW_H) $(TREE_PASS_H) debug.h $(DIAGNOSTIC_H) \ $(TREE_FLOW_H) $(TREE_PASS_H) debug.h $(DIAGNOSTIC_H) \
$(FIBHEAP_H) output.h $(PARAMS_H) $(RTL_H) $(IPA_PROP_H) \ $(FIBHEAP_H) output.h $(PARAMS_H) $(RTL_H) $(IPA_PROP_H) \
gt-cgraphunit.h tree-iterator.h $(COVERAGE_H) $(TREE_DUMP_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 $(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) \ 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) \ $(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) \ ...@@ -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) \ $(TREE_FLOW_H) $(TREE_PASS_H) debug.h $(DIAGNOSTIC_H) $(TREE_DUMP_H) \
$(PARAMS_H) $(RTL_H) $(IPA_PROP_H) \ $(PARAMS_H) $(RTL_H) $(IPA_PROP_H) \
tree-iterator.h $(COVERAGE_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 $(LTO_STREAMER_H) $(EXCEPT_H) $(GCC_PLUGIN_H) gt-cgraphclones.h
cgraphbuild.o : cgraphbuild.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_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_H) langhooks.h $(CGRAPH_H) intl.h pointer-set.h $(GIMPLE_H) \
$(TREE_FLOW_H) $(TREE_PASS_H) $(IPA_UTILS_H) $(EXCEPT_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) \ varpool.o : varpool.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) $(CGRAPH_H) langhooks.h $(DIAGNOSTIC_CORE_H) $(HASHTAB_H) \ $(TREE_H) $(CGRAPH_H) langhooks.h $(DIAGNOSTIC_CORE_H) $(HASHTAB_H) \
$(GGC_H) $(TIMEVAR_H) debug.h $(TARGET_H) output.h $(GIMPLE_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 \ ...@@ -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 \ 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_H) $(TARGET_H) $(GIMPLE_H) $(CGRAPH_H) $(IPA_PROP_H) $(TREE_FLOW_H) \
$(TREE_PASS_H) $(FLAGS_H) $(DIAGNOSTIC_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 \ 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_H) $(TARGET_H) $(CGRAPH_H) $(IPA_PROP_H) $(TREE_FLOW_H) \
$(TREE_PASS_H) $(FLAGS_H) $(DIAGNOSTIC_H) $(TREE_DUMP_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) \ 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 \ $(TREE_H) langhooks.h $(TREE_INLINE_H) $(FLAGS_H) $(CGRAPH_H) intl.h \
$(DIAGNOSTIC_H) $(FIBHEAP_H) $(PARAMS_H) $(TREE_PASS_H) \ $(DIAGNOSTIC_H) $(FIBHEAP_H) $(PARAMS_H) $(TREE_PASS_H) \
$(COVERAGE_H) $(GGC_H) $(TREE_FLOW_H) $(RTL_H) $(IPA_PROP_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) \ 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 \ $(TREE_H) langhooks.h $(TREE_INLINE_H) $(FLAGS_H) $(CGRAPH_H) intl.h \
$(DIAGNOSTIC_H) $(PARAMS_H) $(TREE_PASS_H) $(CFGLOOP_H) \ $(DIAGNOSTIC_H) $(PARAMS_H) $(TREE_PASS_H) $(CFGLOOP_H) \
$(HASHTAB_H) $(COVERAGE_H) $(GGC_H) $(TREE_FLOW_H) $(IPA_PROP_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) $(TREE_STREAMER_H)
ipa-inline-transform.o : ipa-inline-transform.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_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 \ $(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, ...@@ -2913,16 +2913,18 @@ estimate_node_size_and_time (struct cgraph_node *node,
void void
estimate_ipcp_clone_size_and_time (struct cgraph_node *node, estimate_ipcp_clone_size_and_time (struct cgraph_node *node,
VEC (tree, heap) *known_vals, VEC (tree, heap) *known_vals,
VEC (tree, heap) *known_binfos, VEC (tree, heap) *known_binfos,
int *ret_size, int *ret_time) VEC (ipa_agg_jump_function_p, heap) *known_aggs,
int *ret_size, int *ret_time,
inline_hints *hints)
{ {
clause_t clause; clause_t clause;
clause = evaluate_conditions_for_known_args (node, false, known_vals, NULL); clause = evaluate_conditions_for_known_args (node, false, known_vals,
estimate_node_size_and_time (node, clause, known_vals, known_binfos, NULL, known_aggs);
ret_size, ret_time, NULL, estimate_node_size_and_time (node, clause, known_vals, known_binfos,
NULL); known_aggs, ret_size, ret_time, hints, NULL);
} }
/* Translate all conditions from callee representation into caller /* Translate all conditions from callee representation into caller
......
...@@ -19,6 +19,8 @@ You should have received a copy of the GNU General Public License ...@@ -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 along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */ <http://www.gnu.org/licenses/>. */
#include "ipa-prop.h"
/* Representation of inline parameters that do depend on context function is /* Representation of inline parameters that do depend on context function is
inlined into (i.e. known constant values of function parameters. inlined into (i.e. known constant values of function parameters.
...@@ -207,9 +209,9 @@ void initialize_inline_failed (struct cgraph_edge *); ...@@ -207,9 +209,9 @@ void initialize_inline_failed (struct cgraph_edge *);
int estimate_time_after_inlining (struct cgraph_node *, 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 *); int estimate_size_after_inlining (struct cgraph_node *, struct cgraph_edge *);
void estimate_ipcp_clone_size_and_time (struct cgraph_node *, void estimate_ipcp_clone_size_and_time (struct cgraph_node *,
VEC (tree, heap) *known_vals, VEC (tree, heap) *, VEC (tree, heap) *,
VEC (tree, heap) *known_binfos, VEC (ipa_agg_jump_function_p, heap) *,
int *, int *); int *, int *, inline_hints *);
int do_estimate_growth (struct cgraph_node *); int do_estimate_growth (struct cgraph_node *);
void inline_merge_summary (struct cgraph_edge *edge); void inline_merge_summary (struct cgraph_edge *edge);
void inline_update_overall_summary (struct cgraph_node *node); void inline_update_overall_summary (struct cgraph_node *node);
......
...@@ -144,6 +144,7 @@ typedef struct GTY(()) ipa_agg_jf_item ...@@ -144,6 +144,7 @@ typedef struct GTY(()) ipa_agg_jf_item
DEF_VEC_O (ipa_agg_jf_item_t); 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, gc);
DEF_VEC_ALLOC_O (ipa_agg_jf_item_t, heap);
/* Aggregate jump function - i.e. description of contents of aggregates passed /* Aggregate jump function - i.e. description of contents of aggregates passed
either by reference or value. */ either by reference or value. */
...@@ -159,6 +160,9 @@ struct GTY(()) ipa_agg_jump_function ...@@ -159,6 +160,9 @@ struct GTY(()) ipa_agg_jump_function
typedef struct ipa_agg_jump_function *ipa_agg_jump_function_p; typedef struct ipa_agg_jump_function *ipa_agg_jump_function_p;
DEF_VEC_P (ipa_agg_jump_function_p); DEF_VEC_P (ipa_agg_jump_function_p);
DEF_VEC_ALLOC_P (ipa_agg_jump_function_p, heap); 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 /* A jump function for a callsite represents the values passed as actual
arguments of the callsite. See enum jump_func_type for the various arguments of the callsite. See enum jump_func_type for the various
...@@ -322,7 +326,7 @@ struct ipa_node_params ...@@ -322,7 +326,7 @@ struct ipa_node_params
VEC (ipa_param_descriptor_t, heap) *descriptors; VEC (ipa_param_descriptor_t, heap) *descriptors;
/* Pointer to an array of structures describing individual formal /* Pointer to an array of structures describing individual formal
parameters. */ parameters. */
struct ipcp_lattice *lattices; struct ipcp_param_lattices *lattices;
/* Only for versioned nodes this field would not be NULL, /* Only for versioned nodes this field would not be NULL,
it points to the node that IPA cp cloned from. */ it points to the node that IPA cp cloned from. */
struct cgraph_node *ipcp_orig_node; struct cgraph_node *ipcp_orig_node;
...@@ -380,6 +384,27 @@ ipa_is_param_used (struct ipa_node_params *info, int i) ...@@ -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; 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 /* 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. */
typedef struct GTY(()) ipa_edge_args typedef struct GTY(()) ipa_edge_args
...@@ -420,6 +445,8 @@ DEF_VEC_ALLOC_O (ipa_edge_args_t, gc); ...@@ -420,6 +445,8 @@ DEF_VEC_ALLOC_O (ipa_edge_args_t, gc);
/* Vector where the parameter infos are actually stored. */ /* Vector where the parameter infos are actually stored. */
extern VEC (ipa_node_params_t, heap) *ipa_node_params_vector; 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. */ /* Vector where the parameter infos are actually stored. */
extern GTY(()) VEC (ipa_edge_args_t, gc) *ipa_edge_args_vector; 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) ...@@ -487,6 +514,18 @@ ipa_edge_args_info_available_for_edge_p (struct cgraph_edge *edge)
ipa_edge_args_vector)); 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. */ /* Function formal parameters related computations. */
void ipa_initialize_node_params (struct cgraph_node *node); void ipa_initialize_node_params (struct cgraph_node *node);
bool ipa_propagate_indirect_call_infos (struct cgraph_edge *cs, bool ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
...@@ -517,6 +556,7 @@ void ipcp_verify_propagated_values (void); ...@@ -517,6 +556,7 @@ void ipcp_verify_propagated_values (void);
extern alloc_pool ipcp_values_pool; extern alloc_pool ipcp_values_pool;
extern alloc_pool ipcp_sources_pool; extern alloc_pool ipcp_sources_pool;
extern alloc_pool ipcp_agg_lattice_pool;
/* Structure to describe transformations of formal parameters and actual /* Structure to describe transformations of formal parameters and actual
arguments. Each instance describes one new parameter and they are meant to 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, ...@@ -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 ipa_combine_adjustments (ipa_parm_adjustment_vec,
ipa_parm_adjustment_vec); ipa_parm_adjustment_vec);
void ipa_dump_param_adjustments (FILE *, ipa_parm_adjustment_vec, tree); 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_write_jump_functions (void);
void ipa_prop_read_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); void ipa_update_after_lto_read (void);
int ipa_get_param_decl_index (struct ipa_node_params *, tree); int ipa_get_param_decl_index (struct ipa_node_params *, tree);
tree ipa_value_from_jfunc (struct ipa_node_params *info, tree ipa_value_from_jfunc (struct ipa_node_params *info,
struct ipa_jump_func *jfunc); struct ipa_jump_func *jfunc);
unsigned int ipcp_transform_function (struct cgraph_node *node);
/* From tree-sra.c: */ /* From tree-sra.c: */
......
...@@ -58,7 +58,8 @@ const char *lto_section_name[LTO_N_SECTION_TYPES] = ...@@ -58,7 +58,8 @@ const char *lto_section_name[LTO_N_SECTION_TYPES] =
"symbol_nodes", "symbol_nodes",
"opts", "opts",
"cgraphopt", "cgraphopt",
"inline" "inline",
"ipcp_trans"
}; };
......
...@@ -248,6 +248,7 @@ enum lto_section_type ...@@ -248,6 +248,7 @@ enum lto_section_type
LTO_section_opts, LTO_section_opts,
LTO_section_cgraph_opt_sum, LTO_section_cgraph_opt_sum,
LTO_section_inline_summary, LTO_section_inline_summary,
LTO_section_ipcp_transform,
LTO_N_SECTION_TYPES /* Must be last. */ LTO_N_SECTION_TYPES /* Must be last. */
}; };
......
...@@ -901,6 +901,12 @@ DEFPARAM (PARAM_IPA_MAX_AGG_ITEMS, ...@@ -901,6 +901,12 @@ DEFPARAM (PARAM_IPA_MAX_AGG_ITEMS,
"jump functions and lattices", "jump functions and lattices",
16, 0, 0) 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. */ /* WHOPR partitioning configuration. */
DEFPARAM (PARAM_LTO_PARTITIONS, 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> 2012-11-07 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/55226 PR c++/55226
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
/* Float & short constants. */ /* Float & short constants. */
#include <stdio.h> #include <stdio.h>
void t(void); int t(void);
int g (float b, short c) int g (float b, short c)
{ {
t(); t();
...@@ -13,10 +13,11 @@ int g (float b, short c) ...@@ -13,10 +13,11 @@ int g (float b, short c)
} }
int f (float a) int f (float a)
{ {
t(); int i, j = t();
/* a is modified. */ /* a is modified. */
if (a++ > 0) if (a++ > 0)
g (a, 3); for (i = 0; i < j; i++)
g (a, 3);
} }
int main () int main ()
{ {
...@@ -26,7 +27,7 @@ int main () ...@@ -26,7 +27,7 @@ int main ()
return 0; 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 c with const 3" "cp" } } */
/* { dg-final { scan-ipa-dump "replacing param a with const 7" "cp" } } */ /* { dg-final { scan-ipa-dump "replacing param a with const 7" "cp" } } */
/* { dg-final { cleanup-ipa-dump "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-do compile }
! { dg-options "-O3 -fdump-ipa-inline-details" } ! { dg-options "-O3 -fdump-ipa-inline-details -fno-ipa-cp" }
module foo module foo
implicit none 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