* df-scan.c (df_collection_rec): Adjust.
[official-gcc.git] / gcc / tree-profile.c
blob8a3039725ecda0594822dbf3a9d7ca7c53c1742b
1 /* Calculate branch probabilities, and basic block execution counts.
2 Copyright (C) 1990-2013 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 "function.h"
33 #include "basic-block.h"
34 #include "diagnostic-core.h"
35 #include "coverage.h"
36 #include "tree.h"
37 #include "gimple.h"
38 #include "gimple-ssa.h"
39 #include "cgraph.h"
40 #include "tree-cfg.h"
41 #include "tree-ssanames.h"
42 #include "tree-into-ssa.h"
43 #include "tree-pass.h"
44 #include "value-prof.h"
45 #include "profile.h"
46 #include "target.h"
47 #include "tree-cfgcleanup.h"
49 static GTY(()) tree gcov_type_node;
50 static GTY(()) tree tree_interval_profiler_fn;
51 static GTY(()) tree tree_pow2_profiler_fn;
52 static GTY(()) tree tree_one_value_profiler_fn;
53 static GTY(()) tree tree_indirect_call_profiler_fn;
54 static GTY(()) tree tree_average_profiler_fn;
55 static GTY(()) tree tree_ior_profiler_fn;
58 static GTY(()) tree ic_void_ptr_var;
59 static GTY(()) tree ic_gcov_type_ptr_var;
60 static GTY(()) tree ptr_void;
62 /* Do initialization work for the edge profiler. */
64 /* Add code:
65 __thread gcov* __gcov_indirect_call_counters; // pointer to actual counter
66 __thread void* __gcov_indirect_call_callee; // actual callee address
68 static void
69 init_ic_make_global_vars (void)
71 tree gcov_type_ptr;
73 ptr_void = build_pointer_type (void_type_node);
75 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
76 if (flag_lto)
78 ic_void_ptr_var
79 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
80 get_identifier ("__gcov_indirect_call_callee_ltopriv"),
81 ptr_void);
82 TREE_PUBLIC (ic_void_ptr_var) = 1;
83 DECL_COMMON (ic_void_ptr_var) = 1;
84 DECL_VISIBILITY (ic_void_ptr_var) = VISIBILITY_HIDDEN;
85 DECL_VISIBILITY_SPECIFIED (ic_void_ptr_var) = true;
87 else
89 ic_void_ptr_var
90 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
91 get_identifier ("__gcov_indirect_call_callee"),
92 ptr_void);
93 TREE_PUBLIC (ic_void_ptr_var) = 1;
94 DECL_EXTERNAL (ic_void_ptr_var) = 1;
96 TREE_STATIC (ic_void_ptr_var) = 1;
97 DECL_ARTIFICIAL (ic_void_ptr_var) = 1;
98 DECL_INITIAL (ic_void_ptr_var) = NULL;
99 if (targetm.have_tls)
100 DECL_TLS_MODEL (ic_void_ptr_var) =
101 decl_default_tls_model (ic_void_ptr_var);
103 varpool_finalize_decl (ic_void_ptr_var);
105 gcov_type_ptr = build_pointer_type (get_gcov_type ());
106 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
107 if (flag_lto)
109 ic_gcov_type_ptr_var
110 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
111 get_identifier ("__gcov_indirect_call_counters_ltopriv"),
112 gcov_type_ptr);
113 TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
114 DECL_COMMON (ic_gcov_type_ptr_var) = 1;
115 DECL_VISIBILITY (ic_gcov_type_ptr_var) = VISIBILITY_HIDDEN;
116 DECL_VISIBILITY_SPECIFIED (ic_gcov_type_ptr_var) = true;
118 else
120 ic_gcov_type_ptr_var
121 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
122 get_identifier ("__gcov_indirect_call_counters"),
123 gcov_type_ptr);
124 TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
125 DECL_EXTERNAL (ic_gcov_type_ptr_var) = 1;
127 TREE_STATIC (ic_gcov_type_ptr_var) = 1;
128 DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1;
129 DECL_INITIAL (ic_gcov_type_ptr_var) = NULL;
130 if (targetm.have_tls)
131 DECL_TLS_MODEL (ic_gcov_type_ptr_var) =
132 decl_default_tls_model (ic_gcov_type_ptr_var);
134 varpool_finalize_decl (ic_gcov_type_ptr_var);
137 /* Create the type and function decls for the interface with gcov. */
139 void
140 gimple_init_edge_profiler (void)
142 tree interval_profiler_fn_type;
143 tree pow2_profiler_fn_type;
144 tree one_value_profiler_fn_type;
145 tree gcov_type_ptr;
146 tree ic_profiler_fn_type;
147 tree average_profiler_fn_type;
149 if (!gcov_type_node)
151 gcov_type_node = get_gcov_type ();
152 gcov_type_ptr = build_pointer_type (gcov_type_node);
154 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
155 interval_profiler_fn_type
156 = build_function_type_list (void_type_node,
157 gcov_type_ptr, gcov_type_node,
158 integer_type_node,
159 unsigned_type_node, NULL_TREE);
160 tree_interval_profiler_fn
161 = build_fn_decl ("__gcov_interval_profiler",
162 interval_profiler_fn_type);
163 TREE_NOTHROW (tree_interval_profiler_fn) = 1;
164 DECL_ATTRIBUTES (tree_interval_profiler_fn)
165 = tree_cons (get_identifier ("leaf"), NULL,
166 DECL_ATTRIBUTES (tree_interval_profiler_fn));
168 /* void (*) (gcov_type *, gcov_type) */
169 pow2_profiler_fn_type
170 = build_function_type_list (void_type_node,
171 gcov_type_ptr, gcov_type_node,
172 NULL_TREE);
173 tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler",
174 pow2_profiler_fn_type);
175 TREE_NOTHROW (tree_pow2_profiler_fn) = 1;
176 DECL_ATTRIBUTES (tree_pow2_profiler_fn)
177 = tree_cons (get_identifier ("leaf"), NULL,
178 DECL_ATTRIBUTES (tree_pow2_profiler_fn));
180 /* void (*) (gcov_type *, gcov_type) */
181 one_value_profiler_fn_type
182 = build_function_type_list (void_type_node,
183 gcov_type_ptr, gcov_type_node,
184 NULL_TREE);
185 tree_one_value_profiler_fn
186 = build_fn_decl ("__gcov_one_value_profiler",
187 one_value_profiler_fn_type);
188 TREE_NOTHROW (tree_one_value_profiler_fn) = 1;
189 DECL_ATTRIBUTES (tree_one_value_profiler_fn)
190 = tree_cons (get_identifier ("leaf"), NULL,
191 DECL_ATTRIBUTES (tree_one_value_profiler_fn));
193 init_ic_make_global_vars ();
195 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
196 if (flag_lto)
198 /* void (*) (gcov_type, void *) */
199 ic_profiler_fn_type
200 = build_function_type_list (void_type_node,
201 gcov_type_ptr, gcov_type_node,
202 ptr_void, ptr_void,
203 NULL_TREE);
204 tree_indirect_call_profiler_fn
205 = build_fn_decl ("__gcov_indirect_call_profiler",
206 ic_profiler_fn_type);
208 else
210 /* void (*) (gcov_type, void *) */
211 ic_profiler_fn_type
212 = build_function_type_list (void_type_node,
213 gcov_type_node,
214 ptr_void,
215 NULL_TREE);
216 tree_indirect_call_profiler_fn
217 = build_fn_decl ("__gcov_indirect_call_profiler_v2",
218 ic_profiler_fn_type);
220 TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
221 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
222 = tree_cons (get_identifier ("leaf"), NULL,
223 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn));
225 /* void (*) (gcov_type *, gcov_type) */
226 average_profiler_fn_type
227 = build_function_type_list (void_type_node,
228 gcov_type_ptr, gcov_type_node, NULL_TREE);
229 tree_average_profiler_fn
230 = build_fn_decl ("__gcov_average_profiler",
231 average_profiler_fn_type);
232 TREE_NOTHROW (tree_average_profiler_fn) = 1;
233 DECL_ATTRIBUTES (tree_average_profiler_fn)
234 = tree_cons (get_identifier ("leaf"), NULL,
235 DECL_ATTRIBUTES (tree_average_profiler_fn));
236 tree_ior_profiler_fn
237 = build_fn_decl ("__gcov_ior_profiler",
238 average_profiler_fn_type);
239 TREE_NOTHROW (tree_ior_profiler_fn) = 1;
240 DECL_ATTRIBUTES (tree_ior_profiler_fn)
241 = tree_cons (get_identifier ("leaf"), NULL,
242 DECL_ATTRIBUTES (tree_ior_profiler_fn));
244 /* LTO streamer needs assembler names. Because we create these decls
245 late, we need to initialize them by hand. */
246 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn);
247 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn);
248 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn);
249 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn);
250 DECL_ASSEMBLER_NAME (tree_average_profiler_fn);
251 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
255 /* Output instructions as GIMPLE trees to increment the edge
256 execution count, and insert them on E. We rely on
257 gsi_insert_on_edge to preserve the order. */
259 void
260 gimple_gen_edge_profiler (int edgeno, edge e)
262 tree ref, one, gcov_type_tmp_var;
263 gimple stmt1, stmt2, stmt3;
265 ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
266 one = build_int_cst (gcov_type_node, 1);
267 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
268 NULL, "PROF_edge_counter");
269 stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
270 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
271 NULL, "PROF_edge_counter");
272 stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, gcov_type_tmp_var,
273 gimple_assign_lhs (stmt1), one);
274 stmt3 = gimple_build_assign (unshare_expr (ref), gimple_assign_lhs (stmt2));
275 gsi_insert_on_edge (e, stmt1);
276 gsi_insert_on_edge (e, stmt2);
277 gsi_insert_on_edge (e, stmt3);
280 /* Emits code to get VALUE to instrument at GSI, and returns the
281 variable containing the value. */
283 static tree
284 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
286 tree val = value->hvalue.value;
287 if (POINTER_TYPE_P (TREE_TYPE (val)))
288 val = fold_convert (build_nonstandard_integer_type
289 (TYPE_PRECISION (TREE_TYPE (val)), 1), val);
290 return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
291 true, NULL_TREE, true, GSI_SAME_STMT);
294 /* Output instructions as GIMPLE trees to increment the interval histogram
295 counter. VALUE is the expression whose value is profiled. TAG is the
296 tag of the section for counters, BASE is offset of the counter position. */
298 void
299 gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
301 gimple stmt = value->hvalue.stmt;
302 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
303 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
304 gimple call;
305 tree val;
306 tree start = build_int_cst_type (integer_type_node,
307 value->hdata.intvl.int_start);
308 tree steps = build_int_cst_type (unsigned_type_node,
309 value->hdata.intvl.steps);
311 ref_ptr = force_gimple_operand_gsi (&gsi,
312 build_addr (ref, current_function_decl),
313 true, NULL_TREE, true, GSI_SAME_STMT);
314 val = prepare_instrumented_value (&gsi, value);
315 call = gimple_build_call (tree_interval_profiler_fn, 4,
316 ref_ptr, val, start, steps);
317 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
320 /* Output instructions as GIMPLE trees to increment the power of two histogram
321 counter. VALUE is the expression whose value is profiled. TAG is the tag
322 of the section for counters, BASE is offset of the counter position. */
324 void
325 gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
327 gimple stmt = value->hvalue.stmt;
328 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
329 tree ref_ptr = tree_coverage_counter_addr (tag, base);
330 gimple call;
331 tree val;
333 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
334 true, NULL_TREE, true, GSI_SAME_STMT);
335 val = prepare_instrumented_value (&gsi, value);
336 call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val);
337 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
340 /* Output instructions as GIMPLE trees for code to find the most common value.
341 VALUE is the expression whose value is profiled. TAG is the tag of the
342 section for counters, BASE is offset of the counter position. */
344 void
345 gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
347 gimple stmt = value->hvalue.stmt;
348 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
349 tree ref_ptr = tree_coverage_counter_addr (tag, base);
350 gimple call;
351 tree val;
353 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
354 true, NULL_TREE, true, GSI_SAME_STMT);
355 val = prepare_instrumented_value (&gsi, value);
356 call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val);
357 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
361 /* Output instructions as GIMPLE trees for code to find the most
362 common called function in indirect call.
363 VALUE is the call expression whose indirect callee is profiled.
364 TAG is the tag of the section for counters, BASE is offset of the
365 counter position. */
367 void
368 gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
370 tree tmp1;
371 gimple stmt1, stmt2, stmt3;
372 gimple stmt = value->hvalue.stmt;
373 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
374 tree ref_ptr = tree_coverage_counter_addr (tag, base);
376 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
377 true, NULL_TREE, true, GSI_SAME_STMT);
379 /* Insert code:
381 stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
382 stmt2: tmp1 = (void *) (indirect call argument value)
383 stmt3: __gcov_indirect_call_callee = tmp1;
386 stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr);
387 tmp1 = make_temp_ssa_name (ptr_void, NULL, "PROF");
388 stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
389 stmt3 = gimple_build_assign (ic_void_ptr_var, gimple_assign_lhs (stmt2));
391 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
392 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
393 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
397 /* Output instructions as GIMPLE trees for code to find the most
398 common called function in indirect call. Insert instructions at the
399 beginning of every possible called function.
402 void
403 gimple_gen_ic_func_profiler (void)
405 struct cgraph_node * c_node = cgraph_get_node (current_function_decl);
406 gimple_stmt_iterator gsi;
407 gimple stmt1, stmt2;
408 tree tree_uid, cur_func, void0;
410 if (cgraph_only_called_directly_p (c_node))
411 return;
413 gimple_init_edge_profiler ();
415 /* Insert code:
417 stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
418 &current_function_decl)
420 gsi = gsi_after_labels (split_edge (single_succ_edge (ENTRY_BLOCK_PTR)));
422 cur_func = force_gimple_operand_gsi (&gsi,
423 build_addr (current_function_decl,
424 current_function_decl),
425 true, NULL_TREE,
426 true, GSI_SAME_STMT);
427 tree_uid = build_int_cst
428 (gcov_type_node, cgraph_get_node (current_function_decl)->profile_id);
429 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
430 if (flag_lto)
432 tree counter_ptr, ptr_var;
433 counter_ptr = force_gimple_operand_gsi (&gsi, ic_gcov_type_ptr_var,
434 true, NULL_TREE, true,
435 GSI_SAME_STMT);
436 ptr_var = force_gimple_operand_gsi (&gsi, ic_void_ptr_var,
437 true, NULL_TREE, true,
438 GSI_SAME_STMT);
440 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 4,
441 counter_ptr, tree_uid, cur_func, ptr_var);
443 else
445 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2,
446 tree_uid, cur_func);
448 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
450 /* Set __gcov_indirect_call_callee to 0,
451 so that calls from other modules won't get misattributed
452 to the last caller of the current callee. */
453 void0 = build_int_cst (build_pointer_type (void_type_node), 0);
454 stmt2 = gimple_build_assign (ic_void_ptr_var, void0);
455 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
458 /* Output instructions as GIMPLE trees for code to find the most common value
459 of a difference between two evaluations of an expression.
460 VALUE is the expression whose value is profiled. TAG is the tag of the
461 section for counters, BASE is offset of the counter position. */
463 void
464 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
465 unsigned tag ATTRIBUTE_UNUSED,
466 unsigned base ATTRIBUTE_UNUSED)
468 /* FIXME implement this. */
469 #ifdef ENABLE_CHECKING
470 internal_error ("unimplemented functionality");
471 #endif
472 gcc_unreachable ();
475 /* Output instructions as GIMPLE trees to increment the average histogram
476 counter. VALUE is the expression whose value is profiled. TAG is the
477 tag of the section for counters, BASE is offset of the counter position. */
479 void
480 gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
482 gimple stmt = value->hvalue.stmt;
483 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
484 tree ref_ptr = tree_coverage_counter_addr (tag, base);
485 gimple call;
486 tree val;
488 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
489 true, NULL_TREE,
490 true, GSI_SAME_STMT);
491 val = prepare_instrumented_value (&gsi, value);
492 call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
493 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
496 /* Output instructions as GIMPLE trees to increment the ior histogram
497 counter. VALUE is the expression whose value is profiled. TAG is the
498 tag of the section for counters, BASE is offset of the counter position. */
500 void
501 gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
503 gimple stmt = value->hvalue.stmt;
504 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
505 tree ref_ptr = tree_coverage_counter_addr (tag, base);
506 gimple call;
507 tree val;
509 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
510 true, NULL_TREE, true, GSI_SAME_STMT);
511 val = prepare_instrumented_value (&gsi, value);
512 call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
513 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
516 /* Profile all functions in the callgraph. */
518 static unsigned int
519 tree_profiling (void)
521 struct cgraph_node *node;
523 /* This is a small-ipa pass that gets called only once, from
524 cgraphunit.c:ipa_passes(). */
525 gcc_assert (cgraph_state == CGRAPH_STATE_IPA_SSA);
527 init_node_map (true);
529 FOR_EACH_DEFINED_FUNCTION (node)
531 if (!gimple_has_body_p (node->symbol.decl))
532 continue;
534 /* Don't profile functions produced for builtin stuff. */
535 if (DECL_SOURCE_LOCATION (node->symbol.decl) == BUILTINS_LOCATION)
536 continue;
538 push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl));
540 /* Local pure-const may imply need to fixup the cfg. */
541 if (execute_fixup_cfg () & TODO_cleanup_cfg)
542 cleanup_tree_cfg ();
544 branch_prob ();
546 if (! flag_branch_probabilities
547 && flag_profile_values)
548 gimple_gen_ic_func_profiler ();
550 if (flag_branch_probabilities
551 && flag_profile_values
552 && flag_value_profile_transformations)
553 gimple_value_profile_transformations ();
555 /* The above could hose dominator info. Currently there is
556 none coming in, this is a safety valve. It should be
557 easy to adjust it, if and when there is some. */
558 free_dominance_info (CDI_DOMINATORS);
559 free_dominance_info (CDI_POST_DOMINATORS);
560 pop_cfun ();
563 /* Drop pure/const flags from instrumented functions. */
564 FOR_EACH_DEFINED_FUNCTION (node)
566 if (!gimple_has_body_p (node->symbol.decl)
567 || !(!node->clone_of
568 || node->symbol.decl != node->clone_of->symbol.decl))
569 continue;
571 /* Don't profile functions produced for builtin stuff. */
572 if (DECL_SOURCE_LOCATION (node->symbol.decl) == BUILTINS_LOCATION)
573 continue;
575 cgraph_set_const_flag (node, false, false);
576 cgraph_set_pure_flag (node, false, false);
579 /* Update call statements and rebuild the cgraph. */
580 FOR_EACH_DEFINED_FUNCTION (node)
582 basic_block bb;
584 if (!gimple_has_body_p (node->symbol.decl)
585 || !(!node->clone_of
586 || node->symbol.decl != node->clone_of->symbol.decl))
587 continue;
589 /* Don't profile functions produced for builtin stuff. */
590 if (DECL_SOURCE_LOCATION (node->symbol.decl) == BUILTINS_LOCATION)
591 continue;
593 push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl));
595 FOR_EACH_BB (bb)
597 gimple_stmt_iterator gsi;
598 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
600 gimple stmt = gsi_stmt (gsi);
601 if (is_gimple_call (stmt))
602 update_stmt (stmt);
606 /* re-merge split blocks. */
607 cleanup_tree_cfg ();
608 update_ssa (TODO_update_ssa);
610 rebuild_cgraph_edges ();
612 pop_cfun ();
615 del_node_map ();
616 return 0;
619 /* When profile instrumentation, use or test coverage shall be performed. */
621 static bool
622 gate_tree_profile_ipa (void)
624 return (!in_lto_p
625 && (flag_branch_probabilities || flag_test_coverage
626 || profile_arc_flag));
629 namespace {
631 const pass_data pass_data_ipa_tree_profile =
633 SIMPLE_IPA_PASS, /* type */
634 "profile", /* name */
635 OPTGROUP_NONE, /* optinfo_flags */
636 true, /* has_gate */
637 true, /* has_execute */
638 TV_IPA_PROFILE, /* tv_id */
639 0, /* properties_required */
640 0, /* properties_provided */
641 0, /* properties_destroyed */
642 0, /* todo_flags_start */
643 0, /* todo_flags_finish */
646 class pass_ipa_tree_profile : public simple_ipa_opt_pass
648 public:
649 pass_ipa_tree_profile (gcc::context *ctxt)
650 : simple_ipa_opt_pass (pass_data_ipa_tree_profile, ctxt)
653 /* opt_pass methods: */
654 bool gate () { return gate_tree_profile_ipa (); }
655 unsigned int execute () { return tree_profiling (); }
657 }; // class pass_ipa_tree_profile
659 } // anon namespace
661 simple_ipa_opt_pass *
662 make_pass_ipa_tree_profile (gcc::context *ctxt)
664 return new pass_ipa_tree_profile (ctxt);
667 #include "gt-tree-profile.h"