void init_flow (struct function *the_fun) { if (!the_fun->cfg) the_fun->cfg = ggc_alloc_cleared_control_flow_graph (); n_edges_for_function (the_fun) = 0; ENTRY_BLOCK_PTR_FOR_FUNCTION (the_fun) = ggc_alloc_cleared_basic_block_def (); ENTRY_BLOCK_PTR_FOR_FUNCTION (the_fun)->index = ENTRY_BLOCK; EXIT_BLOCK_PTR_FOR_FUNCTION (the_fun) = ggc_alloc_cleared_basic_block_def (); EXIT_BLOCK_PTR_FOR_FUNCTION (the_fun)->index = EXIT_BLOCK; ENTRY_BLOCK_PTR_FOR_FUNCTION (the_fun)->next_bb = EXIT_BLOCK_PTR_FOR_FUNCTION (the_fun); EXIT_BLOCK_PTR_FOR_FUNCTION (the_fun)->prev_bb = ENTRY_BLOCK_PTR_FOR_FUNCTION (the_fun); }
/* Check the consistency of profile information. We can't do that in verify_flow_info, as the counts may get invalid for incompletely solved graphs, later eliminating of conditionals or roundoff errors. It is still practical to have them reported for debugging of simple testcases. */ static void check_bb_profile (basic_block bb, FILE * file, int indent, int flags) { edge e; int sum = 0; gcov_type lsum; edge_iterator ei; struct function *fun = DECL_STRUCT_FUNCTION (current_function_decl); char *s_indent = (char *) alloca ((size_t) indent + 1); memset ((void *) s_indent, ' ', (size_t) indent); s_indent[indent] = '\0'; if (profile_status_for_function (fun) == PROFILE_ABSENT) return; if (bb != EXIT_BLOCK_PTR_FOR_FUNCTION (fun)) { FOR_EACH_EDGE (e, ei, bb->succs) sum += e->probability; if (EDGE_COUNT (bb->succs) && abs (sum - REG_BR_PROB_BASE) > 100) fprintf (file, "%s%sInvalid sum of outgoing probabilities %.1f%%\n", (flags & TDF_COMMENT) ? ";; " : "", s_indent, sum * 100.0 / REG_BR_PROB_BASE); lsum = 0; FOR_EACH_EDGE (e, ei, bb->succs) lsum += e->count; if (EDGE_COUNT (bb->succs) && (lsum - bb->count > 100 || lsum - bb->count < -100)) fprintf (file, "%s%sInvalid sum of outgoing counts %i, should be %i\n", (flags & TDF_COMMENT) ? ";; " : "", s_indent, (int) lsum, (int) bb->count); } if (bb != ENTRY_BLOCK_PTR_FOR_FUNCTION (fun)) { sum = 0; FOR_EACH_EDGE (e, ei, bb->preds) sum += EDGE_FREQUENCY (e); if (abs (sum - bb->frequency) > 100) fprintf (file, "%s%sInvalid sum of incoming frequencies %i, should be %i\n", (flags & TDF_COMMENT) ? ";; " : "", s_indent, sum, bb->frequency); lsum = 0; FOR_EACH_EDGE (e, ei, bb->preds) lsum += e->count; if (lsum - bb->count > 100 || lsum - bb->count < -100) fprintf (file, "%s%sInvalid sum of incoming counts %i, should be %i\n", (flags & TDF_COMMENT) ? ";; " : "", s_indent, (int) lsum, (int) bb->count); } }
/* Computes the frequency of the call statement so that it can be stored in cgraph_edge. BB is the basic block of the call statement. */ int compute_call_stmt_bb_frequency (tree decl, basic_block bb) { int entry_freq = ENTRY_BLOCK_PTR_FOR_FUNCTION (DECL_STRUCT_FUNCTION (decl))->frequency; int freq = bb->frequency; if (profile_status_for_function (DECL_STRUCT_FUNCTION (decl)) == PROFILE_ABSENT) return CGRAPH_FREQ_BASE; if (!entry_freq) entry_freq = 1, freq++; freq = freq * CGRAPH_FREQ_BASE / entry_freq; if (freq > CGRAPH_FREQ_MAX) freq = CGRAPH_FREQ_MAX; return freq; }