]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/tree-profile.c
genattrtab.c (write_header): Include hash-set.h...
[thirdparty/gcc.git] / gcc / tree-profile.c
CommitLineData
6de9cd9a 1/* Calculate branch probabilities, and basic block execution counts.
5624e564 2 Copyright (C) 1990-2015 Free Software Foundation, Inc.
6de9cd9a
DN
3 Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
4 based on some ideas from Dain Samples of UC Berkeley.
5 Further mangling by Bob Manson, Cygnus Support.
6 Converted to use trees by Dale Johannesen, Apple Computer.
7
8This file is part of GCC.
9
10GCC is free software; you can redistribute it and/or modify it under
11the terms of the GNU General Public License as published by the Free
9dcd6f09 12Software Foundation; either version 3, or (at your option) any later
6de9cd9a
DN
13version.
14
15GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16WARRANTY; without even the implied warranty of MERCHANTABILITY or
17FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18for more details.
19
20You should have received a copy of the GNU General Public License
9dcd6f09
NC
21along with GCC; see the file COPYING3. If not see
22<http://www.gnu.org/licenses/>. */
6de9cd9a
DN
23
24/* Generate basic block profile instrumentation and auxiliary files.
1f1e8527 25 Tree-based version. See profile.c for overview. */
6de9cd9a
DN
26
27#include "config.h"
28#include "system.h"
29#include "coretypes.h"
30#include "tm.h"
6de9cd9a 31#include "flags.h"
83685514
AM
32#include "hashtab.h"
33#include "hash-set.h"
34#include "vec.h"
35#include "machmode.h"
36#include "hard-reg-set.h"
37#include "input.h"
6de9cd9a 38#include "function.h"
60393bbc
AM
39#include "predict.h"
40#include "dominance.h"
41#include "cfg.h"
2d1a4cc1 42#include "basic-block.h"
718f9c0f 43#include "diagnostic-core.h"
6de9cd9a 44#include "coverage.h"
40e23961
MC
45#include "double-int.h"
46#include "input.h"
47#include "alias.h"
48#include "symtab.h"
49#include "wide-int.h"
50#include "inchash.h"
6de9cd9a 51#include "tree.h"
40e23961 52#include "fold-const.h"
2fb9a547
AM
53#include "tree-ssa-alias.h"
54#include "internal-fn.h"
55#include "gimple-expr.h"
56#include "is-a.h"
18f429e2 57#include "gimple.h"
d8a2d370
DN
58#include "varasm.h"
59#include "tree-nested.h"
45b0be94 60#include "gimplify.h"
5be5c238 61#include "gimple-iterator.h"
18f429e2 62#include "gimplify-me.h"
442b4905 63#include "gimple-ssa.h"
c582198b
AM
64#include "hash-map.h"
65#include "plugin-api.h"
66#include "ipa-ref.h"
442b4905
AM
67#include "cgraph.h"
68#include "tree-cfg.h"
d8a2d370 69#include "stringpool.h"
442b4905
AM
70#include "tree-ssanames.h"
71#include "tree-into-ssa.h"
6de9cd9a 72#include "tree-pass.h"
6de9cd9a 73#include "value-prof.h"
903d1e67 74#include "profile.h"
d984c8ef 75#include "target.h"
4484a35a 76#include "tree-cfgcleanup.h"
1fe37220 77#include "tree-nested.h"
0a750165 78#include "params.h"
6de9cd9a 79
9885da8e
ZD
80static GTY(()) tree gcov_type_node;
81static GTY(()) tree tree_interval_profiler_fn;
82static GTY(()) tree tree_pow2_profiler_fn;
83static GTY(()) tree tree_one_value_profiler_fn;
6bad2617 84static GTY(()) tree tree_indirect_call_profiler_fn;
86ce5d2f 85static GTY(()) tree tree_time_profiler_fn;
079a182e
JH
86static GTY(()) tree tree_average_profiler_fn;
87static GTY(()) tree tree_ior_profiler_fn;
86ce5d2f 88
f3df9541 89
6bad2617
TB
90static GTY(()) tree ic_void_ptr_var;
91static GTY(()) tree ic_gcov_type_ptr_var;
92static GTY(()) tree ptr_void;
93
f3df9541
AK
94/* Do initialization work for the edge profiler. */
95
6bad2617 96/* Add code:
2fa3d31b 97 __thread gcov* __gcov_indirect_call_counters; // pointer to actual counter
86ce5d2f
ML
98 __thread void* __gcov_indirect_call_callee; // actual callee address
99 __thread int __gcov_function_counter; // time profiler function counter
6bad2617
TB
100*/
101static void
e0cb7e1e 102init_ic_make_global_vars (void)
6bad2617
TB
103{
104 tree gcov_type_ptr;
105
106 ptr_void = build_pointer_type (void_type_node);
b8698a0f 107
748d71f3
JH
108 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
109 if (flag_lto)
110 {
111 ic_void_ptr_var
112 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
113 get_identifier ("__gcov_indirect_call_callee_ltopriv"),
114 ptr_void);
115 TREE_PUBLIC (ic_void_ptr_var) = 1;
116 DECL_COMMON (ic_void_ptr_var) = 1;
117 DECL_VISIBILITY (ic_void_ptr_var) = VISIBILITY_HIDDEN;
118 DECL_VISIBILITY_SPECIFIED (ic_void_ptr_var) = true;
119 }
120 else
121 {
122 ic_void_ptr_var
123 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
0a750165
RX
124 get_identifier (
125 (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
126 "__gcov_indirect_call_topn_callee" :
127 "__gcov_indirect_call_callee")),
748d71f3
JH
128 ptr_void);
129 TREE_PUBLIC (ic_void_ptr_var) = 1;
130 DECL_EXTERNAL (ic_void_ptr_var) = 1;
131 }
6bad2617 132 TREE_STATIC (ic_void_ptr_var) = 1;
6bad2617
TB
133 DECL_ARTIFICIAL (ic_void_ptr_var) = 1;
134 DECL_INITIAL (ic_void_ptr_var) = NULL;
d984c8ef 135 if (targetm.have_tls)
56363ffd 136 set_decl_tls_model (ic_void_ptr_var, decl_default_tls_model (ic_void_ptr_var));
d984c8ef 137
9041d2e6 138 varpool_node::finalize_decl (ic_void_ptr_var);
6bad2617
TB
139
140 gcov_type_ptr = build_pointer_type (get_gcov_type ());
748d71f3
JH
141 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
142 if (flag_lto)
143 {
144 ic_gcov_type_ptr_var
145 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
146 get_identifier ("__gcov_indirect_call_counters_ltopriv"),
147 gcov_type_ptr);
148 TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
149 DECL_COMMON (ic_gcov_type_ptr_var) = 1;
150 DECL_VISIBILITY (ic_gcov_type_ptr_var) = VISIBILITY_HIDDEN;
151 DECL_VISIBILITY_SPECIFIED (ic_gcov_type_ptr_var) = true;
152 }
153 else
154 {
155 ic_gcov_type_ptr_var
156 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
0a750165
RX
157 get_identifier (
158 (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
159 "__gcov_indirect_call_topn_counters" :
160 "__gcov_indirect_call_counters")),
748d71f3
JH
161 gcov_type_ptr);
162 TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
163 DECL_EXTERNAL (ic_gcov_type_ptr_var) = 1;
164 }
6bad2617 165 TREE_STATIC (ic_gcov_type_ptr_var) = 1;
6bad2617
TB
166 DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1;
167 DECL_INITIAL (ic_gcov_type_ptr_var) = NULL;
d984c8ef 168 if (targetm.have_tls)
56363ffd 169 set_decl_tls_model (ic_gcov_type_ptr_var, decl_default_tls_model (ic_gcov_type_ptr_var));
d984c8ef 170
9041d2e6 171 varpool_node::finalize_decl (ic_gcov_type_ptr_var);
6bad2617
TB
172}
173
9696c529
SB
174/* Create the type and function decls for the interface with gcov. */
175
e0cb7e1e
SB
176void
177gimple_init_edge_profiler (void)
f3df9541 178{
9885da8e
ZD
179 tree interval_profiler_fn_type;
180 tree pow2_profiler_fn_type;
181 tree one_value_profiler_fn_type;
182 tree gcov_type_ptr;
6bad2617 183 tree ic_profiler_fn_type;
079a182e 184 tree average_profiler_fn_type;
86ce5d2f 185 tree time_profiler_fn_type;
9885da8e
ZD
186
187 if (!gcov_type_node)
188 {
189 gcov_type_node = get_gcov_type ();
190 gcov_type_ptr = build_pointer_type (gcov_type_node);
191
192 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
193 interval_profiler_fn_type
194 = build_function_type_list (void_type_node,
195 gcov_type_ptr, gcov_type_node,
196 integer_type_node,
197 unsigned_type_node, NULL_TREE);
198 tree_interval_profiler_fn
199 = build_fn_decl ("__gcov_interval_profiler",
200 interval_profiler_fn_type);
4d3814a5
RG
201 TREE_NOTHROW (tree_interval_profiler_fn) = 1;
202 DECL_ATTRIBUTES (tree_interval_profiler_fn)
203 = tree_cons (get_identifier ("leaf"), NULL,
204 DECL_ATTRIBUTES (tree_interval_profiler_fn));
9885da8e
ZD
205
206 /* void (*) (gcov_type *, gcov_type) */
207 pow2_profiler_fn_type
208 = build_function_type_list (void_type_node,
209 gcov_type_ptr, gcov_type_node,
210 NULL_TREE);
211 tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler",
212 pow2_profiler_fn_type);
4d3814a5
RG
213 TREE_NOTHROW (tree_pow2_profiler_fn) = 1;
214 DECL_ATTRIBUTES (tree_pow2_profiler_fn)
215 = tree_cons (get_identifier ("leaf"), NULL,
216 DECL_ATTRIBUTES (tree_pow2_profiler_fn));
9885da8e
ZD
217
218 /* void (*) (gcov_type *, gcov_type) */
219 one_value_profiler_fn_type
220 = build_function_type_list (void_type_node,
221 gcov_type_ptr, gcov_type_node,
222 NULL_TREE);
223 tree_one_value_profiler_fn
224 = build_fn_decl ("__gcov_one_value_profiler",
225 one_value_profiler_fn_type);
4d3814a5
RG
226 TREE_NOTHROW (tree_one_value_profiler_fn) = 1;
227 DECL_ATTRIBUTES (tree_one_value_profiler_fn)
228 = tree_cons (get_identifier ("leaf"), NULL,
229 DECL_ATTRIBUTES (tree_one_value_profiler_fn));
6bad2617 230
e0cb7e1e 231 init_ic_make_global_vars ();
b8698a0f 232
748d71f3
JH
233 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
234 if (flag_lto)
235 {
236 /* void (*) (gcov_type, void *) */
237 ic_profiler_fn_type
238 = build_function_type_list (void_type_node,
239 gcov_type_ptr, gcov_type_node,
240 ptr_void, ptr_void,
241 NULL_TREE);
242 tree_indirect_call_profiler_fn
243 = build_fn_decl ("__gcov_indirect_call_profiler",
244 ic_profiler_fn_type);
245 }
246 else
247 {
248 /* void (*) (gcov_type, void *) */
249 ic_profiler_fn_type
250 = build_function_type_list (void_type_node,
251 gcov_type_node,
252 ptr_void,
253 NULL_TREE);
254 tree_indirect_call_profiler_fn
0a750165
RX
255 = build_fn_decl ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
256 "__gcov_indirect_call_topn_profiler":
257 "__gcov_indirect_call_profiler_v2"),
258 ic_profiler_fn_type);
748d71f3 259 }
4d3814a5
RG
260 TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
261 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
262 = tree_cons (get_identifier ("leaf"), NULL,
263 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn));
264
86ce5d2f
ML
265 /* void (*) (gcov_type *, gcov_type, void *) */
266 time_profiler_fn_type
267 = build_function_type_list (void_type_node,
268 gcov_type_ptr, NULL_TREE);
269 tree_time_profiler_fn
270 = build_fn_decl ("__gcov_time_profiler",
271 time_profiler_fn_type);
272 TREE_NOTHROW (tree_time_profiler_fn) = 1;
273 DECL_ATTRIBUTES (tree_time_profiler_fn)
274 = tree_cons (get_identifier ("leaf"), NULL,
275 DECL_ATTRIBUTES (tree_time_profiler_fn));
276
079a182e
JH
277 /* void (*) (gcov_type *, gcov_type) */
278 average_profiler_fn_type
279 = build_function_type_list (void_type_node,
280 gcov_type_ptr, gcov_type_node, NULL_TREE);
281 tree_average_profiler_fn
282 = build_fn_decl ("__gcov_average_profiler",
283 average_profiler_fn_type);
4d3814a5
RG
284 TREE_NOTHROW (tree_average_profiler_fn) = 1;
285 DECL_ATTRIBUTES (tree_average_profiler_fn)
286 = tree_cons (get_identifier ("leaf"), NULL,
287 DECL_ATTRIBUTES (tree_average_profiler_fn));
079a182e
JH
288 tree_ior_profiler_fn
289 = build_fn_decl ("__gcov_ior_profiler",
290 average_profiler_fn_type);
4d3814a5
RG
291 TREE_NOTHROW (tree_ior_profiler_fn) = 1;
292 DECL_ATTRIBUTES (tree_ior_profiler_fn)
293 = tree_cons (get_identifier ("leaf"), NULL,
294 DECL_ATTRIBUTES (tree_ior_profiler_fn));
295
0bc1b77f
JH
296 /* LTO streamer needs assembler names. Because we create these decls
297 late, we need to initialize them by hand. */
298 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn);
299 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn);
300 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn);
301 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn);
86ce5d2f 302 DECL_ASSEMBLER_NAME (tree_time_profiler_fn);
0bc1b77f
JH
303 DECL_ASSEMBLER_NAME (tree_average_profiler_fn);
304 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
9885da8e 305 }
f3df9541
AK
306}
307
b8698a0f
L
308/* Output instructions as GIMPLE trees to increment the edge
309 execution count, and insert them on E. We rely on
726a989a 310 gsi_insert_on_edge to preserve the order. */
6de9cd9a 311
e0cb7e1e
SB
312void
313gimple_gen_edge_profiler (int edgeno, edge e)
6de9cd9a 314{
83d5977e 315 tree ref, one, gcov_type_tmp_var;
538dd0b7 316 gassign *stmt1, *stmt2, *stmt3;
9225443e 317
9225443e
RG
318 ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
319 one = build_int_cst (gcov_type_node, 1);
83d5977e
RG
320 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
321 NULL, "PROF_edge_counter");
726a989a 322 stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
83d5977e
RG
323 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
324 NULL, "PROF_edge_counter");
0d0e4a03
JJ
325 stmt2 = gimple_build_assign (gcov_type_tmp_var, PLUS_EXPR,
326 gimple_assign_lhs (stmt1), one);
4d3814a5 327 stmt3 = gimple_build_assign (unshare_expr (ref), gimple_assign_lhs (stmt2));
726a989a
RB
328 gsi_insert_on_edge (e, stmt1);
329 gsi_insert_on_edge (e, stmt2);
330 gsi_insert_on_edge (e, stmt3);
6de9cd9a
DN
331}
332
726a989a 333/* Emits code to get VALUE to instrument at GSI, and returns the
9885da8e
ZD
334 variable containing the value. */
335
336static tree
726a989a 337prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
9885da8e 338{
8a76829c 339 tree val = value->hvalue.value;
ada39f0b 340 if (POINTER_TYPE_P (TREE_TYPE (val)))
0d82a1c8
RG
341 val = fold_convert (build_nonstandard_integer_type
342 (TYPE_PRECISION (TREE_TYPE (val)), 1), val);
726a989a
RB
343 return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
344 true, NULL_TREE, true, GSI_SAME_STMT);
9885da8e
ZD
345}
346
b8698a0f
L
347/* Output instructions as GIMPLE trees to increment the interval histogram
348 counter. VALUE is the expression whose value is profiled. TAG is the
6de9cd9a
DN
349 tag of the section for counters, BASE is offset of the counter position. */
350
e0cb7e1e
SB
351void
352gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
6de9cd9a 353{
726a989a
RB
354 gimple stmt = value->hvalue.stmt;
355 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
9885da8e 356 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
538dd0b7 357 gcall *call;
726a989a
RB
358 tree val;
359 tree start = build_int_cst_type (integer_type_node,
360 value->hdata.intvl.int_start);
361 tree steps = build_int_cst_type (unsigned_type_node,
362 value->hdata.intvl.steps);
b8698a0f 363
726a989a 364 ref_ptr = force_gimple_operand_gsi (&gsi,
bde6c65d 365 build_addr (ref, current_function_decl),
726a989a
RB
366 true, NULL_TREE, true, GSI_SAME_STMT);
367 val = prepare_instrumented_value (&gsi, value);
368 call = gimple_build_call (tree_interval_profiler_fn, 4,
369 ref_ptr, val, start, steps);
71ba42fa 370 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
6de9cd9a
DN
371}
372
b8698a0f
L
373/* Output instructions as GIMPLE trees to increment the power of two histogram
374 counter. VALUE is the expression whose value is profiled. TAG is the tag
6de9cd9a
DN
375 of the section for counters, BASE is offset of the counter position. */
376
e0cb7e1e
SB
377void
378gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
6de9cd9a 379{
726a989a
RB
380 gimple stmt = value->hvalue.stmt;
381 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
fc9161c1 382 tree ref_ptr = tree_coverage_counter_addr (tag, base);
538dd0b7 383 gcall *call;
726a989a 384 tree val;
b8698a0f 385
726a989a
RB
386 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
387 true, NULL_TREE, true, GSI_SAME_STMT);
388 val = prepare_instrumented_value (&gsi, value);
389 call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val);
71ba42fa 390 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
6de9cd9a
DN
391}
392
393/* Output instructions as GIMPLE trees for code to find the most common value.
394 VALUE is the expression whose value is profiled. TAG is the tag of the
395 section for counters, BASE is offset of the counter position. */
396
e0cb7e1e
SB
397void
398gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
6de9cd9a 399{
726a989a
RB
400 gimple stmt = value->hvalue.stmt;
401 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
fc9161c1 402 tree ref_ptr = tree_coverage_counter_addr (tag, base);
538dd0b7 403 gcall *call;
726a989a 404 tree val;
b8698a0f 405
726a989a
RB
406 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
407 true, NULL_TREE, true, GSI_SAME_STMT);
408 val = prepare_instrumented_value (&gsi, value);
409 call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val);
71ba42fa 410 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
6de9cd9a
DN
411}
412
6bad2617
TB
413
414/* Output instructions as GIMPLE trees for code to find the most
b8698a0f 415 common called function in indirect call.
88512ba0 416 VALUE is the call expression whose indirect callee is profiled.
6bad2617
TB
417 TAG is the tag of the section for counters, BASE is offset of the
418 counter position. */
419
e0cb7e1e
SB
420void
421gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
6bad2617 422{
726a989a 423 tree tmp1;
538dd0b7 424 gassign *stmt1, *stmt2, *stmt3;
726a989a
RB
425 gimple stmt = value->hvalue.stmt;
426 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
fc9161c1 427 tree ref_ptr = tree_coverage_counter_addr (tag, base);
6bad2617 428
0a750165
RX
429 if ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) &&
430 tag == GCOV_COUNTER_V_INDIR) ||
431 (!PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) &&
432 tag == GCOV_COUNTER_ICALL_TOPNV))
433 return;
434
726a989a
RB
435 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
436 true, NULL_TREE, true, GSI_SAME_STMT);
6bad2617
TB
437
438 /* Insert code:
b8698a0f 439
9696c529
SB
440 stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
441 stmt2: tmp1 = (void *) (indirect call argument value)
442 stmt3: __gcov_indirect_call_callee = tmp1;
6bad2617
TB
443 */
444
726a989a 445 stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr);
83d5977e 446 tmp1 = make_temp_ssa_name (ptr_void, NULL, "PROF");
726a989a 447 stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
4d3814a5 448 stmt3 = gimple_build_assign (ic_void_ptr_var, gimple_assign_lhs (stmt2));
6bad2617 449
726a989a
RB
450 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
451 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
452 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
6bad2617
TB
453}
454
455
456/* Output instructions as GIMPLE trees for code to find the most
457 common called function in indirect call. Insert instructions at the
88512ba0 458 beginning of every possible called function.
6bad2617
TB
459 */
460
e0cb7e1e
SB
461void
462gimple_gen_ic_func_profiler (void)
6bad2617 463{
d52f5295 464 struct cgraph_node * c_node = cgraph_node::get (current_function_decl);
726a989a 465 gimple_stmt_iterator gsi;
538dd0b7
DM
466 gcall *stmt1;
467 gassign *stmt2;
2fa3d31b 468 tree tree_uid, cur_func, void0;
6bad2617 469
d52f5295 470 if (c_node->only_called_directly_p ())
7e8b322a 471 return;
b8698a0f 472
e0cb7e1e 473 gimple_init_edge_profiler ();
b8698a0f 474
9696c529
SB
475 /* Insert code:
476
2fa3d31b
JH
477 stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
478 &current_function_decl)
9696c529 479 */
0a750165 480 gsi = gsi_after_labels (split_edge (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun))));
4d3814a5
RG
481
482 cur_func = force_gimple_operand_gsi (&gsi,
483 build_addr (current_function_decl,
484 current_function_decl),
485 true, NULL_TREE,
486 true, GSI_SAME_STMT);
2fa3d31b 487 tree_uid = build_int_cst
d52f5295 488 (gcov_type_node, cgraph_node::get (current_function_decl)->profile_id);
748d71f3
JH
489 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
490 if (flag_lto)
491 {
492 tree counter_ptr, ptr_var;
493 counter_ptr = force_gimple_operand_gsi (&gsi, ic_gcov_type_ptr_var,
494 true, NULL_TREE, true,
495 GSI_SAME_STMT);
496 ptr_var = force_gimple_operand_gsi (&gsi, ic_void_ptr_var,
497 true, NULL_TREE, true,
498 GSI_SAME_STMT);
499
500 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 4,
501 counter_ptr, tree_uid, cur_func, ptr_var);
502 }
503 else
504 {
505 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2,
506 tree_uid, cur_func);
507 }
4d3814a5
RG
508 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
509
510 /* Set __gcov_indirect_call_callee to 0,
511 so that calls from other modules won't get misattributed
512 to the last caller of the current callee. */
513 void0 = build_int_cst (build_pointer_type (void_type_node), 0);
514 stmt2 = gimple_build_assign (ic_void_ptr_var, void0);
515 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
6bad2617
TB
516}
517
86ce5d2f
ML
518/* Output instructions as GIMPLE tree at the beginning for each function.
519 TAG is the tag of the section for counters, BASE is offset of the
520 counter position and GSI is the iterator we place the counter. */
521
522void
523gimple_gen_time_profiler (unsigned tag, unsigned base,
524 gimple_stmt_iterator &gsi)
525{
526 tree ref_ptr = tree_coverage_counter_addr (tag, base);
538dd0b7 527 gcall *call;
86ce5d2f
ML
528
529 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
530 true, NULL_TREE, true, GSI_SAME_STMT);
531 call = gimple_build_call (tree_time_profiler_fn, 1, ref_ptr);
532 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
533}
534
b8698a0f 535/* Output instructions as GIMPLE trees for code to find the most common value
6de9cd9a
DN
536 of a difference between two evaluations of an expression.
537 VALUE is the expression whose value is profiled. TAG is the tag of the
538 section for counters, BASE is offset of the counter position. */
539
e0cb7e1e
SB
540void
541gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
726a989a
RB
542 unsigned tag ATTRIBUTE_UNUSED,
543 unsigned base ATTRIBUTE_UNUSED)
6de9cd9a
DN
544{
545 /* FIXME implement this. */
1e128c5f
GB
546#ifdef ENABLE_CHECKING
547 internal_error ("unimplemented functionality");
548#endif
549 gcc_unreachable ();
6de9cd9a
DN
550}
551
b8698a0f
L
552/* Output instructions as GIMPLE trees to increment the average histogram
553 counter. VALUE is the expression whose value is profiled. TAG is the
079a182e
JH
554 tag of the section for counters, BASE is offset of the counter position. */
555
e0cb7e1e
SB
556void
557gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
079a182e 558{
726a989a
RB
559 gimple stmt = value->hvalue.stmt;
560 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
fc9161c1 561 tree ref_ptr = tree_coverage_counter_addr (tag, base);
538dd0b7 562 gcall *call;
726a989a 563 tree val;
b8698a0f 564
726a989a 565 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
c6540bde 566 true, NULL_TREE,
726a989a
RB
567 true, GSI_SAME_STMT);
568 val = prepare_instrumented_value (&gsi, value);
569 call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
71ba42fa 570 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
079a182e
JH
571}
572
b8698a0f
L
573/* Output instructions as GIMPLE trees to increment the ior histogram
574 counter. VALUE is the expression whose value is profiled. TAG is the
079a182e
JH
575 tag of the section for counters, BASE is offset of the counter position. */
576
e0cb7e1e
SB
577void
578gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
079a182e 579{
726a989a
RB
580 gimple stmt = value->hvalue.stmt;
581 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
fc9161c1 582 tree ref_ptr = tree_coverage_counter_addr (tag, base);
538dd0b7 583 gcall *call;
726a989a 584 tree val;
b8698a0f 585
726a989a
RB
586 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
587 true, NULL_TREE, true, GSI_SAME_STMT);
588 val = prepare_instrumented_value (&gsi, value);
589 call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
71ba42fa 590 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
079a182e
JH
591}
592
4d3814a5 593/* Profile all functions in the callgraph. */
6de9cd9a 594
c2924966 595static unsigned int
1f1e8527
DJ
596tree_profiling (void)
597{
4d3814a5
RG
598 struct cgraph_node *node;
599
9696c529
SB
600 /* This is a small-ipa pass that gets called only once, from
601 cgraphunit.c:ipa_passes(). */
3dafb85c 602 gcc_assert (symtab->state == IPA_SSA);
9225443e 603
2fa3d31b 604 init_node_map (true);
903d1e67 605
65c70e6b 606 FOR_EACH_DEFINED_FUNCTION (node)
4d3814a5 607 {
67348ccc 608 if (!gimple_has_body_p (node->decl))
4d3814a5
RG
609 continue;
610
611 /* Don't profile functions produced for builtin stuff. */
67348ccc 612 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
4d3814a5
RG
613 continue;
614
07db0f9b
JH
615 /* Do not instrument extern inline functions when testing coverage.
616 While this is not perfectly consistent (early inlined extern inlines
617 will get acocunted), testsuite expects that. */
618 if (DECL_EXTERNAL (node->decl)
619 && flag_test_coverage)
620 continue;
621
67348ccc 622 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
4d3814a5 623
71fb4f92 624 /* Local pure-const may imply need to fixup the cfg. */
49bdc0a6
RG
625 if (execute_fixup_cfg () & TODO_cleanup_cfg)
626 cleanup_tree_cfg ();
9696c529 627
4d3814a5
RG
628 branch_prob ();
629
630 if (! flag_branch_probabilities
631 && flag_profile_values)
e0cb7e1e 632 gimple_gen_ic_func_profiler ();
4d3814a5
RG
633
634 if (flag_branch_probabilities
635 && flag_profile_values
636 && flag_value_profile_transformations)
e0cb7e1e 637 gimple_value_profile_transformations ();
4d3814a5
RG
638
639 /* The above could hose dominator info. Currently there is
640 none coming in, this is a safety valve. It should be
641 easy to adjust it, if and when there is some. */
642 free_dominance_info (CDI_DOMINATORS);
643 free_dominance_info (CDI_POST_DOMINATORS);
4d3814a5
RG
644 pop_cfun ();
645 }
646
647 /* Drop pure/const flags from instrumented functions. */
65c70e6b 648 FOR_EACH_DEFINED_FUNCTION (node)
4d3814a5 649 {
67348ccc 650 if (!gimple_has_body_p (node->decl)
960bfb69 651 || !(!node->clone_of
67348ccc 652 || node->decl != node->clone_of->decl))
4d3814a5
RG
653 continue;
654
655 /* Don't profile functions produced for builtin stuff. */
67348ccc 656 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
4d3814a5
RG
657 continue;
658
d52f5295
ML
659 node->set_const_flag (false, false);
660 node->set_pure_flag (false, false);
4d3814a5
RG
661 }
662
663 /* Update call statements and rebuild the cgraph. */
65c70e6b 664 FOR_EACH_DEFINED_FUNCTION (node)
4d3814a5
RG
665 {
666 basic_block bb;
667
67348ccc 668 if (!gimple_has_body_p (node->decl)
960bfb69 669 || !(!node->clone_of
67348ccc 670 || node->decl != node->clone_of->decl))
4d3814a5
RG
671 continue;
672
673 /* Don't profile functions produced for builtin stuff. */
67348ccc 674 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
4d3814a5
RG
675 continue;
676
67348ccc 677 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
4d3814a5 678
11cd3bed 679 FOR_EACH_BB_FN (bb, cfun)
4d3814a5
RG
680 {
681 gimple_stmt_iterator gsi;
682 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
683 {
684 gimple stmt = gsi_stmt (gsi);
685 if (is_gimple_call (stmt))
686 update_stmt (stmt);
687 }
688 }
689
a64bbb3f
JH
690 /* re-merge split blocks. */
691 cleanup_tree_cfg ();
4d3814a5
RG
692 update_ssa (TODO_update_ssa);
693
3dafb85c 694 cgraph_edge::rebuild_edges ();
4d3814a5 695
4d3814a5
RG
696 pop_cfun ();
697 }
f7b4a383 698
eb4b92c1
TJ
699 handle_missing_profiles ();
700
c3284718 701 del_node_map ();
c2924966 702 return 0;
1f1e8527
DJ
703}
704
27a4cd48
DM
705namespace {
706
707const pass_data pass_data_ipa_tree_profile =
6de9cd9a 708{
27a4cd48
DM
709 SIMPLE_IPA_PASS, /* type */
710 "profile", /* name */
711 OPTGROUP_NONE, /* optinfo_flags */
27a4cd48
DM
712 TV_IPA_PROFILE, /* tv_id */
713 0, /* properties_required */
714 0, /* properties_provided */
715 0, /* properties_destroyed */
716 0, /* todo_flags_start */
717 0, /* todo_flags_finish */
6de9cd9a
DN
718};
719
27a4cd48
DM
720class pass_ipa_tree_profile : public simple_ipa_opt_pass
721{
722public:
c3284718
RS
723 pass_ipa_tree_profile (gcc::context *ctxt)
724 : simple_ipa_opt_pass (pass_data_ipa_tree_profile, ctxt)
27a4cd48
DM
725 {}
726
727 /* opt_pass methods: */
1a3d085c 728 virtual bool gate (function *);
be55bfe6 729 virtual unsigned int execute (function *) { return tree_profiling (); }
27a4cd48
DM
730
731}; // class pass_ipa_tree_profile
732
1a3d085c
TS
733bool
734pass_ipa_tree_profile::gate (function *)
735{
be3c16c4
DC
736 /* When profile instrumentation, use or test coverage shall be performed.
737 But for AutoFDO, this there is no instrumentation, thus this pass is
738 diabled. */
739 return (!in_lto_p && !flag_auto_profile
1a3d085c
TS
740 && (flag_branch_probabilities || flag_test_coverage
741 || profile_arc_flag));
742}
743
27a4cd48
DM
744} // anon namespace
745
746simple_ipa_opt_pass *
747make_pass_ipa_tree_profile (gcc::context *ctxt)
748{
749 return new pass_ipa_tree_profile (ctxt);
750}
751
9885da8e 752#include "gt-tree-profile.h"