diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2017-06-04 20:55:08 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2017-06-04 18:55:08 +0000 |
commit | 3995f3a2207fbde0c31341d79bf49563d681ca9a (patch) | |
tree | 51458cb1039eb15cb224e5b7de48d9e17703b737 /gcc/ipa-cp.c | |
parent | a7e8f816bd09adc24013b5fd3a43128778f6581b (diff) | |
download | gcc-3995f3a2207fbde0c31341d79bf49563d681ca9a.zip gcc-3995f3a2207fbde0c31341d79bf49563d681ca9a.tar.gz gcc-3995f3a2207fbde0c31341d79bf49563d681ca9a.tar.bz2 |
i386.c (make_resolver_func): Update.
2017-05-23 Jan Hubicka <hubicka@ucw.cz>
* config/i386/i386.c (make_resolver_func): Update.
* Makefile.in: Add profile-count.h and profile-count.o
* auto-profile.c (afdo_indirect_call): Update to new API.
(afdo_set_bb_count): Update.
(afdo_propagate_edge): Update.
(afdo_propagate_circuit): Update.
(afdo_calculate_branch_prob): Update.
(afdo_annotate_cfg): Update.
* basic-block.h: Include profile-count.h
(struct edge_def): Turn count to profile_count.
(struct basic_block_def): Likewie.
(REG_BR_PROB_BASE): Move to profile-count.h
(RDIV): Move to profile-count.h
* bb-reorder.c (max_entry_count): Turn to profile_count.
(find_traces): Update.
(rotate_loop):Update.
(connect_traces):Update.
(sanitize_hot_paths):Update.
* bt-load.c (migrate_btr_defs): Update.
* cfg.c (RDIV): Remove.
(init_flow): Use alloc_block.
(alloc_block): Uninitialize count.
(unchecked_make_edge): Uninitialize count.
(check_bb_profile): Update.
(dump_edge_info): Update.
(dump_bb_info): Update.
(update_bb_profile_for_threading): Update.
(scale_bbs_frequencies_int): Update.
(scale_bbs_frequencies_gcov_type): Update.
(scale_bbs_frequencies_profile_count): New.
* cfg.h (update_bb_profile_for_threading): Update.
(scale_bbs_frequencies_profile_count): Declare.
* cfgbuild.c (compute_outgoing_frequencies): Update.
(find_many_sub_basic_blocks): Update.
* cfgcleanup.c (try_forward_edges): Update.
(try_crossjump_to_edge): Update.
* cfgexpand.c (expand_gimple_tailcall): Update.
(construct_exit_block): Update.
* cfghooks.c (verify_flow_info): Update.
(dump_bb_for_graph): Update.
(split_edge): Update.
(make_forwarder_block): Update.
(duplicate_block): Update.
(account_profile_record): Update.
* cfgloop.c (find_subloop_latch_edge_by_profile): Update.
(get_estimated_loop_iterations): Update.
* cfgloopanal.c (expected_loop_iterations_unbounded): Update.
(single_likely_exit): Update.
* cfgloopmanip.c (scale_loop_profile): Update.
(loopify): Update.
(set_zero_probability): Update.
(lv_adjust_loop_entry_edge): Update.
* cfgrtl.c (force_nonfallthru_and_redirect): Update.
(purge_dead_edges): Update.
(rtl_account_profile_record): Update.
* cgraph.c (cgraph_node::create): Uninitialize count.
(symbol_table::create_edge): Uninitialize count.
(cgraph_update_edges_for_call_stmt_node): Update.
(cgraph_edge::dump_edge_flags): Update.
(cgraph_node::dump): Update.
(cgraph_edge::maybe_hot_p): Update.
* cgraph.h: Include profile-count.h
(create_clone), create_edge, create_indirect_edge): Update.
(cgraph_node): Turn count to profile_count.
(cgraph_edge0: Likewise.
(make_speculative, clone): Update.
(create_edge): Update.
(init_lowered_empty_function): Update.
* cgraphclones.c (cgraph_edge::clone): Update.
(duplicate_thunk_for_node): Update.
(cgraph_node::create_clone): Update.
* cgraphunit.c (cgraph_node::analyze): Update.
(cgraph_node::expand_thunk): Update.
* final.c (dump_basic_block_info): Update.
* gimple-streamer-in.c (input_bb): Update.
* gimple-streamer-out.c (output_bb): Update.
* graphite.c (print_global_statistics): Update.
(print_graphite_scop_statistics): Update.
* hsa-brig.c: Include basic-block.h.
* hsa-dump.c: Include basic-block.h.
* hsa-gen.c (T sum_slice): Update.
(convert_switch_statements):Update.
* hsa-regalloc.c: Include basic-block.h.
* ipa-chkp.c (chkp_produce_thunks): Update.
* ipa-cp.c (struct caller_statistics): Update.
(init_caller_stats): Update.
(gather_caller_stats): Update.
(ipcp_cloning_candidate_p): Update.
(good_cloning_opportunity_p): Update.
(get_info_about_necessary_edges): Update.
(dump_profile_updates): Update.
(update_profiling_info): Update.
(update_specialized_profile): Update.
(perhaps_add_new_callers): Update.
(decide_about_value): Update.
(ipa_cp_c_finalize): Update.
* ipa-devirt.c (struct odr_type_warn_count): Update.
(struct decl_warn_count): Update.
(struct final_warning_record): Update.
(possible_polymorphic_call_targets): Update.
(ipa_devirt): Update.
* ipa-fnsummary.c (redirect_to_unreachable): Update.
* ipa-icf.c (sem_function::merge): Update.
* ipa-inline-analysis.c (do_estimate_edge_time): Update.
* ipa-inline.c (compute_uninlined_call_time): Update.
(compute_inlined_call_time): Update.
(want_inline_small_function_p): Update.
(want_inline_self_recursive_call_p): Update.
(edge_badness): Update.
(lookup_recursive_calls): Update.
(recursive_inlining): Update.
(inline_small_functions): Update.
(dump_overall_stats): Update.
(dump_inline_stats): Update.
* ipa-profile.c (ipa_profile_generate_summary): Update.
(ipa_propagate_frequency): Update.
(ipa_profile): Update.
* ipa-prop.c (ipa_make_edge_direct_to_target): Update.
* ipa-utils.c (ipa_merge_profiles): Update.
* loop-doloop.c (doloop_modify): Update.
* loop-unroll.c (report_unroll): Update.
(unroll_loop_runtime_iterations): Update.
* lto-cgraph.c (lto_output_edge): Update.
(lto_output_node): Update.
(input_node): Update.
(input_edge): Update.
(merge_profile_summaries): Update.
* lto-streamer-in.c (input_cfg): Update.
* lto-streamer-out.c (output_cfg): Update.
* mcf.c (create_fixup_graph): Update.
(adjust_cfg_counts): Update.
(sum_edge_counts): Update.
* modulo-sched.c (sms_schedule): Update.
* postreload-gcse.c (eliminate_partially_redundant_load): Update.
* predict.c (maybe_hot_count_p): Update.
(probably_never_executed): Update.
(dump_prediction): Update.
(combine_predictions_for_bb): Update.
(propagate_freq): Update.
(handle_missing_profiles): Update.
(counts_to_freqs): Update.
(rebuild_frequencies): Update.
(force_edge_cold): Update.
* predict.h: Include profile-count.h
(maybe_hot_count_p, counts_to_freqs): UPdate.
* print-rtl-function.c: Do not include cfg.h
* print-rtl.c: Include basic-block.h
* profile-count.c: New file.
* profile-count.h: New file.
* profile.c (is_edge_inconsistent): Update.
(correct_negative_edge_counts): Update.
(is_inconsistent): Update.
(set_bb_counts): Update.
(read_profile_edge_counts): Update.
(compute_frequency_overlap): Update.
(compute_branch_probabilities): Update; Initialize and deinitialize
gcov_count tables.
(branch_prob): Update.
* profile.h (bb_gcov_counts, edge_gcov_counts): New.
(edge_gcov_count): New.
(bb_gcov_count): New.
* shrink-wrap.c (try_shrink_wrapping): Update.
* tracer.c (better_p): Update.
* trans-mem.c (expand_transaction): Update.
(ipa_tm_insert_irr_call): Update.
(ipa_tm_insert_gettmclone_call): Update.
* tree-call-cdce.c: Update.
* tree-cfg.c (gimple_duplicate_sese_region): Update.
(gimple_duplicate_sese_tail): Update.
(gimple_account_profile_record): Update.
(execute_fixup_cfg): Update.
* tree-inline.c (copy_bb): Update.
(copy_edges_for_bb): Update.
(initialize_cfun): Update.
(freqs_to_counts): Update.
(copy_cfg_body): Update.
(expand_call_inline): Update.
* tree-ssa-ifcombine.c (update_profile_after_ifcombine): Update.
* tree-ssa-loop-ivcanon.c (unloop_loops): Update.
(try_unroll_loop_completely): Update.
(try_peel_loop): Update.
* tree-ssa-loop-manip.c (tree_transform_and_unroll_loop): Update.
* tree-ssa-loop-niter.c (estimate_numbers_of_iterations_loop): Update.
* tree-ssa-loop-split.c (connect_loops): Update.
* tree-ssa-loop-unswitch.c (hoist_guard): Update.
* tree-ssa-reassoc.c (branch_fixup): Update.
* tree-ssa-tail-merge.c (replace_block_by): Update.
* tree-ssa-threadupdate.c (create_block_for_threading): Update.
(compute_path_counts): Update.
(update_profile): Update.
(recompute_probabilities): Update.
(update_joiner_offpath_counts): Update.
(estimated_freqs_path): Update.
(freqs_to_counts_path): Update.
(clear_counts_path): Update.
(ssa_fix_duplicate_block_edges): Update.
(duplicate_thread_path): Update.
* tree-switch-conversion.c (case_bit_test_cmp): Update.
(struct switch_conv_info): Update.
* tree-tailcall.c (decrease_profile): Update.
* tree-vect-loop-manip.c (slpeel_add_loop_guard): Update.
* tree-vect-loop.c (scale_profile_for_vect_loop): Update.
* value-prof.c (check_counter): Update.
(gimple_divmod_fixed_value): Update.
(gimple_mod_pow2): Update.
(gimple_mod_subtract): Update.
(gimple_ic_transform): Update.
(gimple_stringop_fixed_value): Update.
* value-prof.h (gimple_ic): Update.
* gcc.dg/tree-ssa/attr-hotcold-2.c: Update template.
From-SVN: r248863
Diffstat (limited to 'gcc/ipa-cp.c')
-rw-r--r-- | gcc/ipa-cp.c | 148 |
1 files changed, 80 insertions, 68 deletions
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index f5e023e74..3c9c3f2 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -360,7 +360,7 @@ object_allocator<ipcp_agg_lattice> ipcp_agg_lattice_pool /* Maximal count found in program. */ -static gcov_type max_count; +static profile_count max_count; /* Original overall size of the program. */ @@ -640,7 +640,7 @@ ipcp_versionable_function_p (struct cgraph_node *node) struct caller_statistics { - gcov_type count_sum; + profile_count count_sum; int n_calls, n_hot_calls, freq_sum; }; @@ -649,7 +649,7 @@ struct caller_statistics static inline void init_caller_stats (struct caller_statistics *stats) { - stats->count_sum = 0; + stats->count_sum = profile_count::zero (); stats->n_calls = 0; stats->n_hot_calls = 0; stats->freq_sum = 0; @@ -667,7 +667,8 @@ gather_caller_stats (struct cgraph_node *node, void *data) for (cs = node->callers; cs; cs = cs->next_caller) if (!cs->caller->thunk.thunk_p) { - stats->count_sum += cs->count; + if (cs->count.initialized_p ()) + stats->count_sum += cs->count; stats->freq_sum += cs->frequency; stats->n_calls++; if (cs->maybe_hot_p ()) @@ -718,9 +719,9 @@ ipcp_cloning_candidate_p (struct cgraph_node *node) /* When profile is available and function is hot, propagate into it even if calls seems cold; constant propagation can improve function's speed significantly. */ - if (max_count) + if (max_count > profile_count::zero ()) { - if (stats.count_sum > node->count * 90 / 100) + if (stats.count_sum > node->count.apply_scale (90, 100)) { if (dump_file) fprintf (dump_file, "Considering %s for cloning; " @@ -2611,7 +2612,7 @@ incorporate_penalties (ipa_node_params *info, int64_t evaluation) static bool good_cloning_opportunity_p (struct cgraph_node *node, int time_benefit, - int freq_sum, gcov_type count_sum, int size_cost) + int freq_sum, profile_count count_sum, int size_cost) { if (time_benefit == 0 || !opt_for_fn (node->decl, flag_ipa_cp_clone) @@ -2621,22 +2622,25 @@ good_cloning_opportunity_p (struct cgraph_node *node, int time_benefit, gcc_assert (size_cost > 0); struct ipa_node_params *info = IPA_NODE_REF (node); - if (max_count) + if (max_count > profile_count::zero ()) { - int factor = (count_sum * 1000) / max_count; + int factor = RDIV (count_sum.probability_in (max_count) + * 1000, REG_BR_PROB_BASE); int64_t evaluation = (((int64_t) time_benefit * factor) / size_cost); evaluation = incorporate_penalties (info, evaluation); if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, " good_cloning_opportunity_p (time: %i, " - "size: %i, count_sum: " HOST_WIDE_INT_PRINT_DEC - "%s%s) -> evaluation: " "%" PRId64 + { + fprintf (dump_file, " good_cloning_opportunity_p (time: %i, " + "size: %i, count_sum: ", time_benefit, size_cost); + count_sum.dump (dump_file); + fprintf (dump_file, "%s%s) -> evaluation: " "%" PRId64 ", threshold: %i\n", - time_benefit, size_cost, (HOST_WIDE_INT) count_sum, info->node_within_scc ? ", scc" : "", info->node_calling_single_call ? ", single_call" : "", evaluation, PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD)); + } return evaluation >= PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD); } @@ -3520,11 +3524,11 @@ template <typename valtype> static bool get_info_about_necessary_edges (ipcp_value<valtype> *val, cgraph_node *dest, int *freq_sum, - gcov_type *count_sum, int *caller_count) + profile_count *count_sum, int *caller_count) { ipcp_value_source<valtype> *src; int freq = 0, count = 0; - gcov_type cnt = 0; + profile_count cnt = profile_count::zero (); bool hot = false; for (src = val->sources; src; src = src->next) @@ -3536,7 +3540,8 @@ get_info_about_necessary_edges (ipcp_value<valtype> *val, cgraph_node *dest, { count++; freq += cs->frequency; - cnt += cs->count; + if (cs->count.initialized_p ()) + cnt += cs->count; hot |= cs->maybe_hot_p (); } cs = get_next_cgraph_edge_clone (cs); @@ -3611,19 +3616,27 @@ dump_profile_updates (struct cgraph_node *orig_node, { struct cgraph_edge *cs; - fprintf (dump_file, " setting count of the specialized node to " - HOST_WIDE_INT_PRINT_DEC "\n", (HOST_WIDE_INT) new_node->count); + fprintf (dump_file, " setting count of the specialized node to "); + new_node->count.dump (dump_file); + fprintf (dump_file, "\n"); for (cs = new_node->callees; cs; cs = cs->next_callee) - fprintf (dump_file, " edge to %s has count " - HOST_WIDE_INT_PRINT_DEC "\n", - cs->callee->name (), (HOST_WIDE_INT) cs->count); + { + fprintf (dump_file, " edge to %s has count ", + cs->callee->name ()); + cs->count.dump (dump_file); + fprintf (dump_file, "\n"); + } - fprintf (dump_file, " setting count of the original node to " - HOST_WIDE_INT_PRINT_DEC "\n", (HOST_WIDE_INT) orig_node->count); + fprintf (dump_file, " setting count of the original node to "); + orig_node->count.dump (dump_file); + fprintf (dump_file, "\n"); for (cs = orig_node->callees; cs; cs = cs->next_callee) - fprintf (dump_file, " edge to %s is left with " - HOST_WIDE_INT_PRINT_DEC "\n", - cs->callee->name (), (HOST_WIDE_INT) cs->count); + { + fprintf (dump_file, " edge to %s is left with ", + cs->callee->name ()); + cs->count.dump (dump_file); + fprintf (dump_file, "\n"); + } } /* After a specialized NEW_NODE version of ORIG_NODE has been created, update @@ -3635,10 +3648,10 @@ update_profiling_info (struct cgraph_node *orig_node, { struct cgraph_edge *cs; struct caller_statistics stats; - gcov_type new_sum, orig_sum; - gcov_type remainder, orig_node_count = orig_node->count; + profile_count new_sum, orig_sum; + profile_count remainder, orig_node_count = orig_node->count; - if (orig_node_count == 0) + if (!(orig_node_count > profile_count::zero ())) return; init_caller_stats (&stats); @@ -3653,18 +3666,22 @@ update_profiling_info (struct cgraph_node *orig_node, if (orig_node_count < orig_sum + new_sum) { if (dump_file) - fprintf (dump_file, " Problem: node %s has too low count " - HOST_WIDE_INT_PRINT_DEC " while the sum of incoming " - "counts is " HOST_WIDE_INT_PRINT_DEC "\n", - orig_node->dump_name (), - (HOST_WIDE_INT) orig_node_count, - (HOST_WIDE_INT) (orig_sum + new_sum)); - - orig_node_count = (orig_sum + new_sum) * 12 / 10; + { + fprintf (dump_file, " Problem: node %s has too low count ", + orig_node->dump_name ()); + orig_node_count.dump (dump_file); + fprintf (dump_file, "while the sum of incoming count is "); + (orig_sum + new_sum).dump (dump_file); + fprintf (dump_file, "\n"); + } + + orig_node_count = (orig_sum + new_sum).apply_scale (12, 10); if (dump_file) - fprintf (dump_file, " proceeding by pretending it was " - HOST_WIDE_INT_PRINT_DEC "\n", - (HOST_WIDE_INT) orig_node_count); + { + fprintf (dump_file, " proceeding by pretending it was "); + orig_node_count.dump (dump_file); + fprintf (dump_file, "\n"); + } } new_node->count = new_sum; @@ -3672,17 +3689,14 @@ update_profiling_info (struct cgraph_node *orig_node, orig_node->count = remainder; for (cs = new_node->callees; cs; cs = cs->next_callee) + /* FIXME: why we care about non-zero frequency here? */ if (cs->frequency) - cs->count = apply_probability (cs->count, - GCOV_COMPUTE_SCALE (new_sum, - orig_node_count)); + cs->count = cs->count.apply_scale (new_sum, orig_node_count); else - cs->count = 0; + cs->count = profile_count::zero (); for (cs = orig_node->callees; cs; cs = cs->next_callee) - cs->count = apply_probability (cs->count, - GCOV_COMPUTE_SCALE (remainder, - orig_node_count)); + cs->count = cs->count.apply_scale (remainder, orig_node_count); if (dump_file) dump_profile_updates (orig_node, new_node); @@ -3695,15 +3709,18 @@ update_profiling_info (struct cgraph_node *orig_node, static void update_specialized_profile (struct cgraph_node *new_node, struct cgraph_node *orig_node, - gcov_type redirected_sum) + profile_count redirected_sum) { struct cgraph_edge *cs; - gcov_type new_node_count, orig_node_count = orig_node->count; + profile_count new_node_count, orig_node_count = orig_node->count; if (dump_file) - fprintf (dump_file, " the sum of counts of redirected edges is " - HOST_WIDE_INT_PRINT_DEC "\n", (HOST_WIDE_INT) redirected_sum); - if (orig_node_count == 0) + { + fprintf (dump_file, " the sum of counts of redirected edges is "); + redirected_sum.dump (dump_file); + fprintf (dump_file, "\n"); + } + if (!(orig_node_count > profile_count::zero ())) return; gcc_assert (orig_node_count >= redirected_sum); @@ -3714,21 +3731,15 @@ update_specialized_profile (struct cgraph_node *new_node, for (cs = new_node->callees; cs; cs = cs->next_callee) if (cs->frequency) - cs->count += apply_probability (cs->count, - GCOV_COMPUTE_SCALE (redirected_sum, - new_node_count)); + cs->count += cs->count.apply_scale (redirected_sum, new_node_count); else - cs->count = 0; + cs->count = profile_count::zero (); for (cs = orig_node->callees; cs; cs = cs->next_callee) { - gcov_type dec = apply_probability (cs->count, - GCOV_COMPUTE_SCALE (redirected_sum, - orig_node_count)); - if (dec < cs->count) - cs->count -= dec; - else - cs->count = 0; + profile_count dec = cs->count.apply_scale (redirected_sum, + orig_node_count); + cs->count -= dec; } if (dump_file) @@ -4423,7 +4434,7 @@ static void perhaps_add_new_callers (cgraph_node *node, ipcp_value<valtype> *val) { ipcp_value_source<valtype> *src; - gcov_type redirected_sum = 0; + profile_count redirected_sum = profile_count::zero (); for (src = val->sources; src; src = src->next) { @@ -4441,13 +4452,14 @@ perhaps_add_new_callers (cgraph_node *node, ipcp_value<valtype> *val) cs->redirect_callee_duplicating_thunks (val->spec_node); val->spec_node->expand_all_artificial_thunks (); - redirected_sum += cs->count; + if (cs->count.initialized_p ()) + redirected_sum = redirected_sum + cs->count; } cs = get_next_cgraph_edge_clone (cs); } } - if (redirected_sum) + if (redirected_sum > profile_count::zero ()) update_specialized_profile (val->spec_node, node, redirected_sum); } @@ -4550,7 +4562,7 @@ decide_about_value (struct cgraph_node *node, int index, HOST_WIDE_INT offset, { struct ipa_agg_replacement_value *aggvals; int freq_sum, caller_count; - gcov_type count_sum; + profile_count count_sum; vec<cgraph_edge *> callers; if (val->spec_node) @@ -5103,7 +5115,7 @@ make_pass_ipa_cp (gcc::context *ctxt) void ipa_cp_c_finalize (void) { - max_count = 0; + max_count = profile_count::zero (); overall_size = 0; max_new_size = 0; } |