IA MCU psABI support: changes to libraries
[gcc.git] / gcc / gcov-io.h
index b80f70696207ead8ccb42050103088bdb0ed2ab7..dcb29441f61e85e23005c1ef2808a0a86de3dfaf 100644 (file)
@@ -1,6 +1,5 @@
 /* File format for coverage information
-   Copyright (C) 1996, 1997, 1998, 2000, 2002,
-   2003, 2004, 2005, 2008, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1996-2015 Free Software Foundation, Inc.
    Contributed by Bob Manson <manson@cygnus.com>.
    Completely remangled by Nathan Sidwell <nathan@codesourcery.com>.
 
@@ -99,7 +98,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
    tags, values [41..9f] for the notes file and [a1..ff] for the data
    file.
 
-   The basic block graph file contains the following records
+   The notes file contains the following records
        note: unit function-graph*
        unit: header int32:checksum string:source
        function-graph: announce_function basic_blocks {arcs | lines}*
@@ -139,7 +138,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
        counts: header int64:count*
        summary: int32:checksum {count-summary}GCOV_COUNTERS_SUMMABLE
        count-summary:  int32:num int32:runs int64:sum
-                       int64:max int64:sum_max
+                       int64:max int64:sum_max histogram
+        histogram: {int32:bitvector}8 histogram-buckets*
+        histogram-buckets: int32:num int64:min int64:sum
 
    The ANNOUNCE_FUNCTION record is the same as that in the note file,
    but without the source location.  The COUNTS gives the
@@ -163,45 +164,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #ifndef GCC_GCOV_IO_H
 #define GCC_GCOV_IO_H
 
-#if IN_LIBGCOV
-/* About the target */
-
-#if BITS_PER_UNIT == 8
-typedef unsigned gcov_unsigned_t __attribute__ ((mode (SI)));
-typedef unsigned gcov_position_t __attribute__ ((mode (SI)));
-#if LONG_LONG_TYPE_SIZE > 32
-typedef signed gcov_type __attribute__ ((mode (DI)));
-#else
-typedef signed gcov_type __attribute__ ((mode (SI)));
-#endif
-#else
-#if BITS_PER_UNIT == 16
-typedef unsigned gcov_unsigned_t __attribute__ ((mode (HI)));
-typedef unsigned gcov_position_t __attribute__ ((mode (HI)));
-#if LONG_LONG_TYPE_SIZE > 32
-typedef signed gcov_type __attribute__ ((mode (SI)));
-#else
-typedef signed gcov_type __attribute__ ((mode (HI)));
-#endif
-#else
-typedef unsigned gcov_unsigned_t __attribute__ ((mode (QI)));
-typedef unsigned gcov_position_t __attribute__ ((mode (QI)));
-#if LONG_LONG_TYPE_SIZE > 32
-typedef signed gcov_type __attribute__ ((mode (HI)));
-#else
-typedef signed gcov_type __attribute__ ((mode (QI)));
-#endif
-#endif
-#endif
-
-
-#if defined (TARGET_POSIX_IO)
-#define GCOV_LOCKED 1
-#else
-#define GCOV_LOCKED 0
-#endif
-
-#else /* !IN_LIBGCOV */
+#ifndef IN_LIBGCOV
 /* About the host */
 
 typedef unsigned gcov_unsigned_t;
@@ -209,7 +172,8 @@ typedef unsigned gcov_position_t;
 /* gcov_type is typedef'd elsewhere for the compiler */
 #if IN_GCOV
 #define GCOV_LINKAGE static
-typedef HOST_WIDEST_INT gcov_type;
+typedef int64_t gcov_type;
+typedef uint64_t gcov_type_unsigned;
 #if IN_GCOV > 0
 #include <sys/types.h>
 #endif
@@ -223,52 +187,21 @@ typedef HOST_WIDEST_INT gcov_type;
 #define GCOV_LOCKED 0
 #endif
 
