PR tree-optimization/88763 reports difficulties in getting useful information from the log of tree-ssa-loop-unswitch.c.
As work towards improving this, this patch eliminates all uses of dump_file from that source file, in favor of the dump API (to support -fopt-info* and -fsave-optimization-record). Doing so required adding a way to dump profile_probability instances, so the patch adds a profile_probability::dump overload for this. Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu. OK for next stage 1? gcc/ChangeLog: PR tree-optimization/88763 * cfgloop.h (find_loop_location): Move decl to here. * profile-count.c (profile_probability::dump): Reimplement in terms of... (profile_probability::print): ...this new function, moving the body here, and porting from FILE * to pretty_printer *. (profile_probability::dump): New function. * profile-count.h (class dump_metadata_t): New forward decl. (profile_probability::print): New decl. (profile_probability::dump): New overloaded decl. * tree-ssa-loop-unswitch.c (tree_unswitch_single_loop): Port from fprintf to the dump_* API. (tree_unswitch_outer_loop): Likewise. (find_loop_guard): Likewise. (hoist_guard): Likewise. * tree-vectorizer.h (find_loop_location): Move from here to cfgloop.h. --- gcc/cfgloop.h | 3 + gcc/profile-count.c | 34 ++++++++--- gcc/profile-count.h | 7 +++ gcc/tree-ssa-loop-unswitch.c | 135 ++++++++++++++++++++++++++----------------- gcc/tree-vectorizer.h | 1 - 5 files changed, 120 insertions(+), 60 deletions(-) diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h index 2e93af3..c175dcb 100644 --- a/gcc/cfgloop.h +++ b/gcc/cfgloop.h @@ -870,4 +870,7 @@ gcov_type_to_wide_int (gcov_type val) return widest_int::from_array (a, 2); } + +extern dump_user_location_t find_loop_location (struct loop *); + #endif /* GCC_CFGLOOP_H */ diff --git a/gcc/profile-count.c b/gcc/profile-count.c index 8c58f86..eaad18d 100644 --- a/gcc/profile-count.c +++ b/gcc/profile-count.c @@ -148,27 +148,47 @@ profile_count::stream_out (struct lto_output_stream *ob) void profile_probability::dump (FILE *f) const { + pretty_printer pp; + print (&pp); + fprintf (f, "%s", pp_formatted_text (&pp)); +} + +/* Print THIS to the PP. */ + +void +profile_probability::print (pretty_printer *pp) const +{ if (!initialized_p ()) - fprintf (f, "uninitialized"); + pp_string (pp, "uninitialized"); else { /* Make difference between 0.00 as a roundoff error and actual 0. Similarly for 1. */ if (m_val == 0) - fprintf (f, "never"); + pp_string (pp, "never"); else if (m_val == max_probability) - fprintf (f, "always"); + pp_string (pp, "always"); else - fprintf (f, "%3.1f%%", (double)m_val * 100 / max_probability); + pp_scalar (pp, "%3.1f%%", (double)m_val * 100 / max_probability); if (m_quality == profile_adjusted) - fprintf (f, " (adjusted)"); + pp_string (pp, " (adjusted)"); else if (m_quality == profile_afdo) - fprintf (f, " (auto FDO)"); + pp_string (pp, " (auto FDO)"); else if (m_quality == profile_guessed) - fprintf (f, " (guessed)"); + pp_string (pp, " (guessed)"); } } +/* Dump THIS to the active dump destinations. */ + +void +profile_probability::dump (const dump_metadata_t &metadata) const +{ + pretty_printer pp; + print (&pp); + dump_printf (metadata, "%s", pp_formatted_text (&pp)); +} + /* Dump THIS to stderr. */ void diff --git a/gcc/profile-count.h b/gcc/profile-count.h index 96b7400..a761836 100644 --- a/gcc/profile-count.h +++ b/gcc/profile-count.h @@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see struct function; class profile_count; +class dump_metadata_t; /* Quality of the profile count. Because gengtype does not support enums inside of classes, this is in global namespace. */ @@ -561,6 +562,12 @@ public: /* Output THIS to F. */ void dump (FILE *f) const; + /* Output THIS to the active dump destinations. */ + void dump (const dump_metadata_t &) const; + + /* Write THIS to PP. */ + void print (pretty_printer *pp) const; + /* Print THIS to stderr. */ void debug () const; diff --git a/gcc/tree-ssa-loop-unswitch.c b/gcc/tree-ssa-loop-unswitch.c index 30a2a9d..3fdbc57 100644 --- a/gcc/tree-ssa-loop-unswitch.c +++ b/gcc/tree-ssa-loop-unswitch.c @@ -281,8 +281,10 @@ tree_unswitch_single_loop (struct loop *loop, int num) /* Do not unswitch in cold regions. */ if (optimize_loop_for_size_p (loop)) { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, ";; Not unswitching cold loops\n"); + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION | TDF_DETAILS, + find_loop_location (loop), + ";; Not unswitching cold loops\n"); return false; } @@ -290,8 +292,10 @@ tree_unswitch_single_loop (struct loop *loop, int num) if (tree_num_loop_insns (loop, &eni_size_weights) > (unsigned) PARAM_VALUE (PARAM_MAX_UNSWITCH_INSNS)) { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, ";; Not unswitching, loop too big\n"); + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION | TDF_DETAILS, + find_loop_location (loop), + ";; Not unswitching, loop too big\n"); return false; } @@ -302,9 +306,11 @@ tree_unswitch_single_loop (struct loop *loop, int num) iterations = likely_max_loop_iterations_int (loop); if (iterations >= 0 && iterations <= 1) { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, ";; Not unswitching, loop is not expected" - " to iterate\n"); + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION | TDF_DETAILS, + find_loop_location (loop), + ";; Not unswitching, loop is not expected" + " to iterate\n"); return false; } } @@ -322,10 +328,11 @@ tree_unswitch_single_loop (struct loop *loop, int num) if (i == loop->num_nodes) { - if (dump_file - && num > PARAM_VALUE (PARAM_MAX_UNSWITCH_LEVEL) - && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, ";; Not unswitching anymore, hit max level\n"); + if (dump_enabled_p ()) + if (num > PARAM_VALUE (PARAM_MAX_UNSWITCH_LEVEL)) + dump_printf_loc (MSG_MISSED_OPTIMIZATION | TDF_DETAILS, + find_loop_location (loop), + ";; Not unswitching anymore, hit max level\n"); if (found == loop->num_nodes) { @@ -447,8 +454,10 @@ tree_unswitch_single_loop (struct loop *loop, int num) } } - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, ";; Unswitching loop\n"); + if (dump_enabled_p ()) + dump_printf_loc (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS, + find_loop_location (loop), + ";; Unswitching loop\n"); initialize_original_copy_tables (); /* Unswitch the loop on this condition. */ @@ -522,9 +531,11 @@ tree_unswitch_outer_loop (struct loop *loop) iterations = likely_max_loop_iterations_int (loop); if (iterations >= 0 && iterations <= 1) { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, ";; Not unswitching, loop is not expected" - " to iterate\n"); + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION | TDF_DETAILS, + find_loop_location (loop), + ";; Not unswitching, loop is not expected" + " to iterate\n"); return false; } @@ -629,22 +640,27 @@ find_loop_guard (struct loop *loop) if (!dominated_by_p (CDI_DOMINATORS, loop->inner->header, guard_edge == fe ? te->dest : fe->dest)) { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, "Guard edge %d --> %d is not around the loop!\n", - guard_edge->src->index, guard_edge->dest->index); + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION | TDF_DETAILS, + find_loop_location (loop), + "Guard edge %d --> %d is not around the loop!\n", + guard_edge->src->index, guard_edge->dest->index); return NULL; } if (guard_edge->dest == loop->latch) { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, "Guard edge destination is loop latch.\n"); + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION | TDF_DETAILS, + find_loop_location (loop), + "Guard edge destination is loop latch.\n"); return NULL; } - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, - "Considering guard %d -> %d in loop %d\n", - guard_edge->src->index, guard_edge->dest->index, loop->num); + if (dump_enabled_p ()) + dump_printf_loc (MSG_NOTE | TDF_DETAILS, find_loop_location (loop), + "Considering guard %d -> %d in loop %d\n", + guard_edge->src->index, guard_edge->dest->index, + loop->num); /* Check if condition operands do not have definitions inside loop since any bb copying is not performed. */ FOR_EACH_SSA_TREE_OPERAND (use, cond, iter, SSA_OP_USE) @@ -654,9 +670,10 @@ find_loop_guard (struct loop *loop) if (def_bb && flow_bb_inside_loop_p (loop, def_bb)) { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, " guard operands have definitions" - " inside loop\n"); + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION | TDF_DETAILS, def, + " guard operands have definitions" + " inside loop\n"); return NULL; } } @@ -669,23 +686,28 @@ find_loop_guard (struct loop *loop) continue; if (bb->flags & BB_IRREDUCIBLE_LOOP) { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, "Block %d is marked as irreducible in loop\n", - bb->index); + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION | TDF_DETAILS, + find_loop_location (loop), + "Block %d is marked as irreducible in loop\n", + bb->index); guard_edge = NULL; goto end; } if (!empty_bb_without_guard_p (loop, bb)) { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, " block %d has side effects\n", bb->index); + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION | TDF_DETAILS, + find_loop_location (loop), + " block %d has side effects\n", bb->index); guard_edge = NULL; goto end; } } - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, " suitable to hoist\n"); + if (dump_enabled_p ()) + dump_printf_loc (MSG_NOTE | TDF_DETAILS, find_loop_location (loop), + " suitable to hoist\n"); end: if (body) free (body); @@ -824,13 +846,15 @@ hoist_guard (struct loop *loop, edge guard) update_stmt (cond_stmt); /* Create new loop pre-header. */ e = split_block (pre_header, last_stmt (pre_header)); - if (dump_file && (dump_flags & TDF_DETAILS)) + if (dump_enabled_p ()) { - fprintf (dump_file, " Moving guard %i->%i (prob ", - guard->src->index, guard->dest->index); - guard->probability.dump (dump_file); - fprintf (dump_file, ") to bb %i, new preheader is %i\n", - e->src->index, e->dest->index); + dump_printf_loc (MSG_NOTE | TDF_DETAILS, cond_stmt, + " Moving guard %i->%i (prob ", + guard->src->index, guard->dest->index); + guard->probability.dump (MSG_NOTE | TDF_DETAILS); + dump_printf (MSG_NOTE | TDF_DETAILS, + ") to bb %i, new preheader is %i\n", + e->src->index, e->dest->index); } gcc_assert (loop_preheader_edge (loop)->src == e->dest); @@ -859,14 +883,17 @@ hoist_guard (struct loop *loop, edge guard) if (skip_count > e->count ()) { - fprintf (dump_file, " Capping count; expect profile inconsistency\n"); + if (dump_enabled_p ()) + dump_printf_loc (MSG_NOTE | TDF_DETAILS, cond_stmt, + " Capping count; expect profile inconsistency\n"); skip_count = e->count (); } - if (dump_file && (dump_flags & TDF_DETAILS)) + if (dump_enabled_p ()) { - fprintf (dump_file, " Estimated probability of skipping loop is "); - new_edge->probability.dump (dump_file); - fprintf (dump_file, "\n"); + dump_printf_loc (MSG_NOTE | TDF_DETAILS, cond_stmt, + " Estimated probability of skipping loop is "); + new_edge->probability.dump (MSG_NOTE | TDF_DETAILS); + dump_printf (MSG_NOTE | TDF_DETAILS, "\n"); } /* Update profile after the transform: @@ -885,19 +912,22 @@ hoist_guard (struct loop *loop, edge guard) where profile does not change. */ basic_block *body = get_loop_body (loop); - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, " Scaling nonguarded BBs in loop:"); + if (dump_enabled_p ()) + dump_printf_loc (MSG_NOTE | TDF_DETAILS, find_loop_location (loop), + " Scaling nonguarded BBs in loop:"); for (unsigned int i = 0; i < loop->num_nodes; i++) { basic_block bb = body[i]; if (!dominated_by_p (CDI_DOMINATORS, bb, not_guard->dest)) { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, " %i", bb->index); + if (dump_enabled_p ()) + dump_printf (MSG_NOTE | TDF_DETAILS, " %i", bb->index); if (e->probability.initialized_p ()) scale_bbs_frequencies (&bb, 1, e->probability); } } + if (dump_enabled_p ()) + dump_printf (MSG_NOTE | TDF_DETAILS, "\n"); if (fix_dom_of_exit) set_immediate_dominator (CDI_DOMINATORS, exit->dest, pre_header); @@ -924,8 +954,9 @@ hoist_guard (struct loop *loop, edge guard) } } - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, "\n guard hoisted.\n"); + if (dump_enabled_p ()) + dump_printf_loc (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS, + cond_stmt, " guard hoisted.\n"); free (body); } diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index d26b0f8..14489ba 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -1436,7 +1436,6 @@ extern void vect_loop_versioning (loop_vec_info, unsigned int, bool, extern struct loop *vect_do_peeling (loop_vec_info, tree, tree, tree *, tree *, tree *, int, bool, bool); extern void vect_prepare_for_masked_peels (loop_vec_info); -extern dump_user_location_t find_loop_location (struct loop *); extern bool vect_can_advance_ivs_p (loop_vec_info); /* In tree-vect-stmts.c. */ -- 1.8.5.3