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