-#endif /* !IN_LIBGCOV */
-
-/* In gcov we want function linkage to be static.  In the compiler we want
-   it extern, so that they can be accessed from elsewhere.  In libgcov we
-   need these functions to be extern, so prefix them with __gcov.  In
-   libgcov they must also be hidden so that the instance in the executable
-   is not also used in a DSO.  */
-#if IN_LIBGCOV
-
-#include "tconfig.h"
-
-#define gcov_var __gcov_var
-#define gcov_open __gcov_open
-#define gcov_close __gcov_close
-#define gcov_write_tag_length __gcov_write_tag_length
-#define gcov_position __gcov_position
-#define gcov_seek __gcov_seek
-#define gcov_rewrite __gcov_rewrite
-#define gcov_is_error __gcov_is_error
-#define gcov_write_unsigned __gcov_write_unsigned
-#define gcov_write_counter __gcov_write_counter
-#define gcov_write_summary __gcov_write_summary
-#define gcov_read_unsigned __gcov_read_unsigned
-#define gcov_read_counter __gcov_read_counter
-#define gcov_read_summary __gcov_read_summary
-
-/* Poison these, so they don't accidentally slip in.  */
-#pragma GCC poison gcov_write_string gcov_write_tag gcov_write_length
-#pragma GCC poison gcov_read_string gcov_sync gcov_time gcov_magic
-
-#ifdef HAVE_GAS_HIDDEN
-#define ATTRIBUTE_HIDDEN  __attribute__ ((__visibility__ ("hidden")))
-#else
-#define ATTRIBUTE_HIDDEN
-#endif
-
-#else
-
 #define ATTRIBUTE_HIDDEN
 
-#endif
+#endif /* !IN_LIBGOCV */
 
 #ifndef GCOV_LINKAGE
 #define GCOV_LINKAGE extern
 #endif
 
+#if IN_LIBGCOV
+#define gcov_nonruntime_assert(EXPR) ((void)(0 && (EXPR)))
+#else
+#define gcov_nonruntime_assert(EXPR) gcc_assert (EXPR)
+#define gcov_error(...) fatal_error (input_location, __VA_ARGS__)
+#endif
+
 /* File suffixes.  */
 #define GCOV_DATA_SUFFIX ".gcda"
 #define GCOV_NOTE_SUFFIX ".gcno"
@@ -309,51 +242,42 @@ typedef HOST_WIDEST_INT gcov_type;
 #define GCOV_TAG_COUNTER_NUM(LENGTH) ((LENGTH) / 2)
 #define GCOV_TAG_OBJECT_SUMMARY  ((gcov_unsigned_t)0xa1000000) /* Obsolete */
 #define GCOV_TAG_PROGRAM_SUMMARY ((gcov_unsigned_t)0xa3000000)
-#define GCOV_TAG_SUMMARY_LENGTH  \
-       (1 + GCOV_COUNTERS_SUMMABLE * (2 + 3 * 2))
+#define GCOV_TAG_SUMMARY_LENGTH(NUM)  \
+        (1 + GCOV_COUNTERS_SUMMABLE * (10 + 3 * 2) + (NUM) * 5)
+#define GCOV_TAG_AFDO_FILE_NAMES ((gcov_unsigned_t)0xaa000000)
+#define GCOV_TAG_AFDO_FUNCTION ((gcov_unsigned_t)0xac000000)
+#define GCOV_TAG_AFDO_WORKING_SET ((gcov_unsigned_t)0xaf000000)
+
 
 /* Counters that are collected.  */
