diff options
author | Jan Hubicka <jh@suse.cz> | 2023-08-24 15:10:46 +0200 |
---|---|---|
committer | Jan Hubicka <jh@suse.cz> | 2023-08-24 15:10:46 +0200 |
commit | 0c78240fd7d519fc27ca822f66a92f85edf43f70 (patch) | |
tree | 273eeb0cf60590b12f8d1d7efbcf7e1d9c4676f3 | |
parent | 7564fe98657ad5ede34bd08f5279778fa8698865 (diff) | |
download | gcc-0c78240fd7d519fc27ca822f66a92f85edf43f70.zip gcc-0c78240fd7d519fc27ca822f66a92f85edf43f70.tar.gz gcc-0c78240fd7d519fc27ca822f66a92f85edf43f70.tar.bz2 |
Check that passes do not forget to define profile
This patch extends verifier to check that all probabilities and counts are
initialized if profile is supposed to be present. This is a bit complicated
by the posibility that we inline !flag_guess_branch_probability function
into function with profile defined and in this case we need to stop
verification. For this reason I added flag to cfg structure tracking this.
Bootstrapped/regtested x86_64-linux, comitted.
gcc/ChangeLog:
* cfg.h (struct control_flow_graph): New field full_profile.
* auto-profile.cc (afdo_annotate_cfg): Set full_profile to true.
* cfg.cc (init_flow): Set full_profile to false.
* graphite.cc (graphite_transform_loops): Set full_profile to false.
* lto-streamer-in.cc (input_cfg): Initialize full_profile flag.
* predict.cc (pass_profile::execute): Set full_profile to true.
* symtab-thunks.cc (expand_thunk): Set full_profile to true.
* tree-cfg.cc (gimple_verify_flow_info): Verify that profile is full
if full_profile is set.
* tree-inline.cc (initialize_cfun): Initialize full_profile.
(expand_call_inline): Combine full_profile.
-rw-r--r-- | gcc/auto-profile.cc | 1 | ||||
-rw-r--r-- | gcc/cfg.cc | 1 | ||||
-rw-r--r-- | gcc/cfg.h | 3 | ||||
-rw-r--r-- | gcc/graphite.cc | 2 | ||||
-rw-r--r-- | gcc/lto-streamer-in.cc | 4 | ||||
-rw-r--r-- | gcc/predict.cc | 1 | ||||
-rw-r--r-- | gcc/symtab-thunks.cc | 1 | ||||
-rw-r--r-- | gcc/tree-cfg.cc | 36 | ||||
-rw-r--r-- | gcc/tree-inline.cc | 2 |
9 files changed, 51 insertions, 0 deletions
diff --git a/gcc/auto-profile.cc b/gcc/auto-profile.cc index e3af355..ff3b763 100644 --- a/gcc/auto-profile.cc +++ b/gcc/auto-profile.cc @@ -1578,6 +1578,7 @@ afdo_annotate_cfg (const stmt_set &promoted_stmts) } update_max_bb_count (); profile_status_for_fn (cfun) = PROFILE_READ; + cfun->cfg->full_profile = true; if (flag_value_profile_transformations) { gimple_value_profile_transformations (); @@ -81,6 +81,7 @@ init_flow (struct function *the_fun) = ENTRY_BLOCK_PTR_FOR_FN (the_fun); the_fun->cfg->edge_flags_allocated = EDGE_ALL_FLAGS; the_fun->cfg->bb_flags_allocated = BB_ALL_FLAGS; + the_fun->cfg->full_profile = false; } /* Helper function for remove_edge and free_cffg. Frees edge structure @@ -78,6 +78,9 @@ struct GTY(()) control_flow_graph { /* Dynamically allocated edge/bb flags. */ int edge_flags_allocated; int bb_flags_allocated; + + /* Set if the profile is computed on every edge and basic block. */ + bool full_profile; }; diff --git a/gcc/graphite.cc b/gcc/graphite.cc index 19f8975..2b387d5 100644 --- a/gcc/graphite.cc +++ b/gcc/graphite.cc @@ -512,6 +512,8 @@ graphite_transform_loops (void) if (changed) { + /* FIXME: Graphite does not update profile meaningfully currently. */ + cfun->cfg->full_profile = false; cleanup_tree_cfg (); profile_status_for_fn (cfun) = PROFILE_ABSENT; release_recorded_exits (cfun); diff --git a/gcc/lto-streamer-in.cc b/gcc/lto-streamer-in.cc index 0cce144..d3128fc 100644 --- a/gcc/lto-streamer-in.cc +++ b/gcc/lto-streamer-in.cc @@ -1030,6 +1030,7 @@ input_cfg (class lto_input_block *ib, class data_in *data_in, basic_block p_bb; unsigned int i; int index; + bool full_profile = false; init_empty_tree_cfg_for_function (fn); @@ -1071,6 +1072,8 @@ input_cfg (class lto_input_block *ib, class data_in *data_in, data_in->location_cache.input_location_and_block (&e->goto_locus, &bp, ib, data_in); e->probability = profile_probability::stream_in (ib); + if (!e->probability.initialized_p ()) + full_profile = false; } @@ -1145,6 +1148,7 @@ input_cfg (class lto_input_block *ib, class data_in *data_in, /* Rebuild the loop tree. */ flow_loops_find (loops); + cfun->cfg->full_profile = full_profile; } diff --git a/gcc/predict.cc b/gcc/predict.cc index 5a1a561..396746c 100644 --- a/gcc/predict.cc +++ b/gcc/predict.cc @@ -4131,6 +4131,7 @@ pass_profile::execute (function *fun) scev_initialize (); tree_estimate_probability (false); + cfun->cfg->full_profile = true; if (nb_loops > 1) scev_finalize (); diff --git a/gcc/symtab-thunks.cc b/gcc/symtab-thunks.cc index 4c04235..23ead0d 100644 --- a/gcc/symtab-thunks.cc +++ b/gcc/symtab-thunks.cc @@ -648,6 +648,7 @@ expand_thunk (cgraph_node *node, bool output_asm_thunks, ? PROFILE_READ : PROFILE_GUESSED; /* FIXME: C++ FE should stop setting TREE_ASM_WRITTEN on thunks. */ TREE_ASM_WRITTEN (thunk_fndecl) = false; + cfun->cfg->full_profile = true; delete_unreachable_blocks (); update_ssa (TODO_update_ssa); checking_verify_flow_info (); diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc index 272d5ce..ffab751 100644 --- a/gcc/tree-cfg.cc +++ b/gcc/tree-cfg.cc @@ -5684,6 +5684,26 @@ gimple_verify_flow_info (void) error ("fallthru to exit from bb %d", e->src->index); err = true; } + if (cfun->cfg->full_profile + && !ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.initialized_p ()) + { + error ("entry block count not initialized"); + err = true; + } + if (cfun->cfg->full_profile + && !EXIT_BLOCK_PTR_FOR_FN (cfun)->count.initialized_p ()) + { + error ("exit block count not initialized"); + err = true; + } + if (cfun->cfg->full_profile + && !single_succ_edge + (ENTRY_BLOCK_PTR_FOR_FN (cfun))->probability.initialized_p ()) + { + error ("probability of edge from entry block not initialized"); + err = true; + } + FOR_EACH_BB_FN (bb, cfun) { @@ -5691,6 +5711,22 @@ gimple_verify_flow_info (void) stmt = NULL; + if (cfun->cfg->full_profile) + { + if (!bb->count.initialized_p ()) + { + error ("count of bb %d not initialized", bb->index); + err = true; + } + FOR_EACH_EDGE (e, ei, bb->succs) + if (!e->probability.initialized_p ()) + { + error ("probability of edge %d->%d not initialized", + bb->index, e->dest->index); + err = true; + } + } + /* Skip labels on the start of basic block. */ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) { diff --git a/gcc/tree-inline.cc b/gcc/tree-inline.cc index 954b39a..1d98d96 100644 --- a/gcc/tree-inline.cc +++ b/gcc/tree-inline.cc @@ -2815,6 +2815,7 @@ initialize_cfun (tree new_fndecl, tree callee_fndecl, profile_count count) init_empty_tree_cfg (); profile_status_for_fn (cfun) = profile_status_for_fn (src_cfun); + cfun->cfg->full_profile = src_cfun->cfg->full_profile; profile_count num = count; profile_count den = ENTRY_BLOCK_PTR_FOR_FN (src_cfun)->count; @@ -4953,6 +4954,7 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id, id->src_cfun = DECL_STRUCT_FUNCTION (fn); id->reset_location = DECL_IGNORED_P (fn); id->call_stmt = call_stmt; + cfun->cfg->full_profile &= id->src_cfun->cfg->full_profile; /* When inlining into an OpenMP SIMD-on-SIMT loop, arrange for new automatic variables to be added to IFN_GOMP_SIMT_ENTER argument list. */ |