diff options
Diffstat (limited to 'gcc/tree-inline.c')
-rw-r--r-- | gcc/tree-inline.c | 113 |
1 files changed, 31 insertions, 82 deletions
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 597addb..040799c 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -1763,16 +1763,15 @@ remap_gimple_stmt (gimple *stmt, copy_body_data *id) later */ static basic_block -copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, +copy_bb (copy_body_data *id, basic_block bb, profile_count num, profile_count den) { gimple_stmt_iterator gsi, copy_gsi, seq_gsi; basic_block copy_basic_block; tree decl; - gcov_type freq; basic_block prev; - bool scale = num.initialized_p () - && (den > 0 || num == profile_count::zero ()); + bool scale = !num.initialized_p () + || (den.nonzero_p () || num == profile_count::zero ()); /* Search for previous copied basic block. */ prev = bb->prev_bb; @@ -1784,15 +1783,8 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, copy_basic_block = create_basic_block (NULL, (basic_block) prev->aux); if (scale) copy_basic_block->count = bb->count.apply_scale (num, den); - - /* We are going to rebuild frequencies from scratch. These values - have just small importance to drive canonicalize_loop_headers. */ - freq = apply_scale ((gcov_type)bb->frequency, frequency_scale); - - /* We recompute frequencies after inlining, so this is quite safe. */ - if (freq > BB_FREQ_MAX) - freq = BB_FREQ_MAX; - copy_basic_block->frequency = freq; + else if (num.initialized_p ()) + copy_basic_block->count = bb->count; copy_gsi = gsi_start_bb (copy_basic_block); @@ -2068,8 +2060,8 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, fprintf (dump_file, "Orig bb: %i, orig bb freq %i, new bb freq %i\n", bb->index, - bb->frequency, - copy_basic_block->frequency); + bb->count.to_frequency (cfun), + copy_basic_block->count.to_frequency (cfun)); } } } @@ -2507,11 +2499,8 @@ initialize_cfun (tree new_fndecl, tree callee_fndecl, profile_count count) profile_status_for_fn (cfun) = profile_status_for_fn (src_cfun); - /* FIXME: When all counts are known to be zero, scaling is also meaningful. - */ if (ENTRY_BLOCK_PTR_FOR_FN (src_cfun)->count.initialized_p () - && count.initialized_p () - && ENTRY_BLOCK_PTR_FOR_FN (src_cfun)->count.initialized_p ()) + && count.ipa ().initialized_p ()) { ENTRY_BLOCK_PTR_FOR_FN (cfun)->count = ENTRY_BLOCK_PTR_FOR_FN (src_cfun)->count.apply_scale (count, @@ -2520,10 +2509,13 @@ initialize_cfun (tree new_fndecl, tree callee_fndecl, profile_count count) EXIT_BLOCK_PTR_FOR_FN (src_cfun)->count.apply_scale (count, ENTRY_BLOCK_PTR_FOR_FN (src_cfun)->count); } - ENTRY_BLOCK_PTR_FOR_FN (cfun)->frequency - = ENTRY_BLOCK_PTR_FOR_FN (src_cfun)->frequency; - EXIT_BLOCK_PTR_FOR_FN (cfun)->frequency = - EXIT_BLOCK_PTR_FOR_FN (src_cfun)->frequency; + else + { + ENTRY_BLOCK_PTR_FOR_FN (cfun)->count + = ENTRY_BLOCK_PTR_FOR_FN (src_cfun)->count; + EXIT_BLOCK_PTR_FOR_FN (cfun)->count + = EXIT_BLOCK_PTR_FOR_FN (src_cfun)->count; + } if (src_cfun->eh) init_eh_for_function (); @@ -2680,27 +2672,11 @@ redirect_all_calls (copy_body_data * id, basic_block bb) } } -/* Convert estimated frequencies into counts for NODE, scaling COUNT - with each bb's frequency. Used when NODE has a 0-weight entry - but we are about to inline it into a non-zero count call bb. - See the comments for handle_missing_profiles() in predict.c for - when this can happen for COMDATs. */ - -void -freqs_to_counts (struct cgraph_node *node, profile_count count) -{ - basic_block bb; - struct function *fn = DECL_STRUCT_FUNCTION (node->decl); - - FOR_ALL_BB_FN(bb, fn) - bb->count = count.apply_scale (bb->frequency, BB_FREQ_MAX); -} - /* Make a copy of the body of FN so that it can be inserted inline in another function. Walks FN via CFG, returns new fndecl. */ static tree -copy_cfg_body (copy_body_data * id, profile_count count, int frequency_scale, +copy_cfg_body (copy_body_data * id, profile_count, basic_block entry_block_map, basic_block exit_block_map, basic_block new_entry) { @@ -2712,31 +2688,10 @@ copy_cfg_body (copy_body_data * id, profile_count count, int frequency_scale, tree new_fndecl = NULL; bool need_debug_cleanup = false; int last; - int incoming_frequency = 0; - profile_count incoming_count = profile_count::zero (); - profile_count num = count; profile_count den = ENTRY_BLOCK_PTR_FOR_FN (src_cfun)->count; - bool scale = num.initialized_p () - && (den > 0 || num == profile_count::zero ()); - - /* This can happen for COMDAT routines that end up with 0 counts - despite being called (see the comments for handle_missing_profiles() - in predict.c as to why). Apply counts to the blocks in the callee - before inlining, using the guessed edge frequencies, so that we don't - end up with a 0-count inline body which can confuse downstream - optimizations such as function splitting. */ - if (!(ENTRY_BLOCK_PTR_FOR_FN (src_cfun)->count > 0) && count > 0) - { - /* Apply the larger of the call bb count and the total incoming - call edge count to the callee. */ - profile_count in_count = profile_count::zero (); - struct cgraph_edge *in_edge; - for (in_edge = id->src_node->callers; in_edge; - in_edge = in_edge->next_caller) - if (in_edge->count.initialized_p ()) - in_count += in_edge->count; - freqs_to_counts (id->src_node, count > in_count ? count : in_count); - } + profile_count num = entry_block_map->count; + + cfun_to_copy = id->src_cfun = DECL_STRUCT_FUNCTION (callee_fndecl); /* Register specific tree functions. */ gimple_register_cfg_hooks (); @@ -2750,25 +2705,18 @@ copy_cfg_body (copy_body_data * id, profile_count count, int frequency_scale, { edge e; edge_iterator ei; + den = profile_count::zero (); FOR_EACH_EDGE (e, ei, new_entry->preds) if (!e->src->aux) - incoming_frequency += EDGE_FREQUENCY (e); - if (scale) - incoming_count = incoming_count.apply_scale (num, den); - else - incoming_count = profile_count::uninitialized (); - incoming_frequency - = apply_scale ((gcov_type)incoming_frequency, frequency_scale); - ENTRY_BLOCK_PTR_FOR_FN (cfun)->count = incoming_count; - ENTRY_BLOCK_PTR_FOR_FN (cfun)->frequency = incoming_frequency; + den += e->count (); + ENTRY_BLOCK_PTR_FOR_FN (cfun)->count = den; } /* Must have a CFG here at this point. */ gcc_assert (ENTRY_BLOCK_PTR_FOR_FN (DECL_STRUCT_FUNCTION (callee_fndecl))); - cfun_to_copy = id->src_cfun = DECL_STRUCT_FUNCTION (callee_fndecl); ENTRY_BLOCK_PTR_FOR_FN (cfun_to_copy)->aux = entry_block_map; EXIT_BLOCK_PTR_FOR_FN (cfun_to_copy)->aux = exit_block_map; @@ -2784,7 +2732,7 @@ copy_cfg_body (copy_body_data * id, profile_count count, int frequency_scale, FOR_EACH_BB_FN (bb, cfun_to_copy) if (!id->blocks_to_copy || bitmap_bit_p (id->blocks_to_copy, bb->index)) { - basic_block new_bb = copy_bb (id, bb, frequency_scale, num, den); + basic_block new_bb = copy_bb (id, bb, num, den); bb->aux = new_bb; new_bb->aux = bb; new_bb->loop_father = entry_block_map->loop_father; @@ -3011,7 +2959,7 @@ copy_tree_body (copy_body_data *id) another function. */ static tree -copy_body (copy_body_data *id, profile_count count, int frequency_scale, +copy_body (copy_body_data *id, profile_count count, basic_block entry_block_map, basic_block exit_block_map, basic_block new_entry) { @@ -3020,7 +2968,7 @@ copy_body (copy_body_data *id, profile_count count, int frequency_scale, /* If this body has a CFG, walk CFG and copy. */ gcc_assert (ENTRY_BLOCK_PTR_FOR_FN (DECL_STRUCT_FUNCTION (fndecl))); - body = copy_cfg_body (id, count, frequency_scale, entry_block_map, exit_block_map, + body = copy_cfg_body (id, count, entry_block_map, exit_block_map, new_entry); copy_debug_stmts (id); @@ -4771,7 +4719,6 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id) a self-referential call; if we're calling ourselves, we need to duplicate our body before altering anything. */ copy_body (id, cg_edge->callee->count, - GCOV_COMPUTE_SCALE (cg_edge->frequency, CGRAPH_FREQ_BASE), bb, return_block, NULL); reset_debug_bindings (id, stmt_gsi); @@ -5146,6 +5093,7 @@ optimize_inline_calls (tree fn) } /* Fold queued statements. */ + counts_to_freqs (); fold_marked_statements (last, id.statements_to_fold); delete id.statements_to_fold; @@ -6090,7 +6038,7 @@ tree_function_versioning (tree old_decl, tree new_decl, } /* Copy the Function's body. */ - copy_body (&id, old_entry_block->count, REG_BR_PROB_BASE, + copy_body (&id, old_entry_block->count, ENTRY_BLOCK_PTR_FOR_FN (cfun), EXIT_BLOCK_PTR_FOR_FN (cfun), new_entry); @@ -6122,6 +6070,7 @@ tree_function_versioning (tree old_decl, tree new_decl, free_dominance_info (CDI_DOMINATORS); free_dominance_info (CDI_POST_DOMINATORS); + counts_to_freqs (); fold_marked_statements (0, id.statements_to_fold); delete id.statements_to_fold; delete_unreachable_blocks_update_callgraph (&id); @@ -6141,20 +6090,20 @@ tree_function_versioning (tree old_decl, tree new_decl, struct cgraph_edge *e; rebuild_frequencies (); - new_version_node->count = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count; + new_version_node->count = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.ipa (); for (e = new_version_node->callees; e; e = e->next_callee) { basic_block bb = gimple_bb (e->call_stmt); e->frequency = compute_call_stmt_bb_frequency (current_function_decl, bb); - e->count = bb->count; + e->count = bb->count.ipa (); } for (e = new_version_node->indirect_calls; e; e = e->next_callee) { basic_block bb = gimple_bb (e->call_stmt); e->frequency = compute_call_stmt_bb_frequency (current_function_decl, bb); - e->count = bb->count; + e->count = bb->count.ipa (); } } |