-#define GCOV_COUNTER_ARCS      0  /* Arc transitions.  */
-#define GCOV_COUNTERS_SUMMABLE 1  /* Counters which can be
-                                     summaried.  */
-#define GCOV_FIRST_VALUE_COUNTER 1 /* The first of counters used for value
-                                     profiling.  They must form a consecutive
-                                     interval and their order must match
-                                     the order of HIST_TYPEs in
-                                     value-prof.h.  */
-#define GCOV_COUNTER_V_INTERVAL        1  /* Histogram of value inside an interval.  */
-#define GCOV_COUNTER_V_POW2    2  /* Histogram of exact power2 logarithm
-                                     of a value.  */
-#define GCOV_COUNTER_V_SINGLE  3  /* The most common value of expression.  */
-#define GCOV_COUNTER_V_DELTA   4  /* The most common difference between
-                                     consecutive values of expression.  */
-
-#define GCOV_COUNTER_V_INDIR   5  /* The most common indirect address */
-#define GCOV_COUNTER_AVERAGE   6  /* Compute average value passed to the
-                                     counter.  */
-#define GCOV_COUNTER_IOR       7  /* IOR of the all values passed to
-                                     counter.  */
-#define GCOV_LAST_VALUE_COUNTER 7  /* The last of counters used for value
-                                     profiling.  */
-#define GCOV_COUNTERS          8
+
+#define DEF_GCOV_COUNTER(COUNTER, NAME, MERGE_FN) COUNTER,
+enum {
+#include "gcov-counter.def"
+GCOV_COUNTERS
+};
+#undef DEF_GCOV_COUNTER
+
+/* Counters which can be summaried.  */
+#define GCOV_COUNTERS_SUMMABLE (GCOV_COUNTER_ARCS + 1)
+
+/* The first of counters used for value profiling.  They must form a
+   consecutive interval and their order must match the order of
+   HIST_TYPEs in value-prof.h.  */
+#define GCOV_FIRST_VALUE_COUNTER GCOV_COUNTERS_SUMMABLE
+
+/* The last of counters used for value profiling.  */
+#define GCOV_LAST_VALUE_COUNTER (GCOV_COUNTERS - 1)
 
 /* Number of counters used for value profiling.  */
 #define GCOV_N_VALUE_COUNTERS \
   (GCOV_LAST_VALUE_COUNTER - GCOV_FIRST_VALUE_COUNTER + 1)
 
-  /* A list of human readable names of the counters */
-#define GCOV_COUNTER_NAMES     {"arcs", "interval", "pow2", "single", \
-                                "delta", "indirect_call", "average", "ior"}
+/* The number of hottest callees to be tracked.  */
+#define GCOV_ICALL_TOPN_VAL  2
 
-  /* Names of merge functions for counters.  */
-#define GCOV_MERGE_FUNCTIONS   {"__gcov_merge_add",    \
-                                "__gcov_merge_add",    \
-                                "__gcov_merge_add",    \
-                                "__gcov_merge_single", \
-                                "__gcov_merge_delta",  \
-                                "__gcov_merge_single", \
-                                "__gcov_merge_add",    \
-                                "__gcov_merge_ior"}
+/* The number of counter entries per icall callsite.  */
+#define GCOV_ICALL_TOPN_NCOUNTS (1 + GCOV_ICALL_TOPN_VAL * 4)
 
 /* Convert a counter index to a tag.  */
 #define GCOV_TAG_FOR_COUNTER(COUNT)                            \
@@ -373,7 +297,7 @@ typedef HOST_WIDEST_INT gcov_type;
 /* Return nonzero if SUB is an immediate subtag of TAG.  */
 #define GCOV_TAG_IS_SUBTAG(TAG,SUB)                            \
        (GCOV_TAG_MASK (TAG) >> 8 == GCOV_TAG_MASK (SUB)        \
-        && !(((SUB) ^ (TAG)) & ~GCOV_TAG_MASK(TAG)))
+        && !(((SUB) ^ (TAG)) & ~GCOV_TAG_MASK (TAG)))
 
 /* Return nonzero if SUB is at a sublevel to TAG.  */
 #define GCOV_TAG_IS_SUBLEVEL(TAG,SUB)                          \
@@ -389,6 +313,29 @@ typedef HOST_WIDEST_INT gcov_type;
 
 /* Structured records.  */
 
