From patchwork Tue Feb 4 23:54:43 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rong Xu X-Patchwork-Id: 316780 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 451B02C0084 for ; Wed, 5 Feb 2014 10:54:54 +1100 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:date:message-id:subject:from:to:content-type; q= dns; s=default; b=vUtgShaGs57007wsx9Gj5PjtQ+iHAibPL3LSX/IClztSpP 4AcbgBeUC+io4C8+bctoAxOE0c14W/IQ32dWPcCTc9Zn24fCVhlKQ5KdHLEjvasi jInWMYVhOQPv1GSuj0e8s+8hgmZ8BXiOEKfWBVmec91VJ/aSs2LaMIzpelNWU= 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 :mime-version:date:message-id:subject:from:to:content-type; s= default; bh=THf3BKtIv4QErRozxOIMW1QSC+Y=; b=ogBjKFCgxW5y1V7rYhI9 c68jLC8+dhpmdcnTGTurBd+TS78qfDWLxv/ZraVMAr/J+m3ufCYa3uJbUFCtXLs0 BtrMDIjzzX2/6MDnD2IHLqW7pxEHPqeJUs+I3iSBRuUtpHjD8CrJ3apyNC8KmauI qikQdLEcInB2BtiA/tRYLA8= Received: (qmail 6216 invoked by alias); 4 Feb 2014 23:54:48 -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 6207 invoked by uid 89); 4 Feb 2014 23:54:47 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-2.1 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-ob0-f179.google.com Received: from mail-ob0-f179.google.com (HELO mail-ob0-f179.google.com) (209.85.214.179) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Tue, 04 Feb 2014 23:54:45 +0000 Received: by mail-ob0-f179.google.com with SMTP id wo20so10375427obc.38 for ; Tue, 04 Feb 2014 15:54:43 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:date:message-id:subject:from:to :content-type; bh=Y9SxbS06s3X4La+zweiqR8DKkE0utN/caGw2tGF/Dmc=; b=iJ2thLTB25hAOH71Nfs0K1AH31xeOQtFd5tgmCG4+iUWucH4Qg+Q/TOpvXSEaM1nZA BYd7opfPwMgpbJfZr5CrKwjkmCOSgbr8hK3T6XT5E3RWMm0z/QLLJa37I9weGeX+IkOZ nldw5E9Dlh2GjiM9Oi7d0mDD57EltK8zPyhAsjy0pdRBtiFWj0Gdvo5jc/jv0HCBW7E5 W8+QUKisjBvo/qj6wCbuGu3BFwfiFNgKs9HAE6dwXig/sKnXD9LcAi6PYjJHvXawWz/j Y5WG3kyjNQVz6lzlz31uuqXG5hdAv+DVood87d64TvqU529d3yHEzOcsrKv53xouHjIx rmcA== X-Gm-Message-State: ALoCoQn0FxMi2f4oULIZYQwIr8UiqVE6o9iY0QVMZunenLUBLRFKoUfoZA0fsOjNcKmrrh+CUYmtPlYP1IXXXXYx7dibVOBAG2KC20bragjTfo0FvQhFOAUD91dfb1mnJvbrZY7FWynqJrXOvj6eOQNAxaQLptwNNt1M6iuaQijfO728vFmeICtvtVC2hW8EDBSu63/HeHwkBAYp/HAcT2/kOE1LhT7wOg== MIME-Version: 1.0 X-Received: by 10.60.65.101 with SMTP id w5mr38748436oes.0.1391558083702; Tue, 04 Feb 2014 15:54:43 -0800 (PST) Received: by 10.182.195.20 with HTTP; Tue, 4 Feb 2014 15:54:43 -0800 (PST) Date: Tue, 4 Feb 2014 15:54:43 -0800 Message-ID: Subject: [google gcc-4_8] unify int and fp scaling in gcov-tool From: Rong Xu To: GCC Patches , David Li , Teresa Johnson X-IsSubscribed: yes Hi, The attached patch uses a callback function to unify the integer and floating-point scaling in gcov-tool. (Also fix a bug in fp scaling of ic and dc counters in earlier code). Tested with spec2006 profiles. OK for checking in? Thanks, -Rong 2014-02-04 Rong Xu * gcc/gcov-tool.c (profile_rewrite2): Remove. (profile_rewrite): Merge int and fp scaling. (do_rewrite): Ditto. * libgcc/libgcov-util.c (typedef gcov_type) New. (__gcov_add_counter_op): Merge int and fp scaling. (__gcov_ior_counter_op): Ditto. (__gcov_delta_counter_op): Ditto. (__gcov_single_counter_op): Ditto. (__gcov_icall_topn_op): Ditto. (__gcov_dc_op): Ditto. (fp_scale): Ditto. (int_scale): Ditto. (gcov_profile_scale): Ditto. (gcov_profile_normalize): Ditto. (__gcov_scale2_add): Remove. (__gcov_scale2_ior): Remove. (__gcov_scale2_delta): Remove. (__gcov_scale2_single): Remove. (__gcov_scale2_icall_topn): Remove. (__gcov_scale2_dc): Remove. (gcov_profile_scale2): Remove. Index: gcc/gcov-tool.c =================================================================== --- gcc/gcov-tool.c (revision 207488) +++ gcc/gcov-tool.c (working copy) @@ -43,8 +43,7 @@ see the files COPYING3 and COPYING.RUNTIME respect extern int gcov_profile_merge (struct gcov_info*, struct gcov_info*, int, int); extern int gcov_profile_normalize (struct gcov_info*, gcov_type); -extern int gcov_profile_scale (struct gcov_info*, float); -extern int gcov_profile_scale2 (struct gcov_info*, int, int); +extern int gcov_profile_scale (struct gcov_info*, float, int, int); extern struct gcov_info* gcov_read_profile_dir (const char*, int); extern void gcov_exit (void); extern void set_gcov_list (struct gcov_info *); @@ -227,45 +226,13 @@ do_merge (int argc, char **argv) return ret; } -/* Scale the counters in profile DIR by a factor of N/D. - Result is written to dir OUT. Return 0 on success. */ - -static int -profile_rewrite2 (const char *dir, const char *out, int n, int d) -{ - char *pwd; - int ret; - struct gcov_info * profile; - - - profile = gcov_read_profile_dir (dir, 0); - if (!profile) - return 1; - - /* Output new profile. */ - unlink_profile_dir (out); - mkdir (out, 0755); - pwd = getcwd (NULL, 0); - gcc_assert (pwd); - ret = chdir (out); - gcc_assert (ret == 0); - - gcov_profile_scale2 (profile, n, d); - - set_gcov_list (profile); - gcov_exit (); - - ret = chdir (pwd); - free (pwd); - return 0; -} - /* If N_VAL is no-zero, normalize the profile by setting the largest counter counter value to N_VAL and scale others counters proportionally. Otherwise, multiply the all counters by SCALE. */ static int -profile_rewrite (const char *d1, const char *out, long long n_val, float scale) +profile_rewrite (const char *d1, const char *out, long long n_val, + float scale, int n, int d) { char *pwd; int ret; @@ -287,7 +254,7 @@ static int if (n_val) gcov_profile_normalize (d1_profile, (gcov_type) n_val); else - gcov_profile_scale (d1_profile, scale); + gcov_profile_scale (d1_profile, scale, n, d); set_gcov_list (d1_profile); gcov_exit (); @@ -604,9 +571,9 @@ do_rewrite (int argc, char **argv) if (argc - optind == 1) { if (denominator > 0) - ret = profile_rewrite2 (argv[optind], output_dir, numerator, denominator); + ret = profile_rewrite (argv[optind], output_dir, 0, 0.0, numerator, denominator); else - ret = profile_rewrite (argv[optind], output_dir, normalize_val, scale); + ret = profile_rewrite (argv[optind], output_dir, normalize_val, scale, 0, 0); } else rewrite_usage (); Index: libgcc/libgcov-util.c =================================================================== --- libgcc/libgcov-util.c (revision 207488) +++ libgcc/libgcov-util.c (working copy) @@ -873,39 +873,38 @@ gcov_profile_merge (struct gcov_info *tgt_profile, return 0; } -/* This part of code is to scale profile counters. */ +typedef gcov_type (*counter_op_fn) (gcov_type, void*, void*); -/* Type of function used to normalize counters. */ -typedef void (*gcov_scale_fn) (gcov_type *, gcov_unsigned_t, double); +/* Performing FN upon arc counters. */ -/* Scale arc counters. N_COUNTERS of counter value in COUNTERS array are - multiplied by a factor F. */ - static void -__gcov_scale_add (gcov_type *counters, unsigned n_counters, double f) +__gcov_add_counter_op (gcov_type *counters, unsigned n_counters, + counter_op_fn fn, void *data1, void *data2) { for (; n_counters; counters++, n_counters--) { gcov_type val = *counters; - *counters = val * f; + *counters = fn(val, data1, data2); } } -/* Scale ior counters. */ +/* Performing FN upon ior counters. */ static void -__gcov_scale_ior (gcov_type *counters ATTRIBUTE_UNUSED, - unsigned n_counters ATTRIBUTE_UNUSED, - double f ATTRIBUTE_UNUSED) +__gcov_ior_counter_op (gcov_type *counters ATTRIBUTE_UNUSED, + unsigned n_counters ATTRIBUTE_UNUSED, + counter_op_fn fn ATTRIBUTE_UNUSED, + void *data1 ATTRIBUTE_UNUSED, + void *data2 ATTRIBUTE_UNUSED) { /* Do nothing. */ } -/* Scale delta counters. Multiplied the counters in COUNTERS array - by a factor of F. */ +/* Performaing FN upon delta counters. */ static void -__gcov_scale_delta (gcov_type *counters, unsigned n_counters, double f) +__gcov_delta_counter_op (gcov_type *counters, unsigned n_counters, + counter_op_fn fn, void *data1, void *data2) { unsigned i, n_measures; @@ -913,16 +912,16 @@ static void n_measures = n_counters / 4; for (i = 0; i < n_measures; i++, counters += 4) { - counters[2] *= f; - counters[3] *= f; + counters[2] = fn (counters[2], data1, data2); + counters[3] = fn (counters[3], data1, data2); } } -/* Scale single counters. Multiplied the counters in COUNTERS array - by a factor of F. */ +/* Performing FN upon single counters. */ static void -__gcov_scale_single (gcov_type *counters, unsigned n_counters, double f) +__gcov_single_counter_op (gcov_type *counters, unsigned n_counters, + counter_op_fn fn, void *data1, void *data2) { unsigned i, n_measures; @@ -930,16 +929,16 @@ static void n_measures = n_counters / 3; for (i = 0; i < n_measures; i++, counters += 3) { - counters[1] *= f; - counters[2] *= f; + counters[1] = fn (counters[1], data1, data2); + counters[2] = fn (counters[2], data1, data2); } } -/* Scale indirect-call profile counters. Multiplied the counters in COUNTERS - array by a factor of F. */ +/* Performing FN upon indirect-call profile counters. */ static void -__gcov_scale_icall_topn (gcov_type *counters, unsigned n_counters, double f) +__gcov_icall_topn_op (gcov_type *counters, unsigned n_counters, + counter_op_fn fn, void *data1, void *data2) { unsigned i; @@ -950,41 +949,65 @@ static void gcov_type *value_array = &counters[i + 1]; for (j = 0; j < GCOV_ICALL_TOPN_NCOUNTS - 1; j += 2) - value_array[1] *= f; + value_array[j + 1] = fn (value_array[j + 1], data1, data2); } } -/* Scale direct-call profile counters. Multiplied the counters in COUNTERS - by a factor of F. */ +/* Performing FN upon direct-call profile counters. */ static void -__gcov_scale_dc (gcov_type *counters, unsigned n_counters, double f) +__gcov_dc_op (gcov_type *counters, unsigned n_counters, + counter_op_fn fn, void *data1, void *data2) { unsigned i; gcc_assert (!(n_counters % 2)); for (i = 0; i < n_counters; i += 2) - counters[1] *= f; + counters[i + 1] = fn (counters[i + 1], data1, data2); } -/* Scaling functions for counters. */ -static gcov_scale_fn ctr_scale_functions[GCOV_COUNTERS] = { - __gcov_scale_add, - __gcov_scale_add, - __gcov_scale_add, - __gcov_scale_single, - __gcov_scale_delta, - __gcov_scale_single, - __gcov_scale_add, - __gcov_scale_ior, - __gcov_scale_icall_topn, - __gcov_scale_dc, + +/* Scaling the counter value V by multiplying *(float*) DATA1. */ + +static gcov_type +fp_scale (gcov_type v, void *data1, void *data2 ATTRIBUTE_UNUSED) +{ + float f = *(float *) data1; + return (gcov_type) (v * f); +} + +/* Scaling the counter value V by multiplying DATA2/DATA1. */ + +static gcov_type +int_scale (gcov_type v, void *data1, void *data2) +{ + int n = *(int *) data1; + int d = *(int *) data2; + return (gcov_type) ((v / d) * n); +} + +/* Type of function used to process counters. */ +typedef void (*gcov_counter_fn) (gcov_type *, gcov_unsigned_t, + counter_op_fn, void *, void *); + +/* Function array to process profile counters. */ +static gcov_counter_fn ctr_functions[GCOV_COUNTERS] = { + __gcov_add_counter_op, + __gcov_add_counter_op, + __gcov_add_counter_op, + __gcov_single_counter_op, + __gcov_delta_counter_op, + __gcov_single_counter_op, + __gcov_add_counter_op, + __gcov_ior_counter_op, + __gcov_icall_topn_op, + __gcov_dc_op, }; /* Driver for scaling profile counters. */ int -gcov_profile_scale (struct gcov_info *profile, float scale_factor) +gcov_profile_scale (struct gcov_info *profile, float scale_factor, int n, int d) { struct gcov_info *gi_ptr; unsigned f_ix; @@ -1010,7 +1033,12 @@ int if (!merge) continue; - (*ctr_scale_functions[t_ix]) (ci_ptr->values, ci_ptr->num, scale_factor); + if (d == 0) + (*ctr_functions[t_ix]) (ci_ptr->values, ci_ptr->num, + fp_scale, &scale_factor, NULL); + else + (*ctr_functions[t_ix]) (ci_ptr->values, ci_ptr->num, + int_scale, &n, &d); ci_ptr++; } } @@ -1054,149 +1082,5 @@ gcov_profile_normalize (struct gcov_info *profile, if (verbose) fprintf (stdout, "max_val is %lld\n", (long long) curr_max_val); - return gcov_profile_scale (profile, scale_factor); + return gcov_profile_scale (profile, scale_factor, 0, 0); } - -/* Type of function used to normalize counters. */ -typedef void (*gcov_scale2_fn) (gcov_type *, gcov_unsigned_t, int, int); - -/* Scale2 arc counters. */ - -static void -__gcov_scale2_add (gcov_type *counters, unsigned n_counters, int n, int d) -{ - for (; n_counters; counters++, n_counters--) - { - gcov_type val = *counters; - *counters = (val / d) * n; - } -} - -/* Scale2 ior counters. */ - -static void -__gcov_scale2_ior (gcov_type *counters ATTRIBUTE_UNUSED, - unsigned n_counters ATTRIBUTE_UNUSED, - int n ATTRIBUTE_UNUSED, - int d ATTRIBUTE_UNUSED) -{ - /* do nothing. */ -} - -/* Scale2 delta counters. */ - -static void -__gcov_scale2_delta (gcov_type *counters, unsigned n_counters, int n, int d) -{ - unsigned i, n_measures; - - gcc_assert (!(n_counters % 4)); - n_measures = n_counters / 4; - for (i = 0; i < n_measures; i++, counters += 4) - { - counters[2] = (counters[2] / d) * n; - counters[3] = (counters[3] / d) * n; - } -} - -/* Scale2 single counters. */ - -static void -__gcov_scale2_single (gcov_type *counters, unsigned n_counters, int n, int d) -{ - unsigned i, n_measures; - - gcc_assert (!(n_counters % 3)); - n_measures = n_counters / 3; - for (i = 0; i < n_measures; i++, counters += 3) - { - counters[1] = (counters[1] / d) * n; - counters[2] = (counters[2] / d) * n; - } -} - -/* Scale2 indirect-call profile counters. Multiplied the counters in COUNTERS - array by a factor of F. */ - -static void -__gcov_scale2_icall_topn (gcov_type *counters, unsigned n_counters, int n, int d) -{ - unsigned i; - - gcc_assert (!(n_counters % GCOV_ICALL_TOPN_NCOUNTS)); - for (i = 0; i < n_counters; i += GCOV_ICALL_TOPN_NCOUNTS) - { - unsigned j; - gcov_type *value_array = &counters[i+1]; - - for (j = 0; j < GCOV_ICALL_TOPN_NCOUNTS - 1; j += 2) - value_array[j+1] = (value_array[j+1] / d) * n; - } -} - -/* Scale2 direct-call profile counters. Multiplied the counters in COUNTERS - by a factor of F. */ - -static void -__gcov_scale2_dc (gcov_type *counters, unsigned n_counters, int n, int d) -{ - unsigned i; - - gcc_assert (!(n_counters % 2)); - for (i = 0; i < n_counters; i += 2) - counters[i+1] = (counters[i+1] / d) * n; -} - -/* Scale2 functions for counters. */ -static gcov_scale2_fn ctr_scale2_functions[GCOV_COUNTERS] = { - __gcov_scale2_add, - __gcov_scale2_add, - __gcov_scale2_add, - __gcov_scale2_single, - __gcov_scale2_delta, - __gcov_scale2_single, - __gcov_scale2_add, - __gcov_scale2_ior, - __gcov_scale2_icall_topn, - __gcov_scale2_dc, -}; - -/* Driver for scale2 profile counters. */ - -int -gcov_profile_scale2 (struct gcov_info *profile, int n, int d) -{ - struct gcov_info *gi_ptr; - unsigned f_ix; - - if (verbose) - fprintf (stdout, "scale_factor is %d/%d\n", n, d); - - gcc_assert (n >= 0 && d > 0); - - /* Scale the counters. */ - for (gi_ptr = profile; gi_ptr; gi_ptr = gi_ptr->next) - 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]; - const struct gcov_ctr_info *ci_ptr; - - if (!gfi_ptr || gfi_ptr->key != gi_ptr) - continue; - - ci_ptr = gfi_ptr->ctrs; - for (t_ix = 0; t_ix != GCOV_COUNTERS; t_ix++) - { - gcov_merge_fn merge = gi_ptr->merge[t_ix]; - - if (!merge) - continue; - (*ctr_scale2_functions[t_ix]) (ci_ptr->values, ci_ptr->num, n, d); - ci_ptr++; - } - } - - return 0; -} -