+2018-06-26 David Malcolm <dmalcolm@redhat.com>
+
+ * 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.
+
2018-06-26 Robin Dapp <rdapp@linux.vnet.ibm.com>
* config/s390/s390.h (enum processor_flags): Do not use
/* 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;
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
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.
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 *);
}
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 ());
}
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))
"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");
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
@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
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
#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. */
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)
/* 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);
}
}
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
/* 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);
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);
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 */
#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. */
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);
{
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
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 ()
/* 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;
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
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,
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");
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,
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 "
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");
{
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 (),
{
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 ());
}
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 ());
}
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 ());
}
(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 ());
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;
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,
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;
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");
}
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");
}
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)
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;
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;
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");
}
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");
}
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");
}
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");
}
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;
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;
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;
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");
}
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");
}
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");
}
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");
}
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");
}
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");
}
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),
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");
{
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
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 ();
/* 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 ();
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 ();
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);
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
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);
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;
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;
= 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. */
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;
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))
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");
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));
location is calculated.
Return the loop location if succeed and NULL if not. */
-source_location
+dump_user_location_t
find_loop_location (struct loop *loop)
{
gimple *stmt = NULL;
gimple_stmt_iterator si;
if (!loop)
- return UNKNOWN_LOCATION;
+ return dump_user_location_t ();
stmt = get_loop_exit_condition (loop);
if (stmt
&& LOCATION_LOCUS (gimple_location (stmt)) > BUILTINS_LOCATION)
- return gimple_location (stmt);
+ return stmt;
/* If we got here the loop is probably not "well formed",
try to estimate the loop location */
if (!loop->header)
- return UNKNOWN_LOCATION;
+ return dump_user_location_t ();
bb = loop->header;
{
stmt = gsi_stmt (si);
if (LOCATION_LOCUS (gimple_location (stmt)) > BUILTINS_LOCATION)
- return gimple_location (stmt);
+ return stmt;
}
- return UNKNOWN_LOCATION;
+ return dump_user_location_t ();
}
/* Return true if PHI defines an IV of the loop to be vectorized. */
}
}
- source_location loop_loc = find_loop_location (loop);
+ dump_user_location_t loop_loc = find_loop_location (loop);
struct loop *scalar_loop = LOOP_VINFO_SCALAR_LOOP (loop_vinfo);
if (prolog_peeling)
{
loop_constraint_set (loop, LOOP_C_INFINITE);
}
- if (LOCATION_LOCUS (vect_location) != UNKNOWN_LOCATION
+ if (LOCATION_LOCUS (vect_location.get_location_t ()) != UNKNOWN_LOCATION
&& dump_enabled_p ())
{
if (version_alias)
reduction operation CODE has a handled computation expression. */
bool
-check_reduction_path (location_t loc, loop_p loop, gphi *phi, tree loop_arg,
- enum tree_code code)
+check_reduction_path (dump_user_location_t loc, loop_p loop, gphi *phi,
+ tree loop_arg, enum tree_code code)
{
auto_vec<std::pair<ssa_op_iter, use_operand_p> > path;
auto_bitmap visited;
else
{
if (LOOP_VINFO_LOOP (loop_vinfo)->force_vectorize)
- warning_at (vect_location, OPT_Wopenmp_simd, "vectorization "
- "did not happen for a simd loop");
+ warning_at (vect_location.get_location_t (), OPT_Wopenmp_simd,
+ "vectorization did not happen for a simd loop");
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
/* Dump a slp tree NODE using flags specified in DUMP_KIND. */
static void
-vect_print_slp_tree (dump_flags_t dump_kind, location_t loc, slp_tree node)
+vect_print_slp_tree (dump_flags_t dump_kind, dump_location_t loc,
+ slp_tree node)
{
int i;
gimple *stmt;
insns++;
if (gimple_location (stmt) != UNKNOWN_LOCATION)
- vect_location = gimple_location (stmt);
+ vect_location = stmt;
if (!vect_find_stmt_data_reference (NULL, stmt, &datarefs))
break;
#include "gimple-pretty-print.h"
-/* Loop or bb location. */
-source_location vect_location;
+/* Loop or bb location, with hotness information. */
+dump_user_location_t vect_location;
/* Vector mapping GIMPLE stmt to stmt_vec_info. */
vec<stmt_vec_info> *stmt_vec_info_vec;
unsigned ret = 0;
vec_info_shared shared;
vect_location = find_loop_location (loop);
- if (LOCATION_LOCUS (vect_location) != UNKNOWN_LOCATION
+ if (LOCATION_LOCUS (vect_location.get_location_t ()) != UNKNOWN_LOCATION
&& dump_enabled_p ())
dump_printf (MSG_NOTE, "\nAnalyzing loop at %s:%d\n",
- LOCATION_FILE (vect_location),
- LOCATION_LINE (vect_location));
+ LOCATION_FILE (vect_location.get_location_t ()),
+ LOCATION_LINE (vect_location.get_location_t ()));
loop_vec_info loop_vinfo = vect_analyze_loop (loop, orig_loop_vinfo, &shared);
loop->aux = loop_vinfo;
ret |= try_vectorize_loop (simduid_to_vf_htab, &num_vectorized_loops,
loop);
- vect_location = UNKNOWN_LOCATION;
+ vect_location = dump_user_location_t ();
statistics_counter_event (cfun, "Vectorized loops", num_vectorized_loops);
if (dump_enabled_p ()
{
varpool_node *vnode;
- vect_location = UNKNOWN_LOCATION;
+ vect_location = dump_user_location_t ();
type_align_map = new hash_map<tree, unsigned>;
/* Increase the alignment of all global arrays for vectorization. */
return tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dr))));
}
-/* Source location */
-extern source_location vect_location;
+/* Source location + hotness information. */
+extern dump_user_location_t vect_location;
/* If dumping is enabled, emit a MSG_NOTE at vect_location about
entering MSG within the vectorizer. MSG should be a string literal. */
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 source_location find_loop_location (struct loop *);
+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. */
extern gimple *vect_force_simple_reduction (loop_vec_info, gimple *,
bool *, bool);
/* Used in gimple-loop-interchange.c. */
-extern bool check_reduction_path (location_t, loop_p, gphi *, tree,
+extern bool check_reduction_path (dump_user_location_t, loop_p, gphi *, tree,
enum tree_code);
/* Drive for loop analysis stage. */
extern loop_vec_info vect_analyze_loop (struct loop *, loop_vec_info,
gcov_type bb_count = bb_count_d.ipa ().to_gcov_type ();
if (*all != bb_count || *count > *all)
{
- location_t locus;
- locus = (stmt != NULL)
- ? gimple_location (stmt)
- : DECL_SOURCE_LOCATION (current_function_decl);
+ dump_user_location_t locus;
+ locus = ((stmt != NULL)
+ ? dump_user_location_t (stmt)
+ : dump_user_location_t::from_function_decl
+ (current_function_decl));
if (flag_profile_correction)
{
if (dump_enabled_p ())
}
else
{
- error_at (locus, "corrupted value profile: %s "
+ error_at (locus.get_location_t (), "corrupted value profile: %s "
"profile counter (%d out of %d) inconsistent with "
"basic-block count (%d)",
name,
bool
check_ic_target (gcall *call_stmt, struct cgraph_node *target)
{
- location_t locus;
if (gimple_check_call_matching_types (call_stmt, target->decl, true))
return true;
- locus = gimple_location (call_stmt);
if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, locus,
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, call_stmt,
"Skipping target %s with mismatching types for icall\n",
target->name ());
return false;