Clean up some minor white space issues in trans-decl.c and trans-expr.c
[official-gcc.git] / gcc / tree-profile.c
blob1f3a726988ac0ba7f7b6bdca733067c833e61cdb
1 /* Calculate branch probabilities, and basic block execution counts.
2 Copyright (C) 1990-2016 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 "target.h"
32 #include "tree.h"
33 #include "gimple.h"
34 #include "cfghooks.h"
35 #include "tree-pass.h"
36 #include "ssa.h"
37 #include "cgraph.h"
38 #include "coverage.h"
39 #include "diagnostic-core.h"
40 #include "fold-const.h"
41 #include "varasm.h"
42 #include "tree-nested.h"
43 #include "gimplify.h"
44 #include "gimple-iterator.h"
45 #include "gimplify-me.h"
46 #include "tree-cfg.h"
47 #include "tree-into-ssa.h"
48 #include "value-prof.h"
49 #include "profile.h"
50 #include "tree-cfgcleanup.h"
51 #include "params.h"
53 static GTY(()) tree gcov_type_node;
54 static GTY(()) tree tree_interval_profiler_fn;
55 static GTY(()) tree tree_pow2_profiler_fn;
56 static GTY(()) tree tree_one_value_profiler_fn;
57 static GTY(()) tree tree_indirect_call_profiler_fn;
58 static GTY(()) tree tree_time_profiler_fn;
59 static GTY(()) tree tree_average_profiler_fn;
60 static GTY(()) tree tree_ior_profiler_fn;
63 static GTY(()) tree ic_void_ptr_var;
64 static GTY(()) tree ic_gcov_type_ptr_var;
65 static GTY(()) tree ptr_void;
67 /* Do initialization work for the edge profiler. */
69 /* Add code:
70 __thread gcov* __gcov_indirect_call_counters; // pointer to actual counter
71 __thread void* __gcov_indirect_call_callee; // actual callee address
72 __thread int __gcov_function_counter; // time profiler function counter
74 static void
75 init_ic_make_global_vars (void)
77 tree gcov_type_ptr;
79 ptr_void = build_pointer_type (void_type_node);
81 ic_void_ptr_var
82 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
83 get_identifier (
84 (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
85 "__gcov_indirect_call_topn_callee" :
86 "__gcov_indirect_call_callee")),
87 ptr_void);
88 TREE_PUBLIC (ic_void_ptr_var) = 1;
89 DECL_EXTERNAL (ic_void_ptr_var) = 1;
90 TREE_STATIC (ic_void_ptr_var) = 1;
91 DECL_ARTIFICIAL (ic_void_ptr_var) = 1;
92 DECL_INITIAL (ic_void_ptr_var) = NULL;
93 if (targetm.have_tls)
94 set_decl_tls_model (ic_void_ptr_var, decl_default_tls_model (ic_void_ptr_var));
96 varpool_node::finalize_decl (ic_void_ptr_var);
98 gcov_type_ptr = build_pointer_type (get_gcov_type ());
100 ic_gcov_type_ptr_var
101 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
102 get_identifier (
103 (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
104 "__gcov_indirect_call_topn_counters" :
105 "__gcov_indirect_call_counters")),
106 gcov_type_ptr);
107 TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
108 DECL_EXTERNAL (ic_gcov_type_ptr_var) = 1;
109 TREE_STATIC (ic_gcov_type_ptr_var) = 1;
110 DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1;
111 DECL_INITIAL (ic_gcov_type_ptr_var) = NULL;
112 if (targetm.have_tls)
113 set_decl_tls_model (ic_gcov_type_ptr_var, decl_default_tls_model (ic_gcov_type_ptr_var));
115 varpool_node::finalize_decl (ic_gcov_type_ptr_var);
118 /* Create the type and function decls for the interface with gcov. */
120 void
121 gimple_init_edge_profiler (void)
123 tree interval_profiler_fn_type;
124 tree pow2_profiler_fn_type;
125 tree one_value_profiler_fn_type;
126 tree gcov_type_ptr;
127 tree ic_profiler_fn_type;
128 tree average_profiler_fn_type;
129 tree time_profiler_fn_type;
131 if (!gcov_type_node)
133 gcov_type_node = get_gcov_type ();
134 gcov_type_ptr = build_pointer_type (gcov_type_node);
136 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
137 interval_profiler_fn_type
138 = build_function_type_list (void_type_node,
139 gcov_type_ptr, gcov_type_node,
140 integer_type_node,
141 unsigned_type_node, NULL_TREE);
142 tree_interval_profiler_fn
143 = build_fn_decl ("__gcov_interval_profiler",
144 interval_profiler_fn_type);
145 TREE_NOTHROW (tree_interval_profiler_fn) = 1;
146 DECL_ATTRIBUTES (tree_interval_profiler_fn)
147 = tree_cons (get_identifier ("leaf"), NULL,
148 DECL_ATTRIBUTES (tree_interval_profiler_fn));
150 /* void (*) (gcov_type *, gcov_type) */
151 pow2_profiler_fn_type
152 = build_function_type_list (void_type_node,
153 gcov_type_ptr, gcov_type_node,
154 NULL_TREE);
155 tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler",
156 pow2_profiler_fn_type);
157 TREE_NOTHROW (tree_pow2_profiler_fn) = 1;
158 DECL_ATTRIBUTES (tree_pow2_profiler_fn)
159 = tree_cons (get_identifier ("leaf"), NULL,
160 DECL_ATTRIBUTES (tree_pow2_profiler_fn));
162 /* void (*) (gcov_type *, gcov_type) */
163 one_value_profiler_fn_type
164 = build_function_type_list (void_type_node,
165 gcov_type_ptr, gcov_type_node,
166 NULL_TREE);
167 tree_one_value_profiler_fn
168 = build_fn_decl ("__gcov_one_value_profiler",
169 one_value_profiler_fn_type);
170 TREE_NOTHROW (tree_one_value_profiler_fn) = 1;
171 DECL_ATTRIBUTES (tree_one_value_profiler_fn)
172 = tree_cons (get_identifier ("leaf"), NULL,
173 DECL_ATTRIBUTES (tree_one_value_profiler_fn));
175 init_ic_make_global_vars ();
177 /* void (*) (gcov_type, void *) */
178 ic_profiler_fn_type
179 = build_function_type_list (void_type_node,
180 gcov_type_node,
181 ptr_void,
182 NULL_TREE);
183 tree_indirect_call_profiler_fn
184 = build_fn_decl ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
185 "__gcov_indirect_call_topn_profiler":
186 "__gcov_indirect_call_profiler_v2"),
187 ic_profiler_fn_type);
189 TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
190 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
191 = tree_cons (get_identifier ("leaf"), NULL,
192 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn));
194 /* void (*) (gcov_type *, gcov_type, void *) */
195 time_profiler_fn_type
196 = build_function_type_list (void_type_node,
197 gcov_type_ptr, NULL_TREE);
198 tree_time_profiler_fn
199 = build_fn_decl ("__gcov_time_profiler",
200 time_profiler_fn_type);
201 TREE_NOTHROW (tree_time_profiler_fn) = 1;
202 DECL_ATTRIBUTES (tree_time_profiler_fn)
203 = tree_cons (get_identifier ("leaf"), NULL,
204 DECL_ATTRIBUTES (tree_time_profiler_fn));
206 /* void (*) (gcov_type *, gcov_type) */
207 average_profiler_fn_type
208 = build_function_type_list (void_type_node,
209 gcov_type_ptr, gcov_type_node, NULL_TREE);
210 tree_average_profiler_fn
211 = build_fn_decl ("__gcov_average_profiler",
212 average_profiler_fn_type);
213 TREE_NOTHROW (tree_average_profiler_fn) = 1;
214 DECL_ATTRIBUTES (tree_average_profiler_fn)
215 = tree_cons (get_identifier ("leaf"), NULL,
216 DECL_ATTRIBUTES (tree_average_profiler_fn));
217 tree_ior_profiler_fn
218 = build_fn_decl ("__gcov_ior_profiler",
219 average_profiler_fn_type);
220 TREE_NOTHROW (tree_ior_profiler_fn) = 1;
221 DECL_ATTRIBUTES (tree_ior_profiler_fn)
222 = tree_cons (get_identifier ("leaf"), NULL,
223 DECL_ATTRIBUTES (tree_ior_profiler_fn));
225 /* LTO streamer needs assembler names. Because we create these decls
226 late, we need to initialize them by hand. */
227 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn);
228 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn);
229 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn);
230 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn);
231 DECL_ASSEMBLER_NAME (tree_time_profiler_fn);
232 DECL_ASSEMBLER_NAME (tree_average_profiler_fn);
233 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
237 /* Output instructions as GIMPLE trees to increment the edge
238 execution count, and insert them on E. We rely on
239 gsi_insert_on_edge to preserve the order. */
241 void
242 gimple_gen_edge_profiler (int edgeno, edge e)
244 tree ref, one, gcov_type_tmp_var;
245 gassign *stmt1, *stmt2, *stmt3;
247 ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
248 one = build_int_cst (gcov_type_node, 1);
249 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
250 NULL, "PROF_edge_counter");
251 stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
252 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
253 NULL, "PROF_edge_counter");
254 stmt2 = gimple_build_assign (gcov_type_tmp_var, PLUS_EXPR,
255 gimple_assign_lhs (stmt1), one);
256 stmt3 = gimple_build_assign (unshare_expr (ref), gimple_assign_lhs (stmt2));
257 gsi_insert_on_edge (e, stmt1);
258 gsi_insert_on_edge (e, stmt2);
259 gsi_insert_on_edge (e, stmt3);
262 /* Emits code to get VALUE to instrument at GSI, and returns the
263 variable containing the value. */
265 static tree
266 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
268 tree val = value->hvalue.value;
269 if (POINTER_TYPE_P (TREE_TYPE (val)))
270 val = fold_convert (build_nonstandard_integer_type
271 (TYPE_PRECISION (TREE_TYPE (val)), 1), val);
272 return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
273 true, NULL_TREE, true, GSI_SAME_STMT);
276 /* Output instructions as GIMPLE trees to increment the interval histogram
277 counter. VALUE is the expression whose value is profiled. TAG is the
278 tag of the section for counters, BASE is offset of the counter position. */
280 void
281 gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
283 gimple *stmt = value->hvalue.stmt;
284 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
285 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
286 gcall *call;
287 tree val;
288 tree start = build_int_cst_type (integer_type_node,
289 value->hdata.intvl.int_start);
290 tree steps = build_int_cst_type (unsigned_type_node,
291 value->hdata.intvl.steps);
293 ref_ptr = force_gimple_operand_gsi (&gsi,
294 build_addr (ref),
295 true, NULL_TREE, true, GSI_SAME_STMT);
296 val = prepare_instrumented_value (&gsi, value);
297 call = gimple_build_call (tree_interval_profiler_fn, 4,
298 ref_ptr, val, start, steps);
299 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
302 /* Output instructions as GIMPLE trees to increment the power of two histogram
303 counter. VALUE is the expression whose value is profiled. TAG is the tag
304 of the section for counters, BASE is offset of the counter position. */
306 void
307 gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
309 gimple *stmt = value->hvalue.stmt;
310 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
311 tree ref_ptr = tree_coverage_counter_addr (tag, base);
312 gcall *call;
313 tree val;
315 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
316 true, NULL_TREE, true, GSI_SAME_STMT);
317 val = prepare_instrumented_value (&gsi, value);
318 call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val);
319 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
322 /* Output instructions as GIMPLE trees for code to find the most common value.
323 VALUE is the expression whose value is profiled. TAG is the tag of the
324 section for counters, BASE is offset of the counter position. */
326 void
327 gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
329 gimple *stmt = value->hvalue.stmt;
330 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
331 tree ref_ptr = tree_coverage_counter_addr (tag, base);
332 gcall *call;
333 tree val;
335 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
336 true, NULL_TREE, true, GSI_SAME_STMT);
337 val = prepare_instrumented_value (&gsi, value);
338 call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val);
339 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
343 /* Output instructions as GIMPLE trees for code to find the most
344 common called function in indirect call.
345 VALUE is the call expression whose indirect callee is profiled.
346 TAG is the tag of the section for counters, BASE is offset of the
347 counter position. */
349 void
350 gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
352 tree tmp1;
353 gassign *stmt1, *stmt2, *stmt3;
354 gimple *stmt = value->hvalue.stmt;
355 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
356 tree ref_ptr = tree_coverage_counter_addr (tag, base);
358 if ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) &&
359 tag == GCOV_COUNTER_V_INDIR) ||
360 (!PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) &&
361 tag == GCOV_COUNTER_ICALL_TOPNV))
362 return;
364 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
365 true, NULL_TREE, true, GSI_SAME_STMT);
367 /* Insert code:
369 stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
370 stmt2: tmp1 = (void *) (indirect call argument value)
371 stmt3: __gcov_indirect_call_callee = tmp1;
374 stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr);
375 tmp1 = make_temp_ssa_name (ptr_void, NULL, "PROF");
376 stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
377 stmt3 = gimple_build_assign (ic_void_ptr_var, gimple_assign_lhs (stmt2));
379 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
380 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
381 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
385 /* Output instructions as GIMPLE trees for code to find the most
386 common called function in indirect call. Insert instructions at the
387 beginning of every possible called function.
390 void
391 gimple_gen_ic_func_profiler (void)
393 struct cgraph_node * c_node = cgraph_node::get (current_function_decl);
394 gimple_stmt_iterator gsi;
395 gcall *stmt1;
396 gassign *stmt2;
397 tree tree_uid, cur_func, void0;
399 if (c_node->only_called_directly_p ())
400 return;
402 gimple_init_edge_profiler ();
404 /* Insert code:
406 stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
407 &current_function_decl)
409 gsi = gsi_after_labels (split_edge (single_succ_edge
410 (ENTRY_BLOCK_PTR_FOR_FN (cfun))));
412 cur_func = force_gimple_operand_gsi (&gsi,
413 build_addr (current_function_decl),
414 true, NULL_TREE,
415 true, GSI_SAME_STMT);
416 tree_uid = build_int_cst
417 (gcov_type_node,
418 cgraph_node::get (current_function_decl)->profile_id);
419 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2,
420 tree_uid, cur_func);
421 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
423 /* Set __gcov_indirect_call_callee to 0,
424 so that calls from other modules won't get misattributed
425 to the last caller of the current callee. */
426 void0 = build_int_cst (build_pointer_type (void_type_node), 0);
427 stmt2 = gimple_build_assign (ic_void_ptr_var, void0);
428 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
431 /* Output instructions as GIMPLE tree at the beginning for each function.
432 TAG is the tag of the section for counters, BASE is offset of the
433 counter position and GSI is the iterator we place the counter. */
435 void
436 gimple_gen_time_profiler (unsigned tag, unsigned base,
437 gimple_stmt_iterator &gsi)
439 tree ref_ptr = tree_coverage_counter_addr (tag, base);
440 gcall *call;
442 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
443 true, NULL_TREE, true, GSI_SAME_STMT);
444 call = gimple_build_call (tree_time_profiler_fn, 1, ref_ptr);
445 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
448 /* Output instructions as GIMPLE trees for code to find the most common value
449 of a difference between two evaluations of an expression.
450 VALUE is the expression whose value is profiled. TAG is the tag of the
451 section for counters, BASE is offset of the counter position. */
453 void
454 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
455 unsigned tag ATTRIBUTE_UNUSED,
456 unsigned base ATTRIBUTE_UNUSED)
458 /* FIXME implement this. */
459 if (flag_checking)
460 internal_error ("unimplemented functionality");
461 gcc_unreachable ();
464 /* Output instructions as GIMPLE trees to increment the average histogram
465 counter. VALUE is the expression whose value is profiled. TAG is the
466 tag of the section for counters, BASE is offset of the counter position. */
468 void
469 gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
471 gimple *stmt = value->hvalue.stmt;
472 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
473 tree ref_ptr = tree_coverage_counter_addr (tag, base);
474 gcall *call;
475 tree val;
477 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
478 true, NULL_TREE,
479 true, GSI_SAME_STMT);
480 val = prepare_instrumented_value (&gsi, value);
481 call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
482 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
485 /* Output instructions as GIMPLE trees to increment the ior histogram
486 counter. VALUE is the expression whose value is profiled. TAG is the
487 tag of the section for counters, BASE is offset of the counter position. */
489 void
490 gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
492 gimple *stmt = value->hvalue.stmt;
493 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
494 tree ref_ptr = tree_coverage_counter_addr (tag, base);
495 gcall *call;
496 tree val;
498 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
499 true, NULL_TREE, true, GSI_SAME_STMT);
500 val = prepare_instrumented_value (&gsi, value);
501 call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
502 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
505 /* Profile all functions in the callgraph. */
507 static unsigned int
508 tree_profiling (void)
510 struct cgraph_node *node;
512 /* This is a small-ipa pass that gets called only once, from
513 cgraphunit.c:ipa_passes(). */
514 gcc_assert (symtab->state == IPA_SSA);
516 init_node_map (true);
518 FOR_EACH_DEFINED_FUNCTION (node)
520 if (!gimple_has_body_p (node->decl))
521 continue;
523 /* Don't profile functions produced for builtin stuff. */
524 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
525 continue;
527 /* Do not instrument extern inline functions when testing coverage.
528 While this is not perfectly consistent (early inlined extern inlines
529 will get acocunted), testsuite expects that. */
530 if (DECL_EXTERNAL (node->decl)
531 && flag_test_coverage)
532 continue;
534 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
536 /* Local pure-const may imply need to fixup the cfg. */
537 if (execute_fixup_cfg () & TODO_cleanup_cfg)
538 cleanup_tree_cfg ();
540 branch_prob ();
542 if (! flag_branch_probabilities
543 && flag_profile_values)
544 gimple_gen_ic_func_profiler ();
546 if (flag_branch_probabilities
547 && flag_profile_values
548 && flag_value_profile_transformations)
549 gimple_value_profile_transformations ();
551 /* The above could hose dominator info. Currently there is
552 none coming in, this is a safety valve. It should be
553 easy to adjust it, if and when there is some. */
554 free_dominance_info (CDI_DOMINATORS);
555 free_dominance_info (CDI_POST_DOMINATORS);
556 pop_cfun ();
559 /* Drop pure/const flags from instrumented functions. */
560 if (profile_arc_flag || flag_test_coverage)
561 FOR_EACH_DEFINED_FUNCTION (node)
563 if (!gimple_has_body_p (node->decl)
564 || !(!node->clone_of
565 || node->decl != node->clone_of->decl))
566 continue;
568 /* Don't profile functions produced for builtin stuff. */
569 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
570 continue;
572 node->set_const_flag (false, false);
573 node->set_pure_flag (false, false);
576 /* Update call statements and rebuild the cgraph. */
577 FOR_EACH_DEFINED_FUNCTION (node)
579 basic_block bb;
581 if (!gimple_has_body_p (node->decl)
582 || !(!node->clone_of
583 || node->decl != node->clone_of->decl))
584 continue;
586 /* Don't profile functions produced for builtin stuff. */
587 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
588 continue;
590 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
592 FOR_EACH_BB_FN (bb, cfun)
594 gimple_stmt_iterator gsi;
595 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
597 gimple *stmt = gsi_stmt (gsi);
598 if (is_gimple_call (stmt))
599 update_stmt (stmt);
603 /* re-merge split blocks. */
604 cleanup_tree_cfg ();
605 update_ssa (TODO_update_ssa);
607 cgraph_edge::rebuild_edges ();
609 pop_cfun ();
612 handle_missing_profiles ();
614 del_node_map ();
615 return 0;
618 namespace {
620 const pass_data pass_data_ipa_tree_profile =
622 SIMPLE_IPA_PASS, /* type */
623 "profile", /* name */
624 OPTGROUP_NONE, /* optinfo_flags */
625 TV_IPA_PROFILE, /* tv_id */
626 0, /* properties_required */
627 0, /* properties_provided */
628 0, /* properties_destroyed */
629 0, /* todo_flags_start */
630 TODO_dump_symtab, /* todo_flags_finish */
633 class pass_ipa_tree_profile : public simple_ipa_opt_pass
635 public:
636 pass_ipa_tree_profile (gcc::context *ctxt)
637 : simple_ipa_opt_pass (pass_data_ipa_tree_profile, ctxt)
640 /* opt_pass methods: */
641 virtual bool gate (function *);
642 virtual unsigned int execute (function *) { return tree_profiling (); }
644 }; // class pass_ipa_tree_profile
646 bool
647 pass_ipa_tree_profile::gate (function *)
649 /* When profile instrumentation, use or test coverage shall be performed.
650 But for AutoFDO, this there is no instrumentation, thus this pass is
651 diabled. */
652 return (!in_lto_p && !flag_auto_profile
653 && (flag_branch_probabilities || flag_test_coverage
654 || profile_arc_flag));
657 } // anon namespace
659 simple_ipa_opt_pass *
660 make_pass_ipa_tree_profile (gcc::context *ctxt)
662 return new pass_ipa_tree_profile (ctxt);
665 #include "gt-tree-profile.h"