+/* Structure used for each bucket of the log2 histogram of counter values.  */
+typedef struct
+{
+  /* Number of counters whose profile count falls within the bucket.  */
+  gcov_unsigned_t num_counters;
+  /* Smallest profile count included in this bucket.  */
+  gcov_type min_value;
+  /* Cumulative value of the profile counts in this bucket.  */
+  gcov_type cum_value;
+} gcov_bucket_type;
+
+/* For a log2 scale histogram with each range split into 4
+   linear sub-ranges, there will be at most 64 (max gcov_type bit size) - 1 log2
+   ranges since the lowest 2 log2 values share the lowest 4 linear
+   sub-range (values 0 - 3).  This is 252 total entries (63*4).  */
+
+#define GCOV_HISTOGRAM_SIZE 252
+
+/* How many unsigned ints are required to hold a bit vector of non-zero
+   histogram entries when the histogram is written to the gcov file.
+   This is essentially a ceiling divide by 32 bits.  */
+#define GCOV_HISTOGRAM_BITVECTOR_SIZE (GCOV_HISTOGRAM_SIZE + 31) / 32
+
 /* Cumulative counter data.  */
 struct gcov_ctr_summary
 {
@@ -397,6 +344,8 @@ struct gcov_ctr_summary
   gcov_type sum_all;           /* sum of all counters accumulated.  */
   gcov_type run_max;           /* maximum value on a single run.  */
   gcov_type sum_max;           /* sum of individual run max values.  */
+  gcov_bucket_type histogram[GCOV_HISTOGRAM_SIZE]; /* histogram of
+                                                      counter values.  */
 };
 
 /* Object & program summary record.  */
@@ -406,121 +355,7 @@ struct gcov_summary
   struct gcov_ctr_summary ctrs[GCOV_COUNTERS_SUMMABLE];
 };
 
