summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-threadupdate.c
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2017-06-04 20:55:08 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2017-06-04 18:55:08 +0000
commit3995f3a2207fbde0c31341d79bf49563d681ca9a (patch)
tree51458cb1039eb15cb224e5b7de48d9e17703b737 /gcc/tree-ssa-threadupdate.c
parenta7e8f816bd09adc24013b5fd3a43128778f6581b (diff)
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/tree-ssa-threadupdate.c')
-rw-r--r--gcc/tree-ssa-threadupdate.c100
1 files changed, 48 insertions, 52 deletions
diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c
index 319826861dc..a77c279b41b 100644
--- a/gcc/tree-ssa-threadupdate.c
+++ b/gcc/tree-ssa-threadupdate.c
@@ -341,7 +341,7 @@ create_block_for_threading (basic_block bb,
/* Zero out the profile, since the block is unreachable for now. */
rd->dup_blocks[count]->frequency = 0;
- rd->dup_blocks[count]->count = 0;
+ rd->dup_blocks[count]->count = profile_count::uninitialized ();
if (duplicate_blocks)
bitmap_set_bit (*duplicate_blocks, rd->dup_blocks[count]->index);
}
@@ -694,16 +694,16 @@ any_remaining_duplicated_blocks (vec<jump_thread_edge *> *path,
static bool
compute_path_counts (struct redirection_data *rd,
ssa_local_info_t *local_info,
- gcov_type *path_in_count_ptr,
- gcov_type *path_out_count_ptr,
+ profile_count *path_in_count_ptr,
+ profile_count *path_out_count_ptr,
int *path_in_freq_ptr)
{
edge e = rd->incoming_edges->e;
vec<jump_thread_edge *> *path = THREAD_PATH (e);
edge elast = path->last ()->e;
- gcov_type nonpath_count = 0;
+ profile_count nonpath_count = profile_count::zero ();
bool has_joiner = false;
- gcov_type path_in_count = 0;
+ profile_count path_in_count = profile_count::zero ();
int path_in_freq = 0;
/* Start by accumulating incoming edge counts to the path's first bb
@@ -761,11 +761,11 @@ compute_path_counts (struct redirection_data *rd,
/* Now compute the fraction of the total count coming into the first
path bb that is from the current threading path. */
- gcov_type total_count = e->dest->count;
+ profile_count total_count = e->dest->count;
/* Handle incoming profile insanities. */
if (total_count < path_in_count)
path_in_count = total_count;
- int onpath_scale = GCOV_COMPUTE_SCALE (path_in_count, total_count);
+ int onpath_scale = path_in_count.probability_in (total_count);
/* Walk the entire path to do some more computation in order to estimate
how much of the path_in_count will flow out of the duplicated threading
@@ -786,16 +786,16 @@ compute_path_counts (struct redirection_data *rd,
nonpath_count with any additional counts coming into the path. Other
blocks along the path may have additional predecessors from outside
the path. */
- gcov_type path_out_count = path_in_count;
- gcov_type min_path_count = path_in_count;
+ profile_count path_out_count = path_in_count;
+ profile_count min_path_count = path_in_count;
for (unsigned int i = 1; i < path->length (); i++)
{
edge epath = (*path)[i]->e;
- gcov_type cur_count = epath->count;
+ profile_count cur_count = epath->count;
if ((*path)[i]->type == EDGE_COPY_SRC_JOINER_BLOCK)
{
has_joiner = true;
- cur_count = apply_probability (cur_count, onpath_scale);
+ cur_count = cur_count.apply_probability (onpath_scale);
}
/* In the joiner case we need to update nonpath_count for any edges
coming into the path that will contribute to the count flowing
@@ -857,15 +857,15 @@ compute_path_counts (struct redirection_data *rd,
will get a count/frequency of PATH_IN_COUNT and PATH_IN_FREQ,
and the duplicate edge EDUP will have a count of PATH_OUT_COUNT. */
static void
-update_profile (edge epath, edge edup, gcov_type path_in_count,
- gcov_type path_out_count, int path_in_freq)
+update_profile (edge epath, edge edup, profile_count path_in_count,
+ profile_count path_out_count, int path_in_freq)
{
/* First update the duplicated block's count / frequency. */
if (edup)
{
basic_block dup_block = edup->src;
- gcc_assert (dup_block->count == 0);
+ gcc_assert (!dup_block->count.initialized_p ());
gcc_assert (dup_block->frequency == 0);
dup_block->count = path_in_count;
dup_block->frequency = path_in_freq;
@@ -876,8 +876,6 @@ update_profile (edge epath, edge edup, gcov_type path_in_count,
into the duplicated block. Handle underflow due to precision/
rounding issues. */
epath->src->count -= path_in_count;
- if (epath->src->count < 0)
- epath->src->count = 0;
epath->src->frequency -= path_in_freq;
if (epath->src->frequency < 0)
epath->src->frequency = 0;
@@ -890,7 +888,7 @@ update_profile (edge epath, edge edup, gcov_type path_in_count,
if (edup)
edup->count = path_out_count;
epath->count -= path_out_count;
- gcc_assert (epath->count >= 0);
+ /* FIXME: can epath->count be legally uninitialized here? */
}
@@ -906,13 +904,12 @@ recompute_probabilities (basic_block bb)
edge_iterator ei;
FOR_EACH_EDGE (esucc, ei, bb->succs)
{
- if (!bb->count)
+ if (!(bb->count > 0))
continue;
/* Prevent overflow computation due to insane profiles. */
if (esucc->count < bb->count)
- esucc->probability = GCOV_COMPUTE_SCALE (esucc->count,
- bb->count);
+ esucc->probability = esucc->count.probability_in (bb->count);
else
/* Can happen with missing/guessed probabilities, since we
may determine that more is flowing along duplicated
@@ -935,8 +932,8 @@ recompute_probabilities (basic_block bb)
static void
update_joiner_offpath_counts (edge epath, basic_block dup_bb,
- gcov_type path_in_count,
- gcov_type path_out_count)
+ profile_count path_in_count,
+ profile_count path_out_count)
{
/* Compute the count that currently flows off path from the joiner.
In other words, the total count of joiner's out edges other than
@@ -945,7 +942,7 @@ update_joiner_offpath_counts (edge epath, basic_block dup_bb,
are sometimes slight insanities where the total out edge count is
larger than the bb count (possibly due to rounding/truncation
errors). */
- gcov_type total_orig_off_path_count = 0;
+ profile_count total_orig_off_path_count = profile_count::zero ();
edge enonpath;
edge_iterator ei;
FOR_EACH_EDGE (enonpath, ei, epath->src->succs)
@@ -960,7 +957,7 @@ update_joiner_offpath_counts (edge epath, basic_block dup_bb,
path's cumulative in count and the portion of that count we
estimated above as flowing from the joiner along the duplicated
path. */
- gcov_type total_dup_off_path_count = path_in_count - path_out_count;
+ profile_count total_dup_off_path_count = path_in_count - path_out_count;
/* Now do the actual updates of the off-path edges. */
FOR_EACH_EDGE (enonpath, ei, epath->src->succs)
@@ -981,17 +978,13 @@ update_joiner_offpath_counts (edge epath, basic_block dup_bb,
among the duplicated off-path edges based on their original
ratio to the full off-path count (total_orig_off_path_count).
*/
- int scale = GCOV_COMPUTE_SCALE (enonpath->count,
- total_orig_off_path_count);
+ int scale = enonpath->count.probability_in (total_orig_off_path_count);
/* Give the duplicated offpath edge a portion of the duplicated
total. */
- enonpathdup->count = apply_scale (scale,
- total_dup_off_path_count);
+ enonpathdup->count = total_dup_off_path_count.apply_probability (scale);
/* Now update the original offpath edge count, handling underflow
due to rounding errors. */
enonpath->count -= enonpathdup->count;
- if (enonpath->count < 0)
- enonpath->count = 0;
}
}
@@ -1010,7 +1003,7 @@ estimated_freqs_path (struct redirection_data *rd)
bool non_zero_freq = false;
FOR_EACH_EDGE (ein, ei, e->dest->preds)
{
- if (ein->count)
+ if (ein->count > 0)
return false;
non_zero_freq |= ein->src->frequency != 0;
}
@@ -1018,13 +1011,13 @@ estimated_freqs_path (struct redirection_data *rd)
for (unsigned int i = 1; i < path->length (); i++)
{
edge epath = (*path)[i]->e;
- if (epath->src->count)
+ if (epath->src->count > 0)
return false;
non_zero_freq |= epath->src->frequency != 0;
edge esucc;
FOR_EACH_EDGE (esucc, ei, epath->src->succs)
{
- if (esucc->count)
+ if (esucc->count > 0)
return false;
non_zero_freq |= esucc->src->frequency != 0;
}
@@ -1055,8 +1048,9 @@ freqs_to_counts_path (struct redirection_data *rd)
/* Scale up the frequency by REG_BR_PROB_BASE, to avoid rounding
errors applying the probability when the frequencies are very
small. */
- ein->count = apply_probability (ein->src->frequency * REG_BR_PROB_BASE,
- ein->probability);
+ ein->count = profile_count::from_gcov_type
+ (apply_probability (ein->src->frequency * REG_BR_PROB_BASE,
+ ein->probability));
}
for (unsigned int i = 1; i < path->length (); i++)
@@ -1066,10 +1060,12 @@ freqs_to_counts_path (struct redirection_data *rd)
/* Scale up the frequency by REG_BR_PROB_BASE, to avoid rounding
errors applying the edge probability when the frequencies are very
small. */
- epath->src->count = epath->src->frequency * REG_BR_PROB_BASE;
+ epath->src->count =
+ profile_count::from_gcov_type
+ (epath->src->frequency * REG_BR_PROB_BASE);
FOR_EACH_EDGE (esucc, ei, epath->src->succs)
- esucc->count = apply_probability (esucc->src->count,
- esucc->probability);
+ esucc->count =
+ esucc->src->count.apply_probability (esucc->probability);
}
}
@@ -1089,15 +1085,15 @@ clear_counts_path (struct redirection_data *rd)
edge ein, esucc;
edge_iterator ei;
FOR_EACH_EDGE (ein, ei, e->dest->preds)
- ein->count = 0;
+ ein->count = profile_count::uninitialized ();
/* First clear counts along original path. */
for (unsigned int i = 1; i < path->length (); i++)
{
edge epath = (*path)[i]->e;
FOR_EACH_EDGE (esucc, ei, epath->src->succs)
- esucc->count = 0;
- epath->src->count = 0;
+ esucc->count = profile_count::uninitialized ();
+ epath->src->count = profile_count::uninitialized ();
}
/* Also need to clear the counts along duplicated path. */
for (unsigned int i = 0; i < 2; i++)
@@ -1106,8 +1102,8 @@ clear_counts_path (struct redirection_data *rd)
if (!dup)
continue;
FOR_EACH_EDGE (esucc, ei, dup->succs)
- esucc->count = 0;
- dup->count = 0;
+ esucc->count = profile_count::uninitialized ();
+ dup->count = profile_count::uninitialized ();
}
}
@@ -1122,8 +1118,8 @@ ssa_fix_duplicate_block_edges (struct redirection_data *rd,
edge e = rd->incoming_edges->e;
vec<jump_thread_edge *> *path = THREAD_PATH (e);
edge elast = path->last ()->e;
- gcov_type path_in_count = 0;
- gcov_type path_out_count = 0;
+ profile_count path_in_count = profile_count::zero ();
+ profile_count path_out_count = profile_count::zero ();
int path_in_freq = 0;
/* This routine updates profile counts, frequencies, and probabilities
@@ -2217,7 +2213,7 @@ duplicate_thread_path (edge entry, edge exit,
edge exit_copy;
edge redirected;
int curr_freq;
- gcov_type curr_count;
+ profile_count curr_count;
if (!can_copy_bbs_p (region, n_region))
return false;
@@ -2268,21 +2264,21 @@ duplicate_thread_path (edge entry, edge exit,
if (curr_freq > region[i]->frequency)
curr_freq = region[i]->frequency;
/* Scale current BB. */
- if (region[i]->count)
+ if (region[i]->count > 0 && curr_count.initialized_p ())
{
/* In the middle of the path we only scale the frequencies.
In last BB we need to update probabilities of outgoing edges
because we know which one is taken at the threaded path. */
if (i + 1 != n_region)
- scale_bbs_frequencies_gcov_type (region + i, 1,
- region[i]->count - curr_count,
- region[i]->count);
+ scale_bbs_frequencies_profile_count (region + i, 1,
+ region[i]->count - curr_count,
+ region[i]->count);
else
update_bb_profile_for_threading (region[i],
curr_freq, curr_count,
exit);
- scale_bbs_frequencies_gcov_type (region_copy + i, 1, curr_count,
- region_copy[i]->count);
+ scale_bbs_frequencies_profile_count (region_copy + i, 1, curr_count,
+ region_copy[i]->count);
}
else if (region[i]->frequency)
{