fortran-modules.exp (list-module-names-1): Remove warning.
[official-gcc.git] / libgcc / libgcov.c
blobee7fda4eac9447874409dc02b685d9d67274548f
1 /* 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, 2011
5 Free Software Foundation, Inc.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
19 Under Section 7 of GPL version 3, you are granted additional
20 permissions described in the GCC Runtime Library Exception, version
21 3.1, as published by the Free Software Foundation.
23 You should have received a copy of the GNU General Public License and
24 a copy of the GCC Runtime Library Exception along with this program;
25 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
26 <http://www.gnu.org/licenses/>. */
28 #include "tconfig.h"
29 #include "tsystem.h"
30 #include "coretypes.h"
31 #include "tm.h"
32 #include "libgcc_tm.h"
33 #include "gthr.h"
35 #if defined(inhibit_libc)
36 #define IN_LIBGCOV (-1)
37 #else
38 #define IN_LIBGCOV 1
39 #if defined(L_gcov)
40 #define GCOV_LINKAGE /* nothing */
41 #endif
42 #endif
43 #include "gcov-io.h"
45 #if defined(inhibit_libc)
46 /* If libc and its header files are not available, provide dummy functions. */
48 #ifdef L_gcov
49 void __gcov_init (struct gcov_info *p __attribute__ ((unused))) {}
50 void __gcov_flush (void) {}
51 #endif
53 #ifdef L_gcov_merge_add
54 void __gcov_merge_add (gcov_type *counters __attribute__ ((unused)),
55 unsigned n_counters __attribute__ ((unused))) {}
56 #endif
58 #ifdef L_gcov_merge_single
59 void __gcov_merge_single (gcov_type *counters __attribute__ ((unused)),
60 unsigned n_counters __attribute__ ((unused))) {}
61 #endif
63 #ifdef L_gcov_merge_delta
64 void __gcov_merge_delta (gcov_type *counters __attribute__ ((unused)),
65 unsigned n_counters __attribute__ ((unused))) {}
66 #endif
68 #else
70 #include <string.h>
71 #if GCOV_LOCKED
72 #include <fcntl.h>
73 #include <errno.h>
74 #include <sys/stat.h>
75 #endif
77 #ifdef L_gcov
78 #include "gcov-io.c"
80 struct gcov_fn_buffer
82 struct gcov_fn_buffer *next;
83 unsigned fn_ix;
84 struct gcov_fn_info info;
85 /* note gcov_fn_info ends in a trailing array. */
88 /* Chain of per-object gcov structures. */
89 static struct gcov_info *gcov_list;
91 /* Size of the longest file name. */
92 static size_t gcov_max_filename = 0;
94 /* Make sure path component of the given FILENAME exists, create
95 missing directories. FILENAME must be writable.
96 Returns zero on success, or -1 if an error occurred. */
98 static int
99 create_file_directory (char *filename)
101 #if !defined(TARGET_POSIX_IO) && !defined(_WIN32)
102 (void) filename;
103 return -1;
104 #else
105 char *s;
107 s = filename;
109 if (HAS_DRIVE_SPEC(s))
110 s += 2;
111 if (IS_DIR_SEPARATOR(*s))
112 ++s;
113 for (; *s != '\0'; s++)
114 if (IS_DIR_SEPARATOR(*s))
116 char sep = *s;
117 *s = '\0';
119 /* Try to make directory if it doesn't already exist. */
120 if (access (filename, F_OK) == -1
121 #ifdef TARGET_POSIX_IO
122 && mkdir (filename, 0755) == -1
123 #else
124 && mkdir (filename) == -1
125 #endif
126 /* The directory might have been made by another process. */
127 && errno != EEXIST)
129 fprintf (stderr, "profiling:%s:Cannot create directory\n",
130 filename);
131 *s = sep;
132 return -1;
135 *s = sep;
137 return 0;
138 #endif
141 static struct gcov_fn_buffer *
142 free_fn_data (const struct gcov_info *gi_ptr, struct gcov_fn_buffer *buffer,
143 unsigned limit)
145 struct gcov_fn_buffer *next;
146 unsigned ix, n_ctr = 0;
148 if (!buffer)
149 return 0;
150 next = buffer->next;
152 for (ix = 0; ix != limit; ix++)
153 if (gi_ptr->merge[ix])
154 free (buffer->info.ctrs[n_ctr++].values);
155 free (buffer);
156 return next;
159 static struct gcov_fn_buffer **
160 buffer_fn_data (const char *filename, const struct gcov_info *gi_ptr,
161 struct gcov_fn_buffer **end_ptr, unsigned fn_ix)
163 unsigned n_ctrs = 0, ix = 0;
164 struct gcov_fn_buffer *fn_buffer;
165 unsigned len;
167 for (ix = GCOV_COUNTERS; ix--;)
168 if (gi_ptr->merge[ix])
169 n_ctrs++;
171 len = sizeof (*fn_buffer) + sizeof (fn_buffer->info.ctrs[0]) * n_ctrs;
172 fn_buffer = (struct gcov_fn_buffer *)malloc (len);
174 if (!fn_buffer)
175 goto fail;
177 fn_buffer->next = 0;
178 fn_buffer->fn_ix = fn_ix;
179 fn_buffer->info.ident = gcov_read_unsigned ();
180 fn_buffer->info.lineno_checksum = gcov_read_unsigned ();
181 fn_buffer->info.cfg_checksum = gcov_read_unsigned ();
183 for (n_ctrs = ix = 0; ix != GCOV_COUNTERS; ix++)
185 gcov_unsigned_t length;
186 gcov_type *values;
188 if (!gi_ptr->merge[ix])
189 continue;
191 if (gcov_read_unsigned () != GCOV_TAG_FOR_COUNTER (ix))
193 len = 0;
194 goto fail;
197 length = GCOV_TAG_COUNTER_NUM (gcov_read_unsigned ());
198 len = length * sizeof (gcov_type);
199 values = (gcov_type *)malloc (len);
200 if (!values)
201 goto fail;
203 fn_buffer->info.ctrs[n_ctrs].num = length;
204 fn_buffer->info.ctrs[n_ctrs].values = values;
206 while (length--)
207 *values++ = gcov_read_counter ();
208 n_ctrs++;
211 *end_ptr = fn_buffer;
212 return &fn_buffer->next;
214 fail:
215 fprintf (stderr, "profiling:%s:Function %u %s %u \n", filename, fn_ix,
216 len ? "cannot allocate" : "counter mismatch", len ? len : ix);
218 return (struct gcov_fn_buffer **)free_fn_data (gi_ptr, fn_buffer, ix);
221 /* Add an unsigned value to the current crc */
223 static gcov_unsigned_t
224 crc32_unsigned (gcov_unsigned_t crc32, gcov_unsigned_t value)
226 unsigned ix;
228 for (ix = 32; ix--; value <<= 1)
230 unsigned feedback;
232 feedback = (value ^ crc32) & 0x80000000 ? 0x04c11db7 : 0;
233 crc32 <<= 1;
234 crc32 ^= feedback;
237 return crc32;
240 /* Check if VERSION of the info block PTR matches libgcov one.
241 Return 1 on success, or zero in case of versions mismatch.
242 If FILENAME is not NULL, its value used for reporting purposes
243 instead of value from the info block. */
245 static int
246 gcov_version (struct gcov_info *ptr, gcov_unsigned_t version,
247 const char *filename)
249 if (version != GCOV_VERSION)
251 char v[4], e[4];
253 GCOV_UNSIGNED2STRING (v, version);
254 GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
256 fprintf (stderr,
257 "profiling:%s:Version mismatch - expected %.4s got %.4s\n",
258 filename? filename : ptr->filename, e, v);
259 return 0;
261 return 1;
264 /* Dump the coverage counts. We merge with existing counts when
265 possible, to avoid growing the .da files ad infinitum. We use this
266 program's checksum to make sure we only accumulate whole program
267 statistics to the correct summary. An object file might be embedded
268 in two separate programs, and we must keep the two program
269 summaries separate. */
271 static void
272 gcov_exit (void)
274 struct gcov_info *gi_ptr;
275 const struct gcov_fn_info *gfi_ptr;
276 struct gcov_summary this_prg; /* summary for program. */
277 struct gcov_summary all_prg; /* summary for all instances of program. */
278 struct gcov_ctr_summary *cs_ptr;
279 const struct gcov_ctr_info *ci_ptr;
280 unsigned t_ix;
281 int f_ix;
282 gcov_unsigned_t c_num;
283 const char *gcov_prefix;
284 int gcov_prefix_strip = 0;
285 size_t prefix_length;
286 char *gi_filename, *gi_filename_up;
287 gcov_unsigned_t crc32 = 0;
289 memset (&all_prg, 0, sizeof (all_prg));
290 /* Find the totals for this execution. */
291 memset (&this_prg, 0, sizeof (this_prg));
292 for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
294 crc32 = crc32_unsigned (crc32, gi_ptr->stamp);
295 crc32 = crc32_unsigned (crc32, gi_ptr->n_functions);
297 for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions; f_ix++)
299 gfi_ptr = gi_ptr->functions[f_ix];
301 if (gfi_ptr && gfi_ptr->key != gi_ptr)
302 gfi_ptr = 0;
304 crc32 = crc32_unsigned (crc32, gfi_ptr ? gfi_ptr->cfg_checksum : 0);
305 crc32 = crc32_unsigned (crc32,
306 gfi_ptr ? gfi_ptr->lineno_checksum : 0);
307 if (!gfi_ptr)
308 continue;
310 ci_ptr = gfi_ptr->ctrs;
311 for (t_ix = 0; t_ix != GCOV_COUNTERS_SUMMABLE; t_ix++)
313 if (!gi_ptr->merge[t_ix])
314 continue;
316 cs_ptr = &this_prg.ctrs[t_ix];
317 cs_ptr->num += ci_ptr->num;
318 crc32 = crc32_unsigned (crc32, ci_ptr->num);
320 for (c_num = 0; c_num < ci_ptr->num; c_num++)
322 cs_ptr->sum_all += ci_ptr->values[c_num];
323 if (cs_ptr->run_max < ci_ptr->values[c_num])
324 cs_ptr->run_max = ci_ptr->values[c_num];
326 ci_ptr++;
332 /* Check if the level of dirs to strip off specified. */
333 char *tmp = getenv("GCOV_PREFIX_STRIP");
334 if (tmp)
336 gcov_prefix_strip = atoi (tmp);
337 /* Do not consider negative values. */
338 if (gcov_prefix_strip < 0)
339 gcov_prefix_strip = 0;
343 /* Get file name relocation prefix. Non-absolute values are ignored. */
344 gcov_prefix = getenv("GCOV_PREFIX");
345 if (gcov_prefix)
347 prefix_length = strlen(gcov_prefix);
349 /* Remove an unnecessary trailing '/' */
350 if (IS_DIR_SEPARATOR (gcov_prefix[prefix_length - 1]))
351 prefix_length--;
353 else
354 prefix_length = 0;
356 /* If no prefix was specified and a prefix stip, then we assume
357 relative. */
358 if (gcov_prefix_strip != 0 && prefix_length == 0)
360 gcov_prefix = ".";
361 prefix_length = 1;
363 /* Allocate and initialize the filename scratch space plus one. */
364 gi_filename = (char *) alloca (prefix_length + gcov_max_filename + 2);
365 if (prefix_length)
366 memcpy (gi_filename, gcov_prefix, prefix_length);
367 gi_filename_up = gi_filename + prefix_length;
369 /* Now merge each file. */
370 for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
372 unsigned n_counts;
373 struct gcov_summary prg; /* summary for this object over all
374 program. */
375 struct gcov_ctr_summary *cs_prg, *cs_tprg, *cs_all;
376 int error = 0;
377 gcov_unsigned_t tag, length;
378 gcov_position_t summary_pos = 0;
379 gcov_position_t eof_pos = 0;
380 const char *fname, *s;
381 struct gcov_fn_buffer *fn_buffer = 0;
382 struct gcov_fn_buffer **fn_tail = &fn_buffer;
384 fname = gi_ptr->filename;
386 /* Avoid to add multiple drive letters into combined path. */
387 if (prefix_length != 0 && HAS_DRIVE_SPEC(fname))
388 fname += 2;
390 /* Build relocated filename, stripping off leading
391 directories from the initial filename if requested. */
392 if (gcov_prefix_strip > 0)
394 int level = 0;
395 s = fname;
396 if (IS_DIR_SEPARATOR(*s))
397 ++s;
399 /* Skip selected directory levels. */
400 for (; (*s != '\0') && (level < gcov_prefix_strip); s++)
401 if (IS_DIR_SEPARATOR(*s))
403 fname = s;
404 level++;
408 /* Update complete filename with stripped original. */
409 if (prefix_length != 0 && !IS_DIR_SEPARATOR (*fname))
411 /* If prefix is given, add directory separator. */
412 strcpy (gi_filename_up, "/");
413 strcpy (gi_filename_up + 1, fname);
415 else
416 strcpy (gi_filename_up, fname);
418 if (!gcov_open (gi_filename))
420 /* Open failed likely due to missed directory.
421 Create directory and retry to open file. */
422 if (create_file_directory (gi_filename))
424 fprintf (stderr, "profiling:%s:Skip\n", gi_filename);
425 continue;
427 if (!gcov_open (gi_filename))
429 fprintf (stderr, "profiling:%s:Cannot open\n", gi_filename);
430 continue;
434 tag = gcov_read_unsigned ();
435 if (tag)
437 /* Merge data from file. */
438 if (tag != GCOV_DATA_MAGIC)
440 fprintf (stderr, "profiling:%s:Not a gcov data file\n",
441 gi_filename);
442 goto read_fatal;
444 length = gcov_read_unsigned ();
445 if (!gcov_version (gi_ptr, length, gi_filename))
446 goto read_fatal;
448 length = gcov_read_unsigned ();
449 if (length != gi_ptr->stamp)
450 /* Read from a different compilation. Overwrite the file. */
451 goto rewrite;
453 /* Look for program summary. */
454 for (f_ix = 0;;)
456 struct gcov_summary tmp;
458 eof_pos = gcov_position ();
459 tag = gcov_read_unsigned ();
460 if (tag != GCOV_TAG_PROGRAM_SUMMARY)
461 break;
463 f_ix--;
464 length = gcov_read_unsigned ();
465 if (length != GCOV_TAG_SUMMARY_LENGTH)
466 goto read_mismatch;
467 gcov_read_summary (&tmp);
468 if ((error = gcov_is_error ()))
469 goto read_error;
470 if (summary_pos || tmp.checksum != crc32)
471 goto next_summary;
473 for (t_ix = 0; t_ix != GCOV_COUNTERS_SUMMABLE; t_ix++)
474 if (tmp.ctrs[t_ix].num != this_prg.ctrs[t_ix].num)
475 goto next_summary;
476 prg = tmp;
477 summary_pos = eof_pos;
479 next_summary:;
482 /* Merge execution counts for each function. */
483 for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions;
484 f_ix++, tag = gcov_read_unsigned ())
486 gfi_ptr = gi_ptr->functions[f_ix];
488 if (tag != GCOV_TAG_FUNCTION)
489 goto read_mismatch;
491 length = gcov_read_unsigned ();
492 if (!length)
493 /* This function did not appear in the other program.
494 We have nothing to merge. */
495 continue;
497 if (length != GCOV_TAG_FUNCTION_LENGTH)
498 goto read_mismatch;
500 if (!gfi_ptr || gfi_ptr->key != gi_ptr)
502 /* This function appears in the other program. We
503 need to buffer the information in order to write
504 it back out -- we'll be inserting data before
505 this point, so cannot simply keep the data in the
506 file. */
507 fn_tail = buffer_fn_data (gi_filename,
508 gi_ptr, fn_tail, f_ix);
509 if (!fn_tail)
510 goto read_mismatch;
511 continue;
514 length = gcov_read_unsigned ();
515 if (length != gfi_ptr->ident)
516 goto read_mismatch;
518 length = gcov_read_unsigned ();
519 if (length != gfi_ptr->lineno_checksum)
520 goto read_mismatch;
522 length = gcov_read_unsigned ();
523 if (length != gfi_ptr->cfg_checksum)
524 goto read_mismatch;
526 ci_ptr = gfi_ptr->ctrs;
527 for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
529 gcov_merge_fn merge = gi_ptr->merge[t_ix];
531 if (!merge)
532 continue;
534 tag = gcov_read_unsigned ();
535 length = gcov_read_unsigned ();
536 if (tag != GCOV_TAG_FOR_COUNTER (t_ix)
537 || length != GCOV_TAG_COUNTER_LENGTH (ci_ptr->num))
538 goto read_mismatch;
539 (*merge) (ci_ptr->values, ci_ptr->num);
540 ci_ptr++;
542 if ((error = gcov_is_error ()))
543 goto read_error;
546 if (tag)
548 read_mismatch:;
549 fprintf (stderr, "profiling:%s:Merge mismatch for %s %u\n",
550 gi_filename, f_ix >= 0 ? "function" : "summary",
551 f_ix < 0 ? -1 - f_ix : f_ix);
552 goto read_fatal;
555 goto rewrite;
557 read_error:;
558 fprintf (stderr, "profiling:%s:%s merging\n", gi_filename,
559 error < 0 ? "Overflow": "Error");
561 goto read_fatal;
563 rewrite:;
564 gcov_rewrite ();
565 if (!summary_pos)
567 memset (&prg, 0, sizeof (prg));
568 summary_pos = eof_pos;
571 /* Merge the summaries. */
572 for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
574 cs_prg = &prg.ctrs[t_ix];
575 cs_tprg = &this_prg.ctrs[t_ix];
576 cs_all = &all_prg.ctrs[t_ix];
578 if (gi_ptr->merge[t_ix])
580 if (!cs_prg->runs++)
581 cs_prg->num = cs_tprg->num;
582 cs_prg->sum_all += cs_tprg->sum_all;
583 if (cs_prg->run_max < cs_tprg->run_max)
584 cs_prg->run_max = cs_tprg->run_max;
585 cs_prg->sum_max += cs_tprg->run_max;
587 else if (cs_prg->runs)
588 goto read_mismatch;
590 if (!cs_all->runs && cs_prg->runs)
591 memcpy (cs_all, cs_prg, sizeof (*cs_all));
592 else if (!all_prg.checksum
593 && (!GCOV_LOCKED || cs_all->runs == cs_prg->runs)
594 && memcmp (cs_all, cs_prg, sizeof (*cs_all)))
596 fprintf (stderr, "profiling:%s:Invocation mismatch - some data files may have been removed%s\n",
597 gi_filename, GCOV_LOCKED
598 ? "" : " or concurrently updated without locking support");
599 all_prg.checksum = ~0u;
603 prg.checksum = crc32;
605 /* Write out the data. */
606 if (!eof_pos)
608 gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION);
609 gcov_write_unsigned (gi_ptr->stamp);
612 if (summary_pos)
613 gcov_seek (summary_pos);
615 /* Generate whole program statistics. */
616 gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, &prg);
618 if (summary_pos < eof_pos)
619 gcov_seek (eof_pos);
621 /* Write execution counts for each function. */
622 for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions; f_ix++)
624 unsigned buffered = 0;
626 if (fn_buffer && fn_buffer->fn_ix == (unsigned)f_ix)
628 /* Buffered data from another program. */
629 buffered = 1;
630 gfi_ptr = &fn_buffer->info;
631 length = GCOV_TAG_FUNCTION_LENGTH;
633 else
635 gfi_ptr = gi_ptr->functions[f_ix];
636 if (gfi_ptr && gfi_ptr->key == gi_ptr)
637 length = GCOV_TAG_FUNCTION_LENGTH;
638 else
639 length = 0;
642 gcov_write_tag_length (GCOV_TAG_FUNCTION, length);
643 if (!length)
644 continue;
646 gcov_write_unsigned (gfi_ptr->ident);
647 gcov_write_unsigned (gfi_ptr->lineno_checksum);
648 gcov_write_unsigned (gfi_ptr->cfg_checksum);
650 ci_ptr = gfi_ptr->ctrs;
651 for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
653 if (!gi_ptr->merge[t_ix])
654 continue;
656 n_counts = ci_ptr->num;
657 gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
658 GCOV_TAG_COUNTER_LENGTH (n_counts));
659 gcov_type *c_ptr = ci_ptr->values;
660 while (n_counts--)
661 gcov_write_counter (*c_ptr++);
662 ci_ptr++;
664 if (buffered)
665 fn_buffer = free_fn_data (gi_ptr, fn_buffer, GCOV_COUNTERS);
668 gcov_write_unsigned (0);
670 read_fatal:;
671 while (fn_buffer)
672 fn_buffer = free_fn_data (gi_ptr, fn_buffer, GCOV_COUNTERS);
674 if ((error = gcov_close ()))
675 fprintf (stderr, error < 0 ?
676 "profiling:%s:Overflow writing\n" :
677 "profiling:%s:Error writing\n",
678 gi_filename);
682 /* Add a new object file onto the bb chain. Invoked automatically
683 when running an object file's global ctors. */
685 void
686 __gcov_init (struct gcov_info *info)
688 if (!info->version || !info->n_functions)
689 return;
690 if (gcov_version (info, info->version, 0))
692 size_t filename_length = strlen(info->filename);
694 /* Refresh the longest file name information */
695 if (filename_length > gcov_max_filename)
696 gcov_max_filename = filename_length;
698 if (!gcov_list)
699 atexit (gcov_exit);
701 info->next = gcov_list;
702 gcov_list = info;
704 info->version = 0;
707 #ifdef __GTHREAD_MUTEX_INIT
708 ATTRIBUTE_HIDDEN __gthread_mutex_t __gcov_flush_mx = __GTHREAD_MUTEX_INIT;
709 #define init_mx_once()
710 #else
711 __gthread_mutex_t __gcov_flush_mx ATTRIBUTE_HIDDEN;
713 static void
714 init_mx (void)
716 __GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_flush_mx);
718 static void
719 init_mx_once (void)
721 static __gthread_once_t once = __GTHREAD_ONCE_INIT;
722 __gthread_once (&once, init_mx);
724 #endif
726 /* Called before fork or exec - write out profile information gathered so
727 far and reset it to zero. This avoids duplication or loss of the
728 profile information gathered so far. */
730 void
731 __gcov_flush (void)
733 const struct gcov_info *gi_ptr;
735 init_mx_once ();
736 __gthread_mutex_lock (&__gcov_flush_mx);
738 gcov_exit ();
739 for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
741 unsigned f_ix;
743 for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++)
745 unsigned t_ix;
746 const struct gcov_fn_info *gfi_ptr = gi_ptr->functions[f_ix];
748 if (!gfi_ptr || gfi_ptr->key != gi_ptr)
749 continue;
750 const struct gcov_ctr_info *ci_ptr = gfi_ptr->ctrs;
751 for (t_ix = 0; t_ix != GCOV_COUNTERS; t_ix++)
753 if (!gi_ptr->merge[t_ix])
754 continue;
756 memset (ci_ptr->values, 0, sizeof (gcov_type) * ci_ptr->num);
757 ci_ptr++;
762 __gthread_mutex_unlock (&__gcov_flush_mx);
765 #endif /* L_gcov */
767 #ifdef L_gcov_merge_add
768 /* The profile merging function that just adds the counters. It is given
769 an array COUNTERS of N_COUNTERS old counters and it reads the same number
770 of counters from the gcov file. */
771 void
772 __gcov_merge_add (gcov_type *counters, unsigned n_counters)
774 for (; n_counters; counters++, n_counters--)
775 *counters += gcov_read_counter ();
777 #endif /* L_gcov_merge_add */
779 #ifdef L_gcov_merge_ior
780 /* The profile merging function that just adds the counters. It is given
781 an array COUNTERS of N_COUNTERS old counters and it reads the same number
782 of counters from the gcov file. */
783 void
784 __gcov_merge_ior (gcov_type *counters, unsigned n_counters)
786 for (; n_counters; counters++, n_counters--)
787 *counters |= gcov_read_counter ();
789 #endif
791 #ifdef L_gcov_merge_single
792 /* The profile merging function for choosing the most common value.
793 It is given an array COUNTERS of N_COUNTERS old counters and it
794 reads the same number of counters from the gcov file. The counters
795 are split into 3-tuples where the members of the tuple have
796 meanings:
798 -- the stored candidate on the most common value of the measured entity
799 -- counter
800 -- total number of evaluations of the value */
801 void
802 __gcov_merge_single (gcov_type *counters, unsigned n_counters)
804 unsigned i, n_measures;
805 gcov_type value, counter, all;
807 gcc_assert (!(n_counters % 3));
808 n_measures = n_counters / 3;
809 for (i = 0; i < n_measures; i++, counters += 3)
811 value = gcov_read_counter ();
812 counter = gcov_read_counter ();
813 all = gcov_read_counter ();
815 if (counters[0] == value)
816 counters[1] += counter;
817 else if (counter > counters[1])
819 counters[0] = value;
820 counters[1] = counter - counters[1];
822 else
823 counters[1] -= counter;
824 counters[2] += all;
827 #endif /* L_gcov_merge_single */
829 #ifdef L_gcov_merge_delta
830 /* The profile merging function for choosing the most common
831 difference between two consecutive evaluations of the value. It is
832 given an array COUNTERS of N_COUNTERS old counters and it reads the
833 same number of counters from the gcov file. The counters are split
834 into 4-tuples where the members of the tuple have meanings:
836 -- the last value of the measured entity
837 -- the stored candidate on the most common difference
838 -- counter
839 -- total number of evaluations of the value */
840 void
841 __gcov_merge_delta (gcov_type *counters, unsigned n_counters)
843 unsigned i, n_measures;
844 gcov_type value, counter, all;
846 gcc_assert (!(n_counters % 4));
847 n_measures = n_counters / 4;
848 for (i = 0; i < n_measures; i++, counters += 4)
850 /* last = */ gcov_read_counter ();
851 value = gcov_read_counter ();
852 counter = gcov_read_counter ();
853 all = gcov_read_counter ();
855 if (counters[1] == value)
856 counters[2] += counter;
857 else if (counter > counters[2])
859 counters[1] = value;
860 counters[2] = counter - counters[2];
862 else
863 counters[2] -= counter;
864 counters[3] += all;
867 #endif /* L_gcov_merge_delta */
869 #ifdef L_gcov_interval_profiler
870 /* If VALUE is in interval <START, START + STEPS - 1>, then increases the
871 corresponding counter in COUNTERS. If the VALUE is above or below
872 the interval, COUNTERS[STEPS] or COUNTERS[STEPS + 1] is increased
873 instead. */
875 void
876 __gcov_interval_profiler (gcov_type *counters, gcov_type value,
877 int start, unsigned steps)
879 gcov_type delta = value - start;
880 if (delta < 0)
881 counters[steps + 1]++;
882 else if (delta >= steps)
883 counters[steps]++;
884 else
885 counters[delta]++;
887 #endif
889 #ifdef L_gcov_pow2_profiler
890 /* If VALUE is a power of two, COUNTERS[1] is incremented. Otherwise
891 COUNTERS[0] is incremented. */
893 void
894 __gcov_pow2_profiler (gcov_type *counters, gcov_type value)
896 if (value & (value - 1))
897 counters[0]++;
898 else
899 counters[1]++;
901 #endif
903 /* Tries to determine the most common value among its inputs. Checks if the
904 value stored in COUNTERS[0] matches VALUE. If this is the case, COUNTERS[1]
905 is incremented. If this is not the case and COUNTERS[1] is not zero,
906 COUNTERS[1] is decremented. Otherwise COUNTERS[1] is set to one and
907 VALUE is stored to COUNTERS[0]. This algorithm guarantees that if this
908 function is called more than 50% of the time with one value, this value
909 will be in COUNTERS[0] in the end.
911 In any case, COUNTERS[2] is incremented. */
913 static inline void
914 __gcov_one_value_profiler_body (gcov_type *counters, gcov_type value)
916 if (value == counters[0])
917 counters[1]++;
918 else if (counters[1] == 0)
920 counters[1] = 1;
921 counters[0] = value;
923 else
924 counters[1]--;
925 counters[2]++;
928 #ifdef L_gcov_one_value_profiler
929 void
930 __gcov_one_value_profiler (gcov_type *counters, gcov_type value)
932 __gcov_one_value_profiler_body (counters, value);
934 #endif
936 #ifdef L_gcov_indirect_call_profiler
938 /* By default, the C++ compiler will use function addresses in the
939 vtable entries. Setting TARGET_VTABLE_USES_DESCRIPTORS to nonzero
940 tells the compiler to use function descriptors instead. The value
941 of this macro says how many words wide the descriptor is (normally 2),
942 but it may be dependent on target flags. Since we do not have access
943 to the target flags here we just check to see if it is set and use
944 that to set VTABLE_USES_DESCRIPTORS to 0 or 1.
946 It is assumed that the address of a function descriptor may be treated
947 as a pointer to a function. */
949 #ifdef TARGET_VTABLE_USES_DESCRIPTORS
950 #define VTABLE_USES_DESCRIPTORS 1
951 #else
952 #define VTABLE_USES_DESCRIPTORS 0
953 #endif
955 /* Tries to determine the most common value among its inputs. */
956 void
957 __gcov_indirect_call_profiler (gcov_type* counter, gcov_type value,
958 void* cur_func, void* callee_func)
960 /* If the C++ virtual tables contain function descriptors then one
961 function may have multiple descriptors and we need to dereference
962 the descriptors to see if they point to the same function. */
963 if (cur_func == callee_func
964 || (VTABLE_USES_DESCRIPTORS && callee_func
965 && *(void **) cur_func == *(void **) callee_func))
966 __gcov_one_value_profiler_body (counter, value);
968 #endif
971 #ifdef L_gcov_average_profiler
972 /* Increase corresponding COUNTER by VALUE. FIXME: Perhaps we want
973 to saturate up. */
975 void
976 __gcov_average_profiler (gcov_type *counters, gcov_type value)
978 counters[0] += value;
979 counters[1] ++;
981 #endif
983 #ifdef L_gcov_ior_profiler
984 /* Increase corresponding COUNTER by VALUE. FIXME: Perhaps we want
985 to saturate up. */
987 void
988 __gcov_ior_profiler (gcov_type *counters, gcov_type value)
990 *counters |= value;
992 #endif
994 #ifdef L_gcov_fork
995 /* A wrapper for the fork function. Flushes the accumulated profiling data, so
996 that they are not counted twice. */
998 pid_t
999 __gcov_fork (void)
1001 pid_t pid;
1002 extern __gthread_mutex_t __gcov_flush_mx;
1003 __gcov_flush ();
1004 pid = fork ();
1005 if (pid == 0)
1006 __GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_flush_mx);
1007 return pid;
1009 #endif
1011 #ifdef L_gcov_execl
1012 /* A wrapper for the execl function. Flushes the accumulated profiling data, so
1013 that they are not lost. */
1016 __gcov_execl (const char *path, char *arg, ...)
1018 va_list ap, aq;
1019 unsigned i, length;
1020 char **args;
1022 __gcov_flush ();
1024 va_start (ap, arg);
1025 va_copy (aq, ap);
1027 length = 2;
1028 while (va_arg (ap, char *))
1029 length++;
1030 va_end (ap);
1032 args = (char **) alloca (length * sizeof (void *));
1033 args[0] = arg;
1034 for (i = 1; i < length; i++)
1035 args[i] = va_arg (aq, char *);
1036 va_end (aq);
1038 return execv (path, args);
1040 #endif
1042 #ifdef L_gcov_execlp
1043 /* A wrapper for the execlp function. Flushes the accumulated profiling data, so
1044 that they are not lost. */
1047 __gcov_execlp (const char *path, char *arg, ...)
1049 va_list ap, aq;
1050 unsigned i, length;
1051 char **args;
1053 __gcov_flush ();
1055 va_start (ap, arg);
1056 va_copy (aq, ap);
1058 length = 2;
1059 while (va_arg (ap, char *))
1060 length++;
1061 va_end (ap);
1063 args = (char **) alloca (length * sizeof (void *));
1064 args[0] = arg;
1065 for (i = 1; i < length; i++)
1066 args[i] = va_arg (aq, char *);
1067 va_end (aq);
1069 return execvp (path, args);
1071 #endif
1073 #ifdef L_gcov_execle
1074 /* A wrapper for the execle function. Flushes the accumulated profiling data, so
1075 that they are not lost. */
1078 __gcov_execle (const char *path, char *arg, ...)
1080 va_list ap, aq;
1081 unsigned i, length;
1082 char **args;
1083 char **envp;
1085 __gcov_flush ();
1087 va_start (ap, arg);
1088 va_copy (aq, ap);
1090 length = 2;
1091 while (va_arg (ap, char *))
1092 length++;
1093 va_end (ap);
1095 args = (char **) alloca (length * sizeof (void *));
1096 args[0] = arg;
1097 for (i = 1; i < length; i++)
1098 args[i] = va_arg (aq, char *);
1099 envp = va_arg (aq, char **);
1100 va_end (aq);
1102 return execve (path, args, envp);
1104 #endif
1106 #ifdef L_gcov_execv
1107 /* A wrapper for the execv function. Flushes the accumulated profiling data, so
1108 that they are not lost. */
1111 __gcov_execv (const char *path, char *const argv[])
1113 __gcov_flush ();
1114 return execv (path, argv);
1116 #endif
1118 #ifdef L_gcov_execvp
1119 /* A wrapper for the execvp function. Flushes the accumulated profiling data, so
1120 that they are not lost. */
1123 __gcov_execvp (const char *path, char *const argv[])
1125 __gcov_flush ();
1126 return execvp (path, argv);
1128 #endif
1130 #ifdef L_gcov_execve
1131 /* A wrapper for the execve function. Flushes the accumulated profiling data, so
1132 that they are not lost. */
1135 __gcov_execve (const char *path, char *const argv[], char *const envp[])
1137 __gcov_flush ();
1138 return execve (path, argv, envp);
1140 #endif
1141 #endif /* inhibit_libc */