]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgcc/libgcov-merge.c
[multiple changes]
[thirdparty/gcc.git] / libgcc / libgcov-merge.c
CommitLineData
d6d3f033
RX
1/* Routines required for instrumenting a program. */
2/* Compile this one with gcc. */
ac1dca3c 3/* Copyright (C) 1989-2014 Free Software Foundation, Inc.
d6d3f033
RX
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 3, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17Under Section 7 of GPL version 3, you are granted additional
18permissions described in the GCC Runtime Library Exception, version
193.1, as published by the Free Software Foundation.
20
21You should have received a copy of the GNU General Public License and
22a copy of the GCC Runtime Library Exception along with this program;
23see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24<http://www.gnu.org/licenses/>. */
25
40d6b753 26#include "libgcov.h"
d6d3f033
RX
27
28#if defined(inhibit_libc)
29/* If libc and its header files are not available, provide dummy functions. */
30
31#ifdef L_gcov_merge_add
32void __gcov_merge_add (gcov_type *counters __attribute__ ((unused)),
33 unsigned n_counters __attribute__ ((unused))) {}
34#endif
35
36#ifdef L_gcov_merge_single
37void __gcov_merge_single (gcov_type *counters __attribute__ ((unused)),
38 unsigned n_counters __attribute__ ((unused))) {}
39#endif
40
41#ifdef L_gcov_merge_delta
42void __gcov_merge_delta (gcov_type *counters __attribute__ ((unused)),
43 unsigned n_counters __attribute__ ((unused))) {}
44#endif
45
46#else
47
48#ifdef L_gcov_merge_add
49/* The profile merging function that just adds the counters. It is given
50 an array COUNTERS of N_COUNTERS old counters and it reads the same number
51 of counters from the gcov file. */
52void
53__gcov_merge_add (gcov_type *counters, unsigned n_counters)
54{
55 for (; n_counters; counters++, n_counters--)
c77556a5 56 *counters += gcov_get_counter ();
d6d3f033
RX
57}
58#endif /* L_gcov_merge_add */
59
60#ifdef L_gcov_merge_ior
61/* The profile merging function that just adds the counters. It is given
62 an array COUNTERS of N_COUNTERS old counters and it reads the same number
63 of counters from the gcov file. */
64void
65__gcov_merge_ior (gcov_type *counters, unsigned n_counters)
66{
67 for (; n_counters; counters++, n_counters--)
c77556a5 68 *counters |= gcov_get_counter_target ();
d6d3f033
RX
69}
70#endif
71
72#ifdef L_gcov_merge_time_profile
73/* Time profiles are merged so that minimum from all valid (greater than zero)
74 is stored. There could be a fork that creates new counters. To have
75 the profile stable, we chosen to pick the smallest function visit time. */
76void
77__gcov_merge_time_profile (gcov_type *counters, unsigned n_counters)
78{
79 unsigned int i;
80 gcov_type value;
81
82 for (i = 0; i < n_counters; i++)
83 {
c77556a5 84 value = gcov_get_counter_target ();
d6d3f033
RX
85
86 if (value && (!counters[i] || value < counters[i]))
87 counters[i] = value;
88 }
89}
90#endif /* L_gcov_merge_time_profile */
91
92#ifdef L_gcov_merge_single
93/* The profile merging function for choosing the most common value.
94 It is given an array COUNTERS of N_COUNTERS old counters and it
95 reads the same number of counters from the gcov file. The counters
96 are split into 3-tuples where the members of the tuple have
97 meanings:
98
99 -- the stored candidate on the most common value of the measured entity
100 -- counter
101 -- total number of evaluations of the value */
102void
103__gcov_merge_single (gcov_type *counters, unsigned n_counters)
104{
105 unsigned i, n_measures;
106 gcov_type value, counter, all;
107
108 gcc_assert (!(n_counters % 3));
109 n_measures = n_counters / 3;
110 for (i = 0; i < n_measures; i++, counters += 3)
111 {
c77556a5
RX
112 value = gcov_get_counter_target ();
113 counter = gcov_get_counter ();
114 all = gcov_get_counter ();
d6d3f033
RX
115
116 if (counters[0] == value)
117 counters[1] += counter;
118 else if (counter > counters[1])
119 {
120 counters[0] = value;
121 counters[1] = counter - counters[1];
122 }
123 else
124 counters[1] -= counter;
125 counters[2] += all;
126 }
127}
128#endif /* L_gcov_merge_single */
129
130#ifdef L_gcov_merge_delta
131/* The profile merging function for choosing the most common
132 difference between two consecutive evaluations of the value. It is
133 given an array COUNTERS of N_COUNTERS old counters and it reads the
134 same number of counters from the gcov file. The counters are split
135 into 4-tuples where the members of the tuple have meanings:
136
137 -- the last value of the measured entity
138 -- the stored candidate on the most common difference
139 -- counter
140 -- total number of evaluations of the value */
141void
142__gcov_merge_delta (gcov_type *counters, unsigned n_counters)
143{
144 unsigned i, n_measures;
145 gcov_type value, counter, all;
146
147 gcc_assert (!(n_counters % 4));
148 n_measures = n_counters / 4;
149 for (i = 0; i < n_measures; i++, counters += 4)
150 {
c77556a5
RX
151 /* last = */ gcov_get_counter ();
152 value = gcov_get_counter_target ();
153 counter = gcov_get_counter ();
154 all = gcov_get_counter ();
d6d3f033
RX
155
156 if (counters[1] == value)
157 counters[2] += counter;
158 else if (counter > counters[2])
159 {
160 counters[1] = value;
161 counters[2] = counter - counters[2];
162 }
163 else
164 counters[2] -= counter;
165 counters[3] += all;
166 }
167}
168#endif /* L_gcov_merge_delta */
169#endif /* inhibit_libc */