From patchwork Wed Aug 6 18:43:29 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 377343 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 61BD7140096 for ; Thu, 7 Aug 2014 04:43:44 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:content-type; q=dns; s=default; b=N3IorJmNSEaFj++TfAruSXyVHure3Q1uQ3oONU1ehC+ HsRKAz+/18+lTDYHT3txAlmjsEnZmfe/pOfl+e/bkCCZkaZYPFVE7CgLsxxdQHNm fEh9KcTsix8s1eXFSy+zskfjsAi41NqRU1wTFotQQPZEMa30gP/ilIzaC3x27GiA = DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:content-type; s=default; bh=bJPr5nlHA3ZXmxz9w03mp+kVTgQ=; b=x4YIgk7sLQiZ1Jvex 9+j739bj/pi97XvoRyAVY4x8U22tXXE+oAzlgquLVaGONMvYTGUWYaR+jJHdubVd nvdNGgzWT1BN0Ng+G0Amvwbs5Jj7daMpReDMujKIl0qWhEDzdZ6JkFULQ/n33n0F 8SG4WrBjZTtY4lbDaulIFP4m6I= Received: (qmail 15443 invoked by alias); 6 Aug 2014 18:43:37 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 15434 invoked by uid 89); 6 Aug 2014 18:43:36 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.6 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-we0-f178.google.com Received: from mail-we0-f178.google.com (HELO mail-we0-f178.google.com) (74.125.82.178) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Wed, 06 Aug 2014 18:43:35 +0000 Received: by mail-we0-f178.google.com with SMTP id w61so3126255wes.37 for ; Wed, 06 Aug 2014 11:43:31 -0700 (PDT) X-Received: by 10.194.71.52 with SMTP id r20mr17311702wju.113.1407350611854; Wed, 06 Aug 2014 11:43:31 -0700 (PDT) Received: from [192.168.44.110] (05436870.skybroadband.com. [5.67.104.112]) by mx.google.com with ESMTPSA id je3sm8638229wic.11.2014.08.06.11.43.30 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 06 Aug 2014 11:43:30 -0700 (PDT) Message-ID: <53E27751.3020808@acm.org> Date: Wed, 06 Aug 2014 19:43:29 +0100 From: Nathan Sidwell User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.7.0 MIME-Version: 1.0 To: GCC Patches CC: Xinliang David Li Subject: gcov rearrangement X-IsSubscribed: yes This patch combines some distinct global variables into a single structure. It gets rid of the final bits of user namespace pollution and allows the renamed gcov_clear to reside in the object file that uses it. I'll commit shortly and then get to the cros-shared object behaviour. nathan 2014-08-06 Nathan Sidwell * Makefile.in (LIBGCOV_INTERFACE): Move _gcov_dump ... (LIBGCOV_DRIVER): ... to here. * libgcov.h (gcov_do_dump): New #define. (struct gcov_root): New. (__gcov_root): New declaration. (__gcov_dump_one): Declare. * libgcov-driver.c (gcov_list, gcov_dump_complete, run_accounted): Delete. (gcov_compute_histogram): Add LIST argument, adjust. (compute_summary): Adjust gcov_compute_histogram call. (gcov_do_dump): Not hidden, static in libgcov. (gcov_clear): Move to interface.c. (__gcov_dump_one): New, broken out of ... (gcov_exit): ... here. Make static. (__gcov_root): New. (__gcov_init): Adjust. * libgcov-interface.c (gcov_clear, gcov_exit): Remove declarations. (__gcov_flush): Use __gcov_dump_one and __gcov_reset. (gcov_clear): Moved from driver.c. Add LIST argument. (__gcov_reset): Adjust for changed interfaces. (__gcov_fork): Remove local declaration of __gcov_flush_mx. Index: libgcc/Makefile.in =================================================================== --- libgcc/Makefile.in (revision 213442) +++ libgcc/Makefile.in (working copy) @@ -859,9 +859,8 @@ LIBGCOV_PROFILER = _gcov_interval_profil _gcov_average_profiler _gcov_ior_profiler \ _gcov_indirect_call_profiler_v2 _gcov_time_profiler LIBGCOV_INTERFACE = _gcov_flush _gcov_fork _gcov_execl _gcov_execlp \ - _gcov_execle _gcov_execv _gcov_execvp _gcov_execve _gcov_reset \ - _gcov_dump -LIBGCOV_DRIVER = _gcov + _gcov_execle _gcov_execv _gcov_execvp _gcov_execve _gcov_reset +LIBGCOV_DRIVER = _gcov _gcov_dump libgcov-merge-objects = $(patsubst %,%$(objext),$(LIBGCOV_MERGE)) libgcov-profiler-objects = $(patsubst %,%$(objext),$(LIBGCOV_PROFILER)) Index: libgcc/libgcov-driver.c =================================================================== --- libgcc/libgcov-driver.c (revision 213442) +++ libgcc/libgcov-driver.c (working copy) @@ -73,16 +73,6 @@ struct gcov_filename size_t prefix; /* chars to prepend to filename */ }; -/* Chain of per-object gcov structures. */ -#ifndef IN_GCOV_TOOL -/* We need to expose this static variable when compiling for gcov-tool. */ -static -#endif -struct gcov_info *gcov_list; - -/* Flag when the profile has already been dumped via __gcov_dump(). */ -static int gcov_dump_complete; - static struct gcov_fn_buffer * free_fn_data (const struct gcov_info *gi_ptr, struct gcov_fn_buffer *buffer, unsigned limit) @@ -222,7 +212,7 @@ gcov_histogram_insert(gcov_bucket_type * /* Computes a histogram of the arc counters to place in the summary SUM. */ static void -gcov_compute_histogram (struct gcov_summary *sum) +gcov_compute_histogram (struct gcov_info *list, struct gcov_summary *sum) { struct gcov_info *gi_ptr; const struct gcov_fn_info *gfi_ptr; @@ -248,7 +238,7 @@ gcov_compute_histogram (struct gcov_summ /* Walk through all the per-object structures and record each of the count values in histogram. */ - for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next) + for (gi_ptr = list; gi_ptr; gi_ptr = gi_ptr->next) { if (!gi_ptr->merge[t_ix]) continue; @@ -279,10 +269,6 @@ gcov_compute_histogram (struct gcov_summ static struct gcov_fn_buffer *fn_buffer; /* buffer for summary from other programs to be written out. */ static struct gcov_summary_buffer *sum_buffer; -/* If application calls fork or exec multiple times, we end up storing - profile repeadely. We should not account this as multiple runs or - functions executed once may mistakely become cold. */ -static int run_accounted = 0; /* This function computes the program level summary and the histo-gram. It computes and returns CRC32 and stored summary in THIS_PRG. @@ -346,7 +332,7 @@ compute_summary (struct gcov_info *list, } } } - gcov_compute_histogram (this_prg); + gcov_compute_histogram (list, this_prg); return crc32; } @@ -752,7 +738,10 @@ read_fatal:; summary and then traverses gcov_list list and dumps the gcov_info objects one by one. */ -void ATTRIBUTE_HIDDEN +#if !IN_GCOV_TOOL +static +#endif +void gcov_do_dump (struct gcov_info *list, int run_counted) { struct gcov_info *gi_ptr; @@ -777,50 +766,24 @@ gcov_do_dump (struct gcov_info *list, in #if !IN_GCOV_TOOL void -gcov_exit (void) +__gcov_dump_one (struct gcov_root *root) { - /* Prevent the counters from being dumped a second time on exit when the - application already wrote out the profile using __gcov_dump(). */ - if (gcov_dump_complete) + if (root->dumped) return; - gcov_dump_complete = 1; - - gcov_do_dump (gcov_list, run_accounted); + gcov_do_dump (root->list, root->run_counted); - run_accounted = 1; + root->dumped = 1; + root->run_counted = 1; } -/* Reset all counters to zero. */ +/* Per-program/shared-object gcov state. */ +struct gcov_root __gcov_root; -void -gcov_clear (void) +static void +gcov_exit (void) { - const struct gcov_info *gi_ptr; - - gcov_dump_complete = 0; - for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next) - { - unsigned f_ix; - - for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++) - { - unsigned t_ix; - const struct gcov_fn_info *gfi_ptr = gi_ptr->functions[f_ix]; - - if (!gfi_ptr || gfi_ptr->key != gi_ptr) - continue; - const struct gcov_ctr_info *ci_ptr = gfi_ptr->ctrs; - for (t_ix = 0; t_ix != GCOV_COUNTERS; t_ix++) - { - if (!gi_ptr->merge[t_ix]) - continue; - - memset (ci_ptr->values, 0, sizeof (gcov_type) * ci_ptr->num); - ci_ptr++; - } - } - } + __gcov_dump_one (&__gcov_root); } /* Add a new object file onto the bb chain. Invoked automatically @@ -833,11 +796,11 @@ __gcov_init (struct gcov_info *info) return; if (gcov_version (info, info->version, 0)) { - if (!gcov_list) + if (!__gcov_root.list) atexit (gcov_exit); - info->next = gcov_list; - gcov_list = info; + info->next = __gcov_root.list; + __gcov_root.list = info; } info->version = 0; } Index: libgcc/libgcov-interface.c =================================================================== --- libgcc/libgcov-interface.c (revision 213442) +++ libgcc/libgcov-interface.c (working copy) @@ -42,8 +42,7 @@ void __gcov_dump (void) {} #else -extern void gcov_clear (void) ATTRIBUTE_HIDDEN; -extern void gcov_exit (void) ATTRIBUTE_HIDDEN; +extern __gthread_mutex_t __gcov_flush_mx ATTRIBUTE_HIDDEN; extern __gthread_mutex_t __gcov_flush_mx ATTRIBUTE_HIDDEN; #ifdef L_gcov_flush @@ -77,8 +76,8 @@ __gcov_flush (void) init_mx_once (); __gthread_mutex_lock (&__gcov_flush_mx); - gcov_exit (); - gcov_clear (); + __gcov_dump_one (&__gcov_root); + __gcov_reset (); __gthread_mutex_unlock (&__gcov_flush_mx); } @@ -87,31 +86,61 @@ __gcov_flush (void) #ifdef L_gcov_reset +/* Reset all counters to zero. */ + +static void +gcov_clear (const struct gcov_info *list) +{ + const struct gcov_info *gi_ptr; + + for (gi_ptr = list; gi_ptr; gi_ptr = gi_ptr->next) + { + unsigned f_ix; + + for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++) + { + unsigned t_ix; + const struct gcov_fn_info *gfi_ptr = gi_ptr->functions[f_ix]; + + if (!gfi_ptr || gfi_ptr->key != gi_ptr) + continue; + const struct gcov_ctr_info *ci_ptr = gfi_ptr->ctrs; + for (t_ix = 0; t_ix != GCOV_COUNTERS; t_ix++) + { + if (!gi_ptr->merge[t_ix]) + continue; + + memset (ci_ptr->values, 0, sizeof (gcov_type) * ci_ptr->num); + ci_ptr++; + } + } + } +} + /* Function that can be called from application to reset counters to zero, in order to collect profile in region of interest. */ void __gcov_reset (void) { - gcov_clear (); + gcov_clear (__gcov_root.list); + __gcov_root.dumped = 0; } #endif /* L_gcov_reset */ #ifdef L_gcov_dump - /* Function that can be called from application to write profile collected so far, in order to collect profile in region of interest. */ void __gcov_dump (void) { - gcov_exit (); + __gcov_dump_one (&__gcov_root); } #endif /* L_gcov_dump */ - #ifdef L_gcov_fork /* A wrapper for the fork function. Flushes the accumulated profiling data, so that they are not counted twice. */ @@ -120,7 +149,6 @@ pid_t __gcov_fork (void) { pid_t pid; - extern __gthread_mutex_t __gcov_flush_mx; __gcov_flush (); pid = fork (); if (pid == 0) Index: libgcc/libgcov.h =================================================================== --- libgcc/libgcov.h (revision 213442) +++ libgcc/libgcov.h (working copy) @@ -100,7 +100,6 @@ typedef unsigned gcov_type_unsigned __at #define gcov_read_unsigned __gcov_read_unsigned #define gcov_read_counter __gcov_read_counter #define gcov_read_summary __gcov_read_summary -#define gcov_do_dump __gcov_do_dump #else /* IN_GCOV_TOOL */ /* About the host. */ @@ -207,6 +206,19 @@ struct gcov_info #endif /* !IN_GCOV_TOOL */ }; +/* Root of a program/shared-object state */ +struct gcov_root +{ + struct gcov_info *list; + unsigned dumped : 1; /* counts have been dumped. */ + unsigned run_counted : 1; /* run has been accounted for. */ +}; + +extern struct gcov_root __gcov_root ATTRIBUTE_HIDDEN; + +/* Dump a set of gcov objects. */ +extern void __gcov_dump_one (struct gcov_root *) ATTRIBUTE_HIDDEN; + /* Register a new object file module. */ extern void __gcov_init (struct gcov_info *) ATTRIBUTE_HIDDEN;