On Fri, Dec 21, 2012 at 9:52 AM, Xinliang David Li <davi...@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 <tejohn...@google.com> wrote: >> On Wed, Dec 19, 2012 at 12:11 PM, Rong Xu <x...@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 <x...@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 | tejohn...@google.com | 408-460-2413 -- Teresa Johnson | Software Engineer | tejohn...@google.com | 408-460-2413