annotate gcc/profile.c @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 /* Calculate branch probabilities, and basic block execution counts.
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 Copyright (C) 1990-2020 Free Software Foundation, Inc.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
4 based on some ideas from Dain Samples of UC Berkeley.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 Further mangling by Bob Manson, Cygnus Support.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
6
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 This file is part of GCC.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 GCC is free software; you can redistribute it and/or modify it under
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 the terms of the GNU General Public License as published by the Free
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
11 Software Foundation; either version 3, or (at your option) any later
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 version.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 for more details.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
18
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
19 You should have received a copy of the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
20 along with GCC; see the file COPYING3. If not see
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 <http://www.gnu.org/licenses/>. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
22
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 /* Generate basic block profile instrumentation and auxiliary files.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
24 Profile generation is optimized, so that not all arcs in the basic
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 block graph need instrumenting. First, the BB graph is closed with
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 one entry (function start), and one exit (function exit). Any
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 ABNORMAL_EDGE cannot be instrumented (because there is no control
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
28 path to place the code). We close the graph by inserting fake
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
29 EDGE_FAKE edges to the EXIT_BLOCK, from the sources of abnormal
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
30 edges that do not go to the exit_block. We ignore such abnormal
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
31 edges. Naturally these fake edges are never directly traversed,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
32 and so *cannot* be directly instrumented. Some other graph
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
33 massaging is done. To optimize the instrumentation we generate the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
34 BB minimal span tree, only edges that are not on the span tree
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
35 (plus the entry point) need instrumenting. From that information
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 all other edge counts can be deduced. By construction all fake
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
37 edges must be on the spanning tree. We also attempt to place
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 EDGE_CRITICAL edges on the spanning tree.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
39
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
40 The auxiliary files generated are <dumpbase>.gcno (at compile time)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
41 and <dumpbase>.gcda (at run time). The format is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
42 described in full in gcov-io.h. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
43
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
44 /* ??? Register allocation should use basic block execution counts to
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
45 give preference to the most commonly executed blocks. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
46
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
47 /* ??? Should calculate branch probabilities before instrumenting code, since
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
48 then we can use arc counts to help decide which arcs to instrument. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
49
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 #include "config.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
51 #include "system.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
52 #include "coretypes.h"
111
kono
parents: 67
diff changeset
53 #include "backend.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
54 #include "rtl.h"
111
kono
parents: 67
diff changeset
55 #include "tree.h"
kono
parents: 67
diff changeset
56 #include "gimple.h"
kono
parents: 67
diff changeset
57 #include "cfghooks.h"
kono
parents: 67
diff changeset
58 #include "cgraph.h"
kono
parents: 67
diff changeset
59 #include "coverage.h"
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
60 #include "diagnostic-core.h"
111
kono
parents: 67
diff changeset
61 #include "cfganal.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
62 #include "value-prof.h"
111
kono
parents: 67
diff changeset
63 #include "gimple-iterator.h"
kono
parents: 67
diff changeset
64 #include "tree-cfg.h"
kono
parents: 67
diff changeset
65 #include "dumpfile.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
66 #include "cfgloop.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
67
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
68 #include "profile.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
69
111
kono
parents: 67
diff changeset
70 /* Map from BBs/edges to gcov counters. */
kono
parents: 67
diff changeset
71 vec<gcov_type> bb_gcov_counts;
kono
parents: 67
diff changeset
72 hash_map<edge,gcov_type> *edge_gcov_counts;
kono
parents: 67
diff changeset
73
kono
parents: 67
diff changeset
74 struct bb_profile_info {
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
75 unsigned int count_valid : 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
76
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
77 /* Number of successor and predecessor edges. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
78 gcov_type succ_count;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
79 gcov_type pred_count;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
80 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
81
111
kono
parents: 67
diff changeset
82 #define BB_INFO(b) ((struct bb_profile_info *) (b)->aux)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
83
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
84
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
85 /* Counter summary from the last set of coverage counts read. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
86
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
87 gcov_summary *profile_info;
111
kono
parents: 67
diff changeset
88
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
89 /* Collect statistics on the performance of this pass for the entire source
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
90 file. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
91
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
92 static int total_num_blocks;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
93 static int total_num_edges;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
94 static int total_num_edges_ignored;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
95 static int total_num_edges_instrumented;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
96 static int total_num_blocks_created;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
97 static int total_num_passes;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
98 static int total_num_times_called;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
99 static int total_hist_br_prob[20];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
100 static int total_num_branches;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
101
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
102 /* Forward declarations. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
103 static void find_spanning_tree (struct edge_list *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
104
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
105 /* Add edge instrumentation code to the entire insn chain.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
106
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
107 F is the first insn of the chain.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 NUM_BLOCKS is the number of basic blocks found in F. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
109
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
110 static unsigned
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
111 instrument_edges (struct edge_list *el)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
112 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
113 unsigned num_instr_edges = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
114 int num_edges = NUM_EDGES (el);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
115 basic_block bb;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
116
111
kono
parents: 67
diff changeset
117 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
118 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
119 edge e;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
120 edge_iterator ei;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
121
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
122 FOR_EACH_EDGE (e, ei, bb->succs)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
123 {
111
kono
parents: 67
diff changeset
124 struct edge_profile_info *inf = EDGE_INFO (e);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
125
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
126 if (!inf->ignore && !inf->on_tree)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
127 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
128 gcc_assert (!(e->flags & EDGE_ABNORMAL));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
129 if (dump_file)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
130 fprintf (dump_file, "Edge %d to %d instrumented%s\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
131 e->src->index, e->dest->index,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
132 EDGE_CRITICAL_P (e) ? " (and split)" : "");
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
133 gimple_gen_edge_profiler (num_instr_edges++, e);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
134 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
135 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
136 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
137
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
138 total_num_blocks_created += num_edges;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
139 if (dump_file)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
140 fprintf (dump_file, "%d edges instrumented\n", num_instr_edges);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
141 return num_instr_edges;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
142 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
143
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
144 /* Add code to measure histograms for values in list VALUES. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
145 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
146 instrument_values (histogram_values values)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
147 {
111
kono
parents: 67
diff changeset
148 unsigned i;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
149
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
150 /* Emit code to generate the histograms before the insns. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
151
111
kono
parents: 67
diff changeset
152 for (i = 0; i < values.length (); i++)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
153 {
111
kono
parents: 67
diff changeset
154 histogram_value hist = values[i];
kono
parents: 67
diff changeset
155 unsigned t = COUNTER_FOR_HIST_TYPE (hist->type);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
156
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
157 if (!coverage_counter_alloc (t, hist->n_counters))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
158 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
159
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
160 switch (hist->type)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
161 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
162 case HIST_TYPE_INTERVAL:
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
163 gimple_gen_interval_profiler (hist, t);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
164 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
165
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
166 case HIST_TYPE_POW2:
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
167 gimple_gen_pow2_profiler (hist, t);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
168 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
169
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
170 case HIST_TYPE_TOPN_VALUES:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
171 gimple_gen_topn_values_profiler (hist, t);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
172 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
173
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
174 case HIST_TYPE_INDIR_CALL:
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
175 gimple_gen_ic_profiler (hist, t);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
176 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
177
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
178 case HIST_TYPE_AVERAGE:
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
179 gimple_gen_average_profiler (hist, t);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
180 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
181
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
182 case HIST_TYPE_IOR:
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
183 gimple_gen_ior_profiler (hist, t);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
184 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
185
111
kono
parents: 67
diff changeset
186 case HIST_TYPE_TIME_PROFILE:
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
187 gimple_gen_time_profiler (t);
111
kono
parents: 67
diff changeset
188 break;
kono
parents: 67
diff changeset
189
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
190 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
191 gcc_unreachable ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
192 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
193 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
194 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
195
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
196
111
kono
parents: 67
diff changeset
197 /* Computes hybrid profile for all matching entries in da_file.
kono
parents: 67
diff changeset
198
kono
parents: 67
diff changeset
199 CFG_CHECKSUM is the precomputed checksum for the CFG. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
200
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
201 static gcov_type *
111
kono
parents: 67
diff changeset
202 get_exec_counts (unsigned cfg_checksum, unsigned lineno_checksum)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
203 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
204 unsigned num_edges = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
205 basic_block bb;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
206 gcov_type *counts;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
207
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
208 /* Count the edges to be (possibly) instrumented. */
111
kono
parents: 67
diff changeset
209 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
210 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
211 edge e;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
212 edge_iterator ei;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
213
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
214 FOR_EACH_EDGE (e, ei, bb->succs)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
215 if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
216 num_edges++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
217 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
218
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
219 counts = get_coverage_counts (GCOV_COUNTER_ARCS, cfg_checksum,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
220 lineno_checksum, num_edges);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
221 if (!counts)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
222 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
223
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
224 return counts;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
225 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
226
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
227 static bool
111
kono
parents: 67
diff changeset
228 is_edge_inconsistent (vec<edge, va_gc> *edges)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
229 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
230 edge e;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
231 edge_iterator ei;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
232 FOR_EACH_EDGE (e, ei, edges)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
233 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
234 if (!EDGE_INFO (e)->ignore)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
235 {
111
kono
parents: 67
diff changeset
236 if (edge_gcov_count (e) < 0
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
237 && (!(e->flags & EDGE_FAKE)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
238 || !block_ends_with_call_p (e->src)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
239 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
240 if (dump_file)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
241 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
242 fprintf (dump_file,
111
kono
parents: 67
diff changeset
243 "Edge %i->%i is inconsistent, count%" PRId64,
kono
parents: 67
diff changeset
244 e->src->index, e->dest->index, edge_gcov_count (e));
kono
parents: 67
diff changeset
245 dump_bb (dump_file, e->src, 0, TDF_DETAILS);
kono
parents: 67
diff changeset
246 dump_bb (dump_file, e->dest, 0, TDF_DETAILS);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
247 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
248 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
249 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
250 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
251 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
252 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
253 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
254
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
255 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
256 correct_negative_edge_counts (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
257 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
258 basic_block bb;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
259 edge e;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
260 edge_iterator ei;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
261
111
kono
parents: 67
diff changeset
262 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
263 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
264 FOR_EACH_EDGE (e, ei, bb->succs)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
265 {
111
kono
parents: 67
diff changeset
266 if (edge_gcov_count (e) < 0)
kono
parents: 67
diff changeset
267 edge_gcov_count (e) = 0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
268 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
269 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
270 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
271
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
272 /* Check consistency.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
273 Return true if inconsistency is found. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
274 static bool
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
275 is_inconsistent (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
276 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
277 basic_block bb;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
278 bool inconsistent = false;
111
kono
parents: 67
diff changeset
279 FOR_EACH_BB_FN (bb, cfun)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
280 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
281 inconsistent |= is_edge_inconsistent (bb->preds);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
282 if (!dump_file && inconsistent)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
283 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
284 inconsistent |= is_edge_inconsistent (bb->succs);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
285 if (!dump_file && inconsistent)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
286 return true;
111
kono
parents: 67
diff changeset
287 if (bb_gcov_count (bb) < 0)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
288 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
289 if (dump_file)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
290 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
291 fprintf (dump_file, "BB %i count is negative "
111
kono
parents: 67
diff changeset
292 "%" PRId64,
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
293 bb->index,
111
kono
parents: 67
diff changeset
294 bb_gcov_count (bb));
kono
parents: 67
diff changeset
295 dump_bb (dump_file, bb, 0, TDF_DETAILS);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
296 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
297 inconsistent = true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
298 }
111
kono
parents: 67
diff changeset
299 if (bb_gcov_count (bb) != sum_edge_counts (bb->preds))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
300 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
301 if (dump_file)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
302 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
303 fprintf (dump_file, "BB %i count does not match sum of incoming edges "
111
kono
parents: 67
diff changeset
304 "%" PRId64" should be %" PRId64,
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
305 bb->index,
111
kono
parents: 67
diff changeset
306 bb_gcov_count (bb),
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
307 sum_edge_counts (bb->preds));
111
kono
parents: 67
diff changeset
308 dump_bb (dump_file, bb, 0, TDF_DETAILS);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
309 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
310 inconsistent = true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
311 }
111
kono
parents: 67
diff changeset
312 if (bb_gcov_count (bb) != sum_edge_counts (bb->succs) &&
kono
parents: 67
diff changeset
313 ! (find_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun)) != NULL
kono
parents: 67
diff changeset
314 && block_ends_with_call_p (bb)))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
315 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
316 if (dump_file)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
317 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
318 fprintf (dump_file, "BB %i count does not match sum of outgoing edges "
111
kono
parents: 67
diff changeset
319 "%" PRId64" should be %" PRId64,
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
320 bb->index,
111
kono
parents: 67
diff changeset
321 bb_gcov_count (bb),
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
322 sum_edge_counts (bb->succs));
111
kono
parents: 67
diff changeset
323 dump_bb (dump_file, bb, 0, TDF_DETAILS);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
324 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
325 inconsistent = true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
326 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
327 if (!dump_file && inconsistent)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
328 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
329 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
330
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
331 return inconsistent;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
332 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
333
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
334 /* Set each basic block count to the sum of its outgoing edge counts */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
335 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
336 set_bb_counts (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
337 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
338 basic_block bb;
111
kono
parents: 67
diff changeset
339 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
340 {
111
kono
parents: 67
diff changeset
341 bb_gcov_count (bb) = sum_edge_counts (bb->succs);
kono
parents: 67
diff changeset
342 gcc_assert (bb_gcov_count (bb) >= 0);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
343 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
344 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
345
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
346 /* Reads profile data and returns total number of edge counts read */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
347 static int
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
348 read_profile_edge_counts (gcov_type *exec_counts)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
349 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
350 basic_block bb;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
351 int num_edges = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
352 int exec_counts_pos = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
353 /* For each edge not on the spanning tree, set its execution count from
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
354 the .da file. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
355 /* The first count in the .da file is the number of times that the function
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
356 was entered. This is the exec_count for block zero. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
357
111
kono
parents: 67
diff changeset
358 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
359 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
360 edge e;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
361 edge_iterator ei;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
362
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
363 FOR_EACH_EDGE (e, ei, bb->succs)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
364 if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
365 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
366 num_edges++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
367 if (exec_counts)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
368 edge_gcov_count (e) = exec_counts[exec_counts_pos++];
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
369 else
111
kono
parents: 67
diff changeset
370 edge_gcov_count (e) = 0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
371
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
372 EDGE_INFO (e)->count_valid = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
373 BB_INFO (bb)->succ_count--;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
374 BB_INFO (e->dest)->pred_count--;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
375 if (dump_file)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
376 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
377 fprintf (dump_file, "\nRead edge from %i to %i, count:",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
378 bb->index, e->dest->index);
111
kono
parents: 67
diff changeset
379 fprintf (dump_file, "%" PRId64,
kono
parents: 67
diff changeset
380 (int64_t) edge_gcov_count (e));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
381 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
382 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
383 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
384
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
385 return num_edges;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
386 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
387
111
kono
parents: 67
diff changeset
388
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
389 /* Compute the branch probabilities for the various branches.
111
kono
parents: 67
diff changeset
390 Annotate them accordingly.
kono
parents: 67
diff changeset
391
kono
parents: 67
diff changeset
392 CFG_CHECKSUM is the precomputed checksum for the CFG. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
393
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
394 static void
111
kono
parents: 67
diff changeset
395 compute_branch_probabilities (unsigned cfg_checksum, unsigned lineno_checksum)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
396 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
397 basic_block bb;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
398 int i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
399 int num_edges = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
400 int changes;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
401 int passes;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
402 int hist_br_prob[20];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
403 int num_branches;
111
kono
parents: 67
diff changeset
404 gcov_type *exec_counts = get_exec_counts (cfg_checksum, lineno_checksum);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
405 int inconsistent = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
406
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
407 /* Very simple sanity checks so we catch bugs in our profiling code. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
408 if (!profile_info)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
409 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
410 if (dump_file)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
411 fprintf (dump_file, "Profile info is missing; giving up\n");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
412 return;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
413 }
111
kono
parents: 67
diff changeset
414
kono
parents: 67
diff changeset
415 bb_gcov_counts.safe_grow_cleared (last_basic_block_for_fn (cfun));
kono
parents: 67
diff changeset
416 edge_gcov_counts = new hash_map<edge,gcov_type>;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
417
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
418 /* Attach extra info block to each bb. */
111
kono
parents: 67
diff changeset
419 alloc_aux_for_blocks (sizeof (struct bb_profile_info));
kono
parents: 67
diff changeset
420 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
421 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
422 edge e;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
423 edge_iterator ei;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
424
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
425 FOR_EACH_EDGE (e, ei, bb->succs)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
426 if (!EDGE_INFO (e)->ignore)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
427 BB_INFO (bb)->succ_count++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
428 FOR_EACH_EDGE (e, ei, bb->preds)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
429 if (!EDGE_INFO (e)->ignore)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
430 BB_INFO (bb)->pred_count++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
431 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
432
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
433 /* Avoid predicting entry on exit nodes. */
111
kono
parents: 67
diff changeset
434 BB_INFO (EXIT_BLOCK_PTR_FOR_FN (cfun))->succ_count = 2;
kono
parents: 67
diff changeset
435 BB_INFO (ENTRY_BLOCK_PTR_FOR_FN (cfun))->pred_count = 2;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
436
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
437 num_edges = read_profile_edge_counts (exec_counts);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
438
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
439 if (dump_file)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
440 fprintf (dump_file, "\n%d edge counts read\n", num_edges);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
441
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
442 /* For every block in the file,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
443 - if every exit/entrance edge has a known count, then set the block count
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
444 - if the block count is known, and every exit/entrance edge but one has
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
445 a known execution count, then set the count of the remaining edge
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
446
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
447 As edge counts are set, decrement the succ/pred count, but don't delete
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
448 the edge, that way we can easily tell when all edges are known, or only
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
449 one edge is unknown. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
450
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
451 /* The order that the basic blocks are iterated through is important.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
452 Since the code that finds spanning trees starts with block 0, low numbered
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
453 edges are put on the spanning tree in preference to high numbered edges.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
454 Hence, most instrumented edges are at the end. Graph solving works much
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
455 faster if we propagate numbers from the end to the start.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
456
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
457 This takes an average of slightly more than 3 passes. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
458
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
459 changes = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
460 passes = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
461 while (changes)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
462 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
463 passes++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
464 changes = 0;
111
kono
parents: 67
diff changeset
465 FOR_BB_BETWEEN (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), NULL, prev_bb)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
466 {
111
kono
parents: 67
diff changeset
467 struct bb_profile_info *bi = BB_INFO (bb);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
468 if (! bi->count_valid)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
469 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
470 if (bi->succ_count == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
471 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
472 edge e;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
473 edge_iterator ei;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
474 gcov_type total = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
475
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
476 FOR_EACH_EDGE (e, ei, bb->succs)
111
kono
parents: 67
diff changeset
477 total += edge_gcov_count (e);
kono
parents: 67
diff changeset
478 bb_gcov_count (bb) = total;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
479 bi->count_valid = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
480 changes = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
481 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
482 else if (bi->pred_count == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
483 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
484 edge e;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
485 edge_iterator ei;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
486 gcov_type total = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
487
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
488 FOR_EACH_EDGE (e, ei, bb->preds)
111
kono
parents: 67
diff changeset
489 total += edge_gcov_count (e);
kono
parents: 67
diff changeset
490 bb_gcov_count (bb) = total;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
491 bi->count_valid = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
492 changes = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
493 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
494 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
495 if (bi->count_valid)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
496 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
497 if (bi->succ_count == 1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
498 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
499 edge e;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
500 edge_iterator ei;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
501 gcov_type total = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
502
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
503 /* One of the counts will be invalid, but it is zero,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
504 so adding it in also doesn't hurt. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
505 FOR_EACH_EDGE (e, ei, bb->succs)
111
kono
parents: 67
diff changeset
506 total += edge_gcov_count (e);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
507
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
508 /* Search for the invalid edge, and set its count. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
509 FOR_EACH_EDGE (e, ei, bb->succs)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
510 if (! EDGE_INFO (e)->count_valid && ! EDGE_INFO (e)->ignore)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
511 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
512
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
513 /* Calculate count for remaining edge by conservation. */
111
kono
parents: 67
diff changeset
514 total = bb_gcov_count (bb) - total;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
515
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
516 gcc_assert (e);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
517 EDGE_INFO (e)->count_valid = 1;
111
kono
parents: 67
diff changeset
518 edge_gcov_count (e) = total;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
519 bi->succ_count--;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
520
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
521 BB_INFO (e->dest)->pred_count--;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
522 changes = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
523 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
524 if (bi->pred_count == 1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
525 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
526 edge e;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
527 edge_iterator ei;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
528 gcov_type total = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
529
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
530 /* One of the counts will be invalid, but it is zero,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
531 so adding it in also doesn't hurt. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
532 FOR_EACH_EDGE (e, ei, bb->preds)
111
kono
parents: 67
diff changeset
533 total += edge_gcov_count (e);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
534
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
535 /* Search for the invalid edge, and set its count. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
536 FOR_EACH_EDGE (e, ei, bb->preds)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
537 if (!EDGE_INFO (e)->count_valid && !EDGE_INFO (e)->ignore)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
538 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
539
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
540 /* Calculate count for remaining edge by conservation. */
111
kono
parents: 67
diff changeset
541 total = bb_gcov_count (bb) - total + edge_gcov_count (e);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
542
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
543 gcc_assert (e);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
544 EDGE_INFO (e)->count_valid = 1;
111
kono
parents: 67
diff changeset
545 edge_gcov_count (e) = total;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
546 bi->pred_count--;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
547
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
548 BB_INFO (e->src)->succ_count--;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
549 changes = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
550 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
551 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
552 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
553 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
554
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
555 total_num_passes += passes;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
556 if (dump_file)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
557 fprintf (dump_file, "Graph solving took %d passes.\n\n", passes);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
558
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
559 /* If the graph has been correctly solved, every block will have a
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
560 succ and pred count of zero. */
111
kono
parents: 67
diff changeset
561 FOR_EACH_BB_FN (bb, cfun)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
562 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
563 gcc_assert (!BB_INFO (bb)->succ_count && !BB_INFO (bb)->pred_count);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
564 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
565
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
566 /* Check for inconsistent basic block counts */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
567 inconsistent = is_inconsistent ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
568
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
569 if (inconsistent)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
570 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
571 if (flag_profile_correction)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
572 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
573 /* Inconsistency detected. Make it flow-consistent. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
574 static int informed = 0;
111
kono
parents: 67
diff changeset
575 if (dump_enabled_p () && informed == 0)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
576 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
577 informed = 1;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
578 dump_printf_loc (MSG_NOTE,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
579 dump_user_location_t::from_location_t (input_location),
111
kono
parents: 67
diff changeset
580 "correcting inconsistent profile data\n");
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
581 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
582 correct_negative_edge_counts ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
583 /* Set bb counts to the sum of the outgoing edge counts */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
584 set_bb_counts ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
585 if (dump_file)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
586 fprintf (dump_file, "\nCalling mcf_smooth_cfg\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
587 mcf_smooth_cfg ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
588 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
589 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
590 error ("corrupted profile info: profile data is not flow-consistent");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
591 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
592
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
593 /* For every edge, calculate its branch probability and add a reg_note
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
594 to the branch insn to indicate this. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
595
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
596 for (i = 0; i < 20; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
597 hist_br_prob[i] = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
598 num_branches = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
599
111
kono
parents: 67
diff changeset
600 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
601 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
602 edge e;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
603 edge_iterator ei;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
604
111
kono
parents: 67
diff changeset
605 if (bb_gcov_count (bb) < 0)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
606 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
607 error ("corrupted profile info: number of iterations for basic block %d thought to be %i",
111
kono
parents: 67
diff changeset
608 bb->index, (int)bb_gcov_count (bb));
kono
parents: 67
diff changeset
609 bb_gcov_count (bb) = 0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
610 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
611 FOR_EACH_EDGE (e, ei, bb->succs)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
612 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
613 /* Function may return twice in the cased the called function is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
614 setjmp or calls fork, but we can't represent this by extra
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
615 edge from the entry, since extra edge from the exit is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
616 already present. We get negative frequency from the entry
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
617 point. */
111
kono
parents: 67
diff changeset
618 if ((edge_gcov_count (e) < 0
kono
parents: 67
diff changeset
619 && e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
kono
parents: 67
diff changeset
620 || (edge_gcov_count (e) > bb_gcov_count (bb)
kono
parents: 67
diff changeset
621 && e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
622 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
623 if (block_ends_with_call_p (bb))
111
kono
parents: 67
diff changeset
624 edge_gcov_count (e) = edge_gcov_count (e) < 0
kono
parents: 67
diff changeset
625 ? 0 : bb_gcov_count (bb);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
626 }
111
kono
parents: 67
diff changeset
627 if (edge_gcov_count (e) < 0
kono
parents: 67
diff changeset
628 || edge_gcov_count (e) > bb_gcov_count (bb))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
629 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
630 error ("corrupted profile info: number of executions for edge %d-%d thought to be %i",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
631 e->src->index, e->dest->index,
111
kono
parents: 67
diff changeset
632 (int)edge_gcov_count (e));
kono
parents: 67
diff changeset
633 edge_gcov_count (e) = bb_gcov_count (bb) / 2;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
634 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
635 }
111
kono
parents: 67
diff changeset
636 if (bb_gcov_count (bb))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
637 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
638 bool set_to_guessed = false;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
639 FOR_EACH_EDGE (e, ei, bb->succs)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
640 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
641 bool prev_never = e->probability == profile_probability::never ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
642 e->probability = profile_probability::probability_in_gcov_type
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
643 (edge_gcov_count (e), bb_gcov_count (bb));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
644 if (e->probability == profile_probability::never ()
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
645 && !prev_never
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
646 && flag_profile_partial_training)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
647 set_to_guessed = true;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
648 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
649 if (set_to_guessed)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
650 FOR_EACH_EDGE (e, ei, bb->succs)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
651 e->probability = e->probability.guessed ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
652 if (bb->index >= NUM_FIXED_BLOCKS
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
653 && block_ends_with_condjump_p (bb)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
654 && EDGE_COUNT (bb->succs) >= 2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
655 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
656 int prob;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
657 edge e;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
658 int index;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
659
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
660 /* Find the branch edge. It is possible that we do have fake
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
661 edges here. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
662 FOR_EACH_EDGE (e, ei, bb->succs)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
663 if (!(e->flags & (EDGE_FAKE | EDGE_FALLTHRU)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
664 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
665
111
kono
parents: 67
diff changeset
666 prob = e->probability.to_reg_br_prob_base ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
667 index = prob * 20 / REG_BR_PROB_BASE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
668
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
669 if (index == 20)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
670 index = 19;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
671 hist_br_prob[index]++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
672
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
673 num_branches++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
674 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
675 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
676 /* As a last resort, distribute the probabilities evenly.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
677 Use simple heuristics that if there are normal edges,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
678 give all abnormals frequency of 0, otherwise distribute the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
679 frequency over abnormals (this is the case of noreturn
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
680 calls). */
111
kono
parents: 67
diff changeset
681 else if (profile_status_for_fn (cfun) == PROFILE_ABSENT)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
682 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
683 int total = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
684
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
685 FOR_EACH_EDGE (e, ei, bb->succs)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
686 if (!(e->flags & (EDGE_COMPLEX | EDGE_FAKE)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
687 total ++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
688 if (total)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
689 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
690 FOR_EACH_EDGE (e, ei, bb->succs)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
691 if (!(e->flags & (EDGE_COMPLEX | EDGE_FAKE)))
111
kono
parents: 67
diff changeset
692 e->probability
kono
parents: 67
diff changeset
693 = profile_probability::guessed_always ().apply_scale (1, total);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
694 else
111
kono
parents: 67
diff changeset
695 e->probability = profile_probability::never ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
696 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
697 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
698 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
699 total += EDGE_COUNT (bb->succs);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
700 FOR_EACH_EDGE (e, ei, bb->succs)
111
kono
parents: 67
diff changeset
701 e->probability
kono
parents: 67
diff changeset
702 = profile_probability::guessed_always ().apply_scale (1, total);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
703 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
704 if (bb->index >= NUM_FIXED_BLOCKS
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
705 && block_ends_with_condjump_p (bb)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
706 && EDGE_COUNT (bb->succs) >= 2)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
707 num_branches++;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
708 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
709 }
111
kono
parents: 67
diff changeset
710
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
711 if (exec_counts
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
712 && (bb_gcov_count (ENTRY_BLOCK_PTR_FOR_FN (cfun))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
713 || !flag_profile_partial_training))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
714 profile_status_for_fn (cfun) = PROFILE_READ;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
715
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
716 /* If we have real data, use them! */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
717 if (bb_gcov_count (ENTRY_BLOCK_PTR_FOR_FN (cfun))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
718 || !flag_guess_branch_prob)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
719 FOR_ALL_BB_FN (bb, cfun)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
720 if (bb_gcov_count (bb) || !flag_profile_partial_training)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
721 bb->count = profile_count::from_gcov_type (bb_gcov_count (bb));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
722 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
723 bb->count = profile_count::guessed_zero ();
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
724 /* If function was not trained, preserve local estimates including statically
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
725 determined zero counts. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
726 else if (profile_status_for_fn (cfun) == PROFILE_READ
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
727 && !flag_profile_partial_training)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
728 FOR_ALL_BB_FN (bb, cfun)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
729 if (!(bb->count == profile_count::zero ()))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
730 bb->count = bb->count.global0 ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
731
111
kono
parents: 67
diff changeset
732 bb_gcov_counts.release ();
kono
parents: 67
diff changeset
733 delete edge_gcov_counts;
kono
parents: 67
diff changeset
734 edge_gcov_counts = NULL;
kono
parents: 67
diff changeset
735
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
736 update_max_bb_count ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
737
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
738 if (dump_file)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
739 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
740 fprintf (dump_file, " Profile feedback for function");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
741 fprintf (dump_file, ((profile_status_for_fn (cfun) == PROFILE_READ)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
742 ? " is available \n"
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
743 : " is not available \n"));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
744
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
745 fprintf (dump_file, "%d branches\n", num_branches);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
746 if (num_branches)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
747 for (i = 0; i < 10; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
748 fprintf (dump_file, "%d%% branches in range %d-%d%%\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
749 (hist_br_prob[i] + hist_br_prob[19-i]) * 100 / num_branches,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
750 5 * i, 5 * i + 5);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
751
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
752 total_num_branches += num_branches;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
753 for (i = 0; i < 20; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
754 total_hist_br_prob[i] += hist_br_prob[i];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
755
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
756 fputc ('\n', dump_file);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
757 fputc ('\n', dump_file);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
758 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
759
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
760 free_aux_for_blocks ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
761 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
762
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
763 /* Sort the histogram value and count for TOPN and INDIR_CALL type. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
764
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
765 static void
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
766 sort_hist_values (histogram_value hist)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
767 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
768 /* counters[2] equal to -1 means that all counters are invalidated. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
769 if (hist->hvalue.counters[2] == -1)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
770 return;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
771
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
772 gcc_assert (hist->type == HIST_TYPE_TOPN_VALUES
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
773 || hist->type == HIST_TYPE_INDIR_CALL);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
774
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
775 gcc_assert (hist->n_counters == GCOV_TOPN_VALUES_COUNTERS);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
776
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
777 /* Hist value is organized as:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
778 [total_executions, value1, counter1, ..., value4, counter4]
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
779 Use decrease bubble sort to rearrange it. The sort starts from <value1,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
780 counter1> and compares counter first. If counter is same, compares the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
781 value, exchange it if small to keep stable. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
782 for (unsigned i = 0; i < GCOV_TOPN_VALUES - 1; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
783 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
784 bool swapped = false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
785 for (unsigned j = 0; j < GCOV_TOPN_VALUES - 1 - i; j++)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
786 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
787 gcov_type *p = &hist->hvalue.counters[2 * j + 1];
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
788 if (p[1] < p[3] || (p[1] == p[3] && p[0] < p[2]))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
789 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
790 std::swap (p[0], p[2]);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
791 std::swap (p[1], p[3]);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
792 swapped = true;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
793 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
794 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
795 if (!swapped)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
796 break;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
797 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
798 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
799 /* Load value histograms values whose description is stored in VALUES array
111
kono
parents: 67
diff changeset
800 from .gcda file.
kono
parents: 67
diff changeset
801
kono
parents: 67
diff changeset
802 CFG_CHECKSUM is the precomputed checksum for the CFG. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
803
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
804 static void
111
kono
parents: 67
diff changeset
805 compute_value_histograms (histogram_values values, unsigned cfg_checksum,
kono
parents: 67
diff changeset
806 unsigned lineno_checksum)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
807 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
808 unsigned i, j, t, any;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
809 unsigned n_histogram_counters[GCOV_N_VALUE_COUNTERS];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
810 gcov_type *histogram_counts[GCOV_N_VALUE_COUNTERS];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
811 gcov_type *act_count[GCOV_N_VALUE_COUNTERS];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
812 gcov_type *aact_count;
111
kono
parents: 67
diff changeset
813 struct cgraph_node *node;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
814
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
815 for (t = 0; t < GCOV_N_VALUE_COUNTERS; t++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
816 n_histogram_counters[t] = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
817
111
kono
parents: 67
diff changeset
818 for (i = 0; i < values.length (); i++)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
819 {
111
kono
parents: 67
diff changeset
820 histogram_value hist = values[i];
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
821 n_histogram_counters[(int) hist->type] += hist->n_counters;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
822 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
823
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
824 any = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
825 for (t = 0; t < GCOV_N_VALUE_COUNTERS; t++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
826 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
827 if (!n_histogram_counters[t])
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
828 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
829 histogram_counts[t] = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
830 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
831 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
832
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
833 histogram_counts[t] = get_coverage_counts (COUNTER_FOR_HIST_TYPE (t),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
834 cfg_checksum,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
835 lineno_checksum,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
836 n_histogram_counters[t]);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
837 if (histogram_counts[t])
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
838 any = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
839 act_count[t] = histogram_counts[t];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
840 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
841 if (!any)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
842 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
843
111
kono
parents: 67
diff changeset
844 for (i = 0; i < values.length (); i++)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
845 {
111
kono
parents: 67
diff changeset
846 histogram_value hist = values[i];
kono
parents: 67
diff changeset
847 gimple *stmt = hist->hvalue.stmt;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
848
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
849 t = (int) hist->type;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
850
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
851 aact_count = act_count[t];
111
kono
parents: 67
diff changeset
852
kono
parents: 67
diff changeset
853 if (act_count[t])
kono
parents: 67
diff changeset
854 act_count[t] += hist->n_counters;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
855
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
856 gimple_add_histogram_value (cfun, stmt, hist);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
857 hist->hvalue.counters = XNEWVEC (gcov_type, hist->n_counters);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
858 for (j = 0; j < hist->n_counters; j++)
111
kono
parents: 67
diff changeset
859 if (aact_count)
kono
parents: 67
diff changeset
860 hist->hvalue.counters[j] = aact_count[j];
kono
parents: 67
diff changeset
861 else
kono
parents: 67
diff changeset
862 hist->hvalue.counters[j] = 0;
kono
parents: 67
diff changeset
863
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
864 if (hist->type == HIST_TYPE_TOPN_VALUES
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
865 || hist->type == HIST_TYPE_INDIR_CALL)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
866 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
867 /* Each count value is multiplied by GCOV_TOPN_VALUES. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
868 if (hist->hvalue.counters[2] != -1)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
869 for (unsigned i = 0; i < GCOV_TOPN_VALUES; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
870 hist->hvalue.counters[2 * i + 2]
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
871 = RDIV (hist->hvalue.counters[2 * i + 2], GCOV_TOPN_VALUES);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
872
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
873 sort_hist_values (hist);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
874 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
875
111
kono
parents: 67
diff changeset
876 /* Time profiler counter is not related to any statement,
kono
parents: 67
diff changeset
877 so that we have to read the counter and set the value to
kono
parents: 67
diff changeset
878 the corresponding call graph node. */
kono
parents: 67
diff changeset
879 if (hist->type == HIST_TYPE_TIME_PROFILE)
kono
parents: 67
diff changeset
880 {
kono
parents: 67
diff changeset
881 node = cgraph_node::get (hist->fun->decl);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
882 if (hist->hvalue.counters[0] >= 0
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
883 && hist->hvalue.counters[0] < INT_MAX / 2)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
884 node->tp_first_run = hist->hvalue.counters[0];
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
885 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
886 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
887 if (flag_profile_correction)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
888 error ("corrupted profile info: invalid time profile");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
889 node->tp_first_run = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
890 }
111
kono
parents: 67
diff changeset
891
kono
parents: 67
diff changeset
892 if (dump_file)
kono
parents: 67
diff changeset
893 fprintf (dump_file, "Read tp_first_run: %d\n", node->tp_first_run);
kono
parents: 67
diff changeset
894 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
895 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
896
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
897 for (t = 0; t < GCOV_N_VALUE_COUNTERS; t++)
111
kono
parents: 67
diff changeset
898 free (histogram_counts[t]);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
899 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
900
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
901 /* Location triplet which records a location. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
902 struct location_triplet
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
903 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
904 const char *filename;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
905 int lineno;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
906 int bb_index;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
907 };
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
908
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
909 /* Traits class for streamed_locations hash set below. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
910
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
911 struct location_triplet_hash : typed_noop_remove <location_triplet>
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
912 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
913 typedef location_triplet value_type;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
914 typedef location_triplet compare_type;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
915
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
916 static hashval_t
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
917 hash (const location_triplet &ref)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
918 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
919 inchash::hash hstate (0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
920 if (ref.filename)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
921 hstate.add_int (strlen (ref.filename));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
922 hstate.add_int (ref.lineno);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
923 hstate.add_int (ref.bb_index);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
924 return hstate.end ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
925 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
926
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
927 static bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
928 equal (const location_triplet &ref1, const location_triplet &ref2)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
929 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
930 return ref1.lineno == ref2.lineno
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
931 && ref1.bb_index == ref2.bb_index
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
932 && ref1.filename != NULL
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
933 && ref2.filename != NULL
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
934 && strcmp (ref1.filename, ref2.filename) == 0;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
935 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
936
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
937 static void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
938 mark_deleted (location_triplet &ref)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
939 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
940 ref.lineno = -1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
941 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
942
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
943 static const bool empty_zero_p = false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
944
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
945 static void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
946 mark_empty (location_triplet &ref)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
947 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
948 ref.lineno = -2;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
949 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
950
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
951 static bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
952 is_deleted (const location_triplet &ref)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
953 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
954 return ref.lineno == -1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
955 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
956
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
957 static bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
958 is_empty (const location_triplet &ref)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
959 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
960 return ref.lineno == -2;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
961 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
962 };
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
963
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
964
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
965
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
966
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
967 /* When passed NULL as file_name, initialize.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
968 When passed something else, output the necessary commands to change
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
969 line to LINE and offset to FILE_NAME. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
970 static void
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
971 output_location (hash_set<location_triplet_hash> *streamed_locations,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
972 char const *file_name, int line,
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
973 gcov_position_t *offset, basic_block bb)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
974 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
975 static char const *prev_file_name;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
976 static int prev_line;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
977 bool name_differs, line_differs;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
978
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
979 location_triplet triplet;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
980 triplet.filename = file_name;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
981 triplet.lineno = line;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
982 triplet.bb_index = bb ? bb->index : 0;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
983
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
984 if (streamed_locations->add (triplet))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
985 return;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
986
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
987 if (!file_name)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
988 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
989 prev_file_name = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
990 prev_line = -1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
991 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
992 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
993
111
kono
parents: 67
diff changeset
994 name_differs = !prev_file_name || filename_cmp (file_name, prev_file_name);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
995 line_differs = prev_line != line;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
996
111
kono
parents: 67
diff changeset
997 if (!*offset)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
998 {
111
kono
parents: 67
diff changeset
999 *offset = gcov_write_tag (GCOV_TAG_LINES);
kono
parents: 67
diff changeset
1000 gcov_write_unsigned (bb->index);
kono
parents: 67
diff changeset
1001 name_differs = line_differs = true;
kono
parents: 67
diff changeset
1002 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1003
111
kono
parents: 67
diff changeset
1004 /* If this is a new source file, then output the
kono
parents: 67
diff changeset
1005 file's name to the .bb file. */
kono
parents: 67
diff changeset
1006 if (name_differs)
kono
parents: 67
diff changeset
1007 {
kono
parents: 67
diff changeset
1008 prev_file_name = file_name;
kono
parents: 67
diff changeset
1009 gcov_write_unsigned (0);
kono
parents: 67
diff changeset
1010 gcov_write_filename (prev_file_name);
kono
parents: 67
diff changeset
1011 }
kono
parents: 67
diff changeset
1012 if (line_differs)
kono
parents: 67
diff changeset
1013 {
kono
parents: 67
diff changeset
1014 gcov_write_unsigned (line);
kono
parents: 67
diff changeset
1015 prev_line = line;
kono
parents: 67
diff changeset
1016 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1017 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1018
111
kono
parents: 67
diff changeset
1019 /* Helper for qsort so edges get sorted from highest frequency to smallest.
kono
parents: 67
diff changeset
1020 This controls the weight for minimal spanning tree algorithm */
kono
parents: 67
diff changeset
1021 static int
kono
parents: 67
diff changeset
1022 compare_freqs (const void *p1, const void *p2)
kono
parents: 67
diff changeset
1023 {
kono
parents: 67
diff changeset
1024 const_edge e1 = *(const const_edge *)p1;
kono
parents: 67
diff changeset
1025 const_edge e2 = *(const const_edge *)p2;
kono
parents: 67
diff changeset
1026
kono
parents: 67
diff changeset
1027 /* Critical edges needs to be split which introduce extra control flow.
kono
parents: 67
diff changeset
1028 Make them more heavy. */
kono
parents: 67
diff changeset
1029 int m1 = EDGE_CRITICAL_P (e1) ? 2 : 1;
kono
parents: 67
diff changeset
1030 int m2 = EDGE_CRITICAL_P (e2) ? 2 : 1;
kono
parents: 67
diff changeset
1031
kono
parents: 67
diff changeset
1032 if (EDGE_FREQUENCY (e1) * m1 + m1 != EDGE_FREQUENCY (e2) * m2 + m2)
kono
parents: 67
diff changeset
1033 return EDGE_FREQUENCY (e2) * m2 + m2 - EDGE_FREQUENCY (e1) * m1 - m1;
kono
parents: 67
diff changeset
1034 /* Stabilize sort. */
kono
parents: 67
diff changeset
1035 if (e1->src->index != e2->src->index)
kono
parents: 67
diff changeset
1036 return e2->src->index - e1->src->index;
kono
parents: 67
diff changeset
1037 return e2->dest->index - e1->dest->index;
kono
parents: 67
diff changeset
1038 }
kono
parents: 67
diff changeset
1039
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1040 /* Only read execution count for thunks. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1041
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1042 void
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1043 read_thunk_profile (struct cgraph_node *node)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1044 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1045 tree old = current_function_decl;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1046 current_function_decl = node->decl;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1047 gcov_type *counts = get_coverage_counts (GCOV_COUNTER_ARCS, 0, 0, 1);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1048 if (counts)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1049 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1050 node->callees->count = node->count
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1051 = profile_count::from_gcov_type (counts[0]);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1052 free (counts);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1053 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1054 current_function_decl = old;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1055 return;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1056 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1057
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1058
111
kono
parents: 67
diff changeset
1059 /* Instrument and/or analyze program behavior based on program the CFG.
kono
parents: 67
diff changeset
1060
kono
parents: 67
diff changeset
1061 This function creates a representation of the control flow graph (of
kono
parents: 67
diff changeset
1062 the function being compiled) that is suitable for the instrumentation
kono
parents: 67
diff changeset
1063 of edges and/or converting measured edge counts to counts on the
kono
parents: 67
diff changeset
1064 complete CFG.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1065
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1066 When FLAG_PROFILE_ARCS is nonzero, this function instruments the edges in
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1067 the flow graph that are needed to reconstruct the dynamic behavior of the
111
kono
parents: 67
diff changeset
1068 flow graph. This data is written to the gcno file for gcov.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1069
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1070 When FLAG_BRANCH_PROBABILITIES is nonzero, this function reads auxiliary
111
kono
parents: 67
diff changeset
1071 information from the gcda file containing edge count information from
kono
parents: 67
diff changeset
1072 previous executions of the function being compiled. In this case, the
kono
parents: 67
diff changeset
1073 control flow graph is annotated with actual execution counts by
kono
parents: 67
diff changeset
1074 compute_branch_probabilities().
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1075
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1076 Main entry point of this file. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1077
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1078 void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1079 branch_prob (bool thunk)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1080 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1081 basic_block bb;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1082 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1083 unsigned num_edges, ignored_edges;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1084 unsigned num_instrumented;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1085 struct edge_list *el;
111
kono
parents: 67
diff changeset
1086 histogram_values values = histogram_values ();
kono
parents: 67
diff changeset
1087 unsigned cfg_checksum, lineno_checksum;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1088
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1089 total_num_times_called++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1090
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1091 flow_call_edges_add (NULL);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1092 add_noreturn_fake_exit_edges ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1093
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1094 hash_set <location_triplet_hash> streamed_locations;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1095
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1096 if (!thunk)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1097 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1098 /* We can't handle cyclic regions constructed using abnormal edges.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1099 To avoid these we replace every source of abnormal edge by a fake
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1100 edge from entry node and every destination by fake edge to exit.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1101 This keeps graph acyclic and our calculation exact for all normal
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1102 edges except for exit and entrance ones.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1103
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1104 We also add fake exit edges for each call and asm statement in the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1105 basic, since it may not return. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1106
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1107 FOR_EACH_BB_FN (bb, cfun)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1108 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1109 int need_exit_edge = 0, need_entry_edge = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1110 int have_exit_edge = 0, have_entry_edge = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1111 edge e;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1112 edge_iterator ei;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1113
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1114 /* Functions returning multiple times are not handled by extra edges.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1115 Instead we simply allow negative counts on edges from exit to the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1116 block past call and corresponding probabilities. We can't go
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1117 with the extra edges because that would result in flowgraph that
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1118 needs to have fake edges outside the spanning tree. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1119
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1120 FOR_EACH_EDGE (e, ei, bb->succs)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1121 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1122 gimple_stmt_iterator gsi;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1123 gimple *last = NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1124
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1125 /* It may happen that there are compiler generated statements
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1126 without a locus at all. Go through the basic block from the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1127 last to the first statement looking for a locus. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1128 for (gsi = gsi_last_nondebug_bb (bb);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1129 !gsi_end_p (gsi);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1130 gsi_prev_nondebug (&gsi))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1131 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1132 last = gsi_stmt (gsi);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1133 if (!RESERVED_LOCATION_P (gimple_location (last)))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1134 break;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1135 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1136
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1137 /* Edge with goto locus might get wrong coverage info unless
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1138 it is the only edge out of BB.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1139 Don't do that when the locuses match, so
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1140 if (blah) goto something;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1141 is not computed twice. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1142 if (last
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1143 && gimple_has_location (last)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1144 && !RESERVED_LOCATION_P (e->goto_locus)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1145 && !single_succ_p (bb)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1146 && (LOCATION_FILE (e->goto_locus)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1147 != LOCATION_FILE (gimple_location (last))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1148 || (LOCATION_LINE (e->goto_locus)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1149 != LOCATION_LINE (gimple_location (last)))))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1150 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1151 basic_block new_bb = split_edge (e);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1152 edge ne = single_succ_edge (new_bb);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1153 ne->goto_locus = e->goto_locus;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1154 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1155 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1156 && e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1157 need_exit_edge = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1158 if (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1159 have_exit_edge = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1160 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1161 FOR_EACH_EDGE (e, ei, bb->preds)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1162 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1163 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1164 && e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1165 need_entry_edge = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1166 if (e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1167 have_entry_edge = 1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1168 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1169
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1170 if (need_exit_edge && !have_exit_edge)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1171 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1172 if (dump_file)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1173 fprintf (dump_file, "Adding fake exit edge to bb %i\n",
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1174 bb->index);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1175 make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), EDGE_FAKE);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1176 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1177 if (need_entry_edge && !have_entry_edge)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1178 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1179 if (dump_file)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1180 fprintf (dump_file, "Adding fake entry edge to bb %i\n",
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1181 bb->index);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1182 make_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun), bb, EDGE_FAKE);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1183 /* Avoid bbs that have both fake entry edge and also some
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1184 exit edge. One of those edges wouldn't be added to the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1185 spanning tree, but we can't instrument any of them. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1186 if (have_exit_edge || need_exit_edge)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1187 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1188 gimple_stmt_iterator gsi;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1189 gimple *first;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1190
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1191 gsi = gsi_start_nondebug_after_labels_bb (bb);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1192 gcc_checking_assert (!gsi_end_p (gsi));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1193 first = gsi_stmt (gsi);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1194 /* Don't split the bbs containing __builtin_setjmp_receiver
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1195 or ABNORMAL_DISPATCHER calls. These are very
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1196 special and don't expect anything to be inserted before
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1197 them. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1198 if (is_gimple_call (first)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1199 && (gimple_call_builtin_p (first, BUILT_IN_SETJMP_RECEIVER)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1200 || (gimple_call_flags (first) & ECF_RETURNS_TWICE)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1201 || (gimple_call_internal_p (first)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1202 && (gimple_call_internal_fn (first)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1203 == IFN_ABNORMAL_DISPATCHER))))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1204 continue;
111
kono
parents: 67
diff changeset
1205
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1206 if (dump_file)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1207 fprintf (dump_file, "Splitting bb %i after labels\n",
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1208 bb->index);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1209 split_block_after_labels (bb);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1210 }
111
kono
parents: 67
diff changeset
1211 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1212 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1213 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1214
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1215 el = create_edge_list ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1216 num_edges = NUM_EDGES (el);
111
kono
parents: 67
diff changeset
1217 qsort (el->index_to_edge, num_edges, sizeof (edge), compare_freqs);
kono
parents: 67
diff changeset
1218 alloc_aux_for_edges (sizeof (struct edge_profile_info));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1219
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1220 /* The basic blocks are expected to be numbered sequentially. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1221 compact_blocks ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1222
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1223 ignored_edges = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1224 for (i = 0 ; i < num_edges ; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1225 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1226 edge e = INDEX_EDGE (el, i);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1227
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1228 /* Mark edges we've replaced by fake edges above as ignored. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1229 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
111
kono
parents: 67
diff changeset
1230 && e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun)
kono
parents: 67
diff changeset
1231 && e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1232 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1233 EDGE_INFO (e)->ignore = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1234 ignored_edges++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1235 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1236 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1237
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1238 /* Create spanning tree from basic block graph, mark each edge that is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1239 on the spanning tree. We insert as many abnormal and critical edges
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1240 as possible to minimize number of edge splits necessary. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1241
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1242 if (!thunk)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1243 find_spanning_tree (el);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1244 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1245 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1246 edge e;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1247 edge_iterator ei;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1248 /* Keep only edge from entry block to be instrumented. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1249 FOR_EACH_BB_FN (bb, cfun)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1250 FOR_EACH_EDGE (e, ei, bb->succs)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1251 EDGE_INFO (e)->ignore = true;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1252 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1253
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1254
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1255 /* Fake edges that are not on the tree will not be instrumented, so
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1256 mark them ignored. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1257 for (num_instrumented = i = 0; i < num_edges; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1258 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1259 edge e = INDEX_EDGE (el, i);
111
kono
parents: 67
diff changeset
1260 struct edge_profile_info *inf = EDGE_INFO (e);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1261
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1262 if (inf->ignore || inf->on_tree)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1263 /*NOP*/;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1264 else if (e->flags & EDGE_FAKE)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1265 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1266 inf->ignore = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1267 ignored_edges++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1268 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1269 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1270 num_instrumented++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1271 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1272
111
kono
parents: 67
diff changeset
1273 total_num_blocks += n_basic_blocks_for_fn (cfun);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1274 if (dump_file)
111
kono
parents: 67
diff changeset
1275 fprintf (dump_file, "%d basic blocks\n", n_basic_blocks_for_fn (cfun));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1276
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1277 total_num_edges += num_edges;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1278 if (dump_file)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1279 fprintf (dump_file, "%d edges\n", num_edges);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1280
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1281 total_num_edges_ignored += ignored_edges;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1282 if (dump_file)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1283 fprintf (dump_file, "%d ignored edges\n", ignored_edges);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1284
111
kono
parents: 67
diff changeset
1285 total_num_edges_instrumented += num_instrumented;
kono
parents: 67
diff changeset
1286 if (dump_file)
kono
parents: 67
diff changeset
1287 fprintf (dump_file, "%d instrumentation edges\n", num_instrumented);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1288
111
kono
parents: 67
diff changeset
1289 /* Compute two different checksums. Note that we want to compute
kono
parents: 67
diff changeset
1290 the checksum in only once place, since it depends on the shape
kono
parents: 67
diff changeset
1291 of the control flow which can change during
kono
parents: 67
diff changeset
1292 various transformations. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1293 if (thunk)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1294 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1295 /* At stream in time we do not have CFG, so we cannot do checksums. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1296 cfg_checksum = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1297 lineno_checksum = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1298 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1299 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1300 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1301 cfg_checksum = coverage_compute_cfg_checksum (cfun);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1302 lineno_checksum = coverage_compute_lineno_checksum ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1303 }
111
kono
parents: 67
diff changeset
1304
kono
parents: 67
diff changeset
1305 /* Write the data from which gcov can reconstruct the basic block
kono
parents: 67
diff changeset
1306 graph and function line numbers (the gcno file). */
kono
parents: 67
diff changeset
1307 if (coverage_begin_function (lineno_checksum, cfg_checksum))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1308 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1309 gcov_position_t offset;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1310
111
kono
parents: 67
diff changeset
1311 /* Basic block flags */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1312 offset = gcov_write_tag (GCOV_TAG_BLOCKS);
111
kono
parents: 67
diff changeset
1313 gcov_write_unsigned (n_basic_blocks_for_fn (cfun));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1314 gcov_write_length (offset);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1315
111
kono
parents: 67
diff changeset
1316 /* Arcs */
kono
parents: 67
diff changeset
1317 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun),
kono
parents: 67
diff changeset
1318 EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1319 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1320 edge e;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1321 edge_iterator ei;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1322
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1323 offset = gcov_write_tag (GCOV_TAG_ARCS);
111
kono
parents: 67
diff changeset
1324 gcov_write_unsigned (bb->index);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1325
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1326 FOR_EACH_EDGE (e, ei, bb->succs)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1327 {
111
kono
parents: 67
diff changeset
1328 struct edge_profile_info *i = EDGE_INFO (e);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1329 if (!i->ignore)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1330 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1331 unsigned flag_bits = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1332
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1333 if (i->on_tree)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1334 flag_bits |= GCOV_ARC_ON_TREE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1335 if (e->flags & EDGE_FAKE)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1336 flag_bits |= GCOV_ARC_FAKE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1337 if (e->flags & EDGE_FALLTHRU)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1338 flag_bits |= GCOV_ARC_FALLTHROUGH;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1339 /* On trees we don't have fallthru flags, but we can
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1340 recompute them from CFG shape. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1341 if (e->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1342 && e->src->next_bb == e->dest)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1343 flag_bits |= GCOV_ARC_FALLTHROUGH;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1344
111
kono
parents: 67
diff changeset
1345 gcov_write_unsigned (e->dest->index);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1346 gcov_write_unsigned (flag_bits);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1347 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1348 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1349
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1350 gcov_write_length (offset);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1351 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1352
111
kono
parents: 67
diff changeset
1353 /* Line numbers. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1354 /* Initialize the output. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1355 output_location (&streamed_locations, NULL, 0, NULL, NULL);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1356
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1357 hash_set<int_hash <location_t, 0, 2> > seen_locations;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1358
111
kono
parents: 67
diff changeset
1359 FOR_EACH_BB_FN (bb, cfun)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1360 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1361 gimple_stmt_iterator gsi;
111
kono
parents: 67
diff changeset
1362 gcov_position_t offset = 0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1363
111
kono
parents: 67
diff changeset
1364 if (bb == ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1365 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1366 location_t loc = DECL_SOURCE_LOCATION (current_function_decl);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1367 seen_locations.add (loc);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1368 expanded_location curr_location = expand_location (loc);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1369 output_location (&streamed_locations, curr_location.file,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1370 curr_location.line, &offset, bb);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1371 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1372
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1373 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1374 {
111
kono
parents: 67
diff changeset
1375 gimple *stmt = gsi_stmt (gsi);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1376 location_t loc = gimple_location (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1377 if (!RESERVED_LOCATION_P (loc))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1378 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1379 seen_locations.add (loc);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1380 output_location (&streamed_locations, gimple_filename (stmt),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1381 gimple_lineno (stmt), &offset, bb);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1382 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1383 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1384
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1385 /* Notice GOTO expressions eliminated while constructing the CFG.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1386 It's hard to distinguish such expression, but goto_locus should
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1387 not be any of already seen location. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1388 location_t loc;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1389 if (single_succ_p (bb)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1390 && (loc = single_succ_edge (bb)->goto_locus)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1391 && !RESERVED_LOCATION_P (loc)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1392 && !seen_locations.contains (loc))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1393 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1394 expanded_location curr_location = expand_location (loc);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1395 output_location (&streamed_locations, curr_location.file,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1396 curr_location.line, &offset, bb);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1397 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1398
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1399 if (offset)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1400 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1401 /* A file of NULL indicates the end of run. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1402 gcov_write_unsigned (0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1403 gcov_write_string (NULL);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1404 gcov_write_length (offset);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1405 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1406 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1407 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1408
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1409 if (flag_profile_values)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1410 gimple_find_values_to_profile (&values);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1411
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1412 if (flag_branch_probabilities)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1413 {
111
kono
parents: 67
diff changeset
1414 compute_branch_probabilities (cfg_checksum, lineno_checksum);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1415 if (flag_profile_values)
111
kono
parents: 67
diff changeset
1416 compute_value_histograms (values, cfg_checksum, lineno_checksum);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1417 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1418
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1419 remove_fake_edges ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1420
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1421 /* For each edge not on the spanning tree, add counting code. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1422 if (profile_arc_flag
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1423 && coverage_counter_alloc (GCOV_COUNTER_ARCS, num_instrumented))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1424 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1425 unsigned n_instrumented;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1426
111
kono
parents: 67
diff changeset
1427 gimple_init_gcov_profiler ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1428
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1429 n_instrumented = instrument_edges (el);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1430
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1431 gcc_assert (n_instrumented == num_instrumented);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1432
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1433 if (flag_profile_values)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1434 instrument_values (values);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1435
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1436 /* Commit changes done by instrumentation. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1437 gsi_commit_edge_inserts ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1438 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1439
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1440 free_aux_for_edges ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1441
111
kono
parents: 67
diff changeset
1442 values.release ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1443 free_edge_list (el);
111
kono
parents: 67
diff changeset
1444 coverage_end_function (lineno_checksum, cfg_checksum);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1445 if (flag_branch_probabilities
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1446 && (profile_status_for_fn (cfun) == PROFILE_READ))
111
kono
parents: 67
diff changeset
1447 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1448 class loop *loop;
111
kono
parents: 67
diff changeset
1449 if (dump_file && (dump_flags & TDF_DETAILS))
kono
parents: 67
diff changeset
1450 report_predictor_hitrates ();
kono
parents: 67
diff changeset
1451
kono
parents: 67
diff changeset
1452 /* At this moment we have precise loop iteration count estimates.
kono
parents: 67
diff changeset
1453 Record them to loop structure before the profile gets out of date. */
kono
parents: 67
diff changeset
1454 FOR_EACH_LOOP (loop, 0)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1455 if (loop->header->count > 0 && loop->header->count.reliable_p ())
111
kono
parents: 67
diff changeset
1456 {
kono
parents: 67
diff changeset
1457 gcov_type nit = expected_loop_iterations_unbounded (loop);
kono
parents: 67
diff changeset
1458 widest_int bound = gcov_type_to_wide_int (nit);
kono
parents: 67
diff changeset
1459 loop->any_estimate = false;
kono
parents: 67
diff changeset
1460 record_niter_bound (loop, bound, true, false);
kono
parents: 67
diff changeset
1461 }
kono
parents: 67
diff changeset
1462 compute_function_frequency ();
kono
parents: 67
diff changeset
1463 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1464 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1465
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1466 /* Union find algorithm implementation for the basic blocks using
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1467 aux fields. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1468
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1469 static basic_block
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1470 find_group (basic_block bb)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1471 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1472 basic_block group = bb, bb1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1473
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1474 while ((basic_block) group->aux != group)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1475 group = (basic_block) group->aux;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1476
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1477 /* Compress path. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1478 while ((basic_block) bb->aux != group)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1479 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1480 bb1 = (basic_block) bb->aux;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1481 bb->aux = (void *) group;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1482 bb = bb1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1483 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1484 return group;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1485 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1486
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1487 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1488 union_groups (basic_block bb1, basic_block bb2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1489 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1490 basic_block bb1g = find_group (bb1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1491 basic_block bb2g = find_group (bb2);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1492
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1493 /* ??? I don't have a place for the rank field. OK. Lets go w/o it,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1494 this code is unlikely going to be performance problem anyway. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1495 gcc_assert (bb1g != bb2g);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1496
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1497 bb1g->aux = bb2g;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1498 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1499
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1500 /* This function searches all of the edges in the program flow graph, and puts
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1501 as many bad edges as possible onto the spanning tree. Bad edges include
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1502 abnormals edges, which can't be instrumented at the moment. Since it is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1503 possible for fake edges to form a cycle, we will have to develop some
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1504 better way in the future. Also put critical edges to the tree, since they
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1505 are more expensive to instrument. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1506
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1507 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1508 find_spanning_tree (struct edge_list *el)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1509 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1510 int i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1511 int num_edges = NUM_EDGES (el);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1512 basic_block bb;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1513
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1514 /* We use aux field for standard union-find algorithm. */
111
kono
parents: 67
diff changeset
1515 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1516 bb->aux = bb;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1517
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1518 /* Add fake edge exit to entry we can't instrument. */
111
kono
parents: 67
diff changeset
1519 union_groups (EXIT_BLOCK_PTR_FOR_FN (cfun), ENTRY_BLOCK_PTR_FOR_FN (cfun));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1520
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1521 /* First add all abnormal edges to the tree unless they form a cycle. Also
111
kono
parents: 67
diff changeset
1522 add all edges to the exit block to avoid inserting profiling code behind
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1523 setting return value from function. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1524 for (i = 0; i < num_edges; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1525 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1526 edge e = INDEX_EDGE (el, i);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1527 if (((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_FAKE))
111
kono
parents: 67
diff changeset
1528 || e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1529 && !EDGE_INFO (e)->ignore
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1530 && (find_group (e->src) != find_group (e->dest)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1531 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1532 if (dump_file)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1533 fprintf (dump_file, "Abnormal edge %d to %d put to tree\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1534 e->src->index, e->dest->index);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1535 EDGE_INFO (e)->on_tree = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1536 union_groups (e->src, e->dest);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1537 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1538 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1539
111
kono
parents: 67
diff changeset
1540 /* And now the rest. Edge list is sorted according to frequencies and
kono
parents: 67
diff changeset
1541 thus we will produce minimal spanning tree. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1542 for (i = 0; i < num_edges; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1543 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1544 edge e = INDEX_EDGE (el, i);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1545 if (!EDGE_INFO (e)->ignore
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1546 && find_group (e->src) != find_group (e->dest))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1547 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1548 if (dump_file)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1549 fprintf (dump_file, "Normal edge %d to %d put to tree\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1550 e->src->index, e->dest->index);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1551 EDGE_INFO (e)->on_tree = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1552 union_groups (e->src, e->dest);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1553 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1554 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1555
111
kono
parents: 67
diff changeset
1556 clear_aux_for_blocks ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1557 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1558
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1559 /* Perform file-level initialization for branch-prob processing. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1560
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1561 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1562 init_branch_prob (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1563 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1564 int i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1565
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1566 total_num_blocks = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1567 total_num_edges = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1568 total_num_edges_ignored = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1569 total_num_edges_instrumented = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1570 total_num_blocks_created = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1571 total_num_passes = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1572 total_num_times_called = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1573 total_num_branches = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1574 for (i = 0; i < 20; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1575 total_hist_br_prob[i] = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1576 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1577
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1578 /* Performs file-level cleanup after branch-prob processing
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1579 is completed. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1580
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1581 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1582 end_branch_prob (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1583 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1584 if (dump_file)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1585 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1586 fprintf (dump_file, "\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1587 fprintf (dump_file, "Total number of blocks: %d\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1588 total_num_blocks);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1589 fprintf (dump_file, "Total number of edges: %d\n", total_num_edges);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1590 fprintf (dump_file, "Total number of ignored edges: %d\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1591 total_num_edges_ignored);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1592 fprintf (dump_file, "Total number of instrumented edges: %d\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1593 total_num_edges_instrumented);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1594 fprintf (dump_file, "Total number of blocks created: %d\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1595 total_num_blocks_created);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1596 fprintf (dump_file, "Total number of graph solution passes: %d\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1597 total_num_passes);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1598 if (total_num_times_called != 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1599 fprintf (dump_file, "Average number of graph solution passes: %d\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1600 (total_num_passes + (total_num_times_called >> 1))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1601 / total_num_times_called);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1602 fprintf (dump_file, "Total number of branches: %d\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1603 total_num_branches);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1604 if (total_num_branches)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1605 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1606 int i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1607
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1608 for (i = 0; i < 10; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1609 fprintf (dump_file, "%d%% branches in range %d-%d%%\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1610 (total_hist_br_prob[i] + total_hist_br_prob[19-i]) * 100
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1611 / total_num_branches, 5*i, 5*i+5);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1612 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1613 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1614 }