From 862b9b225fba6cf3c63234206f2dbc47f1ab5350 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Mon, 8 Jun 2020 20:07:08 +0200 Subject: [PATCH] libgcov: fix TOPN type casting The patch fixes tree-prof.exp tests on solaris11 and i686-linux-gnu, problem was that sizeof of a pointer is different from sizeof gcov_type. I'm going to install it if there are no objections. Thanks, Martin libgcc/ChangeLog: PR gcov-profile/95494 * libgcov-driver.c (write_top_counters): Cast first to intptr_t as sizeof(*) != sizeof(gcov_type). * libgcov.h (gcov_counter_set_if_null): Remove. (gcov_topn_add_value): Cast first to intptr_t and update linked list directly. --- libgcc/libgcov-driver.c | 4 ++-- libgcc/libgcov.h | 49 +++++++++++++++++++++++------------------ 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/libgcc/libgcov-driver.c b/libgcc/libgcov-driver.c index 8348d9f33ec..cbfcae96d19 100644 --- a/libgcc/libgcov-driver.c +++ b/libgcc/libgcov-driver.c @@ -352,8 +352,8 @@ write_top_counters (const struct gcov_ctr_info *ci_ptr, gcov_type pair_count = ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i + 1]; gcov_write_counter (ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i]); gcov_write_counter (pair_count); - for (struct gcov_kvp *node - = (struct gcov_kvp *)ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i + 2]; + gcov_type start = ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i + 2]; + for (struct gcov_kvp *node = (struct gcov_kvp *)(intptr_t)start; node != NULL; node = node->next) { gcov_write_counter (node->value); diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h index 1456100815d..5d237a4c730 100644 --- a/libgcc/libgcov.h +++ b/libgcc/libgcov.h @@ -401,24 +401,6 @@ gcov_counter_add (gcov_type *counter, gcov_type value, *counter += value; } -/* Set NODE to memory location COUNTER and make it with atomic operation - if USE_ATOMIC is true. */ - -static inline int -gcov_counter_set_if_null (gcov_type *counter, struct gcov_kvp *node, - int use_atomic ATTRIBUTE_UNUSED) -{ -#if GCOV_SUPPORTS_ATOMIC - if (use_atomic) - return !__sync_val_compare_and_swap (counter, NULL, (intptr_t)node); - else -#endif - { - *counter = (intptr_t)node; - return 1; - } -} - /* Add key value pair VALUE:COUNT to a top N COUNTERS. When INCREMENT_TOTAL is true, add COUNT to total of the TOP counter. If USE_ATOMIC is true, do it in atomic way. */ @@ -432,7 +414,7 @@ gcov_topn_add_value (gcov_type *counters, gcov_type value, gcov_type count, struct gcov_kvp *prev_node = NULL; struct gcov_kvp *minimal_node = NULL; - struct gcov_kvp *current_node = (struct gcov_kvp *)counters[2]; + struct gcov_kvp *current_node = (struct gcov_kvp *)(intptr_t)counters[2]; while (current_node) { @@ -467,10 +449,33 @@ gcov_topn_add_value (gcov_type *counters, gcov_type value, gcov_type count, int success = 0; if (!counters[2]) - success = gcov_counter_set_if_null (&counters[2], new_node, use_atomic); + { +#if GCOV_SUPPORTS_ATOMIC + if (use_atomic) + { + struct gcov_kvp **ptr = (struct gcov_kvp **)(intptr_t)&counters[2]; + success = !__sync_val_compare_and_swap (ptr, 0, new_node); + } + else +#endif + { + counters[2] = (intptr_t)new_node; + success = 1; + } + } else if (prev_node && !prev_node->next) - success = gcov_counter_set_if_null ((gcov_type *)&prev_node->next, - new_node, use_atomic); + { +#if GCOV_SUPPORTS_ATOMIC + if (use_atomic) + success = !__sync_val_compare_and_swap (&prev_node->next, 0, + new_node); + else +#endif + { + prev_node->next = new_node; + success = 1; + } + } /* Increment number of nodes. */ if (success)