2015-09-25 Vladimir Makarov <vmakarov@redhat.com>
[official-gcc.git] / gcc / tree-profile.c
blobb4b3ae19c99b04331858d62fe2c13dd6e5cb84fc
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.
8 This file is part of GCC.
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.
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.
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/>. */
24 /* Generate basic block profile instrumentation and auxiliary files.
25 Tree-based version. See profile.c for overview. */
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"
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;
68 static GTY(()) tree ic_void_ptr_var;
69 static GTY(()) tree ic_gcov_type_ptr_var;
70 static GTY(()) tree ptr_void;
72 /* Do initialization work for the edge profiler. */
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
79 static void
80 init_ic_make_global_vars (void)
82 tree gcov_type_ptr;
84 ptr_void = build_pointer_type (void_type_node);
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));
101 varpool_node::finalize_decl (ic_void_ptr_var);
103 gcov_type_ptr = build_pointer_type (get_gcov_type ());
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));
120 varpool_node::finalize_decl (ic_gcov_type_ptr_var);
123 /* Create the type and function decls for the interface with gcov. */
125 void
126 gimple_init_edge_profiler (void)
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;
136 if (!gcov_type_node)
138 gcov_type_node = get_gcov_type ();
139 gcov_type_ptr = build_pointer_type (gcov_type_node);
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));
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));
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));
180 init_ic_make_global_vars ();
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);
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));
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));
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));
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);
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. */
246 void
247 gimple_gen_edge_profiler (int edgeno, edge e)
249 tree ref, one, gcov_type_tmp_var;
250 gassign *stmt1, *stmt2, *stmt3;
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);
267 /* Emits code to get VALUE to instrument at GSI, and returns the
268 variable containing the value. */
270 static tree
271 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
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);
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. */
285 void
286 gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
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);
298 ref_ptr = force_gimple_operand_gsi (&gsi,
299 build_addr (ref, current_function_decl),
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);
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. */
311 void
312 gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
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;
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);
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. */
331 void
332 gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
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;
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);
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. */
354 void
355 gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
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);
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;
369 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
370 true, NULL_TREE, true, GSI_SAME_STMT);
372 /* Insert code:
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;
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));
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);
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.
395 void
396 gimple_gen_ic_func_profiler (void)
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;
404 if (c_node->only_called_directly_p ())
405 return;
407 gimple_init_edge_profiler ();
409 /* Insert code:
411 stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
412 &current_function_decl)
414 gsi = gsi_after_labels (split_edge (single_succ_edge
415 (ENTRY_BLOCK_PTR_FOR_FN (cfun))));
417 cur_func = force_gimple_operand_gsi (&gsi,
418 build_addr (current_function_decl,
419 current_function_decl),
420 true, NULL_TREE,
421 true, GSI_SAME_STMT);
422 tree_uid = build_int_cst
423 (gcov_type_node,
424 cgraph_node::get (current_function_decl)->profile_id);
425 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2,
426 tree_uid, cur_func);
427 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
429 /* Set __gcov_indirect_call_callee to 0,
430 so that calls from other modules won't get misattributed
431 to the last caller of the current callee. */
432 void0 = build_int_cst (build_pointer_type (void_type_node), 0);
433 stmt2 = gimple_build_assign (ic_void_ptr_var, void0);
434 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
437 /* Output instructions as GIMPLE tree at the beginning for each function.
438 TAG is the tag of the section for counters, BASE is offset of the
439 counter position and GSI is the iterator we place the counter. */
441 void
442 gimple_gen_time_profiler (unsigned tag, unsigned base,
443 gimple_stmt_iterator &gsi)
445 tree ref_ptr = tree_coverage_counter_addr (tag, base);
446 gcall *call;
448 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
449 true, NULL_TREE, true, GSI_SAME_STMT);
450 call = gimple_build_call (tree_time_profiler_fn, 1, ref_ptr);
451 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
454 /* Output instructions as GIMPLE trees for code to find the most common value
455 of a difference between two evaluations of an expression.
456 VALUE is the expression whose value is profiled. TAG is the tag of the
457 section for counters, BASE is offset of the counter position. */
459 void
460 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
461 unsigned tag ATTRIBUTE_UNUSED,
462 unsigned base ATTRIBUTE_UNUSED)
464 /* FIXME implement this. */
465 #ifdef ENABLE_CHECKING
466 internal_error ("unimplemented functionality");
467 #endif
468 gcc_unreachable ();
471 /* Output instructions as GIMPLE trees to increment the average histogram
472 counter. VALUE is the expression whose value is profiled. TAG is the
473 tag of the section for counters, BASE is offset of the counter position. */
475 void
476 gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
478 gimple *stmt = value->hvalue.stmt;
479 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
480 tree ref_ptr = tree_coverage_counter_addr (tag, base);
481 gcall *call;
482 tree val;
484 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
485 true, NULL_TREE,
486 true, GSI_SAME_STMT);
487 val = prepare_instrumented_value (&gsi, value);
488 call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
489 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
492 /* Output instructions as GIMPLE trees to increment the ior histogram
493 counter. VALUE is the expression whose value is profiled. TAG is the
494 tag of the section for counters, BASE is offset of the counter position. */
496 void
497 gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
499 gimple *stmt = value->hvalue.stmt;
500 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
501 tree ref_ptr = tree_coverage_counter_addr (tag, base);
502 gcall *call;
503 tree val;
505 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
506 true, NULL_TREE, true, GSI_SAME_STMT);
507 val = prepare_instrumented_value (&gsi, value);
508 call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
509 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
512 /* Profile all functions in the callgraph. */
514 static unsigned int
515 tree_profiling (void)
517 struct cgraph_node *node;
519 /* This is a small-ipa pass that gets called only once, from
520 cgraphunit.c:ipa_passes(). */
521 gcc_assert (symtab->state == IPA_SSA);
523 init_node_map (true);
525 FOR_EACH_DEFINED_FUNCTION (node)
527 if (!gimple_has_body_p (node->decl))
528 continue;
530 /* Don't profile functions produced for builtin stuff. */
531 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
532 continue;
534 /* Do not instrument extern inline functions when testing coverage.
535 While this is not perfectly consistent (early inlined extern inlines
536 will get acocunted), testsuite expects that. */
537 if (DECL_EXTERNAL (node->decl)
538 && flag_test_coverage)
539 continue;
541 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
543 /* Local pure-const may imply need to fixup the cfg. */
544 if (execute_fixup_cfg () & TODO_cleanup_cfg)
545 cleanup_tree_cfg ();
547 branch_prob ();
549 if (! flag_branch_probabilities
550 && flag_profile_values)
551 gimple_gen_ic_func_profiler ();
553 if (flag_branch_probabilities
554 && flag_profile_values
555 && flag_value_profile_transformations)
556 gimple_value_profile_transformations ();
558 /* The above could hose dominator info. Currently there is
559 none coming in, this is a safety valve. It should be
560 easy to adjust it, if and when there is some. */
561 free_dominance_info (CDI_DOMINATORS);
562 free_dominance_info (CDI_POST_DOMINATORS);
563 pop_cfun ();
566 /* Drop pure/const flags from instrumented functions. */
567 FOR_EACH_DEFINED_FUNCTION (node)
569 if (!gimple_has_body_p (node->decl)
570 || !(!node->clone_of
571 || node->decl != node->clone_of->decl))
572 continue;
574 /* Don't profile functions produced for builtin stuff. */
575 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
576 continue;
578 node->set_const_flag (false, false);
579 node->set_pure_flag (false, false);
582 /* Update call statements and rebuild the cgraph. */
583 FOR_EACH_DEFINED_FUNCTION (node)
585 basic_block bb;
587 if (!gimple_has_body_p (node->decl)
588 || !(!node->clone_of
589 || node->decl != node->clone_of->decl))
590 continue;
592 /* Don't profile functions produced for builtin stuff. */
593 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
594 continue;
596 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
598 FOR_EACH_BB_FN (bb, cfun)
600 gimple_stmt_iterator gsi;
601 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
603 gimple *stmt = gsi_stmt (gsi);
604 if (is_gimple_call (stmt))
605 update_stmt (stmt);
609 /* re-merge split blocks. */
610 cleanup_tree_cfg ();
611 update_ssa (TODO_update_ssa);
613 cgraph_edge::rebuild_edges ();
615 pop_cfun ();
618 handle_missing_profiles ();
620 del_node_map ();
621 return 0;
624 namespace {
626 const pass_data pass_data_ipa_tree_profile =
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 0, /* todo_flags_finish */
639 class pass_ipa_tree_profile : public simple_ipa_opt_pass
641 public:
642 pass_ipa_tree_profile (gcc::context *ctxt)
643 : simple_ipa_opt_pass (pass_data_ipa_tree_profile, ctxt)
646 /* opt_pass methods: */
647 virtual bool gate (function *);
648 virtual unsigned int execute (function *) { return tree_profiling (); }
650 }; // class pass_ipa_tree_profile
652 bool
653 pass_ipa_tree_profile::gate (function *)
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));
663 } // anon namespace
665 simple_ipa_opt_pass *
666 make_pass_ipa_tree_profile (gcc::context *ctxt)
668 return new pass_ipa_tree_profile (ctxt);
671 #include "gt-tree-profile.h"