cgraph.c (cgraph_turn_edge_to_speculative): Fix debug output.
[official-gcc.git] / gcc / tree-profile.c
blobc99253718392be786069a9626f1fa506a44a2c12
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 "tree-flow.h"
38 #include "tree-pass.h"
39 #include "value-prof.h"
40 #include "cgraph.h"
41 #include "profile.h"
42 #include "target.h"
44 static GTY(()) tree gcov_type_node;
45 static GTY(()) tree tree_interval_profiler_fn;
46 static GTY(()) tree tree_pow2_profiler_fn;
47 static GTY(()) tree tree_one_value_profiler_fn;
48 static GTY(()) tree tree_indirect_call_profiler_fn;
49 static GTY(()) tree tree_average_profiler_fn;
50 static GTY(()) tree tree_ior_profiler_fn;
53 static GTY(()) tree ic_void_ptr_var;
54 static GTY(()) tree ic_gcov_type_ptr_var;
55 static GTY(()) tree ptr_void;
57 /* Do initialization work for the edge profiler. */
59 /* Add code:
60 __thread gcov* __gcov_indirect_call_counters; // pointer to actual counter
61 __thread void* __gcov_indirect_call_callee; // actual callee address
63 static void
64 init_ic_make_global_vars (void)
66 tree gcov_type_ptr;
68 ptr_void = build_pointer_type (void_type_node);
70 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
71 if (flag_lto)
73 ic_void_ptr_var
74 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
75 get_identifier ("__gcov_indirect_call_callee_ltopriv"),
76 ptr_void);
77 TREE_PUBLIC (ic_void_ptr_var) = 1;
78 DECL_COMMON (ic_void_ptr_var) = 1;
79 DECL_VISIBILITY (ic_void_ptr_var) = VISIBILITY_HIDDEN;
80 DECL_VISIBILITY_SPECIFIED (ic_void_ptr_var) = true;
82 else
84 ic_void_ptr_var
85 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
86 get_identifier ("__gcov_indirect_call_callee"),
87 ptr_void);
88 TREE_PUBLIC (ic_void_ptr_var) = 1;
89 DECL_EXTERNAL (ic_void_ptr_var) = 1;
91 TREE_STATIC (ic_void_ptr_var) = 1;
92 DECL_ARTIFICIAL (ic_void_ptr_var) = 1;
93 DECL_INITIAL (ic_void_ptr_var) = NULL;
94 if (targetm.have_tls)
95 DECL_TLS_MODEL (ic_void_ptr_var) =
96 decl_default_tls_model (ic_void_ptr_var);
98 varpool_finalize_decl (ic_void_ptr_var);
100 gcov_type_ptr = build_pointer_type (get_gcov_type ());
101 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
102 if (flag_lto)
104 ic_gcov_type_ptr_var
105 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
106 get_identifier ("__gcov_indirect_call_counters_ltopriv"),
107 gcov_type_ptr);
108 TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
109 DECL_COMMON (ic_gcov_type_ptr_var) = 1;
110 DECL_VISIBILITY (ic_gcov_type_ptr_var) = VISIBILITY_HIDDEN;
111 DECL_VISIBILITY_SPECIFIED (ic_gcov_type_ptr_var) = true;
113 else
115 ic_gcov_type_ptr_var
116 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
117 get_identifier ("__gcov_indirect_call_counters"),
118 gcov_type_ptr);
119 TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
120 DECL_EXTERNAL (ic_gcov_type_ptr_var) = 1;
122 TREE_STATIC (ic_gcov_type_ptr_var) = 1;
123 DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1;
124 DECL_INITIAL (ic_gcov_type_ptr_var) = NULL;
125 if (targetm.have_tls)
126 DECL_TLS_MODEL (ic_gcov_type_ptr_var) =
127 decl_default_tls_model (ic_gcov_type_ptr_var);
129 varpool_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;
144 if (!gcov_type_node)
146 gcov_type_node = get_gcov_type ();
147 gcov_type_ptr = build_pointer_type (gcov_type_node);
149 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
150 interval_profiler_fn_type
151 = build_function_type_list (void_type_node,
152 gcov_type_ptr, gcov_type_node,
153 integer_type_node,
154 unsigned_type_node, NULL_TREE);
155 tree_interval_profiler_fn
156 = build_fn_decl ("__gcov_interval_profiler",
157 interval_profiler_fn_type);
158 TREE_NOTHROW (tree_interval_profiler_fn) = 1;
159 DECL_ATTRIBUTES (tree_interval_profiler_fn)
160 = tree_cons (get_identifier ("leaf"), NULL,
161 DECL_ATTRIBUTES (tree_interval_profiler_fn));
163 /* void (*) (gcov_type *, gcov_type) */
164 pow2_profiler_fn_type
165 = build_function_type_list (void_type_node,
166 gcov_type_ptr, gcov_type_node,
167 NULL_TREE);
168 tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler",
169 pow2_profiler_fn_type);
170 TREE_NOTHROW (tree_pow2_profiler_fn) = 1;
171 DECL_ATTRIBUTES (tree_pow2_profiler_fn)
172 = tree_cons (get_identifier ("leaf"), NULL,
173 DECL_ATTRIBUTES (tree_pow2_profiler_fn));
175 /* void (*) (gcov_type *, gcov_type) */
176 one_value_profiler_fn_type
177 = build_function_type_list (void_type_node,
178 gcov_type_ptr, gcov_type_node,
179 NULL_TREE);
180 tree_one_value_profiler_fn
181 = build_fn_decl ("__gcov_one_value_profiler",
182 one_value_profiler_fn_type);
183 TREE_NOTHROW (tree_one_value_profiler_fn) = 1;
184 DECL_ATTRIBUTES (tree_one_value_profiler_fn)
185 = tree_cons (get_identifier ("leaf"), NULL,
186 DECL_ATTRIBUTES (tree_one_value_profiler_fn));
188 init_ic_make_global_vars ();
190 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
191 if (flag_lto)
193 /* void (*) (gcov_type, void *) */
194 ic_profiler_fn_type
195 = build_function_type_list (void_type_node,
196 gcov_type_ptr, gcov_type_node,
197 ptr_void, ptr_void,
198 NULL_TREE);
199 tree_indirect_call_profiler_fn
200 = build_fn_decl ("__gcov_indirect_call_profiler",
201 ic_profiler_fn_type);
203 else
205 /* void (*) (gcov_type, void *) */
206 ic_profiler_fn_type
207 = build_function_type_list (void_type_node,
208 gcov_type_node,
209 ptr_void,
210 NULL_TREE);
211 tree_indirect_call_profiler_fn
212 = build_fn_decl ("__gcov_indirect_call_profiler_v2",
213 ic_profiler_fn_type);
215 TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
216 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
217 = tree_cons (get_identifier ("leaf"), NULL,
218 DECL_ATTRIBUTES (tree_indirect_call_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_average_profiler_fn);
246 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
250 /* Output instructions as GIMPLE trees to increment the edge
251 execution count, and insert them on E. We rely on
252 gsi_insert_on_edge to preserve the order. */
254 void
255 gimple_gen_edge_profiler (int edgeno, edge e)
257 tree ref, one, gcov_type_tmp_var;
258 gimple stmt1, stmt2, stmt3;
260 ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
261 one = build_int_cst (gcov_type_node, 1);
262 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
263 NULL, "PROF_edge_counter");
264 stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
265 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
266 NULL, "PROF_edge_counter");
267 stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, gcov_type_tmp_var,
268 gimple_assign_lhs (stmt1), one);
269 stmt3 = gimple_build_assign (unshare_expr (ref), gimple_assign_lhs (stmt2));
270 gsi_insert_on_edge (e, stmt1);
271 gsi_insert_on_edge (e, stmt2);
272 gsi_insert_on_edge (e, stmt3);
275 /* Emits code to get VALUE to instrument at GSI, and returns the
276 variable containing the value. */
278 static tree
279 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
281 tree val = value->hvalue.value;
282 if (POINTER_TYPE_P (TREE_TYPE (val)))
283 val = fold_convert (build_nonstandard_integer_type
284 (TYPE_PRECISION (TREE_TYPE (val)), 1), val);
285 return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
286 true, NULL_TREE, true, GSI_SAME_STMT);
289 /* Output instructions as GIMPLE trees to increment the interval histogram
290 counter. VALUE is the expression whose value is profiled. TAG is the
291 tag of the section for counters, BASE is offset of the counter position. */
293 void
294 gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
296 gimple stmt = value->hvalue.stmt;
297 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
298 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
299 gimple call;
300 tree val;
301 tree start = build_int_cst_type (integer_type_node,
302 value->hdata.intvl.int_start);
303 tree steps = build_int_cst_type (unsigned_type_node,
304 value->hdata.intvl.steps);
306 ref_ptr = force_gimple_operand_gsi (&gsi,
307 build_addr (ref, current_function_decl),
308 true, NULL_TREE, true, GSI_SAME_STMT);
309 val = prepare_instrumented_value (&gsi, value);
310 call = gimple_build_call (tree_interval_profiler_fn, 4,
311 ref_ptr, val, start, steps);
312 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
315 /* Output instructions as GIMPLE trees to increment the power of two histogram
316 counter. VALUE is the expression whose value is profiled. TAG is the tag
317 of the section for counters, BASE is offset of the counter position. */
319 void
320 gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
322 gimple stmt = value->hvalue.stmt;
323 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
324 tree ref_ptr = tree_coverage_counter_addr (tag, base);
325 gimple call;
326 tree val;
328 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
329 true, NULL_TREE, true, GSI_SAME_STMT);
330 val = prepare_instrumented_value (&gsi, value);
331 call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val);
332 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
335 /* Output instructions as GIMPLE trees for code to find the most common value.
336 VALUE is the expression whose value is profiled. TAG is the tag of the
337 section for counters, BASE is offset of the counter position. */
339 void
340 gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
342 gimple stmt = value->hvalue.stmt;
343 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
344 tree ref_ptr = tree_coverage_counter_addr (tag, base);
345 gimple call;
346 tree val;
348 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
349 true, NULL_TREE, true, GSI_SAME_STMT);
350 val = prepare_instrumented_value (&gsi, value);
351 call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val);
352 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
356 /* Output instructions as GIMPLE trees for code to find the most
357 common called function in indirect call.
358 VALUE is the call expression whose indirect callee is profiled.
359 TAG is the tag of the section for counters, BASE is offset of the
360 counter position. */
362 void
363 gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
365 tree tmp1;
366 gimple stmt1, stmt2, stmt3;
367 gimple stmt = value->hvalue.stmt;
368 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
369 tree ref_ptr = tree_coverage_counter_addr (tag, base);
371 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
372 true, NULL_TREE, true, GSI_SAME_STMT);
374 /* Insert code:
376 stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
377 stmt2: tmp1 = (void *) (indirect call argument value)
378 stmt3: __gcov_indirect_call_callee = tmp1;
381 stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr);
382 tmp1 = make_temp_ssa_name (ptr_void, NULL, "PROF");
383 stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
384 stmt3 = gimple_build_assign (ic_void_ptr_var, gimple_assign_lhs (stmt2));
386 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
387 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
388 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
392 /* Output instructions as GIMPLE trees for code to find the most
393 common called function in indirect call. Insert instructions at the
394 beginning of every possible called function.
397 void
398 gimple_gen_ic_func_profiler (void)
400 struct cgraph_node * c_node = cgraph_get_node (current_function_decl);
401 gimple_stmt_iterator gsi;
402 gimple stmt1, stmt2;
403 tree tree_uid, cur_func, void0;
405 if (cgraph_only_called_directly_p (c_node))
406 return;
408 gimple_init_edge_profiler ();
410 /* Insert code:
412 stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
413 &current_function_decl)
415 gsi = gsi_after_labels (split_edge (single_succ_edge (ENTRY_BLOCK_PTR)));
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, cgraph_get_node (current_function_decl)->profile_id);
424 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
425 if (flag_lto)
427 tree counter_ptr, ptr_var;
428 counter_ptr = force_gimple_operand_gsi (&gsi, ic_gcov_type_ptr_var,
429 true, NULL_TREE, true,
430 GSI_SAME_STMT);
431 ptr_var = force_gimple_operand_gsi (&gsi, ic_void_ptr_var,
432 true, NULL_TREE, true,
433 GSI_SAME_STMT);
435 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 4,
436 counter_ptr, tree_uid, cur_func, ptr_var);
438 else
440 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2,
441 tree_uid, cur_func);
443 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
445 /* Set __gcov_indirect_call_callee to 0,
446 so that calls from other modules won't get misattributed
447 to the last caller of the current callee. */
448 void0 = build_int_cst (build_pointer_type (void_type_node), 0);
449 stmt2 = gimple_build_assign (ic_void_ptr_var, void0);
450 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
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. */
458 void
459 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
460 unsigned tag ATTRIBUTE_UNUSED,
461 unsigned base ATTRIBUTE_UNUSED)
463 /* FIXME implement this. */
464 #ifdef ENABLE_CHECKING
465 internal_error ("unimplemented functionality");
466 #endif
467 gcc_unreachable ();
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. */
474 void
475 gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
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 gimple call;
481 tree val;
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);
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. */
495 void
496 gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
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 gimple call;
502 tree val;
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);
511 /* Profile all functions in the callgraph. */
513 static unsigned int
514 tree_profiling (void)
516 struct cgraph_node *node;
518 /* This is a small-ipa pass that gets called only once, from
519 cgraphunit.c:ipa_passes(). */
520 gcc_assert (cgraph_state == CGRAPH_STATE_IPA_SSA);
522 init_node_map (true);
524 FOR_EACH_DEFINED_FUNCTION (node)
526 if (!gimple_has_body_p (node->symbol.decl))
527 continue;
529 /* Don't profile functions produced for builtin stuff. */
530 if (DECL_SOURCE_LOCATION (node->symbol.decl) == BUILTINS_LOCATION)
531 continue;
533 push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl));
535 /* Local pure-const may imply need to fixup the cfg. */
536 if (execute_fixup_cfg () & TODO_cleanup_cfg)
537 cleanup_tree_cfg ();
539 branch_prob ();
541 if (! flag_branch_probabilities
542 && flag_profile_values)
543 gimple_gen_ic_func_profiler ();
545 if (flag_branch_probabilities
546 && flag_profile_values
547 && flag_value_profile_transformations)
548 gimple_value_profile_transformations ();
550 /* The above could hose dominator info. Currently there is
551 none coming in, this is a safety valve. It should be
552 easy to adjust it, if and when there is some. */
553 free_dominance_info (CDI_DOMINATORS);
554 free_dominance_info (CDI_POST_DOMINATORS);
555 pop_cfun ();
558 /* Drop pure/const flags from instrumented functions. */
559 FOR_EACH_DEFINED_FUNCTION (node)
561 if (!gimple_has_body_p (node->symbol.decl)
562 || !(!node->clone_of
563 || node->symbol.decl != node->clone_of->symbol.decl))
564 continue;
566 /* Don't profile functions produced for builtin stuff. */
567 if (DECL_SOURCE_LOCATION (node->symbol.decl) == BUILTINS_LOCATION)
568 continue;
570 cgraph_set_const_flag (node, false, false);
571 cgraph_set_pure_flag (node, false, false);
574 /* Update call statements and rebuild the cgraph. */
575 FOR_EACH_DEFINED_FUNCTION (node)
577 basic_block bb;
579 if (!gimple_has_body_p (node->symbol.decl)
580 || !(!node->clone_of
581 || node->symbol.decl != node->clone_of->symbol.decl))
582 continue;
584 /* Don't profile functions produced for builtin stuff. */
585 if (DECL_SOURCE_LOCATION (node->symbol.decl) == BUILTINS_LOCATION)
586 continue;
588 push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl));
590 FOR_EACH_BB (bb)
592 gimple_stmt_iterator gsi;
593 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
595 gimple stmt = gsi_stmt (gsi);
596 if (is_gimple_call (stmt))
597 update_stmt (stmt);
601 update_ssa (TODO_update_ssa);
603 rebuild_cgraph_edges ();
605 pop_cfun ();
608 del_node_map();
609 return 0;
612 /* When profile instrumentation, use or test coverage shall be performed. */
614 static bool
615 gate_tree_profile_ipa (void)
617 return (!in_lto_p
618 && (flag_branch_probabilities || flag_test_coverage
619 || profile_arc_flag));
622 namespace {
624 const pass_data pass_data_ipa_tree_profile =
626 SIMPLE_IPA_PASS, /* type */
627 "profile", /* name */
628 OPTGROUP_NONE, /* optinfo_flags */
629 true, /* has_gate */
630 true, /* has_execute */
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 bool gate () { return gate_tree_profile_ipa (); }
648 unsigned int execute () { return tree_profiling (); }
650 }; // class pass_ipa_tree_profile
652 } // anon namespace
654 simple_ipa_opt_pass *
655 make_pass_ipa_tree_profile (gcc::context *ctxt)
657 return new pass_ipa_tree_profile (ctxt);
660 #include "gt-tree-profile.h"