blob: 613c1f429da8bd42832a0bf1758b58031e677835 [file] [log] [blame]
Andrew Hsieh02075082012-03-06 14:06:15 -08001/* Routines required for instrumenting a program. */
2/* Compile this one with gcc. */
3/* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
4 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009, 2010
5 Free Software Foundation, Inc.
6
7This file is part of GCC.
8
9GCC is free software; you can redistribute it and/or modify it under
10the terms of the GNU General Public License as published by the Free
11Software Foundation; either version 3, or (at your option) any later
12version.
13
14GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15WARRANTY; without even the implied warranty of MERCHANTABILITY or
16FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17for more details.
18
19Under Section 7 of GPL version 3, you are granted additional
20permissions described in the GCC Runtime Library Exception, version
213.1, as published by the Free Software Foundation.
22
23You should have received a copy of the GNU General Public License and
24a copy of the GCC Runtime Library Exception along with this program;
25see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
26<http://www.gnu.org/licenses/>. */
27
28/* Assume compiling for Linux Kernel if __KERNEL__ is defined. */
29#ifdef __KERNEL__
30 /* Define MACROs to be used by kernel compilation. */
31# define L_gcov
32# define L_gcov_interval_profiler
33# define L_gcov_pow2_profiler
34# define L_gcov_one_value_profiler
35# define L_gcov_indirect_call_profiler
36# define L_gcov_average_profiler
37# define L_gcov_ior_profiler
38
39# define HAVE_CC_TLS 0
40# define __GCOV_KERNEL__
41
42# define IN_LIBGCOV 1
43# define IN_GCOV 0
44#else /* __KERNEL__ */
45#include "tconfig.h"
46#include "tsystem.h"
47#include "coretypes.h"
48#include "tm.h"
49#endif /* __KERNEL__ */
50
51#if 1
52#define THREAD_PREFIX __thread
53#else
54#define THREAD_PREFIX
55#endif
56
57#ifndef __GCOV_KERNEL__
58#if defined(inhibit_libc)
59#define IN_LIBGCOV (-1)
60#else
61#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
62#include <stdio.h>
63#define IN_LIBGCOV 1
64#if defined(L_gcov)
65#define GCOV_LINKAGE /* nothing */
66#endif
67#endif
68#endif /* __GCOV_KERNEL__ */
69
70#include "gcov-io.h"
71
72#if defined(inhibit_libc)
73/* If libc and its header files are not available, provide dummy functions. */
74
75#ifdef L_gcov
76void __gcov_init (struct gcov_info *p __attribute__ ((unused))) {}
77void __gcov_flush (void) {}
78#endif
79
80#ifdef L_gcov_merge_add
81void __gcov_merge_add (gcov_type *counters __attribute__ ((unused)),
82 unsigned n_counters __attribute__ ((unused))) {}
83#endif
84
85#ifdef L_gcov_merge_single
86void __gcov_merge_single (gcov_type *counters __attribute__ ((unused)),
87 unsigned n_counters __attribute__ ((unused))) {}
88#endif
89
90#ifdef L_gcov_merge_delta
91void __gcov_merge_delta (gcov_type *counters __attribute__ ((unused)),
92 unsigned n_counters __attribute__ ((unused))) {}
93#endif
94
95#else
96
97#ifndef __GCOV_KERNEL__
98#include <string.h>
99#if GCOV_LOCKED
100#include <fcntl.h>
101#include <errno.h>
102#include <sys/stat.h>
103#endif
104#endif /* __GCOV_KERNEL__ */
105
106#ifdef L_gcov
107#include "gcov-io.c"
108
109/* Utility function for outputing errors. */
110static int
111gcov_error (const char *fmt, ...)
112{
113 int ret;
114 va_list argp;
115 va_start (argp, fmt);
116#ifdef __GCOV_KERNEL__
117 ret = vprintk (fmt, argp);
118#else
119 ret = vfprintf (stderr, fmt, argp);
120#endif
121 va_end (argp);
122 return ret;
123}
124
125#ifndef __GCOV_KERNEL__
126/* Emitted in coverage.c. */
127extern char * __gcov_pmu_profile_filename;
128extern char * __gcov_pmu_profile_options;
129extern gcov_unsigned_t __gcov_pmu_top_n_address;
130
131/* Sampling rate. */
132extern gcov_unsigned_t __gcov_sampling_rate;
133static int gcov_sampling_rate_initialized = 0;
134void __gcov_set_sampling_rate (unsigned int rate);
135
136/* Set sampling rate to RATE. */
137
138void __gcov_set_sampling_rate (unsigned int rate)
139{
140 __gcov_sampling_rate = rate;
141}
142
143/* Per thread sample counter. */
144THREAD_PREFIX gcov_unsigned_t __gcov_sample_counter = 0;
145
146/* Chain of per-object gcov structures. */
147extern struct gcov_info *__gcov_list;
148
149/* Size of the longest file name. */
150static size_t gcov_max_filename = 0;
151#endif /* __GCOV_KERNEL__ */
152
153/* Unique identifier assigned to each module (object file). */
154static gcov_unsigned_t gcov_cur_module_id = 0;
155
156/* Pointer to the direct-call counters (per call-site counters).
157 Initialized by the caller. */
158THREAD_PREFIX gcov_type *__gcov_direct_call_counters ATTRIBUTE_HIDDEN;
159
160/* Direct call callee address. */
161THREAD_PREFIX void *__gcov_direct_call_callee ATTRIBUTE_HIDDEN;
162
163/* Pointer to the indirect-call counters (per call-site counters).
164 Initialized by the caller. */
165THREAD_PREFIX gcov_type *__gcov_indirect_call_topn_counters ATTRIBUTE_HIDDEN;
166
167/* Indirect call callee address. */
168THREAD_PREFIX void *__gcov_indirect_call_topn_callee ATTRIBUTE_HIDDEN;
169
170/* A program checksum allows us to distinguish program data for an
171 object file included in multiple programs. */
172static gcov_unsigned_t gcov_crc32;
173
174/* Dynamic call graph build and form module groups. */
175void __gcov_compute_module_groups (void) ATTRIBUTE_HIDDEN;
176void __gcov_finalize_dyn_callgraph (void) ATTRIBUTE_HIDDEN;
177
178/* Profile summary for the gdca file, used in sanity check? */
179static struct gcov_summary all;
180
181/* Profile summary for this program in current exeuction. */
182static struct gcov_summary this_program;
183
184/* Profile summary for this object in current execuction. */
185static struct gcov_summary this_object;
186
187/* Merged profile summary for this program. */
188static struct gcov_summary program;
189
190/* Merged profile summary for this object. */
191static struct gcov_summary object;
192
193/* Record the position of summary info. */
194static gcov_position_t summary_pos = 0;
195
196/* Record the postion of eof. */
197static gcov_position_t eof_pos = 0;
198
199/* Number of chars in prefix to be stripped. */
200static int gcov_prefix_strip = 0;
201
202/* The length of path prefix. */
203static size_t prefix_length = 0;
204
205/* gi_filename is current object filename.
206 gi_filename_up points to the stripped filename. */
207static char *gi_filename, *gi_filename_up;
208
209static int gcov_open_by_filename (char * gi_filename);
210static int gcov_exit_init (void);
211static void gcov_dump_one_gcov (struct gcov_info *gi_ptr);
212
213/* Make sure path component of the given FILENAME exists, create
214 missing directories. FILENAME must be writable.
215 Returns zero on success, or -1 if an error occurred. */
216
217static int
218create_file_directory (char *filename)
219{
220#if !defined(TARGET_POSIX_IO) && !defined(_WIN32)
221 (void) filename;
222 return -1;
223#else
224 char *s;
225
226 s = filename;
227
228 if (HAS_DRIVE_SPEC(s))
229 s += 2;
230 if (IS_DIR_SEPARATOR(*s))
231 ++s;
232 for (; *s != '\0'; s++)
233 if (IS_DIR_SEPARATOR(*s))
234 {
235 char sep = *s;
236 *s = '\0';
237
238 /* Try to make directory if it doesn't already exist. */
239 if (access (filename, F_OK) == -1
240#ifdef TARGET_POSIX_IO
241 && mkdir (filename, 0755) == -1
242#else
243 && mkdir (filename) == -1
244#endif
245 /* The directory might have been made by another process. */
246 && errno != EEXIST)
247 {
248 fprintf (stderr, "profiling:%s:Cannot create directory\n",
249 filename);
250 *s = sep;
251 return -1;
252 };
253
254 *s = sep;
255 };
256 return 0;
257#endif
258}
259
260/* Open a file with the specified name. */
261
262static int
263gcov_open_by_filename (char * gi_filename)
264{
265 if (!gcov_open (gi_filename))
266 {
267 /* Open failed likely due to missed directory.
268 Create directory and retry to open file. */
269 if (create_file_directory (gi_filename))
270 {
271 gcov_error ("profiling:%s:Skip\n", gi_filename);
272 return -1;
273 }
274 if (!gcov_open (gi_filename))
275 {
276 gcov_error ("profiling:%s:Cannot open\n", gi_filename);
277 return -1;
278 }
279 }
280 return 0;
281}
282
283
284/* Determine whether a counter is active. */
285
286static inline int
287gcov_counter_active (const struct gcov_info *info, unsigned int type)
288{
289 return (1 << type) & info->ctr_mask;
290}
291
292#ifndef __GCOV_KERNEL__
293/* Check if VERSION of the info block PTR matches libgcov one.
294 Return 1 on success, or zero in case of versions mismatch.
295 If FILENAME is not NULL, its value used for reporting purposes
296 instead of value from the info block. */
297
298static int
299gcov_version (struct gcov_info *ptr __attribute__ ((unused)),
300 gcov_unsigned_t version, const char *filename)
301{
302 if (version != GCOV_VERSION)
303 {
304 char v[4], e[4];
305
306 GCOV_UNSIGNED2STRING (v, version);
307 GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
308
309 if (filename)
310 gcov_error ("profiling:%s:Version mismatch - expected %.4s got %.4s\n",
311 filename, e, v);
312 else
313 gcov_error ("profiling:Version mismatch - expected %.4s got %.4s\n", e, v);
314 return 0;
315 }
316 return 1;
317}
318
319#define GCOV_GET_FILENAME gcov_strip_leading_dirs
320
321/* Strip GCOV_PREFIX_STRIP levels of leading '/' from FILENAME and
322 put the result into GI_FILENAME_UP. */
323
324static void
325gcov_strip_leading_dirs (int prefix_length, int gcov_prefix_strip,
326 const char *filename, char *gi_filename_up)
327{
328 /* Avoid to add multiple drive letters into combined path. */
329 if (prefix_length != 0 && HAS_DRIVE_SPEC(filename))
330 filename += 2;
331
332 /* Build relocated filename, stripping off leading
333 directories from the initial filename if requested. */
334 if (gcov_prefix_strip > 0)
335 {
336 int level = 0;
337 const char *s = filename;
338 if (IS_DIR_SEPARATOR(*s))
339 ++s;
340
341 /* Skip selected directory levels. */
342 for (; (*s != '\0') && (level < gcov_prefix_strip); s++)
343 if (IS_DIR_SEPARATOR(*s))
344 {
345 filename = s;
346 level++;
347 }
348 }
349 /* Update complete filename with stripped original. */
350 if (prefix_length != 0 && !IS_DIR_SEPARATOR (*filename))
351 {
352 /* If prefix is given, add directory separator. */
353 strcpy (gi_filename_up, "/");
354 strcpy (gi_filename_up + 1, filename);
355 }
356 else
357 strcpy (gi_filename_up, filename);
358}
359
360/* This function allocates the space to store current file name. */
361
362static void
363gcov_alloc_filename (void)
364{
365 /* Get file name relocation prefix. Non-absolute values are ignored. */
366 char *gcov_prefix = 0;
367
368 prefix_length = 0;
369 gcov_prefix_strip = 0;
370
371 {
372 /* Check if the level of dirs to strip off specified. */
373 char *tmp = getenv ("GCOV_PREFIX_STRIP");
374 if (tmp)
375 {
376 gcov_prefix_strip = atoi (tmp);
377 /* Do not consider negative values. */
378 if (gcov_prefix_strip < 0)
379 gcov_prefix_strip = 0;
380 }
381 }
382 /* Get file name relocation prefix. Non-absolute values are ignored. */
383 gcov_prefix = getenv ("GCOV_PREFIX");
384 if (gcov_prefix)
385 {
386 prefix_length = strlen(gcov_prefix);
387
388 /* Remove an unnecessary trailing '/' */
389 if (IS_DIR_SEPARATOR (gcov_prefix[prefix_length - 1]))
390 prefix_length--;
391 }
392 else
393 prefix_length = 0;
394
395 /* If no prefix was specified and a prefix stip, then we assume
396 relative. */
397 if (gcov_prefix_strip != 0 && prefix_length == 0)
398 {
399 gcov_prefix = ".";
400 prefix_length = 1;
401 }
402
403 /* Allocate and initialize the filename scratch space. */
404 gi_filename = (char *) malloc (prefix_length + gcov_max_filename + 2);
405 if (prefix_length)
406 memcpy (gi_filename, gcov_prefix, prefix_length);
407
408 gi_filename_up = gi_filename + prefix_length;
409}
410
411/* Stop the pmu profiler and dump pmu profile info into the global file. */
412
413static void
414pmu_profile_stop (void)
415{
416 const char *pmu_profile_filename = __gcov_pmu_profile_filename;
417 const char *pmu_options = __gcov_pmu_profile_options;
418 size_t filename_length;
419 int gcda_error;
420
421 if (!pmu_profile_filename || !pmu_options)
422 return;
423
424 __gcov_stop_pmu_profiler ();
425
426 filename_length = strlen (pmu_profile_filename);
427 if (filename_length > gcov_max_filename)
428 gcov_max_filename = filename_length;
429 /* Allocate and initialize the filename scratch space. */
430 gcov_alloc_filename ();
431 GCOV_GET_FILENAME (prefix_length, gcov_prefix_strip, pmu_profile_filename,
432 gi_filename_up);
433 /* Open the gcda file for writing. We don't support merge yet. */
434 gcda_error = gcov_open_by_filename (gi_filename);
435 __gcov_end_pmu_profiler (gcda_error);
436 if ((gcda_error = gcov_close ()))
437 gcov_error (gcda_error < 0 ? "pmu_profile_stop:%s:Overflow writing\n" :
438 "pmu_profile_stop:%s:Error writing\n",
439 gi_filename);
440}
441
442/* Sort N entries in VALUE_ARRAY in descending order.
443 Each entry in VALUE_ARRAY has two values. The sorting
444 is based on the second value. */
445
446GCOV_LINKAGE void
447gcov_sort_n_vals (gcov_type *value_array, int n)
448{
449 int j, k;
450 for (j = 2; j < n; j += 2)
451 {
452 gcov_type cur_ent[2];
453 cur_ent[0] = value_array[j];
454 cur_ent[1] = value_array[j + 1];
455 k = j - 2;
456 while (k >= 0 && value_array[k + 1] < cur_ent[1])
457 {
458 value_array[k + 2] = value_array[k];
459 value_array[k + 3] = value_array[k+1];
460 k -= 2;
461 }
462 value_array[k + 2] = cur_ent[0];
463 value_array[k + 3] = cur_ent[1];
464 }
465}
466
467/* Sort the profile counters for all indirect call sites. Counters
468 for each call site are allocated in array COUNTERS. */
469
470static void
471gcov_sort_icall_topn_counter (const struct gcov_ctr_info *counters)
472{
473 int i;
474 gcov_type *values;
475 int n = counters->num;
476 gcc_assert (!(n % GCOV_ICALL_TOPN_NCOUNTS));
477
478 values = counters->values;
479
480 for (i = 0; i < n; i += GCOV_ICALL_TOPN_NCOUNTS)
481 {
482 gcov_type *value_array = &values[i + 1];
483 gcov_sort_n_vals (value_array, GCOV_ICALL_TOPN_NCOUNTS - 1);
484 }
485}
486
487/* Write imported files (auxiliary modules) for primary module GI_PTR
488 into file GI_FILENAME. */
489
490static void
491gcov_write_import_file (char *gi_filename, struct gcov_info *gi_ptr)
492{
493 char *gi_imports_filename;
494 const char *gcov_suffix;
495 FILE *imports_file;
496 size_t prefix_length, suffix_length;
497
498 gcov_suffix = getenv ("GCOV_IMPORTS_SUFFIX");
499 if (!gcov_suffix || !strlen (gcov_suffix))
500 gcov_suffix = ".imports";
501 suffix_length = strlen (gcov_suffix);
502 prefix_length = strlen (gi_filename);
503 gi_imports_filename = (char *) alloca (prefix_length + suffix_length + 1);
504 memset (gi_imports_filename, 0, prefix_length + suffix_length + 1);
505 memcpy (gi_imports_filename, gi_filename, prefix_length);
506 memcpy (gi_imports_filename + prefix_length, gcov_suffix, suffix_length);
507 imports_file = fopen (gi_imports_filename, "w");
508 if (imports_file)
509 {
510 const struct dyn_imp_mod **imp_mods;
511 unsigned i, imp_len;
512 imp_mods = gcov_get_sorted_import_module_array (gi_ptr, &imp_len);
513 if (imp_mods)
514 {
515 for (i = 0; i < imp_len; i++)
516 {
517 fprintf (imports_file, "%s\n",
518 imp_mods[i]->imp_mod->mod_info->source_filename);
519 fprintf (imports_file, "%s%s\n",
520 imp_mods[i]->imp_mod->mod_info->da_filename, GCOV_DATA_SUFFIX);
521 }
522 free (imp_mods);
523 }
524 fclose (imports_file);
525 }
526}
527
528static void
529gcov_dump_module_info (void)
530{
531 struct gcov_info *gi_ptr;
532
533 __gcov_compute_module_groups ();
534
535 /* Now write out module group info. */
536 for (gi_ptr = __gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
537 {
538 int error;
539
540 GCOV_GET_FILENAME (prefix_length, gcov_prefix_strip, gi_ptr->filename,
541 gi_filename_up);
542 error = gcov_open_by_filename (gi_filename);
543 if (error != 0)
544 continue;
545
546 /* Overwrite the zero word at the of the file. */
547 gcov_rewrite ();
548 gcov_seek (gi_ptr->eof_pos);
549
550 gcov_write_module_infos (gi_ptr);
551 gcov_truncate ();
552
553 if ((error = gcov_close ()))
554 gcov_error (error < 0 ? "profiling:%s:Overflow writing\n" :
555 "profiling:%s:Error writing\n",
556 gi_filename);
557 gcov_write_import_file (gi_filename, gi_ptr);
558 }
559 __gcov_finalize_dyn_callgraph ();
560}
561
562/* Dump the coverage counts. We merge with existing counts when
563 possible, to avoid growing the .da files ad infinitum. We use this
564 program's checksum to make sure we only accumulate whole program
565 statistics to the correct summary. An object file might be embedded
566 in two separate programs, and we must keep the two program
567 summaries separate. */
568
569static void
570gcov_exit (void)
571{
572 struct gcov_info *gi_ptr;
573 int dump_module_info;
574
575 /* Stop and write the PMU profile data into the global file. */
576 pmu_profile_stop ();
577
578 dump_module_info = gcov_exit_init ();
579
580 for (gi_ptr = __gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
581 gcov_dump_one_gcov (gi_ptr);
582
583 if (dump_module_info)
584 gcov_dump_module_info ();
585
586 free (gi_filename);
587}
588
589/* Add a new object file onto the bb chain. Invoked automatically
590 when running an object file's global ctors. */
591
592void
593__gcov_init (struct gcov_info *info)
594{
595 if (!gcov_sampling_rate_initialized)
596 {
597 const char* env_value_str = getenv ("GCOV_SAMPLING_RATE");
598 if (env_value_str)
599 {
600 int env_value_int = atoi(env_value_str);
601 if (env_value_int >= 1)
602 __gcov_sampling_rate = env_value_int;
603 }
604 gcov_sampling_rate_initialized = 1;
605 }
606
607 if (!info->version)
608 return;
609
610 if (gcov_version (info, info->version, 0))
611 {
612 const char *ptr = info->filename;
613 gcov_unsigned_t crc32 = gcov_crc32;
614 size_t filename_length = strlen (info->filename);
615 struct gcov_pmu_info pmu_info;
616
617 /* Refresh the longest file name information. */
618 if (filename_length > gcov_max_filename)
619 gcov_max_filename = filename_length;
620
621 /* Initialize the pmu profiler. */
622 pmu_info.pmu_profile_filename = __gcov_pmu_profile_filename;
623 pmu_info.pmu_tool = __gcov_pmu_profile_options;
624 pmu_info.pmu_top_n_address = __gcov_pmu_top_n_address;
625 __gcov_init_pmu_profiler (&pmu_info);
626 if (pmu_info.pmu_profile_filename)
627 {
628 /* Refresh the longest file name information. */
629 filename_length = strlen (pmu_info.pmu_profile_filename);
630 if (filename_length > gcov_max_filename)
631 gcov_max_filename = filename_length;
632 }
633
634 /* Assign the module ID (starting at 1). */
635 info->mod_info->ident = (++gcov_cur_module_id);
636 gcc_assert (EXTRACT_MODULE_ID_FROM_GLOBAL_ID (GEN_FUNC_GLOBAL_ID (
637 info->mod_info->ident, 0))
638 == info->mod_info->ident);
639
640 do
641 {
642 unsigned ix;
643 gcov_unsigned_t value = *ptr << 24;
644
645 for (ix = 8; ix--; value <<= 1)
646 {
647 gcov_unsigned_t feedback;
648
649 feedback = (value ^ crc32) & 0x80000000 ? 0x04c11db7 : 0;
650 crc32 <<= 1;
651 crc32 ^= feedback;
652 }
653 } while (*ptr++);
654
655 gcov_crc32 = crc32;
656
657 if (!__gcov_list)
658 {
659 atexit (gcov_exit);
660 /* Start pmu profiler. */
661 __gcov_start_pmu_profiler ();
662 }
663
664 info->next = __gcov_list;
665 __gcov_list = info;
666 }
667 info->version = 0;
668}
669
670/* Called before fork or exec - write out profile information gathered so
671 far and reset it to zero. This avoids duplication or loss of the
672 profile information gathered so far. */
673
674void
675__gcov_flush (void)
676{
677 const struct gcov_info *gi_ptr;
678
679 __gcov_stop_pmu_profiler ();
680 gcov_exit ();
681 for (gi_ptr = __gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
682 {
683 unsigned t_ix;
684 const struct gcov_ctr_info *ci_ptr;
685
686 for (t_ix = 0, ci_ptr = gi_ptr->counts; t_ix != GCOV_COUNTERS; t_ix++)
687 if (gcov_counter_active (gi_ptr, t_ix))
688 {
689 memset (ci_ptr->values, 0, sizeof (gcov_type) * ci_ptr->num);
690 ci_ptr++;
691 }
692 }
693 __gcov_start_pmu_profiler ();
694}
695
696#else /* __GCOV_KERNEL__ */
697
698#define GCOV_GET_FILENAME gcov_get_filename
699
700/* Copy the filename to the buffer. */
701
702static inline void
703gcov_get_filename (int prefix_length __attribute__ ((unused)),
704 int gcov_prefix_strip __attribute__ ((unused)),
705 const char *filename, char *gi_filename_up)
706{
707 strcpy (gi_filename_up, filename);
708}
709
710/* Sort the profile counters for all indirect call sites. Counters
711 for each call site are allocated in array COUNTERS. */
712
713static void
714gcov_sort_icall_topn_counter (const struct gcov_ctr_info *counters)
715{
716 /* Empty */
717}
718
719/* Reserves a buffer to store the name of the file being processed. */
720static char _kernel_gi_filename[520];
721
722/* This function allocates the space to store current file name. */
723
724static void
725gcov_alloc_filename (void)
726{
727 prefix_length = 0;
728 gcov_prefix_strip = 0;
729 gi_filename = _kernel_gi_filename;
730 gi_filename_up = _kernel_gi_filename;
731}
732
733#endif /* __GCOV_KERNEL__ */
734
735/* Determine number of active counters in gcov_info INFO,
736 the counter arrays are stored in VALUES if the coming
737 value of VALUES !=0. If FLAG_SORT_ICALL_TOPN_COUNTER !=0,
738 the icall_topn_counter in INFO will be sorted.
739 Return: the number of active counter types. */
740
741static unsigned int
742gcov_counter_array (const struct gcov_info *info,
743 gcov_type *values[GCOV_COUNTERS],
744 int flag_sort_icall_topn_counter)
745{
746 unsigned int i;
747 unsigned int result = 0;
748
749 for (i = 0; i < GCOV_COUNTERS; i++) {
750 if (gcov_counter_active (info, i))
751 {
752 if (values)
753 values[result] = info->counts[result].values;
754 if (flag_sort_icall_topn_counter &&
755 (i == GCOV_COUNTER_ICALL_TOPNV))
756 gcov_sort_icall_topn_counter (&info->counts[result]);
757 result++;
758 }
759 }
760 return result;
761}
762
763/* Compute object summary recored in gcov_info INFO. The result is
764 stored in OBJ_SUM. Note that the caller is responsible for
765 zeroing out OBJ_SUM, otherwise the summary is accumulated. */
766
767static void
768gcov_object_summary (struct gcov_info *info,
769 struct gcov_summary *obj_sum)
770{
771 const struct gcov_ctr_info *ci_ptr;
772 struct gcov_ctr_summary *cs_ptr;
773 gcov_unsigned_t c_num;
774 unsigned t_ix;
775
776 /* Totals for this object file. */
777 ci_ptr = info->counts;
778 for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
779 {
780 if (!gcov_counter_active (info, t_ix))
781 continue;
782
783 cs_ptr = &(obj_sum->ctrs[t_ix]);
784 cs_ptr->num += ci_ptr->num;
785 for (c_num = 0; c_num < ci_ptr->num; c_num++)
786 {
787 cs_ptr->sum_all += ci_ptr->values[c_num];
788 if (cs_ptr->run_max < ci_ptr->values[c_num])
789 cs_ptr->run_max = ci_ptr->values[c_num];
790 }
791 ci_ptr++;
792 }
793}
794
795/* Merge with existing gcda file in the same directory to avoid
796 excessive growthe of the files. */
797
798static int
799gcov_merge_gcda_file (struct gcov_info *info,
800 gcov_type *values[GCOV_COUNTERS],
801 unsigned fi_stride)
802{
803 struct gcov_ctr_summary *cs_obj, *cs_tobj, *cs_prg, *cs_tprg, *cs_all;
804 unsigned t_ix, f_ix;
805
806#ifndef __GCOV_KERNEL__
807 const struct gcov_fn_info *fi_ptr;
808 unsigned c_ix, n_counts;
809 int error = 0;
810 gcov_unsigned_t tag, length;
811
812 eof_pos = 0;
813 summary_pos = 0;
814
815 tag = gcov_read_unsigned ();
816 if (tag)
817 {
818 /* Merge data from file. */
819 if (tag != GCOV_DATA_MAGIC)
820 {
821 gcov_error ("profiling:%s:Not a gcov data file\n", gi_filename);
822 goto read_fatal;
823 }
824 length = gcov_read_unsigned ();
825 if (!gcov_version (info, length, gi_filename))
826 goto read_fatal;
827
828 length = gcov_read_unsigned ();
829 if (length != info->stamp)
830 /* Read from a different compilation. Overwrite the file. */
831 goto rewrite;
832
833 /* Merge execution counts for each function. */
834 for (f_ix = 0; f_ix < info->n_functions; f_ix++)
835 {
836 fi_ptr = (const struct gcov_fn_info *)
837 ((const char *) info->functions + f_ix * fi_stride);
838 tag = gcov_read_unsigned ();
839 length = gcov_read_unsigned ();
840
841 /* Check function. */
842 if (tag != GCOV_TAG_FUNCTION
843 || length != GCOV_TAG_FUNCTION_LENGTH
844 || gcov_read_unsigned () != fi_ptr->ident
845 || gcov_read_unsigned () != fi_ptr->lineno_checksum
846 || gcov_read_unsigned () != fi_ptr->cfg_checksum)
847 goto read_mismatch;
848
849 c_ix = 0;
850 for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
851 {
852 gcov_merge_fn merge;
853
854 if (!((1 << t_ix) & info->ctr_mask))
855 continue;
856
857 n_counts = fi_ptr->n_ctrs[c_ix];
858 merge = info->counts[c_ix].merge;
859
860 tag = gcov_read_unsigned ();
861 length = gcov_read_unsigned ();
862 if (tag != GCOV_TAG_FOR_COUNTER (t_ix)
863 || length != GCOV_TAG_COUNTER_LENGTH (n_counts))
864 goto read_mismatch;
865 (*merge) (values[c_ix], n_counts);
866 values[c_ix] += n_counts;
867 c_ix++;
868 }
869 if ((error = gcov_is_error ()))
870 goto read_error;
871 }
872
873 f_ix = ~0u;
874 /* Check program & object summary. */
875 while (1)
876 {
877 int is_program;
878
879 eof_pos = gcov_position ();
880 tag = gcov_read_unsigned ();
881 if (!tag)
882 break;
883
884 length = gcov_read_unsigned ();
885 is_program = tag == GCOV_TAG_PROGRAM_SUMMARY;
886 if (length != GCOV_TAG_SUMMARY_LENGTH
887 || (!is_program && tag != GCOV_TAG_OBJECT_SUMMARY))
888 goto read_mismatch;
889 gcov_read_summary (is_program ? &program : &object);
890 if ((error = gcov_is_error ()))
891 goto read_error;
892 if (is_program && program.checksum == gcov_crc32)
893 {
894 summary_pos = eof_pos;
895 goto rewrite;
896 }
897 }
898 }
899
900 goto rewrite;
901
902read_error:;
903 gcov_error (error < 0 ? "profiling:%s:Overflow merging\n"
904 : "profiling:%s:Error merging\n", gi_filename);
905 goto read_fatal;
906
907#endif /* __GCOV_KERNEL__ */
908
909 goto rewrite;
910
911read_mismatch:;
912 gcov_error ("profiling:%s:Merge mismatch for %s\n", gi_filename,
913 f_ix + 1 ? "function" : "summaries");
914 goto read_fatal; /* work-around the compiler warning */
915
916read_fatal:;
917 gcov_close ();
918 return 1;
919
920rewrite:;
921 gcov_rewrite ();
922 if (!summary_pos)
923 memset (&program, 0, sizeof (program));
924
925 /* Merge the summaries. */
926 f_ix = ~0u;
927 for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
928 {
929 cs_obj = &object.ctrs[t_ix];
930 cs_tobj = &this_object.ctrs[t_ix];
931 cs_prg = &program.ctrs[t_ix];
932 cs_tprg = &this_program.ctrs[t_ix];
933 cs_all = &all.ctrs[t_ix];
934
935 if ((1 << t_ix) & info->ctr_mask)
936 {
937 if (!cs_obj->runs++)
938 cs_obj->num = cs_tobj->num;
939 else if (cs_obj->num != cs_tobj->num)
940 goto read_mismatch;
941 cs_obj->sum_all += cs_tobj->sum_all;
942 if (cs_obj->run_max < cs_tobj->run_max)
943 cs_obj->run_max = cs_tobj->run_max;
944 cs_obj->sum_max += cs_tobj->run_max;
945
946 if (!cs_prg->runs++)
947 cs_prg->num = cs_tprg->num;
948 else if (cs_prg->num != cs_tprg->num)
949 goto read_mismatch;
950 cs_prg->sum_all += cs_tprg->sum_all;
951 if (cs_prg->run_max < cs_tprg->run_max)
952 cs_prg->run_max = cs_tprg->run_max;
953 cs_prg->sum_max += cs_tprg->run_max;
954 }
955 else if (cs_obj->num || cs_prg->num)
956 goto read_mismatch;
957
958 if (!cs_all->runs && cs_prg->runs)
959 memcpy (cs_all, cs_prg, sizeof (*cs_all));
960 else if (!all.checksum
961 && (!GCOV_LOCKED || cs_all->runs == cs_prg->runs)
962 && memcmp (cs_all, cs_prg, sizeof (*cs_all)))
963 {
964 gcov_error ("profiling:%s:Invocation mismatch - "
965 "some data files may have been removed%s",
966 gi_filename, GCOV_LOCKED
967 ? "" : " or concurrent update without locking support");
968 all.checksum = ~0u;
969 }
970 }
971
972 return 0;
973}
974
975/* Calculate the function_info stride. This depends on the
976 number of counter types being measured.
977 NUM_COUNTER_TYPES is number of counter types recorded.
978 Return: the number of bytes for accessing next fn_info
979 (aligned to gcov_fn_info). */
980
981static unsigned
982gcov_compute_fi_stride (unsigned num_counter_types)
983{
984 unsigned fi_stride;
985
986 fi_stride = offsetof (struct gcov_fn_info, n_ctrs) +
987 num_counter_types * sizeof (unsigned);
988 if (__alignof__ (struct gcov_fn_info) > sizeof (unsigned))
989 {
990 fi_stride += __alignof__ (struct gcov_fn_info) - 1;
991 fi_stride &= ~(__alignof__ (struct gcov_fn_info) - 1);
992 }
993 return fi_stride;
994}
995
996/* This function returns the size of gcda file to be written. Note
997 the size is in units of gcov_type. */
998
999GCOV_LINKAGE unsigned
1000gcov_gcda_file_size (struct gcov_info *gi_ptr)
1001{
1002 unsigned size;
1003 const struct gcov_fn_info *fi_ptr;
1004 unsigned f_ix, t_ix, c_ix;
1005 unsigned n_counts;
1006 unsigned fi_stride;
1007 gcov_type *values[GCOV_COUNTERS];
1008
1009 c_ix = gcov_counter_array (gi_ptr, values, 0);
1010 fi_stride = gcov_compute_fi_stride (c_ix);
1011
1012 /* GCOV_DATA_MAGIC, GCOV_VERSION and time_stamp. */
1013 size = 3;
1014
1015 /* size for each function. */
1016 for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++)
1017 {
1018 fi_ptr = (const struct gcov_fn_info *)
1019 ((const char *) gi_ptr->functions + f_ix * fi_stride);
1020
1021 size += 2 /* tag_length itself */
1022 + GCOV_TAG_FUNCTION_LENGTH; /* ident, lineno_cksum, cfg_cksm */
1023
1024 c_ix = 0;
1025 for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
1026 {
1027 if (!((1 << t_ix) & gi_ptr->ctr_mask))
1028 continue;
1029
1030 n_counts = fi_ptr->n_ctrs[c_ix];
1031 size += 2 + GCOV_TAG_COUNTER_LENGTH (n_counts);
1032 c_ix++;
1033 }
1034 }
1035
1036 /* Object summary. */
1037 size += 2 + GCOV_TAG_SUMMARY_LENGTH;
1038
1039 /* Program summary. */
1040 size += 2 + GCOV_TAG_SUMMARY_LENGTH;
1041
1042 size += 1;
1043
1044 return size*4;
1045}
1046
1047/* Write profile data (including summary and module grouping information,
1048 if available, to file. */
1049
1050static void
1051gcov_write_gcda_file (struct gcov_info *gi_ptr,
1052 unsigned fi_stride)
1053{
1054 const struct gcov_fn_info *fi_ptr;
1055 gcov_type *values[GCOV_COUNTERS];
1056 unsigned t_ix, c_ix, f_ix, n_counts;
1057 int error = 0;
1058
1059 /* Write out the data. */
1060 gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION);
1061 gcov_write_unsigned (gi_ptr->stamp);
1062
1063 gcov_counter_array (gi_ptr, values, 0);
1064
1065 /* Write execution counts for each function. */
1066 for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++)
1067 {
1068 fi_ptr = (const struct gcov_fn_info *)
1069 ((const char *) gi_ptr->functions + f_ix * fi_stride);
1070
1071 /* Announce function. */
1072 gcov_write_tag_length (GCOV_TAG_FUNCTION, GCOV_TAG_FUNCTION_LENGTH);
1073 gcov_write_unsigned (fi_ptr->ident);
1074 gcov_write_unsigned (fi_ptr->lineno_checksum);
1075 gcov_write_unsigned (fi_ptr->cfg_checksum);
1076
1077 c_ix = 0;
1078 for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
1079 {
1080 gcov_type *c_ptr;
1081
1082 if (!((1 << t_ix) & gi_ptr->ctr_mask))
1083 continue;
1084
1085 n_counts = fi_ptr->n_ctrs[c_ix];
1086
1087 gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
1088 GCOV_TAG_COUNTER_LENGTH (n_counts));
1089 c_ptr = values[c_ix];
1090 while (n_counts--)
1091 gcov_write_counter (*c_ptr++);
1092
1093 values[c_ix] = c_ptr;
1094 c_ix++;
1095 }
1096 }
1097
1098 /* Object file summary. */
1099 gcov_write_summary (GCOV_TAG_OBJECT_SUMMARY, &object);
1100
1101 /* Generate whole program statistics. */
1102 program.checksum = gcov_crc32;
1103 if (eof_pos)
1104 gcov_seek (eof_pos);
1105 gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, &program);
1106 if (!summary_pos)
1107 gcov_write_unsigned (0);
1108
1109 /* TODO: there is a problem here -- if there are other program
1110 summary data after the matching one, setting eof_pos to this
1111 position means that the module info table will overwrite the
1112 those other program summary. It also means a mismatch error
1113 may occur at the next merge if no matching program summary is
1114 found before the module info data. */
1115 if (!summary_pos)
1116 gi_ptr->eof_pos = gcov_position () - 1;
1117 else
1118 gi_ptr->eof_pos = gcov_position ();
1119
1120 if ((error = gcov_close ()))
1121 gcov_error (error < 0 ?
1122 "profiling:%s:Overflow writing\n" :
1123 "profiling:%s:Error writing\n",
1124 gi_filename);
1125}
1126
1127/* Do some preparation work before calling the actual dumping
1128 routine.
1129 Return: 1 when module grouping info needs to be dumped,
1130 0 otherwise. */
1131
1132static int
1133gcov_exit_init (void)
1134{
1135 struct gcov_info *gi_ptr;
1136 int dump_module_info = 0;
1137
1138 dump_module_info = 0;
1139 gcov_prefix_strip = 0;
1140
1141 memset (&all, 0, sizeof (all));
1142
1143 /* Find the totals for this execution. */
1144 memset (&this_program, 0, sizeof (this_program));
1145 for (gi_ptr = __gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
1146 {
1147 gcov_object_summary (gi_ptr, &this_program);
1148
1149 /* The IS_PRIMARY field is overloaded to indicate if this module
1150 is FDO/LIPO. */
1151 dump_module_info |= gi_ptr->mod_info->is_primary;
1152 }
1153
1154 gcov_alloc_filename ();
1155
1156 return dump_module_info;
1157}
1158
1159/* Dump one entry in the gcov_info list (for one object). */
1160
1161static void
1162gcov_dump_one_gcov (struct gcov_info *gi_ptr)
1163{
1164 gcov_type *values[GCOV_COUNTERS];
1165 unsigned fi_stride;
1166 unsigned c_ix;
1167 int ret;
1168
1169 memset (&this_object, 0, sizeof (this_object));
1170 memset (&object, 0, sizeof (object));
1171
1172 gcov_object_summary (gi_ptr, &this_object);
1173
1174 c_ix = gcov_counter_array (gi_ptr, values, 1);
1175
1176 fi_stride = gcov_compute_fi_stride (c_ix);
1177
1178 GCOV_GET_FILENAME (prefix_length, gcov_prefix_strip, gi_ptr->filename,
1179 gi_filename_up);
1180
1181 if (gcov_open_by_filename (gi_filename) == -1)
1182 return;
1183
1184 /* Now merge this file. */
1185 ret = gcov_merge_gcda_file (gi_ptr, values, fi_stride);
1186 if (ret != 0 ) return;
1187
1188 gcov_write_gcda_file (gi_ptr, fi_stride);
1189}
1190
1191#endif /* L_gcov */
1192
1193#ifdef L_gcov_merge_add
1194/* The profile merging function that just adds the counters. It is given
1195 an array COUNTERS of N_COUNTERS old counters and it reads the same number
1196 of counters from the gcov file. */
1197void
1198__gcov_merge_add (gcov_type *counters, unsigned n_counters)
1199{
1200 for (; n_counters; counters++, n_counters--)
1201 *counters += gcov_read_counter ();
1202}
1203#endif /* L_gcov_merge_add */
1204
1205#ifdef L_gcov_merge_ior
1206/* The profile merging function that just adds the counters. It is given
1207 an array COUNTERS of N_COUNTERS old counters and it reads the same number
1208 of counters from the gcov file. */
1209void
1210__gcov_merge_ior (gcov_type *counters, unsigned n_counters)
1211{
1212 for (; n_counters; counters++, n_counters--)
1213 *counters |= gcov_read_counter ();
1214}
1215#endif
1216
1217#ifdef L_gcov_merge_reusedist
1218
1219/* Return the weighted arithmetic mean of two values. */
1220
1221static gcov_type
1222__gcov_weighted_mean2 (gcov_type value1, gcov_type count1,
1223 gcov_type value2, gcov_type count2)
1224{
1225 if (count1 + count2 == 0)
1226 return 0;
1227 else
1228 return (value1 * count1 + value2 * count2) / (count1 + count2);
1229}
1230
1231void
1232__gcov_merge_reusedist (gcov_type *counters, unsigned n_counters)
1233{
1234 unsigned i;
1235
1236 gcc_assert(!(n_counters % 4));
1237
1238 for (i = 0; i < n_counters; i += 4)
1239 {
1240 /* Decode current values. */
1241 gcov_type c_mean_dist = counters[i];
1242 gcov_type c_mean_size = counters[i+1];
1243 gcov_type c_count = counters[i+2];
1244 gcov_type c_dist_x_size = counters[i+3];
1245
1246 /* Read and decode values in file. */
1247 gcov_type f_mean_dist = __gcov_read_counter ();
1248 gcov_type f_mean_size = __gcov_read_counter ();
1249 gcov_type f_count = __gcov_read_counter ();
1250 gcov_type f_dist_x_size = __gcov_read_counter ();
1251
1252 /* Compute aggregates. */
1253 gcov_type a_mean_dist = __gcov_weighted_mean2 (
1254 f_mean_dist, f_count, c_mean_dist, c_count);
1255 gcov_type a_mean_size = __gcov_weighted_mean2 (
1256 f_mean_size, f_count, c_mean_size, c_count);
1257 gcov_type a_count = f_count + c_count;
1258 gcov_type a_dist_x_size = f_dist_x_size + c_dist_x_size;
1259
1260 /* Encode back into counters. */
1261 counters[i] = a_mean_dist;
1262 counters[i+1] = a_mean_size;
1263 counters[i+2] = a_count;
1264 counters[i+3] = a_dist_x_size;
1265 }
1266}
1267
1268#endif
1269
1270#ifdef L_gcov_merge_dc
1271
1272/* Returns 1 if the function global id GID is not valid. */
1273
1274static int
1275__gcov_is_gid_insane (gcov_type gid)
1276{
1277 if (EXTRACT_MODULE_ID_FROM_GLOBAL_ID (gid) == 0
1278 || EXTRACT_FUNC_ID_FROM_GLOBAL_ID (gid) == 0)
1279 return 1;
1280 return 0;
1281}
1282
1283/* The profile merging function used for merging direct call counts
1284 This function is given array COUNTERS of N_COUNTERS old counters and it
1285 reads the same number of counters from the gcov file. */
1286
1287void
1288__gcov_merge_dc (gcov_type *counters, unsigned n_counters)
1289{
1290 unsigned i;
1291
1292 gcc_assert (!(n_counters % 2));
1293 for (i = 0; i < n_counters; i += 2)
1294 {
1295 gcov_type global_id = gcov_read_counter ();
1296 gcov_type call_count = gcov_read_counter ();
1297
1298 /* Note that global id counter may never have been set if no calls were
1299 made from this call-site. */
1300 if (counters[i] && global_id)
1301 {
1302 /* TODO race condition requires us do the following correction. */
1303 if (__gcov_is_gid_insane (counters[i]))
1304 counters[i] = global_id;
1305 else if (__gcov_is_gid_insane (global_id))
1306 global_id = counters[i];
1307
1308 gcc_assert (counters[i] == global_id);
1309 }
1310 else if (global_id)
1311 counters[i] = global_id;
1312
1313 counters[i + 1] += call_count;
1314
1315 /* Reset. */
1316 if (__gcov_is_gid_insane (counters[i]))
1317 counters[i] = counters[i + 1] = 0;
1318
1319 /* Assert that the invariant (global_id == 0) <==> (call_count == 0)
1320 holds true after merging. */
1321 if (counters[i] == 0)
1322 counters[i+1] = 0;
1323 if (counters[i + 1] == 0)
1324 counters[i] = 0;
1325 }
1326}
1327#endif
1328
1329#ifdef L_gcov_merge_icall_topn
1330/* The profile merging function used for merging indirect call counts
1331 This function is given array COUNTERS of N_COUNTERS old counters and it
1332 reads the same number of counters from the gcov file. */
1333
1334void
1335__gcov_merge_icall_topn (gcov_type *counters, unsigned n_counters)
1336{
1337 unsigned i, j, k, m;
1338
1339 gcc_assert (!(n_counters % GCOV_ICALL_TOPN_NCOUNTS));
1340 for (i = 0; i < n_counters; i += GCOV_ICALL_TOPN_NCOUNTS)
1341 {
1342 gcov_type *value_array = &counters[i + 1];
1343 unsigned tmp_size = 2 * (GCOV_ICALL_TOPN_NCOUNTS - 1);
1344 gcov_type *tmp_array
1345 = (gcov_type *) alloca (tmp_size * sizeof (gcov_type));
1346
1347 for (j = 0; j < tmp_size; j++)
1348 tmp_array[j] = 0;
1349
1350 for (j = 0; j < GCOV_ICALL_TOPN_NCOUNTS - 1; j += 2)
1351 {
1352 tmp_array[j] = value_array[j];
1353 tmp_array[j + 1] = value_array [j + 1];
1354 }
1355
1356 /* Skip the number_of_eviction entry. */
1357 gcov_read_counter ();
1358 for (k = 0; k < GCOV_ICALL_TOPN_NCOUNTS - 1; k += 2)
1359 {
1360 int found = 0;
1361 gcov_type global_id = gcov_read_counter ();
1362 gcov_type call_count = gcov_read_counter ();
1363 for (m = 0; m < j; m += 2)
1364 {
1365 if (tmp_array[m] == global_id)
1366 {
1367 found = 1;
1368 tmp_array[m + 1] += call_count;
1369 break;
1370 }
1371 }
1372 if (!found)
1373 {
1374 tmp_array[j] = global_id;
1375 tmp_array[j + 1] = call_count;
1376 j += 2;
1377 }
1378 }
1379 /* Now sort the temp array */
1380 gcov_sort_n_vals (tmp_array, j);
1381
1382 /* Now copy back the top half of the temp array */
1383 for (k = 0; k < GCOV_ICALL_TOPN_NCOUNTS - 1; k += 2)
1384 {
1385 value_array[k] = tmp_array[k];
1386 value_array[k + 1] = tmp_array[k + 1];
1387 }
1388 }
1389}
1390#endif
1391
1392
1393#ifdef L_gcov_merge_single
1394/* The profile merging function for choosing the most common value.
1395 It is given an array COUNTERS of N_COUNTERS old counters and it
1396 reads the same number of counters from the gcov file. The counters
1397 are split into 3-tuples where the members of the tuple have
1398 meanings:
1399
1400 -- the stored candidate on the most common value of the measured entity
1401 -- counter
1402 -- total number of evaluations of the value */
1403void
1404__gcov_merge_single (gcov_type *counters, unsigned n_counters)
1405{
1406 unsigned i, n_measures;
1407 gcov_type value, counter, all;
1408
1409 gcc_assert (!(n_counters % 3));
1410 n_measures = n_counters / 3;
1411 for (i = 0; i < n_measures; i++, counters += 3)
1412 {
1413 value = gcov_read_counter ();
1414 counter = gcov_read_counter ();
1415 all = gcov_read_counter ();
1416
1417 if (counters[0] == value)
1418 counters[1] += counter;
1419 else if (counter > counters[1])
1420 {
1421 counters[0] = value;
1422 counters[1] = counter - counters[1];
1423 }
1424 else
1425 counters[1] -= counter;
1426 counters[2] += all;
1427 }
1428}
1429#endif /* L_gcov_merge_single */
1430
1431#ifdef L_gcov_merge_delta
1432/* The profile merging function for choosing the most common
1433 difference between two consecutive evaluations of the value. It is
1434 given an array COUNTERS of N_COUNTERS old counters and it reads the
1435 same number of counters from the gcov file. The counters are split
1436 into 4-tuples where the members of the tuple have meanings:
1437
1438 -- the last value of the measured entity
1439 -- the stored candidate on the most common difference
1440 -- counter
1441 -- total number of evaluations of the value */
1442void
1443__gcov_merge_delta (gcov_type *counters, unsigned n_counters)
1444{
1445 unsigned i, n_measures;
1446 gcov_type value, counter, all;
1447
1448 gcc_assert (!(n_counters % 4));
1449 n_measures = n_counters / 4;
1450 for (i = 0; i < n_measures; i++, counters += 4)
1451 {
1452 /* last = */ gcov_read_counter ();
1453 value = gcov_read_counter ();
1454 counter = gcov_read_counter ();
1455 all = gcov_read_counter ();
1456
1457 if (counters[1] == value)
1458 counters[2] += counter;
1459 else if (counter > counters[2])
1460 {
1461 counters[1] = value;
1462 counters[2] = counter - counters[2];
1463 }
1464 else
1465 counters[2] -= counter;
1466 counters[3] += all;
1467 }
1468}
1469#endif /* L_gcov_merge_delta */
1470
1471#ifdef L_gcov_interval_profiler
1472/* If VALUE is in interval <START, START + STEPS - 1>, then increases the
1473 corresponding counter in COUNTERS. If the VALUE is above or below
1474 the interval, COUNTERS[STEPS] or COUNTERS[STEPS + 1] is increased
1475 instead. */
1476
1477void
1478__gcov_interval_profiler (gcov_type *counters, gcov_type value,
1479 int start, unsigned steps)
1480{
1481 gcov_type delta = value - start;
1482 if (delta < 0)
1483 counters[steps + 1]++;
1484 else if (delta >= steps)
1485 counters[steps]++;
1486 else
1487 counters[delta]++;
1488}
1489#endif
1490
1491#ifdef L_gcov_pow2_profiler
1492/* If VALUE is a power of two, COUNTERS[1] is incremented. Otherwise
1493 COUNTERS[0] is incremented. */
1494
1495void
1496__gcov_pow2_profiler (gcov_type *counters, gcov_type value)
1497{
1498 if (value & (value - 1))
1499 counters[0]++;
1500 else
1501 counters[1]++;
1502}
1503#endif
1504
1505/* Tries to determine the most common value among its inputs. Checks if the
1506 value stored in COUNTERS[0] matches VALUE. If this is the case, COUNTERS[1]
1507 is incremented. If this is not the case and COUNTERS[1] is not zero,
1508 COUNTERS[1] is decremented. Otherwise COUNTERS[1] is set to one and
1509 VALUE is stored to COUNTERS[0]. This algorithm guarantees that if this
1510 function is called more than 50% of the time with one value, this value
1511 will be in COUNTERS[0] in the end.
1512
1513 In any case, COUNTERS[2] is incremented. */
1514
1515static inline void
1516__gcov_one_value_profiler_body (gcov_type *counters, gcov_type value)
1517{
1518 if (value == counters[0])
1519 counters[1]++;
1520 else if (counters[1] == 0)
1521 {
1522 counters[1] = 1;
1523 counters[0] = value;
1524 }
1525 else
1526 counters[1]--;
1527 counters[2]++;
1528}
1529
1530#ifdef L_gcov_indirect_call_topn_profiler
1531/* Tries to keep track the most frequent N values in the counters where
1532 N is specified by parameter TOPN_VAL. To track top N values, 2*N counter
1533 entries are used.
1534 counter[0] --- the accumative count of the number of times one entry in
1535 in the counters gets evicted/replaced due to limited capacity.
1536 When this value reaches a threshold, the bottom N values are
1537 cleared.
1538 counter[1] through counter[2*N] records the top 2*N values collected so far.
1539 Each value is represented by two entries: count[2*i+1] is the ith value, and
1540 count[2*i+2] is the number of times the value is seen. */
1541
1542static void
1543__gcov_topn_value_profiler_body (gcov_type *counters, gcov_type value,
1544 gcov_unsigned_t topn_val)
1545{
1546 unsigned i, found = 0, have_zero_count = 0;
1547
1548 gcov_type *entry;
1549 gcov_type *lfu_entry = &counters[1];
1550 gcov_type *value_array = &counters[1];
1551 gcov_type *num_eviction = &counters[0];
1552
1553 /* There are 2*topn_val values tracked, each value takes two slots in the
1554 counter array */
1555 for ( i = 0; i < (topn_val << 2); i += 2)
1556 {
1557 entry = &value_array[i];
1558 if ( entry[0] == value)
1559 {
1560 entry[1]++ ;
1561 found = 1;
1562 break;
1563 }
1564 else if (entry[1] == 0)
1565 {
1566 lfu_entry = entry;
1567 have_zero_count = 1;
1568 }
1569 else if (entry[1] < lfu_entry[1])
1570 lfu_entry = entry;
1571 }
1572
1573 if (found)
1574 return;
1575
1576 /* lfu_entry is either an empty entry or an entry
1577 with lowest count, which will be evicted. */
1578 lfu_entry[0] = value;
1579 lfu_entry[1] = 1;
1580
1581#define GCOV_ICALL_COUNTER_CLEAR_THRESHOLD 3000
1582
1583 /* Too many evictions -- time to clear bottom entries to
1584 avoid hot values bumping each other out. */
1585 if ( !have_zero_count
1586 && ++*num_eviction >= GCOV_ICALL_COUNTER_CLEAR_THRESHOLD)
1587 {
1588 unsigned i, j;
1589 gcov_type *p, minv;
1590 gcov_type* tmp_cnts
1591 = (gcov_type *)alloca (topn_val * sizeof(gcov_type));
1592
1593 *num_eviction = 0;
1594
1595 for ( i = 0; i < topn_val; i++ )
1596 tmp_cnts[i] = 0;
1597
1598 /* Find the largest topn_val values from the group of
1599 2*topn_val values and put them into tmp_cnts. */
1600
1601 for ( i = 0; i < 2 * topn_val; i += 2 )
1602 {
1603 p = 0;
1604 for ( j = 0; j < topn_val; j++ )
1605 {
1606 if ( !p || tmp_cnts[j] < *p )
1607 p = &tmp_cnts[j];
1608 }
1609 if ( value_array[i + 1] > *p )
1610 *p = value_array[i + 1];
1611 }
1612
1613 minv = tmp_cnts[0];
1614 for ( j = 1; j < topn_val; j++ )
1615 {
1616 if (tmp_cnts[j] < minv)
1617 minv = tmp_cnts[j];
1618 }
1619 /* Zero out low value entries */
1620 for ( i = 0; i < 2 * topn_val; i += 2 )
1621 {
1622 if (value_array[i + 1] < minv)
1623 {
1624 value_array[i] = 0;
1625 value_array[i + 1] = 0;
1626 }
1627 }
1628 }
1629}
1630#endif
1631
1632#ifdef L_gcov_one_value_profiler
1633void
1634__gcov_one_value_profiler (gcov_type *counters, gcov_type value)
1635{
1636 __gcov_one_value_profiler_body (counters, value);
1637}
1638#endif
1639
1640#ifdef L_gcov_indirect_call_profiler
1641
1642/* By default, the C++ compiler will use function addresses in the
1643 vtable entries. Setting TARGET_VTABLE_USES_DESCRIPTORS to nonzero
1644 tells the compiler to use function descriptors instead. The value
1645 of this macro says how many words wide the descriptor is (normally 2),
1646 but it may be dependent on target flags. Since we do not have access
1647 to the target flags here we just check to see if it is set and use
1648 that to set VTABLE_USES_DESCRIPTORS to 0 or 1.
1649
1650 It is assumed that the address of a function descriptor may be treated
1651 as a pointer to a function. */
1652
1653#ifdef TARGET_VTABLE_USES_DESCRIPTORS
1654#define VTABLE_USES_DESCRIPTORS 1
1655#else
1656#define VTABLE_USES_DESCRIPTORS 0
1657#endif
1658
1659/* Tries to determine the most common value among its inputs. */
1660void
1661__gcov_indirect_call_profiler (gcov_type* counter, gcov_type value,
1662 void* cur_func, void* callee_func)
1663{
1664 /* If the C++ virtual tables contain function descriptors then one
1665 function may have multiple descriptors and we need to dereference
1666 the descriptors to see if they point to the same function. */
1667 if (cur_func == callee_func
1668 || (VTABLE_USES_DESCRIPTORS && callee_func
1669 && *(void **) cur_func == *(void **) callee_func))
1670 __gcov_one_value_profiler_body (counter, value);
1671}
1672#endif
1673
1674
1675#ifdef L_gcov_indirect_call_topn_profiler
1676extern THREAD_PREFIX gcov_type *__gcov_indirect_call_topn_counters ATTRIBUTE_HIDDEN;
1677extern THREAD_PREFIX void *__gcov_indirect_call_topn_callee ATTRIBUTE_HIDDEN;
1678#ifdef TARGET_VTABLE_USES_DESCRIPTORS
1679#define VTABLE_USES_DESCRIPTORS 1
1680#else
1681#define VTABLE_USES_DESCRIPTORS 0
1682#endif
1683void
1684__gcov_indirect_call_topn_profiler (void *cur_func,
1685 void *cur_module_gcov_info,
1686 gcov_unsigned_t cur_func_id)
1687{
1688 void *callee_func = __gcov_indirect_call_topn_callee;
1689 gcov_type *counter = __gcov_indirect_call_topn_counters;
1690 /* If the C++ virtual tables contain function descriptors then one
1691 function may have multiple descriptors and we need to dereference
1692 the descriptors to see if they point to the same function. */
1693 if (cur_func == callee_func
1694 || (VTABLE_USES_DESCRIPTORS && callee_func
1695 && *(void **) cur_func == *(void **) callee_func))
1696 {
1697 gcov_type global_id
1698 = ((struct gcov_info *) cur_module_gcov_info)->mod_info->ident;
1699 global_id = GEN_FUNC_GLOBAL_ID (global_id, cur_func_id);
1700 __gcov_topn_value_profiler_body (counter, global_id, GCOV_ICALL_TOPN_VAL);
1701 __gcov_indirect_call_topn_callee = 0;
1702 }
1703}
1704
1705#endif
1706
1707#ifdef L_gcov_direct_call_profiler
1708extern THREAD_PREFIX gcov_type *__gcov_direct_call_counters ATTRIBUTE_HIDDEN;
1709extern THREAD_PREFIX void *__gcov_direct_call_callee ATTRIBUTE_HIDDEN;
1710/* Direct call profiler. */
1711void
1712__gcov_direct_call_profiler (void *cur_func,
1713 void *cur_module_gcov_info,
1714 gcov_unsigned_t cur_func_id)
1715{
1716 if (cur_func == __gcov_direct_call_callee)
1717 {
1718 gcov_type global_id
1719 = ((struct gcov_info *) cur_module_gcov_info)->mod_info->ident;
1720 global_id = GEN_FUNC_GLOBAL_ID (global_id, cur_func_id);
1721 __gcov_direct_call_counters[0] = global_id;
1722 __gcov_direct_call_counters[1]++;
1723 __gcov_direct_call_callee = 0;
1724 }
1725}
1726#endif
1727
1728
1729#ifdef L_gcov_average_profiler
1730/* Increase corresponding COUNTER by VALUE. FIXME: Perhaps we want
1731 to saturate up. */
1732
1733void
1734__gcov_average_profiler (gcov_type *counters, gcov_type value)
1735{
1736 counters[0] += value;
1737 counters[1] ++;
1738}
1739#endif
1740
1741#ifdef L_gcov_ior_profiler
1742/* Increase corresponding COUNTER by VALUE. FIXME: Perhaps we want
1743 to saturate up. */
1744
1745void
1746__gcov_ior_profiler (gcov_type *counters, gcov_type value)
1747{
1748 *counters |= value;
1749}
1750#endif
1751
1752#ifdef L_gcov_fork
1753/* A wrapper for the fork function. Flushes the accumulated profiling data, so
1754 that they are not counted twice. */
1755
1756pid_t
1757__gcov_fork (void)
1758{
1759 __gcov_flush ();
1760 return fork ();
1761}
1762#endif
1763
1764#ifdef L_gcov_execl
1765/* A wrapper for the execl function. Flushes the accumulated profiling data, so
1766 that they are not lost. */
1767
1768int
1769__gcov_execl (const char *path, char *arg, ...)
1770{
1771 va_list ap, aq;
1772 unsigned i, length;
1773 char **args;
1774
1775 __gcov_flush ();
1776
1777 va_start (ap, arg);
1778 va_copy (aq, ap);
1779
1780 length = 2;
1781 while (va_arg (ap, char *))
1782 length++;
1783 va_end (ap);
1784
1785 args = (char **) alloca (length * sizeof (void *));
1786 args[0] = arg;
1787 for (i = 1; i < length; i++)
1788 args[i] = va_arg (aq, char *);
1789 va_end (aq);
1790
1791 return execv (path, args);
1792}
1793#endif
1794
1795#ifdef L_gcov_execlp
1796/* A wrapper for the execlp function. Flushes the accumulated profiling data, so
1797 that they are not lost. */
1798
1799int
1800__gcov_execlp (const char *path, char *arg, ...)
1801{
1802 va_list ap, aq;
1803 unsigned i, length;
1804 char **args;
1805
1806 __gcov_flush ();
1807
1808 va_start (ap, arg);
1809 va_copy (aq, ap);
1810
1811 length = 2;
1812 while (va_arg (ap, char *))
1813 length++;
1814 va_end (ap);
1815
1816 args = (char **) alloca (length * sizeof (void *));
1817 args[0] = arg;
1818 for (i = 1; i < length; i++)
1819 args[i] = va_arg (aq, char *);
1820 va_end (aq);
1821
1822 return execvp (path, args);
1823}
1824#endif
1825
1826#ifdef L_gcov_execle
1827/* A wrapper for the execle function. Flushes the accumulated profiling data, so
1828 that they are not lost. */
1829
1830int
1831__gcov_execle (const char *path, char *arg, ...)
1832{
1833 va_list ap, aq;
1834 unsigned i, length;
1835 char **args;
1836 char **envp;
1837
1838 __gcov_flush ();
1839
1840 va_start (ap, arg);
1841 va_copy (aq, ap);
1842
1843 length = 2;
1844 while (va_arg (ap, char *))
1845 length++;
1846 va_end (ap);
1847
1848 args = (char **) alloca (length * sizeof (void *));
1849 args[0] = arg;
1850 for (i = 1; i < length; i++)
1851 args[i] = va_arg (aq, char *);
1852 envp = va_arg (aq, char **);
1853 va_end (aq);
1854
1855 return execve (path, args, envp);
1856}
1857#endif
1858
1859#ifdef L_gcov_execv
1860/* A wrapper for the execv function. Flushes the accumulated profiling data, so
1861 that they are not lost. */
1862
1863int
1864__gcov_execv (const char *path, char *const argv[])
1865{
1866 __gcov_flush ();
1867 return execv (path, argv);
1868}
1869#endif
1870
1871#ifdef L_gcov_execvp
1872/* A wrapper for the execvp function. Flushes the accumulated profiling data, so
1873 that they are not lost. */
1874
1875int
1876__gcov_execvp (const char *path, char *const argv[])
1877{
1878 __gcov_flush ();
1879 return execvp (path, argv);
1880}
1881#endif
1882
1883#ifdef L_gcov_execve
1884/* A wrapper for the execve function. Flushes the accumulated profiling data, so
1885 that they are not lost. */
1886
1887int
1888__gcov_execve (const char *path, char *const argv[], char *const envp[])
1889{
1890 __gcov_flush ();
1891 return execve (path, argv, envp);
1892}
1893#endif
1894
1895#ifdef __GCOV_KERNEL__
1896/*
1897 * Provide different implementation for the following functions:
1898 * __gcov_init
1899 * __gcov_exit
1900 *
1901 * Provide the following dummy merge functions:
1902 * __gcov_merge_add
1903 * __gcov_merge_single
1904 * __gcov_merge_delta
1905 * __gcov_merge_ior
1906 * __gcov_merge_icall_topn
1907 * __gcov_merge_dc
1908 * __gcov_merge_reusedist
1909 *
1910 * Reuse the following functions:
1911 * __gcov_interval_profiler()
1912 * __gcov_pow2_profiler()
1913 * __gcov_average_profiler()
1914 * __gcov_ior_profiler()
1915 * __gcov_one_value_profiler()
1916 * __gcov_indirect_call_profiler()
1917 * |-> __gcov_one_value_profiler_body()
1918 *
1919 * For LIPO: (TBD)
1920 * Change slightly for the following functions:
1921 * __gcov_merge_icall_topn
1922 * __gcov_merge_dc
1923 *
1924 * Reuse the following functions:
1925 * __gcov_direct_call_profiler()
1926 * __gcov_indirect_call_topn_profiler()
1927 * |-> __gcov_topn_value_profiler_body()
1928 *
1929 */
1930
1931/* Current virual gcda file. This is for kernel use only. */
1932gcov_kernel_vfile *gcov_current_file;
1933
1934/* Set current virutal gcda file. It needs to be set before dumping
1935 profile data. */
1936
1937void
1938gcov_set_vfile (gcov_kernel_vfile *file)
1939{
1940 gcov_current_file = file;
1941}
1942
1943/* Dump one entry in the gcov_info list (for one object) in kernel. */
1944
1945void
1946gcov_kernel_dump_one_gcov (struct gcov_info *info)
1947{
1948 gcc_assert (gcov_current_file);
1949
1950 gcov_exit_init ();
1951
1952 gcov_dump_one_gcov (info);
1953}
1954
1955#define DUMMY_FUNC(func) \
1956void func (gcov_type *counters __attribute__ ((unused)), \
1957 unsigned n_counters __attribute__ ((unused))) {}
1958
1959DUMMY_FUNC (__gcov_merge_add)
1960EXPORT_SYMBOL (__gcov_merge_add);
1961
1962DUMMY_FUNC (__gcov_merge_single)
1963EXPORT_SYMBOL (__gcov_merge_single);
1964
1965DUMMY_FUNC (__gcov_merge_delta)
1966EXPORT_SYMBOL (__gcov_merge_delta);
1967
1968DUMMY_FUNC(__gcov_merge_ior)
1969EXPORT_SYMBOL (__gcov_merge_ior);
1970
1971DUMMY_FUNC (__gcov_merge_icall_topn)
1972EXPORT_SYMBOL (__gcov_merge_icall_topn);
1973
1974DUMMY_FUNC (__gcov_merge_dc)
1975EXPORT_SYMBOL (__gcov_merge_dc);
1976
1977DUMMY_FUNC (__gcov_merge_reusedist)
1978EXPORT_SYMBOL (__gcov_merge_reusedist);
1979
1980EXPORT_SYMBOL (__gcov_average_profiler);
1981EXPORT_SYMBOL (__gcov_indirect_call_profiler);
1982EXPORT_SYMBOL (__gcov_interval_profiler);
1983EXPORT_SYMBOL (__gcov_ior_profiler);
1984EXPORT_SYMBOL (__gcov_one_value_profiler);
1985EXPORT_SYMBOL (__gcov_pow2_profiler);
1986
1987#endif /* __GCOV_KERNEL__ */
1988
1989#endif /* inhibit_libc */