===================================================================
@@ -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 ();
===================================================================
@@ -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;
-}
-