> From: Dhruv Chawla <[email protected]>
>
> Signed-off-by: Dhruv Chawla <[email protected]>
>
> gcc/ChangeLog:
>
> * auto-profile.cc (string_table::~string_table): Update to free
> original_names_map_.
> (string_table::original_names_map_): New member.
> (string_table::clashing_names_map_): Likewise.
> (string_table::get_original_name): New function.
> (string_table::read): Figure out clashes while reading.
> (autofdo_source_profile::offline_external_functions): Call
> get_original_name.
OK,
thanks!
Honza
> ---
> gcc/auto-profile.cc | 82 ++++++++++++++++++++++++++++++++++++++++++---
> 1 file changed, 78 insertions(+), 4 deletions(-)
>
> diff --git a/gcc/auto-profile.cc b/gcc/auto-profile.cc
> index 5e62c7f6b59..a24061e02fe 100644
> --- a/gcc/auto-profile.cc
> +++ b/gcc/auto-profile.cc
> @@ -260,6 +260,11 @@ public:
> /* For a given filename, returns the index. */
> int get_filename_index (const char *name) const;
>
> + /* Get the original name and file name index for a node. This will return
> the
> + name from the current TU if there are multiple symbols that map to
> + NAME. */
> + std::pair<const char *, int> get_original_name (const char *name) const;
> +
> /* Read profile, return TRUE on success. */
> bool read ();
>
> @@ -288,6 +293,9 @@ private:
> string_index_map symbol_name_map_;
> string_index_map filename_map_;
> string_index_map symbol_to_filename_map_;
> +
> + string_string_map original_names_map_;
> + clashing_name_map clashing_names_map_;
> };
>
> /* Profile of a function instance:
> @@ -683,7 +691,6 @@ static gcov_type afdo_count_scale = 1;
>
> /* Helper functions. */
>
> -
> /* Return the original name of NAME: strip the suffix that starts
> with '.' for names that are generetad after auto-profile pass.
> This is to match profiled names with the names in the IR at this stage.
> @@ -922,6 +929,9 @@ string_table::~string_table ()
> free (const_cast<char *> (symbol_names_[i]));
> for (unsigned i = 0; i < filenames_.length (); i++)
> free (const_cast<char *> (filenames_[i]));
> + for (auto it = original_names_map_.begin (); it != original_names_map_.end
> ();
> + it++)
> + free (it->second);
> }
>
>
> @@ -1006,6 +1016,50 @@ string_table::get_filename_index (const char *name)
> const
> : iter->second;
> }
>
> +/* Get the original name and file name index for a node. This will return
> the
> + name from the current TU if there are multiple symbols that map to
> + NAME. */
> +
> +std::pair<const char *, int>
> +string_table::get_original_name (const char *name) const
> +{
> + /* Check if the un-prefixed name differs from the actual name. */
> + auto stripped = original_names_map_.find (name);
> +
> + /* The original name for the symbol is its name, i.e. there are no
> + suffixes. */
> + if (stripped == original_names_map_.end ())
> + return {name, get_filename_by_symbol (name)};
> +
> + /* Figure out if a clash exists. */
> + auto clash = clashing_names_map_.find (stripped->second);
> + gcc_assert (clash != clashing_names_map_.end ());
> +
> + /* Try to find a function from the current TU. */
> + gcc_assert (clash->second.length () >= 1);
> + if (symtab_node *n
> + = cgraph_node::get_for_asmname (get_identifier (stripped->second));
> + n && is_a<cgraph_node *> (n))
> + for (cgraph_node *cn = dyn_cast<cgraph_node *> (n); cn;)
> + {
> + /* Check if there is a symbol in the current TU that has the same name
> + as in the GCOV. */
> + for (auto name : clash->second)
> + {
> + int filename_idx = get_filename_by_symbol (name);
> + if (cn->definition && cn->has_gimple_body_p ()
> + && !strcmp (get_normalized_path (DECL_SOURCE_FILE (cn->decl)),
> + get_filename (filename_idx)))
> + return {stripped->second, filename_idx};
> + }
> + cn = dyn_cast<cgraph_node *> (cn->next_sharing_asm_name);
> + }
> +
> + /* No match found. Just stick to the current symbol and return the
> stripped
> + name. */
> + return {stripped->second, get_filename_by_symbol (name)};
> +}
> +
> /* Add new symbol name STRING (with an associated file name FILENAME_IDX) and
> return its index. */
>
> @@ -1064,6 +1118,25 @@ string_table::read ()
> symbol_name_map_[symbol_names_.last ()] = i;
> unsigned filename_idx = gcov_read_unsigned ();
> symbol_to_filename_map_[symbol_names_.last ()] = filename_idx;
> + char *original = const_cast<char *> (
> + autofdo::get_original_name (symbol_names_.last ()));
> + if (strcmp (original, symbol_names_.last ()))
> + {
> + /* Take ownership of ORIGINAL. */
> + original_names_map_[symbol_names_.last ()] = original;
> + clashing_names_map_[original].safe_push (i);
> + /* It is possible that a public symbol with the stripped name exists.
> + If it does exist, add it as well. */
> + auto publik = symbol_name_map_.find (original);
> + if (publik != symbol_name_map_.end ()
> + && clashing_names_map_.find (publik->first)
> + == clashing_names_map_.end ())
> + clashing_names_map_[publik->first].safe_push (publik->second);
> + }
> + else
> + /* There are no suffixes to remove. */
> + free (original);
> +
> if (gcov_is_error ())
> return false;
> }
> @@ -2169,10 +2242,11 @@ autofdo_source_profile::offline_external_functions ()
> for (size_t i = 1; i < afdo_string_table->num_entries (); i++)
> {
> const char *n1 = afdo_string_table->get_symbol_name (i);
> - char *n2 = get_original_name (n1);
> + std::pair<const char *, int> name_filename
> + = afdo_string_table->get_original_name (n1);
> + const char *n2 = name_filename.first;
> if (!strcmp (n1, n2))
> {
> - free (n2);
> /* Watch for duplicate entries.
> This seems to happen in practice and may be useful to distingush
> multiple static symbols of the same name, but we do not realy
> @@ -2194,7 +2268,7 @@ autofdo_source_profile::offline_external_functions ()
> int index = afdo_string_table->get_index (n2);
> if (index == -1)
> index = afdo_string_table->add_symbol_name (xstrdup (n2),
> -
> string_table::unknown_filename);
> + name_filename.second);
> to_symbol_name.put (i, index);
> }
> last_name = afdo_string_table->num_entries ();
> --
> 2.44.0
>