diff options
Diffstat (limited to 'gcc/cfgrtl.c')
-rw-r--r-- | gcc/cfgrtl.c | 162 |
1 files changed, 89 insertions, 73 deletions
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index 623d04f4499..6ef47b7e61f 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -1155,7 +1155,7 @@ try_redirect_by_replacing_jump (edge e, basic_block target, bool in_cfglayout) else e->flags = 0; - e->probability = REG_BR_PROB_BASE; + e->probability = profile_probability::always (); e->count = src->count; if (e->dest != target) @@ -1504,12 +1504,10 @@ force_nonfallthru_and_redirect (edge e, basic_block target, rtx jump_label) { int prob = XINT (note, 0); - b->probability = prob; - b->count = e->count.apply_probability (prob); + b->probability = profile_probability::from_reg_br_prob_note (prob); + b->count = e->count.apply_probability (b->probability); e->probability -= e->probability; e->count -= b->count; - if (e->probability < 0) - e->probability = 0; } } @@ -1618,7 +1616,7 @@ force_nonfallthru_and_redirect (edge e, basic_block target, rtx jump_label) { rtx_insn *new_head; profile_count count = e->count; - int probability = e->probability; + profile_probability probability = e->probability; /* Create the new structures. */ /* If the old block ended with a tablejump, skip its table @@ -1646,7 +1644,7 @@ force_nonfallthru_and_redirect (edge e, basic_block target, rtx jump_label) /* Redirect old edge. */ redirect_edge_pred (e, jump_block); - e->probability = REG_BR_PROB_BASE; + e->probability = profile_probability::always (); /* If e->src was previously region crossing, it no longer is and the reg crossing note should be removed. */ @@ -1656,7 +1654,7 @@ force_nonfallthru_and_redirect (edge e, basic_block target, rtx jump_label) add also edge from asm goto bb to target. */ if (asm_goto_edge) { - new_edge->probability /= 2; + new_edge->probability = new_edge->probability.apply_scale (1, 2); new_edge->count = new_edge->count.apply_scale (1, 2); jump_block->count = jump_block->count.apply_scale (1, 2); jump_block->frequency /= 2; @@ -2111,8 +2109,6 @@ commit_edge_insertions (void) static void rtl_dump_bb (FILE *outf, basic_block bb, int indent, dump_flags_t flags) { - rtx_insn *insn; - rtx_insn *last; char *s_indent; s_indent = (char *) alloca ((size_t) indent + 1); @@ -2126,18 +2122,22 @@ rtl_dump_bb (FILE *outf, basic_block bb, int indent, dump_flags_t flags) } if (bb->index != ENTRY_BLOCK && bb->index != EXIT_BLOCK) - for (insn = BB_HEAD (bb), last = NEXT_INSN (BB_END (bb)); insn != last; - insn = NEXT_INSN (insn)) - { - if (flags & TDF_DETAILS) - df_dump_insn_top (insn, outf); - if (! (flags & TDF_SLIM)) - print_rtl_single (outf, insn); - else - dump_insn_slim (outf, insn); - if (flags & TDF_DETAILS) - df_dump_insn_bottom (insn, outf); - } + { + rtx_insn *last = BB_END (bb); + if (last) + last = NEXT_INSN (last); + for (rtx_insn *insn = BB_HEAD (bb); insn != last; insn = NEXT_INSN (insn)) + { + if (flags & TDF_DETAILS) + df_dump_insn_top (insn, outf); + if (! (flags & TDF_SLIM)) + print_rtl_single (outf, insn); + else + dump_insn_slim (outf, insn); + if (flags & TDF_DETAILS) + df_dump_insn_bottom (insn, outf); + } + } if (df && (flags & TDF_DETAILS)) { @@ -2251,12 +2251,13 @@ void update_br_prob_note (basic_block bb) { rtx note; - if (!JUMP_P (BB_END (bb))) + if (!JUMP_P (BB_END (bb)) || !BRANCH_EDGE (bb)->probability.initialized_p ()) return; note = find_reg_note (BB_END (bb), REG_BR_PROB, NULL_RTX); - if (!note || XINT (note, 0) == BRANCH_EDGE (bb)->probability) + if (!note + || XINT (note, 0) == BRANCH_EDGE (bb)->probability.to_reg_br_prob_note ()) return; - XINT (note, 0) = BRANCH_EDGE (bb)->probability; + XINT (note, 0) = BRANCH_EDGE (bb)->probability.to_reg_br_prob_note (); } /* Get the last insn associated with block BB (that includes barriers and @@ -2283,6 +2284,29 @@ get_last_bb_insn (basic_block bb) return end; } +/* Add all BBs reachable from entry via hot paths into the SET. */ + +void +find_bbs_reachable_by_hot_paths (hash_set<basic_block> *set) +{ + auto_vec<basic_block, 64> worklist; + + set->add (ENTRY_BLOCK_PTR_FOR_FN (cfun)); + worklist.safe_push (ENTRY_BLOCK_PTR_FOR_FN (cfun)); + + while (worklist.length () > 0) + { + basic_block bb = worklist.pop (); + edge_iterator ei; + edge e; + + FOR_EACH_EDGE (e, ei, bb->succs) + if (BB_PARTITION (e->dest) != BB_COLD_PARTITION + && !set->add (e->dest)) + worklist.safe_push (e->dest); + } +} + /* Sanity check partition hotness to ensure that basic blocks in the cold partition don't dominate basic blocks in the hot partition. If FLAG_ONLY is true, report violations as errors. Otherwise @@ -2296,49 +2320,25 @@ find_partition_fixes (bool flag_only) basic_block bb; vec<basic_block> bbs_in_cold_partition = vNULL; vec<basic_block> bbs_to_fix = vNULL; + hash_set<basic_block> set; /* Callers check this. */ gcc_checking_assert (crtl->has_bb_partition); - FOR_EACH_BB_FN (bb, cfun) - if ((BB_PARTITION (bb) == BB_COLD_PARTITION)) - bbs_in_cold_partition.safe_push (bb); - - if (bbs_in_cold_partition.is_empty ()) - return vNULL; - - bool dom_calculated_here = !dom_info_available_p (CDI_DOMINATORS); - - if (dom_calculated_here) - calculate_dominance_info (CDI_DOMINATORS); - - while (! bbs_in_cold_partition.is_empty ()) - { - bb = bbs_in_cold_partition.pop (); - /* Any blocks dominated by a block in the cold section - must also be cold. */ - basic_block son; - for (son = first_dom_son (CDI_DOMINATORS, bb); - son; - son = next_dom_son (CDI_DOMINATORS, son)) - { - /* If son is not yet cold, then mark it cold here and - enqueue it for further processing. */ - if ((BB_PARTITION (son) != BB_COLD_PARTITION)) - { - if (flag_only) - error ("non-cold basic block %d dominated " - "by a block in the cold partition (%d)", son->index, bb->index); - else - BB_SET_PARTITION (son, BB_COLD_PARTITION); - bbs_to_fix.safe_push (son); - bbs_in_cold_partition.safe_push (son); - } - } - } + find_bbs_reachable_by_hot_paths (&set); - if (dom_calculated_here) - free_dominance_info (CDI_DOMINATORS); + FOR_EACH_BB_FN (bb, cfun) + if (!set.contains (bb) + && BB_PARTITION (bb) != BB_COLD_PARTITION) + { + if (flag_only) + error ("non-cold basic block %d reachable only " + "by paths crossing the cold partition", bb->index); + else + BB_SET_PARTITION (bb, BB_COLD_PARTITION); + bbs_to_fix.safe_push (bb); + bbs_in_cold_partition.safe_push (bb); + } return bbs_to_fix; } @@ -2447,11 +2447,22 @@ rtl_verify_edges (void) && EDGE_COUNT (bb->succs) >= 2 && any_condjump_p (BB_END (bb))) { - if (XINT (note, 0) != BRANCH_EDGE (bb)->probability - && profile_status_for_fn (cfun) != PROFILE_ABSENT) + if (!BRANCH_EDGE (bb)->probability.initialized_p ()) + { + if (profile_status_for_fn (cfun) != PROFILE_ABSENT) + { + error ("verify_flow_info: " + "REG_BR_PROB is set but cfg probability is not"); + err = 1; + } + } + else if (XINT (note, 0) + != BRANCH_EDGE (bb)->probability.to_reg_br_prob_note () + && profile_status_for_fn (cfun) != PROFILE_ABSENT) { error ("verify_flow_info: REG_BR_PROB does not match cfg %i %i", - XINT (note, 0), BRANCH_EDGE (bb)->probability); + XINT (note, 0), + BRANCH_EDGE (bb)->probability.to_reg_br_prob_note ()); err = 1; } } @@ -3143,7 +3154,7 @@ purge_dead_edges (basic_block bb) /* Redistribute probabilities. */ if (single_succ_p (bb)) { - single_succ_edge (bb)->probability = REG_BR_PROB_BASE; + single_succ_edge (bb)->probability = profile_probability::always (); single_succ_edge (bb)->count = bb->count; } else @@ -3154,8 +3165,9 @@ purge_dead_edges (basic_block bb) b = BRANCH_EDGE (bb); f = FALLTHRU_EDGE (bb); - b->probability = XINT (note, 0); - f->probability = REG_BR_PROB_BASE - b->probability; + b->probability = profile_probability::from_reg_br_prob_note + (XINT (note, 0)); + f->probability = b->probability.invert (); b->count = bb->count.apply_probability (b->probability); f->count = bb->count.apply_probability (f->probability); } @@ -3208,7 +3220,7 @@ purge_dead_edges (basic_block bb) gcc_assert (single_succ_p (bb)); - single_succ_edge (bb)->probability = REG_BR_PROB_BASE; + single_succ_edge (bb)->probability = profile_probability::always (); single_succ_edge (bb)->count = bb->count; if (dump_file) @@ -3781,7 +3793,8 @@ fixup_reorder_chain (void) rtx note = find_reg_note (bb_end_jump, REG_BR_PROB, 0); if (note - && XINT (note, 0) < REG_BR_PROB_BASE / 2 + && profile_probability::from_reg_br_prob_note + (XINT (note, 0)) < profile_probability::even () && invert_jump (bb_end_jump, (e_fall->dest == EXIT_BLOCK_PTR_FOR_FN (cfun) @@ -4891,7 +4904,9 @@ rtl_flow_call_edges_add (sbitmap blocks) blocks_split++; } - make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), EDGE_FAKE); + edge ne = make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), EDGE_FAKE); + ne->probability = profile_probability::guessed_never (); + ne->count = profile_count::guessed_zero (); } if (insn == BB_HEAD (bb)) @@ -4931,7 +4946,8 @@ rtl_lv_add_condition_to_bb (basic_block first_head , start_sequence (); op0 = force_operand (op0, NULL_RTX); op1 = force_operand (op1, NULL_RTX); - do_compare_rtx_and_jump (op0, op1, comp, 0, mode, NULL_RTX, NULL, label, -1); + do_compare_rtx_and_jump (op0, op1, comp, 0, mode, NULL_RTX, NULL, label, + profile_probability::uninitialized ()); jump = get_last_insn (); JUMP_LABEL (jump) = label; LABEL_NUSES (label)++; |