jit: document union types
[official-gcc.git] / gcc / tree-profile.c
blobbcb5cb9953f3bed31c7a390d6d1655ea4287bbac
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 "tm.h"
31 #include "flags.h"
32 #include "hard-reg-set.h"
33 #include "function.h"
34 #include "predict.h"
35 #include "dominance.h"
36 #include "cfg.h"
37 #include "basic-block.h"
38 #include "diagnostic-core.h"
39 #include "coverage.h"
40 #include "alias.h"
41 #include "symtab.h"
42 #include "tree.h"
43 #include "fold-const.h"
44 #include "tree-ssa-alias.h"
45 #include "internal-fn.h"
46 #include "gimple-expr.h"
47 #include "gimple.h"
48 #include "varasm.h"
49 #include "tree-nested.h"
50 #include "gimplify.h"
51 #include "gimple-iterator.h"
52 #include "gimplify-me.h"
53 #include "gimple-ssa.h"
54 #include "cgraph.h"
55 #include "tree-cfg.h"
56 #include "stringpool.h"
57 #include "tree-ssanames.h"
58 #include "tree-into-ssa.h"
59 #include "tree-pass.h"
60 #include "value-prof.h"
61 #include "profile.h"
62 #include "target.h"
63 #include "tree-cfgcleanup.h"
64 #include "tree-nested.h"
65 #include "params.h"
67 static GTY(()) tree gcov_type_node;
68 static GTY(()) tree tree_interval_profiler_fn;
69 static GTY(()) tree tree_pow2_profiler_fn;
70 static GTY(()) tree tree_one_value_profiler_fn;
71 static GTY(()) tree tree_indirect_call_profiler_fn;
72 static GTY(()) tree tree_time_profiler_fn;
73 static GTY(()) tree tree_average_profiler_fn;
74 static GTY(()) tree tree_ior_profiler_fn;
77 static GTY(()) tree ic_void_ptr_var;
78 static GTY(()) tree ic_gcov_type_ptr_var;
79 static GTY(()) tree ptr_void;
81 /* Do initialization work for the edge profiler. */
83 /* Add code:
84 __thread gcov* __gcov_indirect_call_counters; // pointer to actual counter
85 __thread void* __gcov_indirect_call_callee; // actual callee address
86 __thread int __gcov_function_counter; // time profiler function counter
88 static void
89 init_ic_make_global_vars (void)
91 tree gcov_type_ptr;
93 ptr_void = build_pointer_type (void_type_node);
95 ic_void_ptr_var
96 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
97 get_identifier (
98 (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
99 "__gcov_indirect_call_topn_callee" :
100 "__gcov_indirect_call_callee")),
101 ptr_void);
102 TREE_PUBLIC (ic_void_ptr_var) = 1;
103 DECL_EXTERNAL (ic_void_ptr_var) = 1;
104 TREE_STATIC (ic_void_ptr_var) = 1;
105 DECL_ARTIFICIAL (ic_void_ptr_var) = 1;
106 DECL_INITIAL (ic_void_ptr_var) = NULL;
107 if (targetm.have_tls)
108 set_decl_tls_model (ic_void_ptr_var, decl_default_tls_model (ic_void_ptr_var));
110 varpool_node::finalize_decl (ic_void_ptr_var);
112 gcov_type_ptr = build_pointer_type (get_gcov_type ());
114 ic_gcov_type_ptr_var
115 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
116 get_identifier (
117 (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
118 "__gcov_indirect_call_topn_counters" :
119 "__gcov_indirect_call_counters")),
120 gcov_type_ptr);
121 TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
122 DECL_EXTERNAL (ic_gcov_type_ptr_var) = 1;
123 TREE_STATIC (ic_gcov_type_ptr_var) = 1;
124 DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1;
125 DECL_INITIAL (ic_gcov_type_ptr_var) = NULL;
126 if (targetm.have_tls)
127 set_decl_tls_model (ic_gcov_type_ptr_var, decl_default_tls_model (ic_gcov_type_ptr_var));
129 varpool_node::finalize_decl (ic_gcov_type_ptr_var);
132 /* Create the type and function decls for the interface with gcov. */
134 void
135 gimple_init_edge_profiler (void)
137 tree interval_profiler_fn_type;
138 tree pow2_profiler_fn_type;
139 tree one_value_profiler_fn_type;
140 tree gcov_type_ptr;
141 tree ic_profiler_fn_type;
142 tree average_profiler_fn_type;
143 tree time_profiler_fn_type;
145 if (!gcov_type_node)
147 gcov_type_node = get_gcov_type ();
148 gcov_type_ptr = build_pointer_type (gcov_type_node);
150 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
151 interval_profiler_fn_type
152 = build_function_type_list (void_type_node,
153 gcov_type_ptr, gcov_type_node,
154 integer_type_node,
155 unsigned_type_node, NULL_TREE);
156 tree_interval_profiler_fn
157 = build_fn_decl ("__gcov_interval_profiler",
158 interval_profiler_fn_type);
159 TREE_NOTHROW (tree_interval_profiler_fn) = 1;
160 DECL_ATTRIBUTES (tree_interval_profiler_fn)
161 = tree_cons (get_identifier ("leaf"), NULL,
162 DECL_ATTRIBUTES (tree_interval_profiler_fn));
164 /* void (*) (gcov_type *, gcov_type) */
165 pow2_profiler_fn_type
166 = build_function_type_list (void_type_node,
167 gcov_type_ptr, gcov_type_node,
168 NULL_TREE);
169 tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler",
170 pow2_profiler_fn_type);
171 TREE_NOTHROW (tree_pow2_profiler_fn) = 1;
172 DECL_ATTRIBUTES (tree_pow2_profiler_fn)
173 = tree_cons (get_identifier ("leaf"), NULL,
174 DECL_ATTRIBUTES (tree_pow2_profiler_fn));
176 /* void (*) (gcov_type *, gcov_type) */
177 one_value_profiler_fn_type
178 = build_function_type_list (void_type_node,
179 gcov_type_ptr, gcov_type_node,
180 NULL_TREE);
181 tree_one_value_profiler_fn
182 = build_fn_decl ("__gcov_one_value_profiler",
183 one_value_profiler_fn_type);
184 TREE_NOTHROW (tree_one_value_profiler_fn) = 1;
185 DECL_ATTRIBUTES (tree_one_value_profiler_fn)
186 = tree_cons (get_identifier ("leaf"), NULL,
187 DECL_ATTRIBUTES (tree_one_value_profiler_fn));
189 init_ic_make_global_vars ();
191 /* void (*) (gcov_type, void *) */
192 ic_profiler_fn_type
193 = build_function_type_list (void_type_node,
194 gcov_type_node,
195 ptr_void,
196 NULL_TREE);
197 tree_indirect_call_profiler_fn
198 = build_fn_decl ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
199 "__gcov_indirect_call_topn_profiler":
200 "__gcov_indirect_call_profiler_v2"),
201 ic_profiler_fn_type);
203 TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
204 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
205 = tree_cons (get_identifier ("leaf"), NULL,
206 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn));
208 /* void (*) (gcov_type *, gcov_type, void *) */
209 time_profiler_fn_type
210 = build_function_type_list (void_type_node,
211 gcov_type_ptr, NULL_TREE);
212 tree_time_profiler_fn
213 = build_fn_decl ("__gcov_time_profiler",
214 time_profiler_fn_type);
215 TREE_NOTHROW (tree_time_profiler_fn) = 1;
216 DECL_ATTRIBUTES (tree_time_profiler_fn)
217 = tree_cons (get_identifier ("leaf"), NULL,
218 DECL_ATTRIBUTES (tree_time_profiler_fn));
220 /* void (*) (gcov_type *, gcov_type) */
221 average_profiler_fn_type
222 = build_function_type_list (void_type_node,
223 gcov_type_ptr, gcov_type_node, NULL_TREE);
224 tree_average_profiler_fn
225 = build_fn_decl ("__gcov_average_profiler",
226 average_profiler_fn_type);
227 TREE_NOTHROW (tree_average_profiler_fn) = 1;
228 DECL_ATTRIBUTES (tree_average_profiler_fn)
229 = tree_cons (get_identifier ("leaf"), NULL,
230 DECL_ATTRIBUTES (tree_average_profiler_fn));
231 tree_ior_profiler_fn
232 = build_fn_decl ("__gcov_ior_profiler",
233 average_profiler_fn_type);
234 TREE_NOTHROW (tree_ior_profiler_fn) = 1;
235 DECL_ATTRIBUTES (tree_ior_profiler_fn)
236 = tree_cons (get_identifier ("leaf"), NULL,
237 DECL_ATTRIBUTES (tree_ior_profiler_fn));
239 /* LTO streamer needs assembler names. Because we create these decls
240 late, we need to initialize them by hand. */
241 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn);
242 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn);
243 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn);
244 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn);
245 DECL_ASSEMBLER_NAME (tree_time_profiler_fn);
246 DECL_ASSEMBLER_NAME (tree_average_profiler_fn);
247 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
251 /* Output instructions as GIMPLE trees to increment the edge
252 execution count, and insert them on E. We rely on
253 gsi_insert_on_edge to preserve the order. */
255 void
256 gimple_gen_edge_profiler (int edgeno, edge e)
258 tree ref, one, gcov_type_tmp_var;
259 gassign *stmt1, *stmt2, *stmt3;
261 ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
262 one = build_int_cst (gcov_type_node, 1);
263 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
264 NULL, "PROF_edge_counter");
265 stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
266 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
267 NULL, "PROF_edge_counter");
268 stmt2 = gimple_build_assign (gcov_type_tmp_var, PLUS_EXPR,
269 gimple_assign_lhs (stmt1), one);
270 stmt3 = gimple_build_assign (unshare_expr (ref), gimple_assign_lhs (stmt2));
271 gsi_insert_on_edge (e, stmt1);
272 gsi_insert_on_edge (e, stmt2);
273 gsi_insert_on_edge (e, stmt3);
276 /* Emits code to get VALUE to instrument at GSI, and returns the
277 variable containing the value. */
279 static tree
280 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
282 tree val = value->hvalue.value;
283 if (POINTER_TYPE_P (TREE_TYPE (val)))
284 val = fold_convert (build_nonstandard_integer_type
285 (TYPE_PRECISION (TREE_TYPE (val)), 1), val);
286 return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
287 true, NULL_TREE, true, GSI_SAME_STMT);
290 /* Output instructions as GIMPLE trees to increment the interval histogram
291 counter. VALUE is the expression whose value is profiled. TAG is the
292 tag of the section for counters, BASE is offset of the counter position. */
294 void
295 gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
297 gimple stmt = value->hvalue.stmt;
298 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
299 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
300 gcall *call;
301 tree val;
302 tree start = build_int_cst_type (integer_type_node,
303 value->hdata.intvl.int_start);
304 tree steps = build_int_cst_type (unsigned_type_node,
305 value->hdata.intvl.steps);
307 ref_ptr = force_gimple_operand_gsi (&gsi,
308 build_addr (ref, current_function_decl),
309 true, NULL_TREE, true, GSI_SAME_STMT);
310 val = prepare_instrumented_value (&gsi, value);
311 call = gimple_build_call (tree_interval_profiler_fn, 4,
312 ref_ptr, val, start, steps);
313 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
316 /* Output instructions as GIMPLE trees to increment the power of two histogram
317 counter. VALUE is the expression whose value is profiled. TAG is the tag
318 of the section for counters, BASE is offset of the counter position. */
320 void
321 gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
323 gimple stmt = value->hvalue.stmt;
324 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
325 tree ref_ptr = tree_coverage_counter_addr (tag, base);
326 gcall *call;
327 tree val;
329 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
330 true, NULL_TREE, true, GSI_SAME_STMT);
331 val = prepare_instrumented_value (&gsi, value);
332 call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val);
333 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
336 /* Output instructions as GIMPLE trees for code to find the most common value.
337 VALUE is the expression whose value is profiled. TAG is the tag of the
338 section for counters, BASE is offset of the counter position. */
340 void
341 gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
343 gimple stmt = value->hvalue.stmt;
344 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
345 tree ref_ptr = tree_coverage_counter_addr (tag, base);
346 gcall *call;
347 tree val;
349 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
350 true, NULL_TREE, true, GSI_SAME_STMT);
351 val = prepare_instrumented_value (&gsi, value);
352 call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val);
353 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
357 /* Output instructions as GIMPLE trees for code to find the most
358 common called function in indirect call.
359 VALUE is the call expression whose indirect callee is profiled.
360 TAG is the tag of the section for counters, BASE is offset of the
361 counter position. */
363 void
364 gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
366 tree tmp1;
367 gassign *stmt1, *stmt2, *stmt3;
368 gimple stmt = value->hvalue.stmt;
369 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
370 tree ref_ptr = tree_coverage_counter_addr (tag, base);
372 if ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) &&
373 tag == GCOV_COUNTER_V_INDIR) ||
374 (!PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) &&
375 tag == GCOV_COUNTER_ICALL_TOPNV))
376 return;
378 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
379 true, NULL_TREE, true, GSI_SAME_STMT);
381 /* Insert code:
383 stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
384 stmt2: tmp1 = (void *) (indirect call argument value)
385 stmt3: __gcov_indirect_call_callee = tmp1;
388 stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr);
389 tmp1 = make_temp_ssa_name (ptr_void, NULL, "PROF");
390 stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
391 stmt3 = gimple_build_assign (ic_void_ptr_var, gimple_assign_lhs (stmt2));
393 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
394 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
395 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
399 /* Output instructions as GIMPLE trees for code to find the most
400 common called function in indirect call. Insert instructions at the
401 beginning of every possible called function.
404 void
405 gimple_gen_ic_func_profiler (void)
407 struct cgraph_node * c_node = cgraph_node::get (current_function_decl);
408 gimple_stmt_iterator gsi;
409 gcall *stmt1;
410 gassign *stmt2;
411 tree tree_uid, cur_func, void0;
413 if (c_node->only_called_directly_p ())
414 return;
416 gimple_init_edge_profiler ();
418 /* Insert code:
420 stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
421 &current_function_decl)
423 gsi = gsi_after_labels (split_edge (single_succ_edge
424 (ENTRY_BLOCK_PTR_FOR_FN (cfun))));
426 cur_func = force_gimple_operand_gsi (&gsi,
427 build_addr (current_function_decl,
428 current_function_decl),
429 true, NULL_TREE,
430 true, GSI_SAME_STMT);
431 tree_uid = build_int_cst
432 (gcov_type_node,
433 cgraph_node::get (current_function_decl)->profile_id);
434 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2,
435 tree_uid, cur_func);
436 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
438 /* Set __gcov_indirect_call_callee to 0,
439 so that calls from other modules won't get misattributed
440 to the last caller of the current callee. */
441 void0 = build_int_cst (build_pointer_type (void_type_node), 0);
442 stmt2 = gimple_build_assign (ic_void_ptr_var, void0);
443 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
446 /* Output instructions as GIMPLE tree at the beginning for each function.
447 TAG is the tag of the section for counters, BASE is offset of the
448 counter position and GSI is the iterator we place the counter. */
450 void
451 gimple_gen_time_profiler (unsigned tag, unsigned base,
452 gimple_stmt_iterator &gsi)
454 tree ref_ptr = tree_coverage_counter_addr (tag, base);
455 gcall *call;
457 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
458 true, NULL_TREE, true, GSI_SAME_STMT);
459 call = gimple_build_call (tree_time_profiler_fn, 1, ref_ptr);
460 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
463 /* Output instructions as GIMPLE trees for code to find the most common value
464 of a difference between two evaluations of an expression.
465 VALUE is the expression whose value is profiled. TAG is the tag of the
466 section for counters, BASE is offset of the counter position. */
468 void
469 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
470 unsigned tag ATTRIBUTE_UNUSED,
471 unsigned base ATTRIBUTE_UNUSED)
473 /* FIXME implement this. */
474 #ifdef ENABLE_CHECKING
475 internal_error ("unimplemented functionality");
476 #endif
477 gcc_unreachable ();
480 /* Output instructions as GIMPLE trees to increment the average histogram
481 counter. VALUE is the expression whose value is profiled. TAG is the
482 tag of the section for counters, BASE is offset of the counter position. */
484 void
485 gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
487 gimple stmt = value->hvalue.stmt;
488 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
489 tree ref_ptr = tree_coverage_counter_addr (tag, base);
490 gcall *call;
491 tree val;
493 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
494 true, NULL_TREE,
495 true, GSI_SAME_STMT);
496 val = prepare_instrumented_value (&gsi, value);
497 call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
498 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
501 /* Output instructions as GIMPLE trees to increment the ior histogram
502 counter. VALUE is the expression whose value is profiled. TAG is the
503 tag of the section for counters, BASE is offset of the counter position. */
505 void
506 gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
508 gimple stmt = value->hvalue.stmt;
509 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
510 tree ref_ptr = tree_coverage_counter_addr (tag, base);
511 gcall *call;
512 tree val;
514 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
515 true, NULL_TREE, true, GSI_SAME_STMT);
516 val = prepare_instrumented_value (&gsi, value);
517 call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
518 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
521 /* Profile all functions in the callgraph. */
523 static unsigned int
524 tree_profiling (void)
526 struct cgraph_node *node;
528 /* This is a small-ipa pass that gets called only once, from
529 cgraphunit.c:ipa_passes(). */
530 gcc_assert (symtab->state == IPA_SSA);
532 init_node_map (true);
534 FOR_EACH_DEFINED_FUNCTION (node)
536 if (!gimple_has_body_p (node->decl))
537 continue;
539 /* Don't profile functions produced for builtin stuff. */
540 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
541 continue;
543 /* Do not instrument extern inline functions when testing coverage.
544 While this is not perfectly consistent (early inlined extern inlines
545 will get acocunted), testsuite expects that. */
546 if (DECL_EXTERNAL (node->decl)
547 && flag_test_coverage)
548 continue;
550 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
552 /* Local pure-const may imply need to fixup the cfg. */
553 if (execute_fixup_cfg () & TODO_cleanup_cfg)
554 cleanup_tree_cfg ();
556 branch_prob ();
558 if (! flag_branch_probabilities
559 && flag_profile_values)
560 gimple_gen_ic_func_profiler ();
562 if (flag_branch_probabilities
563 && flag_profile_values
564 && flag_value_profile_transformations)
565 gimple_value_profile_transformations ();
567 /* The above could hose dominator info. Currently there is
568 none coming in, this is a safety valve. It should be
569 easy to adjust it, if and when there is some. */
570 free_dominance_info (CDI_DOMINATORS);
571 free_dominance_info (CDI_POST_DOMINATORS);
572 pop_cfun ();
575 /* Drop pure/const flags from instrumented functions. */
576 FOR_EACH_DEFINED_FUNCTION (node)
578 if (!gimple_has_body_p (node->decl)
579 || !(!node->clone_of
580 || node->decl != node->clone_of->decl))
581 continue;
583 /* Don't profile functions produced for builtin stuff. */
584 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
585 continue;
587 node->set_const_flag (false, false);
588 node->set_pure_flag (false, false);
591 /* Update call statements and rebuild the cgraph. */
592 FOR_EACH_DEFINED_FUNCTION (node)
594 basic_block bb;
596 if (!gimple_has_body_p (node->decl)
597 || !(!node->clone_of
598 || node->decl != node->clone_of->decl))
599 continue;
601 /* Don't profile functions produced for builtin stuff. */
602 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
603 continue;
605 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
607 FOR_EACH_BB_FN (bb, cfun)
609 gimple_stmt_iterator gsi;
610 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
612 gimple stmt = gsi_stmt (gsi);
613 if (is_gimple_call (stmt))
614 update_stmt (stmt);
618 /* re-merge split blocks. */
619 cleanup_tree_cfg ();
620 update_ssa (TODO_update_ssa);
622 cgraph_edge::rebuild_edges ();
624 pop_cfun ();
627 handle_missing_profiles ();
629 del_node_map ();
630 return 0;
633 namespace {
635 const pass_data pass_data_ipa_tree_profile =
637 SIMPLE_IPA_PASS, /* type */
638 "profile", /* name */
639 OPTGROUP_NONE, /* optinfo_flags */
640 TV_IPA_PROFILE, /* tv_id */
641 0, /* properties_required */
642 0, /* properties_provided */
643 0, /* properties_destroyed */
644 0, /* todo_flags_start */
645 0, /* todo_flags_finish */
648 class pass_ipa_tree_profile : public simple_ipa_opt_pass
650 public:
651 pass_ipa_tree_profile (gcc::context *ctxt)
652 : simple_ipa_opt_pass (pass_data_ipa_tree_profile, ctxt)
655 /* opt_pass methods: */
656 virtual bool gate (function *);
657 virtual unsigned int execute (function *) { return tree_profiling (); }
659 }; // class pass_ipa_tree_profile
661 bool
662 pass_ipa_tree_profile::gate (function *)
664 /* When profile instrumentation, use or test coverage shall be performed.
665 But for AutoFDO, this there is no instrumentation, thus this pass is
666 diabled. */
667 return (!in_lto_p && !flag_auto_profile
668 && (flag_branch_probabilities || flag_test_coverage
669 || profile_arc_flag));
672 } // anon namespace
674 simple_ipa_opt_pass *
675 make_pass_ipa_tree_profile (gcc::context *ctxt)
677 return new pass_ipa_tree_profile (ctxt);
680 #include "gt-tree-profile.h"