On Tue, Jun 26, 2018 at 3:54 PM David Malcolm <dmalc...@redhat.com> wrote: > > On Mon, 2018-06-25 at 15:34 +0200, Richard Biener wrote: > > On Wed, Jun 20, 2018 at 6:34 PM David Malcolm <dmalc...@redhat.com> > > wrote: > > > > > > Here's v3 of the patch (one big patch this time, rather than a > > > kit). > > > > > > Like the v2 patch kit, this patch reuses the existing dump API, > > > rather than inventing its own. > > > > > > Specifically, it uses the dump_* functions in dumpfile.h that don't > > > take a FILE *, the ones that implicitly write to dump_file and/or > > > alt_dump_file. I needed a name for them, so I've taken to calling > > > them the "structured dump API" (better name ideas welcome). > > > > > > v3 eliminates v2's optinfo_guard class, instead using "dump_*_loc" > > > calls as delimiters when consolidating "dump_*" calls. There's a > > > new dump_context class which has responsibility for consolidating > > > them into optimization records. > > > > > > The dump_*_loc calls now capture more than just a location_t: they > > > capture the profile_count and the location in GCC's own sources > > > where > > > the dump is being emitted from. > > > > > > This works by introducing a new "dump_location_t" class as the > > > argument of those dump_*_loc calls. The dump_location_t can > > > be constructed from a gimple * or from an rtx_insn *, so that > > > rather than writing: > > > > > > dump_printf_loc (MSG_NOTE, gimple_location (stmt), > > > "some message: %i", 42); > > > > > > you can write: > > > > > > dump_printf_loc (MSG_NOTE, stmt, > > > "some message: %i", 42); > > > > > > and the dump_location_t constructor will grab the location_t and > > > profile_count of stmt, and the location of the "dump_printf_loc" > > > callsite (and gracefully handle "stmt" being NULL). > > > > > > Earlier versions of the patch captured the location of the > > > dump_*_loc call via preprocessor hacks, or didn't work properly; > > > this version of the patch works more cleanly: internally, > > > dump_location_t is split into two new classes: > > > * dump_user_location_t: the location_t and profile_count within > > > the *user's code*, and > > > * dump_impl_location_t: the __builtin_FILE/LINE/FUNCTION within > > > the *implementation* code (i.e. GCC or a plugin), captured > > > "automagically" via default params > > > > > > These classes are sometimes used elsewhere in the code. For > > > example, "vect_location" becomes a dump_user_location_t > > > (location_t and profile_count), so that in e.g: > > > > > > vect_location = find_loop_location (loop); > > > > > > it's capturing the location_t and profile_count, and then when > > > it's used here: > > > > > > dump_printf_loc (MSG_NOTE, vect_location, "foo"); > > > > > > the dump_location_t is constructed from the vect_location > > > plus the dump_impl_location_t at that callsite. > > > > > > In contrast, loop-unroll.c's report_unroll's "locus" param > > > becomes a dump_location_t: we're interested in where it was > > > called from, not in the locations of the various dump_*_loc calls > > > within it. > > > > > > Previous versions of the patch captured a gimple *, and needed > > > GTY markers; in this patch, the dump_user_location_t is now just a > > > location_t and a profile_count. > > > > > > The v2 patch added an overload for dump_printf_loc so that you > > > could pass in either a location_t, or the new type; this version > > > of the patch eliminates that: they all now take dump_location_t. > > > > > > Doing so required adding support for rtx_insn *, so that one can > > > write this kind of thing in RTL passes: > > > > > > dump_printf_loc (MSG_NOTE, insn, "foo"); > > > > > > One knock-on effect is that get_loop_location now returns a > > > dump_user_location_t rather than a location_t, so that it has > > > hotness information. > > > > > > Richi: would you like me to split out this location-handling > > > code into a separate patch? (It's kind of redundant without > > > adding the remarks and optimization records work, but if that's > > > easier I can do it) > > > > I think that would be easier because it doesn't require the JSON > > stuff and so I'll happily approve it. > > > > Thus - trying to review that bits (and sorry for the delay). > > > > + location_t srcloc = loc.get_location_t (); > > + > > if (dump_file && (dump_kind & pflags)) > > { > > - dump_loc (dump_kind, dump_file, loc); > > + dump_loc (dump_kind, dump_file, srcloc); > > print_gimple_stmt (dump_file, gs, spc, dump_flags | > > extra_dump_flags); > > } > > > > if (alt_dump_file && (dump_kind & alt_flags)) > > { > > - dump_loc (dump_kind, alt_dump_file, loc); > > + dump_loc (dump_kind, alt_dump_file, srcloc); > > print_gimple_stmt (alt_dump_file, gs, spc, dump_flags | > > extra_dump_flags); > > } > > + > > + if (optinfo_enabled_p ()) > > + { > > + optinfo &info = begin_next_optinfo (loc); > > + info.handle_dump_file_kind (dump_kind); > > + info.add_stmt (gs, extra_dump_flags); > > + } > > > > seeing this in multiple places. I seem to remember that > > dump_file / alt_dump_file was suposed to handle dumping > > into two locations - a dump file and optinfo (or stdout). This looks > > like the optinfo "stream" is even more separate. Could that > > obsolete the alt_dump_file stream? I'd need to review existing stuff > > in more detail to answer but maybe you already know from recently > > digging into this. > > Possibly. I attempted this in v1 of the patch, but it was mixed in with > a bunch of other stuff. I'll have another go at doing this. > > > Oh, and all the if (optinfo_enable_p ()) stuff is for the followup > > then, right? > > Yes. > > > I like the boiler-plate changes to dump_* using stuff a lot, so the > > infrastructure to do that (the location wrapping) and these boiler- > > plate > > changes are pre-approved if split out. > > Thanks. I split out the location wrapping, and have committed it to > trunk (r262149). It's not clear to me exactly what other parts you liked, > so I'm going to try to split out more of the non-JSON bits in the > hope that some parts are good enough as-is, and I'll post them for review > as followups. > > For reference, here's what I've committed (I added some obvious changes > to doc/optinfo.texi). > > > I think the *_REMARK stuff should get attention of the respective > > maintainers - not sure what the difference between NOTE and REMARK > > is ;) > > Me neither :) I think it might come down to "this is purely a debugging > message for a pass maintainer" (MSG_NOTE) vs "this is a high-level thing > that an advanced user want to see" (MSG_REMARK???). > > One idea that occurred to me: are we overusing dump_flags_t? It's a > mixture of TDF_* bitfields (used by our internal dumps) plus MSG_* > bitfields (used with -fopt-info). IIRC the only TDF_ bitfield that's > ever used with the MSG_* bitfields is TDF_DETAILS. Might it make sense > to split out the MSG_* bitfields into a different type (dump_level_t???) > to reinforce this split? (and thus the dump_* entrypoints that don't take > a FILE * would take this new type). I'm not sure if this is a good idea > or not.
Making it even more complicated doesn't make it easier to use it "correctly". So I'd rather try to simplify it. How passes use TDF_DETAILS vs. non-details is already highly inconsistent. This is why I liked the original optinfo work because it somehow made user-interesting vs. developer-interesting with the same API (and to the same dump-file). Just that MSG_NOTE is exposed to users while I think it should be developer-only... IMHO the TDF_ stuff should control things at the stmt/tree/BB level, thus be IL specific flags while the MSG_ stuff should control pass-specific dumping detail. Richard. > > Thanks and sorry again for the repeated delays... > > Richard. > > Thanks > Dave > > [...snip...] > > gcc/ChangeLog: > * cfgloop.c (get_loop_location): Convert return type from > location_t to dump_user_location_t, replacing INSN_LOCATION lookups > by implicit construction from rtx_insn *, and using > dump_user_location_t::from_function_decl for the fallback case. > * cfgloop.h (get_loop_location): Convert return type from > location_t to dump_user_location_t. > * cgraphunit.c (walk_polymorphic_call_targets): Update call to > dump_printf_loc to pass in a dump_location_t rather than a > location_t, via the gimple stmt. > * coverage.c (get_coverage_counts): Update calls to > dump_printf_loc to pass in dump_location_t rather than a > location_t. > * doc/optinfo.texi (Dump types): Convert example of > dump_printf_loc from taking "locus" to taking "insn". Update > description of the "_loc" calls to cover dump_location_t. > * dumpfile.c: Include "backend.h", "gimple.h", "rtl.h", and > "selftest.h". > (dump_user_location_t::dump_user_location_t): New constructors, > from gimple *stmt and rtx_insn *. > (dump_user_location_t::from_function_decl): New function. > (dump_loc): Make static. > (dump_gimple_stmt_loc): Convert param "loc" from location_t to > const dump_location_t &. > (dump_generic_expr_loc): Delete. > (dump_printf_loc): Convert param "loc" from location_t to > const dump_location_t &. > (selftest::test_impl_location): New function. > (selftest::dumpfile_c_tests): New function. > * dumpfile.h: Include "profile-count.h". > (class dump_user_location_t): New class. > (struct dump_impl_location_t): New struct. > (class dump_location_t): New class. > (dump_printf_loc): Convert 2nd param from source_location to > const dump_location_t &. > (dump_generic_expr_loc): Delete. > (dump_gimple_stmt_loc): Convert 2nd param from source_location to > const dump_location_t &. > * gimple-fold.c (fold_gimple_assign): Update call to > dump_printf_loc to pass in a dump_location_t rather than a > location_t, via the gimple stmt. > (gimple_fold_call): Likewise. > * gimple-loop-interchange.cc > (loop_cand::analyze_iloop_reduction_var): Update for change to > check_reduction_path. > (tree_loop_interchange::interchange): Update for change to > find_loop_location. > * graphite-isl-ast-to-gimple.c (scop_to_isl_ast): Update for > change in return-type of find_loop_location. > (graphite_regenerate_ast_isl): Likewise. > * graphite-optimize-isl.c (optimize_isl): Likewise. > * graphite.c (graphite_transform_loops): Likewise. > * ipa-devirt.c (ipa_devirt): Update call to dump_printf_loc to > pass in a dump_location_t rather than a location_t, via the > gimple stmt. > * ipa-prop.c (ipa_make_edge_direct_to_target): Likewise. > * ipa.c (walk_polymorphic_call_targets): Likewise. > * loop-unroll.c (report_unroll): Convert "locus" param from > location_t to dump_location_t. > (decide_unrolling): Update for change to get_loop_location's > return type. > * omp-grid.c (struct grid_prop): Convert field "target_loc" from > location_t to dump_user_location_t. > (grid_find_single_omp_among_assignments_1): Updates calls to > dump_printf_loc to pass in a dump_location_t rather than a > location_t, via the gimple stmt. > (grid_parallel_clauses_gridifiable): Convert "tloc" from > location_t to dump_location_t. Updates calls to dump_printf_loc > to pass in a dump_location_t rather than a location_t, via the > gimple stmt. > (grid_inner_loop_gridifiable_p): Likewise. > (grid_dist_follows_simple_pattern): Likewise. > (grid_gfor_follows_tiling_pattern): Likewise. > (grid_target_follows_gridifiable_pattern): Likewise. > (grid_attempt_target_gridification): Convert initialization > of local "grid" from memset to zero-initialization; FIXME: does > this require C++11? Update call to dump_printf_loc to pass in a > optinfo_location rather than a location_t, via the gimple stmt. > * profile.c (read_profile_edge_counts): Updates call to > dump_printf_loc to pass in a dump_location_t rather than a > location_t > (compute_branch_probabilities): Likewise. > * selftest-run-tests.c (selftest::run_tests): Call > dumpfile_c_tests. > * selftest.h (dumpfile_c_tests): New decl. > * tree-loop-distribution.c (pass_loop_distribution::execute): > Update for change in return type of find_loop_location. > * tree-parloops.c (parallelize_loops): Likewise. > * tree-ssa-loop-ivcanon.c (try_unroll_loop_completely): Convert > "locus" from location_t to dump_user_location_t. > (canonicalize_loop_induction_variables): Likewise. > * tree-ssa-loop-ivopts.c (tree_ssa_iv_optimize_loop): Update > for change in return type of find_loop_location. > * tree-ssa-loop-niter.c (number_of_iterations_exit): Update call > to dump_printf_loc to pass in a dump_location_t rather than a > location_t, via the stmt. > * tree-ssa-sccvn.c (eliminate_dom_walker::before_dom_children): > Likewise. > * tree-vect-loop-manip.c (find_loop_location): Convert return > type from source_location to dump_user_location_t. > (vect_do_peeling): Update for above change. > (vect_loop_versioning): Update for change in type of > vect_location. > * tree-vect-loop.c (check_reduction_path): Convert "loc" param > from location_t to dump_user_location_t. > (vect_estimate_min_profitable_iters): Update for change in type > of vect_location. > * tree-vect-slp.c (vect_print_slp_tree): Convert param "loc" from > location_t to dump_location_t. > (vect_slp_bb): Update for change in type of vect_location. > * tree-vectorizer.c (vect_location): Convert from source_location > to dump_user_location_t. > (try_vectorize_loop_1): Update for change in vect_location's type. > (vectorize_loops): Likewise. > (increase_alignment): Likewise. > * tree-vectorizer.h (vect_location): Convert from source_location > to dump_user_location_t. > (find_loop_location): Convert return type from source_location to > dump_user_location_t. > (check_reduction_path): Convert 1st param from location_t to > dump_user_location_t. > * value-prof.c (check_counter): Update call to dump_printf_loc to > pass in a dump_user_location_t rather than a location_t; update > call to error_at for change in type of "locus". > (check_ic_target): Update call to dump_printf_loc to > pass in a dump_user_location_t rather than a location_t, via the > call_stmt. > --- > gcc/cfgloop.c | 12 +-- > gcc/cfgloop.h | 2 +- > gcc/cgraphunit.c | 3 +- > gcc/coverage.c | 22 ++++-- > gcc/doc/optinfo.texi | 16 +++- > gcc/dumpfile.c | 133 ++++++++++++++++++++++++++------- > gcc/dumpfile.h | 156 > +++++++++++++++++++++++++++++++++++++-- > gcc/gimple-fold.c | 6 +- > gcc/gimple-loop-interchange.cc | 4 +- > gcc/graphite-isl-ast-to-gimple.c | 4 +- > gcc/graphite-optimize-isl.c | 4 +- > gcc/graphite.c | 2 +- > gcc/ipa-devirt.c | 3 +- > gcc/ipa-prop.c | 10 +-- > gcc/ipa.c | 9 +-- > gcc/loop-unroll.c | 4 +- > gcc/omp-grid.c | 47 ++++++------ > gcc/profile.c | 14 +++- > gcc/selftest-run-tests.c | 1 + > gcc/selftest.h | 1 + > gcc/tree-loop-distribution.c | 2 +- > gcc/tree-parloops.c | 3 +- > gcc/tree-ssa-loop-ivcanon.c | 8 +- > gcc/tree-ssa-loop-ivopts.c | 2 +- > gcc/tree-ssa-loop-niter.c | 2 +- > gcc/tree-ssa-sccvn.c | 3 +- > gcc/tree-vect-loop-manip.c | 16 ++-- > gcc/tree-vect-loop.c | 8 +- > gcc/tree-vect-slp.c | 5 +- > gcc/tree-vectorizer.c | 14 ++-- > gcc/tree-vectorizer.h | 8 +- > gcc/value-prof.c | 15 ++-- > 32 files changed, 386 insertions(+), 153 deletions(-) > > diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c > index 8af793c..e27cd39 100644 > --- a/gcc/cfgloop.c > +++ b/gcc/cfgloop.c > @@ -1800,7 +1800,7 @@ loop_exits_from_bb_p (struct loop *loop, basic_block bb) > > /* Return location corresponding to the loop control condition if possible. > */ > > -location_t > +dump_user_location_t > get_loop_location (struct loop *loop) > { > rtx_insn *insn = NULL; > @@ -1819,7 +1819,7 @@ get_loop_location (struct loop *loop) > FOR_BB_INSNS_REVERSE (desc->in_edge->src, insn) > { > if (INSN_P (insn) && INSN_HAS_LOCATION (insn)) > - return INSN_LOCATION (insn); > + return insn; > } > } > /* If loop has a single exit, then the loop control branch > @@ -1829,24 +1829,24 @@ get_loop_location (struct loop *loop) > FOR_BB_INSNS_REVERSE (exit->src, insn) > { > if (INSN_P (insn) && INSN_HAS_LOCATION (insn)) > - return INSN_LOCATION (insn); > + return insn; > } > } > /* Next check the latch, to see if it is non-empty. */ > FOR_BB_INSNS_REVERSE (loop->latch, insn) > { > if (INSN_P (insn) && INSN_HAS_LOCATION (insn)) > - return INSN_LOCATION (insn); > + return insn; > } > /* Finally, if none of the above identifies the loop control branch, > return the first location in the loop header. */ > FOR_BB_INSNS (loop->header, insn) > { > if (INSN_P (insn) && INSN_HAS_LOCATION (insn)) > - return INSN_LOCATION (insn); > + return insn; > } > /* If all else fails, simply return the current function location. */ > - return DECL_SOURCE_LOCATION (current_function_decl); > + return dump_user_location_t::from_function_decl (current_function_decl); > } > > /* Records that every statement in LOOP is executed I_BOUND times. > diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h > index af9bfab..80a31c4 100644 > --- a/gcc/cfgloop.h > +++ b/gcc/cfgloop.h > @@ -357,7 +357,7 @@ extern bool loop_exit_edge_p (const struct loop *, > const_edge); > extern bool loop_exits_to_bb_p (struct loop *, basic_block); > extern bool loop_exits_from_bb_p (struct loop *, basic_block); > extern void mark_loop_exit_edges (void); > -extern location_t get_loop_location (struct loop *loop); > +extern dump_user_location_t get_loop_location (struct loop *loop); > > /* Loops & cfg manipulation. */ > extern basic_block *get_loop_body (const struct loop *); > diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c > index 04b6919..7cfb8a0 100644 > --- a/gcc/cgraphunit.c > +++ b/gcc/cgraphunit.c > @@ -928,8 +928,7 @@ walk_polymorphic_call_targets (hash_set<void *> > *reachable_call_targets, > } > if (dump_enabled_p ()) > { > - location_t locus = gimple_location_safe (edge->call_stmt); > - dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, locus, > + dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, edge->call_stmt, > "devirtualizing call in %s to %s\n", > edge->caller->name (), target->name ()); > } > diff --git a/gcc/coverage.c b/gcc/coverage.c > index 84fff13..350cc45 100644 > --- a/gcc/coverage.c > +++ b/gcc/coverage.c > @@ -342,12 +342,16 @@ get_coverage_counts (unsigned counter, unsigned > expected, > static int warned = 0; > > if (!warned++ && dump_enabled_p ()) > - dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location, > - (flag_guess_branch_prob > - ? "file %s not found, execution counts estimated\n" > - : "file %s not found, execution counts assumed to " > - "be zero\n"), > - da_file_name); > + { > + dump_user_location_t loc > + = dump_user_location_t::from_location_t (input_location); > + dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc, > + (flag_guess_branch_prob > + ? "file %s not found, execution counts > estimated\n" > + : "file %s not found, execution counts assumed to > " > + "be zero\n"), > + da_file_name); > + } > return NULL; > } > if (PARAM_VALUE (PARAM_PROFILE_FUNC_INTERNAL_ID)) > @@ -378,7 +382,9 @@ get_coverage_counts (unsigned counter, unsigned expected, > "its profile data (counter %qs)", id, ctr_names[counter]); > if (warning_printed && dump_enabled_p ()) > { > - dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location, > + dump_user_location_t loc > + = dump_user_location_t::from_location_t (input_location); > + dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc, > "use -Wno-error=coverage-mismatch to tolerate " > "the mismatch but performance may drop if the " > "function is hot\n"); > @@ -386,7 +392,7 @@ get_coverage_counts (unsigned counter, unsigned expected, > if (!seen_error () > && !warned++) > { > - dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location, > + dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc, > "coverage mismatch ignored\n"); > dump_printf (MSG_OPTIMIZED_LOCATIONS, > flag_guess_branch_prob > diff --git a/gcc/doc/optinfo.texi b/gcc/doc/optinfo.texi > index 8c28501..6202802 100644 > --- a/gcc/doc/optinfo.texi > +++ b/gcc/doc/optinfo.texi > @@ -168,7 +168,7 @@ when any of the following flags is enabled > > @example > int report_flags = MSG_OPTIMIZED_LOCATIONS | TDF_RTL | TDF_DETAILS; > -dump_printf_loc (report_flags, locus, > +dump_printf_loc (report_flags, insn, > "loop turned into non-loop; it never loops.\n"); > @end example > > @@ -181,7 +181,19 @@ Output gimple statement. > > Note that the above methods also have variants prefixed with > @code{_loc}, such as @code{dump_printf_loc}, which are similar except > -they also output the source location information. > +they also output the source location information. The @code{_loc} variants > +take a @code{const dump_location_t &}. This class can be constructed from > +a @code{gimple *} or from a @code{rtx_insn *}, and so callers can pass > +a @code{gimple *} or a @code{rtx_insn *} as the @code{_loc} argument. > +The @code{dump_location_t} constructor will extract the source location > +from the statement or instruction, along with the profile count, and > +the location in GCC's own source code (or the plugin) from which the dump > +call was emitted. Only the source location is currently used. > +There is also a @code{dump_user_location_t} class, capturing the > +source location and profile count, but not the dump emission location, > +so that locations in the user's code can be passed around. This > +can also be constructed from a @code{gimple *} and from a @code{rtx_insn *}, > +and it too can be passed as the @code{_loc} argument. > > @end ftable > > diff --git a/gcc/dumpfile.c b/gcc/dumpfile.c > index 2f11284..122e420 100644 > --- a/gcc/dumpfile.c > +++ b/gcc/dumpfile.c > @@ -29,6 +29,10 @@ along with GCC; see the file COPYING3. If not see > #include "profile-count.h" > #include "tree-cfg.h" > #include "langhooks.h" > +#include "backend.h" /* for gimple.h. */ > +#include "gimple.h" /* for dump_user_location_t ctor. */ > +#include "rtl.h" /* for dump_user_location_t ctor. */ > +#include "selftest.h" > > /* If non-NULL, return one past-the-end of the matching SUBPART of > the WHOLE string. */ > @@ -358,9 +362,51 @@ dump_open_alternate_stream (struct dump_file_info *dfi) > return stream; > } > > +/* Construct a dump_user_location_t from STMT (using its location and > + hotness). */ > + > +dump_user_location_t::dump_user_location_t (gimple *stmt) > +: m_count (), m_loc (UNKNOWN_LOCATION) > +{ > + if (stmt) > + { > + if (stmt->bb) > + m_count = stmt->bb->count; > + m_loc = gimple_location (stmt); > + } > +} > + > +/* Construct a dump_user_location_t from an RTL instruction (using its > + location and hotness). */ > + > +dump_user_location_t::dump_user_location_t (rtx_insn *insn) > +: m_count (), m_loc (UNKNOWN_LOCATION) > +{ > + if (insn) > + { > + basic_block bb = BLOCK_FOR_INSN (insn); > + if (bb) > + m_count = bb->count; > + m_loc = INSN_LOCATION (insn); > + } > +} > + > +/* Construct from a function declaration. This one requires spelling out > + to avoid accidentally constructing from other kinds of tree. */ > + > +dump_user_location_t > +dump_user_location_t::from_function_decl (tree fndecl) > +{ > + gcc_assert (fndecl); > + > + // FIXME: profile count for function? > + return dump_user_location_t (profile_count (), > + DECL_SOURCE_LOCATION (fndecl)); > +} > + > /* Print source location on DFILE if enabled. */ > > -void > +static void > dump_loc (dump_flags_t dump_kind, FILE *dfile, source_location loc) > { > if (dump_kind) > @@ -393,18 +439,19 @@ dump_gimple_stmt (dump_flags_t dump_kind, dump_flags_t > extra_dump_flags, > /* Similar to dump_gimple_stmt, except additionally print source location. > */ > > void > -dump_gimple_stmt_loc (dump_flags_t dump_kind, source_location loc, > +dump_gimple_stmt_loc (dump_flags_t dump_kind, const dump_location_t &loc, > dump_flags_t extra_dump_flags, gimple *gs, int spc) > { > + location_t srcloc = loc.get_location_t (); > if (dump_file && (dump_kind & pflags)) > { > - dump_loc (dump_kind, dump_file, loc); > + dump_loc (dump_kind, dump_file, srcloc); > print_gimple_stmt (dump_file, gs, spc, dump_flags | extra_dump_flags); > } > > if (alt_dump_file && (dump_kind & alt_flags)) > { > - dump_loc (dump_kind, alt_dump_file, loc); > + dump_loc (dump_kind, alt_dump_file, srcloc); > print_gimple_stmt (alt_dump_file, gs, spc, dump_flags | > extra_dump_flags); > } > } > @@ -423,27 +470,6 @@ dump_generic_expr (dump_flags_t dump_kind, dump_flags_t > extra_dump_flags, > print_generic_expr (alt_dump_file, t, dump_flags | extra_dump_flags); > } > > - > -/* Similar to dump_generic_expr, except additionally print the source > - location. */ > - > -void > -dump_generic_expr_loc (dump_flags_t dump_kind, source_location loc, > - dump_flags_t extra_dump_flags, tree t) > -{ > - if (dump_file && (dump_kind & pflags)) > - { > - dump_loc (dump_kind, dump_file, loc); > - print_generic_expr (dump_file, t, dump_flags | extra_dump_flags); > - } > - > - if (alt_dump_file && (dump_kind & alt_flags)) > - { > - dump_loc (dump_kind, alt_dump_file, loc); > - print_generic_expr (alt_dump_file, t, dump_flags | extra_dump_flags); > - } > -} > - > /* Output a formatted message using FORMAT on appropriate dump streams. */ > > void > @@ -469,13 +495,14 @@ dump_printf (dump_flags_t dump_kind, const char > *format, ...) > /* Similar to dump_printf, except source location is also printed. */ > > void > -dump_printf_loc (dump_flags_t dump_kind, source_location loc, > +dump_printf_loc (dump_flags_t dump_kind, const dump_location_t &loc, > const char *format, ...) > { > + location_t srcloc = loc.get_location_t (); > if (dump_file && (dump_kind & pflags)) > { > va_list ap; > - dump_loc (dump_kind, dump_file, loc); > + dump_loc (dump_kind, dump_file, srcloc); > va_start (ap, format); > vfprintf (dump_file, format, ap); > va_end (ap); > @@ -484,7 +511,7 @@ dump_printf_loc (dump_flags_t dump_kind, source_location > loc, > if (alt_dump_file && (dump_kind & alt_flags)) > { > va_list ap; > - dump_loc (dump_kind, alt_dump_file, loc); > + dump_loc (dump_kind, alt_dump_file, srcloc); > va_start (ap, format); > vfprintf (alt_dump_file, format, ap); > va_end (ap); > @@ -1059,3 +1086,53 @@ enable_rtl_dump_file (void) > NULL); > return num_enabled > 0; > } > + > +#if CHECKING_P > + > +namespace selftest { > + > +/* Verify that the dump_location_t constructors capture the source location > + at which they were called (provided that the build compiler is > sufficiently > + recent). */ > + > +static void > +test_impl_location () > +{ > +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) > + /* Default ctor. */ > + { > + dump_location_t loc; > + const int expected_line = __LINE__ - 1; > + ASSERT_STR_CONTAINS (loc.get_impl_location ().m_file, "dumpfile.c"); > + ASSERT_EQ (loc.get_impl_location ().m_line, expected_line); > + } > + > + /* Constructing from a gimple. */ > + { > + dump_location_t loc ((gimple *)NULL); > + const int expected_line = __LINE__ - 1; > + ASSERT_STR_CONTAINS (loc.get_impl_location ().m_file, "dumpfile.c"); > + ASSERT_EQ (loc.get_impl_location ().m_line, expected_line); > + } > + > + /* Constructing from an rtx_insn. */ > + { > + dump_location_t loc ((rtx_insn *)NULL); > + const int expected_line = __LINE__ - 1; > + ASSERT_STR_CONTAINS (loc.get_impl_location ().m_file, "dumpfile.c"); > + ASSERT_EQ (loc.get_impl_location ().m_line, expected_line); > + } > +#endif > +} > + > +/* Run all of the selftests within this file. */ > + > +void > +dumpfile_c_tests () > +{ > + test_impl_location (); > +} > + > +} // namespace selftest > + > +#endif /* CHECKING_P */ > diff --git a/gcc/dumpfile.h b/gcc/dumpfile.h > index f6ad670..90d8930 100644 > --- a/gcc/dumpfile.h > +++ b/gcc/dumpfile.h > @@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see > #ifndef GCC_DUMPFILE_H > #define GCC_DUMPFILE_H 1 > > +#include "profile-count.h" > > /* Different tree dump places. When you add new tree dump places, > extend the DUMP_FILES array in dumpfile.c. */ > @@ -268,20 +269,165 @@ struct dump_file_info > bool graph_dump_initialized; > }; > > +/* A class for describing where in the user's source that a dump message > + relates to, with various constructors for convenience. > + In particular, this lets us associate dump messages > + with hotness information (e.g. from PGO), allowing them to > + be prioritized by code hotness. */ > + > +class dump_user_location_t > +{ > + public: > + /* Default constructor, analogous to UNKNOWN_LOCATION. */ > + dump_user_location_t () : m_count (), m_loc (UNKNOWN_LOCATION) {} > + > + /* Construct from a gimple statement (using its location and hotness). */ > + dump_user_location_t (gimple *stmt); > + > + /* Construct from an RTL instruction (using its location and hotness). */ > + dump_user_location_t (rtx_insn *insn); > + > + /* Construct from a location_t. This one is deprecated (since it doesn't > + capture hotness information); it thus needs to be spelled out. */ > + static dump_user_location_t > + from_location_t (location_t loc) > + { > + return dump_user_location_t (profile_count (), loc); > + } > + > + /* Construct from a function declaration. This one requires spelling out > + to avoid accidentally constructing from other kinds of tree. */ > + static dump_user_location_t > + from_function_decl (tree fndecl); > + > + profile_count get_count () const { return m_count; } > + location_t get_location_t () const { return m_loc; } > + > + private: > + /* Private ctor from count and location, for use by from_location_t. */ > + dump_user_location_t (profile_count count, location_t loc) > + : m_count (count), m_loc (loc) > + {} > + > + profile_count m_count; > + location_t m_loc; > +}; > + > +/* A class for identifying where in the compiler's own source > + (or a plugin) that a dump message is being emitted from. */ > + > +struct dump_impl_location_t > +{ > + dump_impl_location_t ( > +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) > + const char *file = __builtin_FILE (), > + int line = __builtin_LINE (), > + const char *function = __builtin_FUNCTION () > +#else > + const char *file = __FILE__, > + int line = __LINE__, > + const char *function = NULL > +#endif > + ) > + : m_file (file), m_line (line), m_function (function) > + {} > + > + const char *m_file; > + int m_line; > + const char *m_function; > +}; > + > +/* A bundle of information for describing the location of a dump message: > + (a) the source location and hotness within the user's code, together with > + (b) the source location within the compiler/plugin. > + > + The constructors use default parameters so that (b) gets sets up > + automatically. > + > + The upshot is that you can pass in e.g. a gimple * to dump_printf_loc, > + and the dump call will automatically record where in GCC's source > + code the dump was emitted from. */ > + > +class dump_location_t > +{ > + public: > + /* Default constructor, analogous to UNKNOWN_LOCATION. */ > + dump_location_t (const dump_impl_location_t &impl_location > + = dump_impl_location_t ()) > + : m_user_location (dump_user_location_t ()), > + m_impl_location (impl_location) > + { > + } > + > + /* Construct from a gimple statement (using its location and hotness). */ > + dump_location_t (gimple *stmt, > + const dump_impl_location_t &impl_location > + = dump_impl_location_t ()) > + : m_user_location (dump_user_location_t (stmt)), > + m_impl_location (impl_location) > + { > + } > + > + /* Construct from an RTL instruction (using its location and hotness). */ > + dump_location_t (rtx_insn *insn, > + const dump_impl_location_t &impl_location > + = dump_impl_location_t ()) > + : m_user_location (dump_user_location_t (insn)), > + m_impl_location (impl_location) > + { > + } > + > + /* Construct from a dump_user_location_t. */ > + dump_location_t (const dump_user_location_t &user_location, > + const dump_impl_location_t &impl_location > + = dump_impl_location_t ()) > + : m_user_location (user_location), > + m_impl_location (impl_location) > + { > + } > + > + /* Construct from a location_t. This one is deprecated (since it doesn't > + capture hotness information), and thus requires spelling out. */ > + static dump_location_t > + from_location_t (location_t loc, > + const dump_impl_location_t &impl_location > + = dump_impl_location_t ()) > + { > + return dump_location_t (dump_user_location_t::from_location_t (loc), > + impl_location); > + } > + > + const dump_user_location_t & > + get_user_location () const { return m_user_location; } > + > + const dump_impl_location_t & > + get_impl_location () const { return m_impl_location; } > + > + location_t get_location_t () const > + { > + return m_user_location.get_location_t (); > + } > + > + profile_count get_count () const { return m_user_location.get_count (); } > + > + private: > + dump_user_location_t m_user_location; > + dump_impl_location_t m_impl_location; > +}; > + > /* In dumpfile.c */ > extern FILE *dump_begin (int, dump_flags_t *); > extern void dump_end (int, FILE *); > extern int opt_info_switch_p (const char *); > extern const char *dump_flag_name (int); > extern void dump_printf (dump_flags_t, const char *, ...) ATTRIBUTE_PRINTF_2; > -extern void dump_printf_loc (dump_flags_t, source_location, > - const char *, ...) ATTRIBUTE_PRINTF_3; > +extern void dump_printf_loc (dump_flags_t, const dump_location_t &, > + const char *, ...) ATTRIBUTE_PRINTF_3; > extern void dump_function (int phase, tree fn); > extern void dump_basic_block (dump_flags_t, basic_block, int); > -extern void dump_generic_expr_loc (dump_flags_t, source_location, > dump_flags_t, tree); > extern void dump_generic_expr (dump_flags_t, dump_flags_t, tree); > -extern void dump_gimple_stmt_loc (dump_flags_t, source_location, > dump_flags_t, > - gimple *, int); > +extern void dump_gimple_stmt_loc (dump_flags_t, const dump_location_t &, > + dump_flags_t, gimple *, int); > extern void dump_gimple_stmt (dump_flags_t, dump_flags_t, gimple *, int); > extern void print_combine_total_stats (void); > extern bool enable_rtl_dump_file (void); > diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c > index a01bce7..f12e4a7 100644 > --- a/gcc/gimple-fold.c > +++ b/gcc/gimple-fold.c > @@ -347,8 +347,7 @@ fold_gimple_assign (gimple_stmt_iterator *si) > { > if (dump_enabled_p ()) > { > - location_t loc = gimple_location_safe (stmt); > - dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc, > + dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt, > "resolving virtual function address " > "reference to function %s\n", > targets.length () == 1 > @@ -4061,8 +4060,7 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool > inplace) > tree lhs = gimple_call_lhs (stmt); > if (dump_enabled_p ()) > { > - location_t loc = gimple_location_safe (stmt); > - dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc, > + dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt, > "folding virtual function call to %s\n", > targets.length () == 1 > ? targets[0]->name () > diff --git a/gcc/gimple-loop-interchange.cc b/gcc/gimple-loop-interchange.cc > index eb35263..08aeb8e 100644 > --- a/gcc/gimple-loop-interchange.cc > +++ b/gcc/gimple-loop-interchange.cc > @@ -523,7 +523,7 @@ loop_cand::analyze_iloop_reduction_var (tree var) > > /* Handle and verify a series of stmts feeding the reduction op. */ > if (single_use != next_def > - && !check_reduction_path (UNKNOWN_LOCATION, m_loop, phi, next, > + && !check_reduction_path (dump_user_location_t (), m_loop, phi, next, > gimple_assign_rhs_code (single_use))) > return false; > > @@ -1578,7 +1578,7 @@ bool > tree_loop_interchange::interchange (vec<data_reference_p> datarefs, > vec<ddr_p> ddrs) > { > - location_t loc = find_loop_location (m_loop_nest[0]); > + dump_user_location_t loc = find_loop_location (m_loop_nest[0]); > bool changed_p = false; > /* In each iteration we try to interchange I-th loop with (I+1)-th loop. > The overall effect is to push inner loop to outermost level in whole > diff --git a/gcc/graphite-isl-ast-to-gimple.c > b/gcc/graphite-isl-ast-to-gimple.c > index b607b12..9e78465 100644 > --- a/gcc/graphite-isl-ast-to-gimple.c > +++ b/gcc/graphite-isl-ast-to-gimple.c > @@ -1409,7 +1409,7 @@ scop_to_isl_ast (scop_p scop) > isl_ctx_set_max_operations (scop->isl_context, old_max_operations); > if (isl_ctx_last_error (scop->isl_context) != isl_error_none) > { > - location_t loc = find_loop_location > + dump_user_location_t loc = find_loop_location > (scop->scop_info->region.entry->dest->loop_father); > if (isl_ctx_last_error (scop->isl_context) == isl_error_quota) > dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc, > @@ -1518,7 +1518,7 @@ graphite_regenerate_ast_isl (scop_p scop) > > if (t.codegen_error_p ()) > { > - location_t loc = find_loop_location > + dump_user_location_t loc = find_loop_location > (scop->scop_info->region.entry->dest->loop_father); > dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc, > "loop nest not optimized, code generation error\n"); > diff --git a/gcc/graphite-optimize-isl.c b/gcc/graphite-optimize-isl.c > index 456a797..35e9ac0 100644 > --- a/gcc/graphite-optimize-isl.c > +++ b/gcc/graphite-optimize-isl.c > @@ -160,7 +160,7 @@ optimize_isl (scop_p scop) > if (!scop->transformed_schedule > || isl_ctx_last_error (scop->isl_context) != isl_error_none) > { > - location_t loc = find_loop_location > + dump_user_location_t loc = find_loop_location > (scop->scop_info->region.entry->dest->loop_father); > if (isl_ctx_last_error (scop->isl_context) == isl_error_quota) > dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc, > @@ -182,7 +182,7 @@ optimize_isl (scop_p scop) > > if (same_schedule) > { > - location_t loc = find_loop_location > + dump_user_location_t loc = find_loop_location > (scop->scop_info->region.entry->dest->loop_father); > dump_printf_loc (MSG_NOTE, loc, > "loop nest not optimized, optimized schedule is " > diff --git a/gcc/graphite.c b/gcc/graphite.c > index bcf4828..ddf16a8 100644 > --- a/gcc/graphite.c > +++ b/gcc/graphite.c > @@ -412,7 +412,7 @@ graphite_transform_loops (void) > changed = true; > if (graphite_regenerate_ast_isl (scop)) > { > - location_t loc = find_loop_location > + dump_user_location_t loc = find_loop_location > (scops[i]->scop_info->region.entry->dest->loop_father); > dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc, > "loop nest optimized\n"); > diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c > index 308b6e6..e99d8cc 100644 > --- a/gcc/ipa-devirt.c > +++ b/gcc/ipa-devirt.c > @@ -3755,8 +3755,7 @@ ipa_devirt (void) > { > if (dump_enabled_p ()) > { > - location_t locus = gimple_location_safe (e->call_stmt); > - dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, locus, > + dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, e->call_stmt, > "speculatively devirtualizing call " > "in %s to %s\n", > n->dump_name (), > diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c > index 000c05f..8b19fe3 100644 > --- a/gcc/ipa-prop.c > +++ b/gcc/ipa-prop.c > @@ -2842,8 +2842,7 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, > tree target, > { > if (dump_enabled_p ()) > { > - location_t loc = gimple_location_safe (ie->call_stmt); > - dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc, > + dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt, > "discovered direct call non-invariant > %s\n", > ie->caller->dump_name ()); > } > @@ -2853,8 +2852,7 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, > tree target, > > if (dump_enabled_p ()) > { > - location_t loc = gimple_location_safe (ie->call_stmt); > - dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc, > + dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt, > "discovered direct call to non-function in %s, > " > "making it __builtin_unreachable\n", > ie->caller->dump_name ()); > @@ -2942,9 +2940,7 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, > tree target, > } > if (dump_enabled_p ()) > { > - location_t loc = gimple_location_safe (ie->call_stmt); > - > - dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc, > + dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt, > "converting indirect call in %s to direct call to > %s\n", > ie->caller->name (), callee->name ()); > } > diff --git a/gcc/ipa.c b/gcc/ipa.c > index 82fc334..3b6b5e5 100644 > --- a/gcc/ipa.c > +++ b/gcc/ipa.c > @@ -225,13 +225,8 @@ walk_polymorphic_call_targets (hash_set<void *> > *reachable_call_targets, > (builtin_decl_implicit (BUILT_IN_UNREACHABLE)); > > if (dump_enabled_p ()) > - { > - location_t locus; > - if (edge->call_stmt) > - locus = gimple_location (edge->call_stmt); > - else > - locus = UNKNOWN_LOCATION; > - dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, locus, > + { > + dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, edge->call_stmt, > "devirtualizing call in %s to %s\n", > edge->caller->dump_name (), > target->dump_name ()); > diff --git a/gcc/loop-unroll.c b/gcc/loop-unroll.c > index 5a03932..48bbda0 100644 > --- a/gcc/loop-unroll.c > +++ b/gcc/loop-unroll.c > @@ -189,7 +189,7 @@ static rtx get_expansion (struct var_to_expand *); > appropriate given the dump or -fopt-info settings. */ > > static void > -report_unroll (struct loop *loop, location_t locus) > +report_unroll (struct loop *loop, dump_location_t locus) > { > dump_flags_t report_flags = MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS; > > @@ -220,7 +220,7 @@ decide_unrolling (int flags) > FOR_EACH_LOOP (loop, LI_FROM_INNERMOST) > { > loop->lpt_decision.decision = LPT_NONE; > - location_t locus = get_loop_location (loop); > + dump_user_location_t locus = get_loop_location (loop); > > if (dump_enabled_p ()) > dump_printf_loc (MSG_NOTE, locus, > diff --git a/gcc/omp-grid.c b/gcc/omp-grid.c > index ffa301e..6edc92f 100644 > --- a/gcc/omp-grid.c > +++ b/gcc/omp-grid.c > @@ -91,7 +91,7 @@ struct grid_prop > bool tiling; > /* Location of the target construct for optimization information > messages. */ > - location_t target_loc; > + dump_user_location_t target_loc; > /* The collapse clause of the involved loops. Collapse value of all of > them > must be the same for gridification to take place. */ > size_t collapse; > @@ -177,10 +177,10 @@ grid_find_single_omp_among_assignments_1 (gimple_seq > seq, grid_prop *grid, > GRID_MISSED_MSG_PREFIX "%s construct " > "contains multiple OpenMP constructs\n", > name); > - dump_printf_loc (MSG_NOTE, gimple_location (*ret), > + dump_printf_loc (MSG_NOTE, *ret, > "The first OpenMP construct within " > "a parallel\n"); > - dump_printf_loc (MSG_NOTE, gimple_location (stmt), > + dump_printf_loc (MSG_NOTE, stmt, > "The second OpenMP construct within " > "a parallel\n"); > } > @@ -195,7 +195,7 @@ grid_find_single_omp_among_assignments_1 (gimple_seq seq, > grid_prop *grid, > dump_printf_loc (MSG_MISSED_OPTIMIZATION, grid->target_loc, > GRID_MISSED_MSG_PREFIX "%s construct contains " > "a complex statement\n", name); > - dump_printf_loc (MSG_NOTE, gimple_location (stmt), > + dump_printf_loc (MSG_NOTE, stmt, > "This statement cannot be analyzed for " > "gridification\n"); > } > @@ -286,7 +286,7 @@ grid_find_ungridifiable_statement (gimple_stmt_iterator > *gsi, > loop that is evaluated for possible gridification. */ > > static bool > -grid_parallel_clauses_gridifiable (gomp_parallel *par, location_t tloc) > +grid_parallel_clauses_gridifiable (gomp_parallel *par, dump_user_location_t > tloc) > { > tree clauses = gimple_omp_parallel_clauses (par); > while (clauses) > @@ -300,7 +300,7 @@ grid_parallel_clauses_gridifiable (gomp_parallel *par, > location_t tloc) > GRID_MISSED_MSG_PREFIX "because there is " > "a num_threads clause of the parallel " > "construct\n"); > - dump_printf_loc (MSG_NOTE, gimple_location (par), > + dump_printf_loc (MSG_NOTE, par, > "Parallel construct has a num_threads > clause\n"); > } > return false; > @@ -311,7 +311,7 @@ grid_parallel_clauses_gridifiable (gomp_parallel *par, > location_t tloc) > dump_printf_loc (MSG_MISSED_OPTIMIZATION, tloc, > GRID_MISSED_MSG_PREFIX "a reduction clause " > "is present\n "); > - dump_printf_loc (MSG_NOTE, gimple_location (par), > + dump_printf_loc (MSG_NOTE, par, > "Parallel construct has a reduction clause\n"); > } > return false; > @@ -341,7 +341,7 @@ grid_inner_loop_gridifiable_p (gomp_for *gfor, grid_prop > *grid) > GRID_MISSED_MSG_PREFIX "the inner loop " > "loop bounds computation contains a complex " > "statement\n"); > - dump_printf_loc (MSG_NOTE, gimple_location (gfor), > + dump_printf_loc (MSG_NOTE, gfor, > "Loop construct cannot be analyzed for " > "gridification\n"); > } > @@ -361,7 +361,7 @@ grid_inner_loop_gridifiable_p (gomp_for *gfor, grid_prop > *grid) > dump_printf_loc (MSG_MISSED_OPTIMIZATION, grid->target_loc, > GRID_MISSED_MSG_PREFIX "the inner loop " > "has a non-automatic schedule clause\n"); > - dump_printf_loc (MSG_NOTE, gimple_location (gfor), > + dump_printf_loc (MSG_NOTE, gfor, > "Loop construct has a non automatic " > "schedule clause\n"); > } > @@ -375,7 +375,7 @@ grid_inner_loop_gridifiable_p (gomp_for *gfor, grid_prop > *grid) > dump_printf_loc (MSG_MISSED_OPTIMIZATION, grid->target_loc, > GRID_MISSED_MSG_PREFIX "a reduction " > "clause is present\n "); > - dump_printf_loc (MSG_NOTE, gimple_location (gfor), > + dump_printf_loc (MSG_NOTE, gfor, > "Loop construct has a reduction schedule " > "clause\n"); > } > @@ -404,7 +404,7 @@ grid_inner_loop_gridifiable_p (gomp_for *gfor, grid_prop > *grid) > GRID_MISSED_MSG_PREFIX "the inner loop contains " > "statement %s which cannot be transformed\n", > gimple_code_name[(int) gimple_code (bad)]); > - dump_printf_loc (MSG_NOTE, gimple_location (bad), > + dump_printf_loc (MSG_NOTE, bad, > "This statement cannot be analyzed for " > "gridification\n"); > } > @@ -422,7 +422,7 @@ grid_inner_loop_gridifiable_p (gomp_for *gfor, grid_prop > *grid) > static bool > grid_dist_follows_simple_pattern (gomp_for *dist, grid_prop *grid) > { > - location_t tloc = grid->target_loc; > + dump_user_location_t tloc = grid->target_loc; > gimple *stmt = grid_find_single_omp_among_assignments (gimple_omp_body > (dist), > grid, "distribute"); > gomp_parallel *par; > @@ -468,7 +468,7 @@ grid_gfor_follows_tiling_pattern (gomp_for *gfor, > grid_prop *grid) > dump_printf_loc (MSG_MISSED_OPTIMIZATION, grid->target_loc, > GRID_MISSED_MSG_PREFIX "an inner loop is not " > "a simple for loop\n"); > - dump_printf_loc (MSG_NOTE, gimple_location (gfor), > + dump_printf_loc (MSG_NOTE, gfor, > "This statement is not a simple for loop\n"); > } > return false; > @@ -484,7 +484,7 @@ grid_gfor_follows_tiling_pattern (gomp_for *gfor, > grid_prop *grid) > dump_printf_loc (MSG_MISSED_OPTIMIZATION, grid->target_loc, > GRID_MISSED_MSG_PREFIX "an inner loop does not " > "have use the same collapse clause\n"); > - dump_printf_loc (MSG_NOTE, gimple_location (gfor), > + dump_printf_loc (MSG_NOTE, gfor, > "Loop construct uses a different collapse > clause\n"); > } > return false; > @@ -524,7 +524,7 @@ grid_gfor_follows_tiling_pattern (gomp_for *gfor, > grid_prop *grid) > dump_printf_loc (MSG_MISSED_OPTIMIZATION, grid->target_loc, > GRID_MISSED_MSG_PREFIX "the distribute and " > "an internal loop do not agree on tile > size\n"); > - dump_printf_loc (MSG_NOTE, gimple_location (gfor), > + dump_printf_loc (MSG_NOTE, gfor, > "Loop construct does not seem to loop over " > "a tile size\n"); > } > @@ -636,7 +636,7 @@ grid_dist_follows_tiling_pattern (gimple_seq seq, > grid_prop *grid, > dump_printf_loc (MSG_MISSED_OPTIMIZATION, grid->target_loc, > GRID_MISSED_MSG_PREFIX "the distribute " > "construct contains a try..catch > region\n"); > - dump_printf_loc (MSG_NOTE, gimple_location (try_stmt), > + dump_printf_loc (MSG_NOTE, try_stmt, > "This statement cannot be analyzed for " > "tiled gridification\n"); > } > @@ -661,7 +661,7 @@ grid_dist_follows_tiling_pattern (gimple_seq seq, > grid_prop *grid, > dump_printf_loc (MSG_MISSED_OPTIMIZATION, grid->target_loc, > GRID_MISSED_MSG_PREFIX "the distribute " > "construct contains a call\n"); > - dump_printf_loc (MSG_NOTE, gimple_location (stmt), > + dump_printf_loc (MSG_NOTE, stmt, > "This statement cannot be analyzed for " > "tiled gridification\n"); > } > @@ -677,7 +677,7 @@ grid_dist_follows_tiling_pattern (gimple_seq seq, > grid_prop *grid, > GRID_MISSED_MSG_PREFIX "a parallel " > "construct contains another parallel " > "construct\n"); > - dump_printf_loc (MSG_NOTE, gimple_location (stmt), > + dump_printf_loc (MSG_NOTE, stmt, > "This parallel construct is nested in " > "another one\n"); > } > @@ -698,7 +698,7 @@ grid_dist_follows_tiling_pattern (gimple_seq seq, > grid_prop *grid, > GRID_MISSED_MSG_PREFIX "a loop " > "construct is not nested within a parallel > " > "construct\n"); > - dump_printf_loc (MSG_NOTE, gimple_location (stmt), > + dump_printf_loc (MSG_NOTE, stmt, > "This loop construct is not nested in " > "a parallel construct\n"); > } > @@ -714,7 +714,7 @@ grid_dist_follows_tiling_pattern (gimple_seq seq, > grid_prop *grid, > dump_printf_loc (MSG_MISSED_OPTIMIZATION, grid->target_loc, > GRID_MISSED_MSG_PREFIX "the distribute " > "construct contains a complex statement\n"); > - dump_printf_loc (MSG_NOTE, gimple_location (stmt), > + dump_printf_loc (MSG_NOTE, stmt, > "This statement cannot be analyzed for " > "tiled gridification\n"); > } > @@ -734,7 +734,7 @@ grid_target_follows_gridifiable_pattern (gomp_target > *target, grid_prop *grid) > if (gimple_omp_target_kind (target) != GF_OMP_TARGET_KIND_REGION) > return false; > > - location_t tloc = gimple_location (target); > + dump_user_location_t tloc = target; > grid->target_loc = tloc; > gimple *stmt > = grid_find_single_omp_among_assignments (gimple_omp_body (target), > @@ -1257,14 +1257,13 @@ grid_attempt_target_gridification (gomp_target > *target, > gbind *tgt_bind) > { > /* removed group_size */ > - grid_prop grid; > - memset (&grid, 0, sizeof (grid)); > + grid_prop grid = {}; > if (!target || !grid_target_follows_gridifiable_pattern (target, &grid)) > return; > > location_t loc = gimple_location (target); > if (dump_enabled_p ()) > - dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc, > + dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, target, > "Target construct will be turned into a gridified HSA " > "kernel\n"); > > diff --git a/gcc/profile.c b/gcc/profile.c > index 8ba6dc7..0cd0270 100644 > --- a/gcc/profile.c > +++ b/gcc/profile.c > @@ -447,9 +447,14 @@ read_profile_edge_counts (gcov_type *exec_counts) > { > static bool informed = 0; > if (dump_enabled_p () && !informed) > - dump_printf_loc (MSG_NOTE, input_location, > - "corrupted profile info: edge > count" > - " exceeds maximal count\n"); > + { > + dump_location_t loc > + = dump_location_t::from_location_t > + (input_location); > + dump_printf_loc (MSG_NOTE, loc, > + "corrupted profile info: edge > count" > + " exceeds maximal count\n"); > + } > informed = 1; > } > else > @@ -672,7 +677,8 @@ compute_branch_probabilities (unsigned cfg_checksum, > unsigned lineno_checksum) > if (dump_enabled_p () && informed == 0) > { > informed = 1; > - dump_printf_loc (MSG_NOTE, input_location, > + dump_printf_loc (MSG_NOTE, > + dump_location_t::from_location_t > (input_location), > "correcting inconsistent profile data\n"); > } > correct_negative_edge_counts (); > diff --git a/gcc/selftest-run-tests.c b/gcc/selftest-run-tests.c > index fe221ff..a9aacc02 100644 > --- a/gcc/selftest-run-tests.c > +++ b/gcc/selftest-run-tests.c > @@ -59,6 +59,7 @@ selftest::run_tests () > /* Low-level data structures. */ > bitmap_c_tests (); > sbitmap_c_tests (); > + dumpfile_c_tests (); > et_forest_c_tests (); > hash_map_tests_c_tests (); > hash_set_tests_c_tests (); > diff --git a/gcc/selftest.h b/gcc/selftest.h > index fc47b2c..a5507cc 100644 > --- a/gcc/selftest.h > +++ b/gcc/selftest.h > @@ -188,6 +188,7 @@ extern void attribute_c_tests (); > extern void bitmap_c_tests (); > extern void diagnostic_c_tests (); > extern void diagnostic_show_locus_c_tests (); > +extern void dumpfile_c_tests (); > extern void edit_context_c_tests (); > extern void et_forest_c_tests (); > extern void fibonacci_heap_c_tests (); > diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c > index c6e0a60..1206614 100644 > --- a/gcc/tree-loop-distribution.c > +++ b/gcc/tree-loop-distribution.c > @@ -3117,7 +3117,7 @@ pass_loop_distribution::execute (function *fun) > break; > > const char *str = loop->inner ? " nest" : ""; > - location_t loc = find_loop_location (loop); > + dump_user_location_t loc = find_loop_location (loop); > if (!cd) > { > calculate_dominance_info (CDI_DOMINATORS); > diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c > index c49f032..e79a954 100644 > --- a/gcc/tree-parloops.c > +++ b/gcc/tree-parloops.c > @@ -3286,7 +3286,6 @@ parallelize_loops (bool oacc_kernels_p) > struct tree_niter_desc niter_desc; > struct obstack parloop_obstack; > HOST_WIDE_INT estimated; > - source_location loop_loc; > > /* Do not parallelize loops in the functions created by parallelization. > */ > if (!oacc_kernels_p > @@ -3411,7 +3410,7 @@ parallelize_loops (bool oacc_kernels_p) > changed = true; > skip_loop = loop->inner; > > - loop_loc = find_loop_location (loop); > + dump_user_location_t loop_loc = find_loop_location (loop); > if (loop->inner) > dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loop_loc, > "parallelizing outer loop %d\n", loop->num); > diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c > index 24bf60e..5f741c3 100644 > --- a/gcc/tree-ssa-loop-ivcanon.c > +++ b/gcc/tree-ssa-loop-ivcanon.c > @@ -691,7 +691,7 @@ try_unroll_loop_completely (struct loop *loop, > edge exit, tree niter, bool may_be_zero, > enum unroll_level ul, > HOST_WIDE_INT maxiter, > - location_t locus, bool allow_peel) > + dump_user_location_t locus, bool allow_peel) > { > unsigned HOST_WIDE_INT n_unroll = 0; > bool n_unroll_found = false; > @@ -1162,7 +1162,7 @@ canonicalize_loop_induction_variables (struct loop > *loop, > tree niter; > HOST_WIDE_INT maxiter; > bool modified = false; > - location_t locus = UNKNOWN_LOCATION; > + dump_user_location_t locus; > struct tree_niter_desc niter_desc; > bool may_be_zero = false; > > @@ -1177,7 +1177,7 @@ canonicalize_loop_induction_variables (struct loop > *loop, > = niter_desc.may_be_zero && !integer_zerop (niter_desc.may_be_zero); > } > if (TREE_CODE (niter) == INTEGER_CST) > - locus = gimple_location (last_stmt (exit->src)); > + locus = last_stmt (exit->src); > else > { > /* For non-constant niter fold may_be_zero into niter again. */ > @@ -1204,7 +1204,7 @@ canonicalize_loop_induction_variables (struct loop > *loop, > niter = find_loop_niter_by_eval (loop, &exit); > > if (exit) > - locus = gimple_location (last_stmt (exit->src)); > + locus = last_stmt (exit->src); > > if (TREE_CODE (niter) != INTEGER_CST) > exit = NULL; > diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c > index 519649a..6b445bd 100644 > --- a/gcc/tree-ssa-loop-ivopts.c > +++ b/gcc/tree-ssa-loop-ivopts.c > @@ -7535,7 +7535,7 @@ tree_ssa_iv_optimize_loop (struct ivopts_data *data, > struct loop *loop) > > gcc_assert (!data->niters); > data->current_loop = loop; > - data->loop_loc = find_loop_location (loop); > + data->loop_loc = find_loop_location (loop).get_location_t (); > data->speed = optimize_loop_for_speed_p (loop); > > if (dump_file && (dump_flags & TDF_DETAILS)) > diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c > index f5ffc0f..03588a0 100644 > --- a/gcc/tree-ssa-loop-niter.c > +++ b/gcc/tree-ssa-loop-niter.c > @@ -2627,7 +2627,7 @@ number_of_iterations_exit (struct loop *loop, edge exit, > return true; > > if (warn) > - dump_printf_loc (MSG_MISSED_OPTIMIZATION, gimple_location_safe (stmt), > + dump_printf_loc (MSG_MISSED_OPTIMIZATION, stmt, > "missed loop optimization: niters analysis ends up " > "with assumptions.\n"); > > diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c > index 3d025c2..e5eddf9 100644 > --- a/gcc/tree-ssa-sccvn.c > +++ b/gcc/tree-ssa-sccvn.c > @@ -5866,8 +5866,7 @@ eliminate_dom_walker::before_dom_children (basic_block > b) > fn = builtin_decl_implicit (BUILT_IN_UNREACHABLE); > if (dump_enabled_p ()) > { > - location_t loc = gimple_location (stmt); > - dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc, > + dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt, > "converting indirect call to " > "function %s\n", > lang_hooks.decl_printable_name (fn, > 2)); > diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c