This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [google 4.7] fdo build for linux kernel (issue6968046)
On Fri, Dec 21, 2012 at 9:52 AM, Xinliang David Li <davidxl@google.com> wrote:
> Kernel build does not link in libgcc, which defines the function.
Then will the same issue occur with the reference to __builtin_clzll
in gcov_histo_index in gcov-io.c?
Teresa
>
> David
>
> On Fri, Dec 21, 2012 at 8:31 AM, Teresa Johnson <tejohnson@google.com> wrote:
>> On Wed, Dec 19, 2012 at 12:11 PM, Rong Xu <xur@google.com> wrote:
>>> Hi,
>>>
>>> This patch updates the support for FDO build in linux kernel for gcc 4.7.
>>> Tested with 2.6.34 kernel and google internal benchmarks.
>>>
>>> Thanks,
>>>
>>> -Rong
>>>
>>> 2012-12-19 Rong Xu <xur@google.com>
>>>
>>> * libgcc/libgcov.c
>>> (gcov_counter_active): v4.7 kernel fdo support.
>>> (crc32_unsigned): Include in GCOV_KERNEL build.
>>> (gcov_alloc_filename): Remove from GCOV_KERNEL build.
>>> (gcov_sort_icall_topn_counter): Ditto.
>>> (gcov_dump_module_info): Ditto.
>>> (gcov_compute_histogram): v4.7 kernel fdo support.
>>> (gcov_merge_gcda_file): Ditto.
>>> (gcov_gcda_file_size): Ditto.
>>> (gcov_write_gcda_file): Ditto.
>>> (__gcov_topn_value_profiler_body): Ditto.
>>> (gcov_set_vfile): Ditto.
>>> (gcov_kernel_dump_gcov_init): Ditto.
>>> (gcov_kernel_dump_one_gcov): Ditto.
>>> * gcc/gcov-io.c (gcov_read_string): Ditto.
>>> (static int k_popcountll): Ditto.
>>> (gcov_read_summary): Ditto.
>>> (kernel_file_fclose): Ditto.
>>> (kernel_file_ftell): Ditto.
>>> (kernel_file_fwrite): Ditto.
>>> * gcc/gcov-io.h (struct gcov_info): remove const keyword.
>>>
>>> Index: libgcc/libgcov.c
>>> ===================================================================
>>> --- libgcc/libgcov.c (revision 194562)
>>> +++ libgcc/libgcov.c (working copy)
>>> @@ -46,11 +46,11 @@ see the files COPYING3 and COPYING.RUNTIME respect
>>> #include "tsystem.h"
>>> #include "coretypes.h"
>>> #include "tm.h"
>>> -#endif /* __KERNEL__ */
>>> #include "libgcc_tm.h"
>>> #include "gthr.h"
>>> +#endif /* __KERNEL__ */
>>>
>>> -#if 1
>>> +#ifndef __KERNEL__
>>> #define THREAD_PREFIX __thread
>>> #else
>>> #define THREAD_PREFIX
>>> @@ -120,6 +120,7 @@ extern int gcov_dump_complete ATTRIBUTE_HIDDEN;
>>> #ifdef L_gcov
>>> #include "gcov-io.c"
>>>
>>> +#ifndef __GCOV_KERNEL__
>>> /* Create a strong reference to these symbols so that they are
>>> unconditionally pulled into the instrumented binary, even when
>>> the only reference is a weak reference. This is necessary because
>>> @@ -134,6 +135,7 @@ extern int gcov_dump_complete ATTRIBUTE_HIDDEN;
>>> these symbols will always need to be resolved. */
>>> void (*__gcov_dummy_ref1)() = &__gcov_reset;
>>> void (*__gcov_dummy_ref2)() = &__gcov_dump;
>>> +#endif /* __GCOV_KERNEL__ */
>>>
>>> /* Utility function for outputing errors. */
>>> static int
>>> @@ -151,6 +153,10 @@ gcov_error (const char *fmt, ...)
>>> return ret;
>>> }
>>>
>>> +/* A program checksum allows us to distinguish program data for an
>>> + object file included in multiple programs. */
>>> +static gcov_unsigned_t gcov_crc32;
>>> +
>>> #ifndef __GCOV_KERNEL__
>>> /* Emitted in coverage.c. */
>>> extern char * __gcov_pmu_profile_filename;
>>> @@ -183,10 +189,6 @@ THREAD_PREFIX gcov_unsigned_t __gcov_sample_counte
>>> /* Chain of per-object gcov structures. */
>>> extern struct gcov_info *__gcov_list;
>>>
>>> -/* A program checksum allows us to distinguish program data for an
>>> - object file included in multiple programs. */
>>> -static gcov_unsigned_t gcov_crc32;
>>> -
>>> /* Size of the longest file name. */
>>> static size_t gcov_max_filename = 0;
>>>
>>> @@ -323,8 +325,6 @@ gcov_counter_active (const struct gcov_info *info,
>>> return (info->merge[type] != 0);
>>> }
>>>
>>> -#ifndef __GCOV_KERNEL__
>>> -
>>> /* Add an unsigned value to the current crc */
>>>
>>> static gcov_unsigned_t
>>> @@ -344,6 +344,8 @@ crc32_unsigned (gcov_unsigned_t crc32, gcov_unsign
>>> return crc32;
>>> }
>>>
>>> +#ifndef __GCOV_KERNEL__
>>> +
>>> /* Check if VERSION of the info block PTR matches libgcov one.
>>> Return 1 on success, or zero in case of versions mismatch.
>>> If FILENAME is not NULL, its value used for reporting purposes
>>> @@ -464,6 +466,8 @@ gcov_alloc_filename (void)
>>> gi_filename_up = gi_filename + prefix_length;
>>> }
>>>
>>> +#endif /* __GCOV_KERNEL__ */
>>> +
>>> /* Sort N entries in VALUE_ARRAY in descending order.
>>> Each entry in VALUE_ARRAY has two values. The sorting
>>> is based on the second value. */
>>> @@ -509,6 +513,8 @@ gcov_sort_icall_topn_counter (const struct gcov_ct
>>> }
>>> }
>>>
>>> +#ifndef __GCOV_KERNEL__
>>> +
>>> /* Write imported files (auxiliary modules) for primary module GI_PTR
>>> into file GI_FILENAME. */
>>>
>>> @@ -586,6 +592,8 @@ gcov_dump_module_info (void)
>>> __gcov_finalize_dyn_callgraph ();
>>> }
>>>
>>> +#endif /* __GCOV_KERNEL__ */
>>> +
>>> /* Insert counter VALUE into HISTOGRAM. */
>>>
>>> static void
>>> @@ -656,6 +664,8 @@ gcov_compute_histogram (struct gcov_summary *sum)
>>> }
>>> }
>>>
>>> +#ifndef __GCOV_KERNEL__
>>> +
>>> /* Dump the coverage counts. We merge with existing counts when
>>> possible, to avoid growing the .da files ad infinitum. We use this
>>> program's checksum to make sure we only accumulate whole program
>>> @@ -1013,12 +1023,7 @@ gcov_merge_gcda_file (struct gcov_info *gi_ptr)
>>> goto read_error;
>>> }
>>> if (tag && tag != GCOV_TAG_MODULE_INFO)
>>> - {
>>> - read_mismatch:;
>>> - fprintf (stderr, "profiling:%s:Merge mismatch for %s\n",
>>> - gi_filename, f_ix + 1 ? "function" : "summaries");
>>> - goto read_fatal;
>>> - }
>>> + goto read_mismatch;
>>> }
>>> goto rewrite;
>>>
>>> @@ -1031,6 +1036,11 @@ read_error:;
>>>
>>> goto rewrite;
>>>
>>> +read_mismatch:;
>>> + gcov_error ("profiling:%s:Merge mismatch for %s\n",
>>> + gi_filename, f_ix + 1 ? "function" : "summaries");
>>> + goto read_fatal;
>>> +
>>> read_fatal:;
>>> gcov_close ();
>>> return 1;
>>> @@ -1076,7 +1086,7 @@ rewrite:;
>>> sizeof (*cs_all) - (sizeof (gcov_bucket_type)
>>> * GCOV_HISTOGRAM_SIZE)))
>>> {
>>> - fprintf (stderr, "profiling:%s:Invocation mismatch - "
>>> + gcov_error ("profiling:%s:Invocation mismatch - "
>>> "some data files may have been removed%s\n",
>>> gi_filename, GCOV_LOCKED
>>> ? "" : " or concurrent update without locking support");
>>> @@ -1093,14 +1103,14 @@ rewrite:;
>>> the size is in units of gcov_type. */
>>>
>>> GCOV_LINKAGE unsigned
>>> -gcov_gcda_file_size (struct gcov_info *gi_ptr,
>>> - struct gcov_summary *sum)
>>> +gcov_gcda_file_size (struct gcov_info *gi_ptr)
>>> {
>>> unsigned size;
>>> const struct gcov_fn_info *fi_ptr;
>>> unsigned f_ix, t_ix, h_ix, h_cnt = 0;
>>> unsigned n_counts;
>>> const struct gcov_ctr_info *ci_ptr;
>>> + struct gcov_summary *sum = &this_program;
>>> const struct gcov_ctr_summary *csum;
>>>
>>> /* GCOV_DATA_MAGIC, GCOV_VERSION and time_stamp. */
>>> @@ -1181,13 +1191,14 @@ gcov_write_gcda_file (struct gcov_info *gi_ptr)
>>> ci_ptr = gfi_ptr->ctrs;
>>> for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
>>> {
>>> + gcov_type *c_ptr;
>>> if (!gi_ptr->merge[t_ix])
>>> continue;
>>>
>>> n_counts = ci_ptr->num;
>>> gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
>>> GCOV_TAG_COUNTER_LENGTH (n_counts));
>>> - gcov_type *c_ptr = ci_ptr->values;
>>> + c_ptr = ci_ptr->values;
>>> while (n_counts--)
>>> gcov_write_counter (*c_ptr++);
>>> ci_ptr++;
>>> @@ -1692,7 +1703,7 @@ __gcov_topn_value_profiler_body (gcov_type *counte
>>> {
>>> unsigned i, j;
>>> gcov_type *p, minv;
>>> - gcov_type* tmp_cnts
>>> + gcov_type* tmp_cnts
>>> = (gcov_type *)alloca (topn_val * sizeof(gcov_type));
>>>
>>> *num_eviction = 0;
>>> @@ -2050,15 +2061,20 @@ gcov_set_vfile (gcov_kernel_vfile *file)
>>> gcov_current_file = file;
>>> }
>>>
>>> +/* Init function before dumping the gcda file in kernel. */
>>> +
>>> +void
>>> +gcov_kernel_dump_gcov_init (void)
>>> +{
>>> + gcov_exit_init ();
>>> +}
>>> +
>>> /* Dump one entry in the gcov_info list (for one object) in kernel. */
>>>
>>> void
>>> gcov_kernel_dump_one_gcov (struct gcov_info *info)
>>> {
>>> gcc_assert (gcov_current_file);
>>> -
>>> - gcov_exit_init ();
>>> -
>>> gcov_dump_one_gcov (info);
>>> }
>>>
>>> Index: gcc/gcov-io.c
>>> ===================================================================
>>> --- gcc/gcov-io.c (revision 194562)
>>> +++ gcc/gcov-io.c (working copy)
>>> @@ -662,6 +662,30 @@ gcov_read_string (void)
>>> return (const char *) gcov_read_words (length);
>>> }
>>>
>>> +#ifdef __GCOV_KERNEL__
>>> +static const unsigned char __popcount_tab[256] =
>>> +{
>>> + 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
>>> + 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
>>> + 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
>>> + 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
>>> + 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
>>> + 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
>>> + 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
>>> + 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
>>> +};
>>> +
>>> +static int k_popcountll (long long x)
>>> +{
>>> + int i, ret = 0;
>>> +
>>> + for (i = 0; i < 8*sizeof(long long) ; i += 8)
>>> + ret += __popcount_tab[(x >> i) & 0xff];
>>> +
>>> + return ret;
>>> +}
>>> +#endif
>>> +
>>> GCOV_LINKAGE void
>>> gcov_read_summary (struct gcov_summary *summary)
>>> {
>>> @@ -683,7 +707,11 @@ gcov_read_summary (struct gcov_summary *summary)
>>> for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++)
>>> {
>>> histo_bitvector[bv_ix] = gcov_read_unsigned ();
>>> +#ifndef __GCOV_KERNEL__
>>> h_cnt += __builtin_popcountll (histo_bitvector[bv_ix]);
>>> +#else
>>> + h_cnt += k_popcountll (histo_bitvector[bv_ix]);
>>> +#endif
>>
>> Is the issue here that __builtin_popcountll is not available? I just
>> committed a fix to trunk to deal with a similar issue, can you see if
>> this would address the problem here too?
>>
>> http://gcc.gnu.org/ml/gcc-bugs/2012-12/msg01976.html
>>
>> Thanks,
>> Teresa
>>
>>> }
>>> bv_ix = 0;
>>> h_ix = 0;
>>> @@ -1137,7 +1165,6 @@ kernel_file_fclose (gcov_kernel_vfile *fp)
>>> long
>>> kernel_file_ftell (gcov_kernel_vfile *fp)
>>> {
>>> - gcc_assert (0); /* should not reach here */
>>> return 0;
>>> }
>>>
>>> @@ -1192,8 +1219,9 @@ kernel_file_fwrite (const void *ptr, size_t size,
>>> if (vsize <= vpos)
>>> {
>>> printk (KERN_ERR
>>> - "GCOV_KERNEL: something wrong: vbuf=%p vsize=%u vpos=%u\n",
>>> - vbuf, vsize, vpos);
>>> + "GCOV_KERNEL: something wrong in file %s: vbuf=%p vsize=%u"
>>> + " vpos=%u\n",
>>> + fp->info->filename, vbuf, vsize, vpos);
>>> return 0;
>>> }
>>> len = vsize - vpos;
>>> @@ -1207,8 +1235,9 @@ kernel_file_fwrite (const void *ptr, size_t size,
>>>
>>> if (len != nitems)
>>> printk (KERN_ERR
>>> - "GCOV_KERNEL: something wrong: size=%lu nitems=%lu ret=%d\n",
>>> - size, nitems, len);
>>> + "GCOV_KERNEL: something wrong in file %s: size=%lu nitems=%lu"
>>> + " ret=%d, vsize=%u vpos=%u \n",
>>> + fp->info->filename, size, nitems, len, vsize, vpos);
>>> return len;
>>> }
>>>
>>> Index: gcc/gcov-io.h
>>> ===================================================================
>>> --- gcc/gcov-io.h (revision 194562)
>>> +++ gcc/gcov-io.h (working copy)
>>> @@ -300,6 +300,14 @@ typedef unsigned gcov_type_unsigned __attribute__
>>>
>>> #endif /* BITS_PER_UNIT == 8 */
>>>
>>> +#if LONG_LONG_TYPE_SIZE > 32
>>> +#define GCOV_TYPE_SYNC_FETCH_AND_ADD_FN __sync_fetch_and_add_8
>>> +#define GCOV_TYPE_SYNC_FETCH_AND_ADD BUILT_IN_SYNC_FETCH_AND_ADD_8
>>> +#else
>>> +#define GCOV_TYPE_SYNC_FETCH_AND_ADD_FN __sync_fetch_and_add_4
>>> +#define GCOV_TYPE_SYNC_FETCH_AND_ADD BUILT_IN_SYNC_FETCH_AND_ADD_4
>>> +#endif
>>> +
>>> #undef EXTRACT_MODULE_ID_FROM_GLOBAL_ID
>>> #undef EXTRACT_FUNC_ID_FROM_GLOBAL_ID
>>> #undef GEN_FUNC_GLOBAL_ID
>>> @@ -322,6 +330,18 @@ typedef unsigned gcov_type_unsigned __attribute__
>>> typedef unsigned gcov_unsigned_t;
>>> typedef unsigned gcov_position_t;
>>>
>>> +#if LONG_LONG_TYPE_SIZE > 32
>>> +#define GCOV_TYPE_SYNC_FETCH_AND_ADD_FN __sync_fetch_and_add_8
>>> +#define GCOV_TYPE_SYNC_FETCH_AND_ADD BUILT_IN_SYNC_FETCH_AND_ADD_8
>>> +#else
>>> +#define GCOV_TYPE_SYNC_FETCH_AND_ADD_FN __sync_fetch_and_add_4
>>> +#define GCOV_TYPE_SYNC_FETCH_AND_ADD BUILT_IN_SYNC_FETCH_AND_ADD_4
>>> +#endif
>>> +#define PROFILE_GEN_EDGE_ATOMIC (flag_profile_gen_atomic == 1 || \
>>> + flag_profile_gen_atomic == 3)
>>> +#define PROFILE_GEN_VALUE_ATOMIC (flag_profile_gen_atomic == 2 || \
>>> + flag_profile_gen_atomic == 3)
>>> +
>>> /* gcov_type is typedef'd elsewhere for the compiler */
>>> #if IN_GCOV
>>> #define GCOV_LINKAGE static
>>> @@ -781,8 +801,8 @@ struct gcov_info
>>> unused) */
>>>
>>> unsigned n_functions; /* number of functions */
>>> - const struct gcov_fn_info *const *functions; /* pointer to pointers
>>> - to function information */
>>> + const struct gcov_fn_info **functions; /* pointer to pointers
>>> + to function information */
>>> };
>>>
>>> /* Information about a single imported module. */
>>> @@ -988,8 +1008,7 @@ static void gcov_rewrite (void);
>>> GCOV_LINKAGE void gcov_seek (gcov_position_t /*position*/) ATTRIBUTE_HIDDEN;
>>> GCOV_LINKAGE void gcov_truncate (void) ATTRIBUTE_HIDDEN;
>>> GCOV_LINKAGE gcov_unsigned_t gcov_string_length (const char *) ATTRIBUTE_HIDDEN;
>>> -GCOV_LINKAGE unsigned gcov_gcda_file_size (struct gcov_info *,
>>> - struct gcov_summary *);
>>> +GCOV_LINKAGE unsigned gcov_gcda_file_size (struct gcov_info *);
>>> #else
>>> /* Available outside libgcov */
>>> GCOV_LINKAGE void gcov_sync (gcov_position_t /*base*/,
>>>
>>> --
>>> This patch is available for review at http://codereview.appspot.com/6968046
>>
>>
>>
>> --
>> Teresa Johnson | Software Engineer | tejohnson@google.com | 408-460-2413
--
Teresa Johnson | Software Engineer | tejohnson@google.com | 408-460-2413