[gcc r16-1772] Impove diagnostics of mismatched discriminators in auto-profile
Jan Hubicka
hubicka@gcc.gnu.org
Mon Jun 30 07:15:26 GMT 2025
https://gcc.gnu.org/g:483acdc188012cf5b1fc14a82402764c920470aa
commit r16-1772-g483acdc188012cf5b1fc14a82402764c920470aa
Author: Jan Hubicka <hubicka@ucw.cz>
Date: Sun Jun 29 07:05:16 2025 +0200
Impove diagnostics of mismatched discriminators in auto-profile
We are missing discriminator info in auto-profiles, for example in exchange2.
I am not sure why, since I see the info still present in dwarf2out, so it may
be bug at create_gcov side.
This patch makes the workaround to ouptput better diagnostics (to actually show
the soruce location). This needs promotion of location info through the inline
stack API, so I turned it from pair to actual structure. Overall I think pairs
are overused in this source and makes it harder to read.
Bootstrapped/regtested x86_64-linux, comitted.
gcc/ChangeLog:
* auto-profile.cc (struct decl_lineno): Turn to structure; add
location.
(dump_inline_stack): Update.
(get_inline_stack): Update.
(get_relative_location_for_locus): Fixup formating.
(function_instance::get_function_instance_by_decl): Add
LOCATION parameter; improve dumping.
(autofdo_source_profile::get_callsite_total_count): Improve dumping;
update.
(walk_block): Update.
(autofdo_source_profile::offline_unrealized_inlines): Update.
(autofdo_source_profile::get_count_info): Update.
Diff:
---
gcc/auto-profile.cc | 126 ++++++++++++++++++++++++++++++++--------------------
1 file changed, 78 insertions(+), 48 deletions(-)
diff --git a/gcc/auto-profile.cc b/gcc/auto-profile.cc
index 7cf1e8f1b815..44e7faa8fee6 100644
--- a/gcc/auto-profile.cc
+++ b/gcc/auto-profile.cc
@@ -144,10 +144,17 @@ private:
};
/* Represent a source location: (function_decl, lineno). */
-typedef std::pair<tree, unsigned> decl_lineno;
+struct decl_lineno
+{
+ tree decl;
+ /* Relative locations stored in auto-profile. */
+ unsigned int afdo_loc;
+ /* Actual location afdo_loc was computed from used to output diagnostics. */
+ location_t location;
+};
/* Represent an inline stack. vector[0] is the leaf node. */
-typedef auto_vec<decl_lineno> inline_stack;
+typedef auto_vec<decl_lineno, 20> inline_stack;
/* String array that stores function names. */
typedef auto_vec<char *> string_vector;
@@ -273,9 +280,11 @@ public:
}
/* Traverse callsites of the current function_instance to find one at the
- location of LINENO and callee name represented in DECL. */
+ location of LINENO and callee name represented in DECL.
+ LOCATION should match LINENO and is used to output diagnostics. */
function_instance *get_function_instance_by_decl (unsigned lineno,
- tree decl) const;
+ tree decl,
+ location_t location) const;
/* Merge profile of clones. Note that cloning hasnt been performed when
we annotate the CFG (at this stage). */
@@ -620,8 +629,8 @@ dump_inline_stack (FILE *f, inline_stack *stack)
{
fprintf (f, "%s%s:",
first ? "" : "; ",
- IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (p.first)));
- dump_afdo_loc (f, p.second);
+ IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (p.decl)));
+ dump_afdo_loc (f, p.afdo_loc);
first = false;
}
fprintf (f, "\n");
@@ -649,11 +658,11 @@ get_inline_stack (location_t locus, inline_stack *stack,
tree decl = get_function_decl_from_block (block);
stack->safe_push (
- std::make_pair (decl, get_combined_location (locus, decl)));
+ {decl, get_combined_location (locus, decl), locus});
locus = tmp_locus;
}
}
- stack->safe_push (std::make_pair (fn, get_combined_location (locus, fn)));
+ stack->safe_push ({fn, get_combined_location (locus, fn), locus});
}
/* Same as get_inline_stack for a given node which may be
@@ -696,7 +705,7 @@ get_relative_location_for_locus (tree fn, tree block, location_t locus)
block = BLOCK_SUPERCONTEXT (block))
if (inlined_function_outer_scope_p (block))
return get_combined_location (locus,
- get_function_decl_from_block (block));
+ get_function_decl_from_block (block));
return get_combined_location (locus, fn);
}
@@ -806,7 +815,8 @@ function_instance::~function_instance ()
function_instance *
function_instance::get_function_instance_by_decl (unsigned lineno,
- tree decl) const
+ tree decl,
+ location_t location) const
{
int func_name_idx = afdo_string_table->get_index_by_decl (decl);
if (func_name_idx != -1)
@@ -816,32 +826,27 @@ function_instance::get_function_instance_by_decl (unsigned lineno,
if (ret != callsites.end ())
return ret->second;
}
- if (dump_file)
- {
- for (auto const &iter : callsites)
- if (iter.first.first == lineno)
- {
- fprintf (dump_file, "Looking for %s:",
- IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
- dump_afdo_loc (dump_file, lineno);
- fprintf (dump_file, " in ");
- this->dump_inline_stack (dump_file);
- fprintf (dump_file, " has mismatching call at smae loc to %s\n",
- afdo_string_table->get_name (iter.first.second));
- }
- }
- /* ??? If this is used to determine count, we will end up over-eastimating it
- if offlined function has multiple callers. */
if (DECL_FROM_INLINE (decl))
{
function_instance
*ret = get_function_instance_by_decl (lineno,
- DECL_ABSTRACT_ORIGIN (decl));
- if (ret && dump_file)
- fprintf (dump_file, "Passing to offline instance:%s\n",
- IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
+ DECL_ABSTRACT_ORIGIN (decl),
+ location);
return ret;
}
+ if (dump_enabled_p ())
+ {
+ for (auto const &iter : callsites)
+ if (iter.first.first == lineno)
+ dump_printf_loc (MSG_NOTE | MSG_PRIORITY_INTERNALS,
+ dump_user_location_t::from_location_t (location),
+ "auto-profile has mismatched function name %s"
+ " instaed of %s at loc %i:%i",
+ afdo_string_table->get_name (iter.first.second),
+ IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),
+ lineno << 16,
+ lineno & 65535);
+ }
return NULL;
}
@@ -1487,7 +1492,8 @@ walk_block (tree fn, function_instance *s, tree block)
BLOCK_SOURCE_LOCATION (block));
function_instance *ns
= s->get_function_instance_by_decl
- (loc, BLOCK_ABSTRACT_ORIGIN (block));
+ (loc, BLOCK_ABSTRACT_ORIGIN (block),
+ BLOCK_SOURCE_LOCATION (block));
if (!ns)
{
if (dump_file)
@@ -1545,7 +1551,8 @@ autofdo_source_profile::offline_unrealized_inlines ()
fprintf (dump_file, "Marking realized %s\n",
afdo_string_table->get_name (index));
f->set_realized ();
- if (DECL_INITIAL (n->decl) != error_mark_node)
+ if (DECL_INITIAL (n->decl)
+ && DECL_INITIAL (n->decl) != error_mark_node)
walk_block (n->decl, f, DECL_INITIAL (n->decl));
}
if (n->next_sharing_asm_name)
@@ -1729,7 +1736,7 @@ autofdo_source_profile::get_count_info (location_t gimple_loc,
function_instance *s = get_function_instance_by_inline_stack (stack);
if (s == NULL)
return false;
- return s->get_count_info (stack[0].second, info);
+ return s->get_count_info (stack[0].afdo_loc, info);
}
/* Update value profile INFO for STMT from the inlined indirect callsite.
@@ -1836,7 +1843,7 @@ autofdo_source_profile::get_callsite_total_count (
struct cgraph_edge *edge) const
{
inline_stack stack;
- stack.safe_push (std::make_pair (edge->callee->decl, 0));
+ stack.safe_push ({edge->callee->decl, 0, UNKNOWN_LOCATION});
get_inline_stack_in_node (gimple_location (edge->call_stmt), &stack,
edge->caller);
@@ -1948,35 +1955,58 @@ autofdo_source_profile::get_function_instance_by_inline_stack (
const inline_stack &stack) const
{
name_function_instance_map::const_iterator iter = map_.find (
- afdo_string_table->get_index_by_decl (stack[stack.length () - 1].first));
+ afdo_string_table->get_index_by_decl (stack[stack.length () - 1].decl));
if (iter == map_.end ())
{
if (dump_file)
fprintf (dump_file, "No offline instance for %s\n",
IDENTIFIER_POINTER
- (DECL_ASSEMBLER_NAME (stack[stack.length () - 1].first)));
+ (DECL_ASSEMBLER_NAME (stack[stack.length () - 1].decl)));
return NULL;
}
function_instance *s = iter->second;
for (unsigned i = stack.length () - 1; i > 0; i--)
{
function_instance *os = s;
- s = s->get_function_instance_by_decl (stack[i].second,
- stack[i - 1].first);
- /* Try lost locus. */
+ s = s->get_function_instance_by_decl (stack[i].afdo_loc,
+ stack[i - 1].decl,
+ stack[i].location);
+ /* Try lost discriminator. */
if (!s)
- s = os->get_function_instance_by_decl (stack[i].second & ~65535,
- stack[i - 1].first);
- if (s == NULL)
{
- if (dump_file)
+ s = os->get_function_instance_by_decl (stack[i].afdo_loc & ~65535,
+ stack[i - 1].decl,
+ stack[i].location);
+ if (s && dump_enabled_p ())
{
- fprintf (dump_file, "No instance for %s at loc ",
- IDENTIFIER_POINTER
- (DECL_ASSEMBLER_NAME (stack[i - 1].first)));
- dump_afdo_loc (dump_file, stack[i].second);
- fprintf (dump_file, "\n");
+ dump_printf_loc (MSG_NOTE | MSG_PRIORITY_INTERNALS,
+ dump_user_location_t::from_location_t
+ (stack[i].location),
+ "auto-profile apparently has a missing "
+ "discriminator for inlined call "
+ "of %s at relative loc %i:%i\n",
+ IDENTIFIER_POINTER
+ (DECL_ASSEMBLER_NAME (stack[i - 1].decl)),
+ stack[i].afdo_loc >> 16,
+ stack[i].afdo_loc & 65535);
}
+ }
+ if (s == NULL)
+ {
+ /* afdo inliner extends the stack by last entry with unknown
+ location while chekcing if function was inlined during train run.
+ We do not want to print diagnostics about every function
+ which is not inlined. */
+ if (s && dump_enabled_p () && stack[i].location != UNKNOWN_LOCATION)
+ dump_printf_loc (MSG_NOTE | MSG_PRIORITY_INTERNALS,
+ dump_user_location_t::from_location_t
+ (stack[i].location),
+ "auto-profile has no inlined function instance "
+ "for inlined call of %s at relative loc %i:%i\n",
+ IDENTIFIER_POINTER
+ (DECL_ASSEMBLER_NAME (stack[i - 1].decl)),
+ stack[i].afdo_loc >> 16,
+ stack[i].afdo_loc & 65535);
return NULL;
}
}
More information about the Gcc-cvs
mailing list