-/* Structures embedded in coveraged program.  The structures generated
-   by write_profile must match these.  */
-
-#if IN_LIBGCOV
-/* Information about counters for a single function.  */
-struct gcov_ctr_info
-{
-  gcov_unsigned_t num;         /* number of counters.  */
-  gcov_type *values;           /* their values.  */
-};
-
-/* Information about a single function.  This uses the trailing array
-   idiom. The number of counters is determined from the merge pointer
-   array in gcov_info.  The key is used to detect which of a set of
-   comdat functions was selected -- it points to the gcov_info object
-   of the object file containing the selected comdat function.  */
-
-struct gcov_fn_info
-{
-  const struct gcov_info *key;         /* comdat key */
-  gcov_unsigned_t ident;               /* unique ident of function */
-  gcov_unsigned_t lineno_checksum;     /* function lineo_checksum */
-  gcov_unsigned_t cfg_checksum;                /* function cfg checksum */
-  struct gcov_ctr_info ctrs[0];                /* instrumented counters */
-};
-
-/* Type of function used to merge counters.  */
-typedef void (*gcov_merge_fn) (gcov_type *, gcov_unsigned_t);
-
-/* Information about a single object file.  */
-struct gcov_info
-{
-  gcov_unsigned_t version;     /* expected version number */
-  struct gcov_info *next;      /* link to next, used by libgcov */
-
-  gcov_unsigned_t stamp;       /* uniquifying time stamp */
-  const char *filename;                /* output file name */
-
-  gcov_merge_fn merge[GCOV_COUNTERS];  /* merge functions (null for
-                                         unused) */
-  
-  unsigned n_functions;                /* number of functions */
-  const struct gcov_fn_info *const *functions; /* pointer to pointers
-                                                 to function information  */
-};
-
-/* Register a new object file module.  */
-extern void __gcov_init (struct gcov_info *) ATTRIBUTE_HIDDEN;
-
-/* Called before fork, to avoid double counting.  */
-extern void __gcov_flush (void) ATTRIBUTE_HIDDEN;
-
-/* The merge function that just sums the counters.  */
-extern void __gcov_merge_add (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
-
-/* The merge function to choose the most common value.  */
-extern void __gcov_merge_single (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
-
-/* The merge function to choose the most common difference between
-   consecutive values.  */
-extern void __gcov_merge_delta (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
-
-/* The merge function that just ors the counters together.  */
-extern void __gcov_merge_ior (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
-
-/* The profiler functions.  */
-extern void __gcov_interval_profiler (gcov_type *, gcov_type, int, unsigned);
-extern void __gcov_pow2_profiler (gcov_type *, gcov_type);
-extern void __gcov_one_value_profiler (gcov_type *, gcov_type);
-extern void __gcov_indirect_call_profiler (gcov_type *, gcov_type, void *, void *);
-extern void __gcov_average_profiler (gcov_type *, gcov_type);
-extern void __gcov_ior_profiler (gcov_type *, gcov_type);
-
-#ifndef inhibit_libc
-/* The wrappers around some library functions..  */
-extern pid_t __gcov_fork (void) ATTRIBUTE_HIDDEN;
-extern int __gcov_execl (const char *, char *, ...) ATTRIBUTE_HIDDEN;
-extern int __gcov_execlp (const char *, char *, ...) ATTRIBUTE_HIDDEN;
-extern int __gcov_execle (const char *, char *, ...) ATTRIBUTE_HIDDEN;
-extern int __gcov_execv (const char *, char *const []) ATTRIBUTE_HIDDEN;
-extern int __gcov_execvp (const char *, char *const []) ATTRIBUTE_HIDDEN;
-extern int __gcov_execve (const char *, char  *const [], char *const [])
-  ATTRIBUTE_HIDDEN;
-#endif
-
-#endif /* IN_LIBGCOV */
-
-#if IN_LIBGCOV >= 0
-
-/* Optimum number of gcov_unsigned_t's read from or written to disk.  */
-#define GCOV_BLOCK_SIZE (1 << 10)
-
-GCOV_LINKAGE struct gcov_var
-{
-  FILE *file;
-  gcov_position_t start;       /* Position of first byte of block */
-  unsigned offset;             /* Read/write position within the block.  */
-  unsigned length;             /* Read limit in the block.  */
-  unsigned overread;           /* Number of words overread.  */
-  int error;                   /* < 0 overflow, > 0 disk error.  */
-  int mode;                    /* < 0 writing, > 0 reading */
-#if IN_LIBGCOV
-  /* Holds one block plus 4 bytes, thus all coverage reads & writes
-     fit within this buffer and we always can transfer GCOV_BLOCK_SIZE
-     to and from the disk. libgcov never backtracks and only writes 4
-     or 8 byte objects.  */
-  gcov_unsigned_t buffer[GCOV_BLOCK_SIZE + 1];
-#else
-  int endian;                  /* Swap endianness.  */
-  /* Holds a variable length block, as the compiler can write
-     strings and needs to backtrack.  */
-  size_t alloc;
-  gcov_unsigned_t *buffer;
-#endif
-} gcov_var ATTRIBUTE_HIDDEN;
+#if !defined(inhibit_libc)
 
 /* Functions for reading and writing gcov files. In libgcov you can
    open the file for reading then writing. Elsewhere you can open the
@@ -531,38 +366,20 @@ GCOV_LINKAGE struct gcov_var
    you use the functions for reading, then gcov_rewrite then the
    functions for writing.  Your file may become corrupted if you break
    these invariants.  */
-#if IN_LIBGCOV
-GCOV_LINKAGE int gcov_open (const char */*name*/) ATTRIBUTE_HIDDEN;
-#else
+
+#if !IN_LIBGCOV
 GCOV_LINKAGE int gcov_open (const char */*name*/, int /*direction*/);
 GCOV_LINKAGE int gcov_magic (gcov_unsigned_t, gcov_unsigned_t);
 #endif
-GCOV_LINKAGE int gcov_close (void) ATTRIBUTE_HIDDEN;
 
 /* Available everywhere.  */
-static gcov_position_t gcov_position (void);
-static int gcov_is_error (void);
-
+GCOV_LINKAGE int gcov_close (void) ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE gcov_unsigned_t gcov_read_unsigned (void) ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE gcov_type gcov_read_counter (void) ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE void gcov_read_summary (struct gcov_summary *) ATTRIBUTE_HIDDEN;
-
-#if IN_LIBGCOV
-/* Available only in libgcov */
-GCOV_LINKAGE void gcov_write_counter (gcov_type) ATTRIBUTE_HIDDEN;
-GCOV_LINKAGE void gcov_write_tag_length (gcov_unsigned_t, gcov_unsigned_t)
-    ATTRIBUTE_HIDDEN;
-GCOV_LINKAGE void gcov_write_summary (gcov_unsigned_t /*tag*/,
-                                     const struct gcov_summary *)
-    ATTRIBUTE_HIDDEN;
-static void gcov_rewrite (void);
-GCOV_LINKAGE void gcov_seek (gcov_position_t /*position*/) ATTRIBUTE_HIDDEN;
-#else
-/* Available outside libgcov */
 GCOV_LINKAGE const char *gcov_read_string (void);
 GCOV_LINKAGE void gcov_sync (gcov_position_t /*base*/,
                             gcov_unsigned_t /*length */);
-#endif
 
 #if !IN_GCOV
 /* Available outside gcov */
@@ -571,47 +388,39 @@ GCOV_LINKAGE void gcov_write_unsigned (gcov_unsigned_t) ATTRIBUTE_HIDDEN;
 
 #if !IN_GCOV && !IN_LIBGCOV
 /* Available only in compiler */
+GCOV_LINKAGE unsigned gcov_histo_index (gcov_type value);
 GCOV_LINKAGE void gcov_write_string (const char *);
 GCOV_LINKAGE gcov_position_t gcov_write_tag (gcov_unsigned_t);
 GCOV_LINKAGE void gcov_write_length (gcov_position_t /*position*/);
 #endif
 
-#if IN_GCOV > 0
-/* Available in gcov */
-GCOV_LINKAGE time_t gcov_time (void);
-#endif
-
-/* Save the current position in the gcov file.  */
-
-static inline gcov_position_t
-gcov_position (void)
-{
-  gcc_assert (gcov_var.mode > 0);
-  return gcov_var.start + gcov_var.offset;
-}
+#if IN_GCOV <= 0 && !IN_LIBGCOV
+/* Available in gcov-dump and the compiler.  */
 
-/* Return nonzero if the error flag is set.  */
+/* Number of data points in the working set summary array. Using 128
+   provides information for at least every 1% increment of the total
+   profile size. The last entry is hardwired to 99.9% of the total.  */
+#define NUM_GCOV_WORKING_SETS 128
 
-static inline int
-gcov_is_error (void)
+/* Working set size statistics for a given percentage of the entire
+   profile (sum_all from the counter summary).  */
+typedef struct gcov_working_set_info
 {
-  return gcov_var.file ? gcov_var.error : 1;
-}
-
-#if IN_LIBGCOV
-/* Move to beginning of file and initialize for writing.  */
+  /* Number of hot counters included in this working set.  */
+  unsigned num_counters;
+  /* Smallest counter included in this working set.  */
+  gcov_type min_counter;
+} gcov_working_set_t;
+
+GCOV_LINKAGE void compute_working_sets (const struct gcov_ctr_summary *summary,
+                                        gcov_working_set_t *gcov_working_sets);
+#endif
 
-static inline void
-gcov_rewrite (void)
-{
-  gcc_assert (gcov_var.mode > 0);
-  gcov_var.mode = -1;
-  gcov_var.start = 0;
-  gcov_var.offset = 0;
-  fseek (gcov_var.file, 0L, SEEK_SET);
-}
+#if IN_GCOV > 0
+/* Available in gcov */
+GCOV_LINKAGE time_t gcov_time (void);
 #endif
 
-#endif /* IN_LIBGCOV >= 0 */
+#endif /* !inhibit_libc  */
 
 #endif /* GCC_GCOV_IO_H */