system.h (dump_file): Do not define.
[platform/upstream/gcc.git] / gcc / tree-profile.c
1 /* Calculate branch probabilities, and basic block execution counts.
2    Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999,
3    2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010
4    Free Software Foundation, Inc.
5    Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
6    based on some ideas from Dain Samples of UC Berkeley.
7    Further mangling by Bob Manson, Cygnus Support.
8    Converted to use trees by Dale Johannesen, Apple Computer.
9
10 This file is part of GCC.
11
12 GCC is free software; you can redistribute it and/or modify it under
13 the terms of the GNU General Public License as published by the Free
14 Software Foundation; either version 3, or (at your option) any later
15 version.
16
17 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
18 WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with GCC; see the file COPYING3.  If not see
24 <http://www.gnu.org/licenses/>.  */
25
26 /* Generate basic block profile instrumentation and auxiliary files.
27    Tree-based version.  See profile.c for overview.  */
28
29 #include "config.h"
30 #include "system.h"
31 #include "coretypes.h"
32 #include "tm.h"
33 #include "flags.h"
34 #include "function.h"
35 #include "basic-block.h"
36 #include "diagnostic-core.h"
37 #include "coverage.h"
38 #include "tree.h"
39 #include "tree-flow.h"
40 #include "tree-pass.h"
41 #include "value-prof.h"
42 #include "cgraph.h"
43 #include "profile.h"
44 #include "target.h"
45
46 static GTY(()) tree gcov_type_node;
47 static GTY(()) tree gcov_type_tmp_var;
48 static GTY(()) tree tree_interval_profiler_fn;
49 static GTY(()) tree tree_pow2_profiler_fn;
50 static GTY(()) tree tree_one_value_profiler_fn;
51 static GTY(()) tree tree_indirect_call_profiler_fn;
52 static GTY(()) tree tree_average_profiler_fn;
53 static GTY(()) tree tree_ior_profiler_fn;
54 \f
55
56 static GTY(()) tree ic_void_ptr_var;
57 static GTY(()) tree ic_gcov_type_ptr_var;
58 static GTY(()) tree ptr_void;
59
60 /* Do initialization work for the edge profiler.  */
61
62 /* Add code:
63    static gcov* __gcov_indirect_call_counters; // pointer to actual counter
64    static void* __gcov_indirect_call_callee; // actual callee address
65 */
66 static void
67 init_ic_make_global_vars (void)
68 {
69   tree  gcov_type_ptr;
70
71   ptr_void = build_pointer_type (void_type_node);
72
73   ic_void_ptr_var
74     = build_decl (UNKNOWN_LOCATION, VAR_DECL,
75                   get_identifier ("__gcov_indirect_call_callee"),
76                   ptr_void);
77   TREE_STATIC (ic_void_ptr_var) = 1;
78   TREE_PUBLIC (ic_void_ptr_var) = 0;
79   DECL_ARTIFICIAL (ic_void_ptr_var) = 1;
80   DECL_INITIAL (ic_void_ptr_var) = NULL;
81   if (targetm.have_tls)
82     DECL_TLS_MODEL (ic_void_ptr_var) =
83       decl_default_tls_model (ic_void_ptr_var);
84
85   varpool_finalize_decl (ic_void_ptr_var);
86
87   gcov_type_ptr = build_pointer_type (get_gcov_type ());
88   ic_gcov_type_ptr_var
89     = build_decl (UNKNOWN_LOCATION, VAR_DECL,
90                   get_identifier ("__gcov_indirect_call_counters"),
91                   gcov_type_ptr);
92   TREE_STATIC (ic_gcov_type_ptr_var) = 1;
93   TREE_PUBLIC (ic_gcov_type_ptr_var) = 0;
94   DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1;
95   DECL_INITIAL (ic_gcov_type_ptr_var) = NULL;
96   if (targetm.have_tls)
97     DECL_TLS_MODEL (ic_gcov_type_ptr_var) =
98       decl_default_tls_model (ic_gcov_type_ptr_var);
99
100   varpool_finalize_decl (ic_gcov_type_ptr_var);
101 }
102
103 void
104 gimple_init_edge_profiler (void)
105 {
106   tree interval_profiler_fn_type;
107   tree pow2_profiler_fn_type;
108   tree one_value_profiler_fn_type;
109   tree gcov_type_ptr;
110   tree ic_profiler_fn_type;
111   tree average_profiler_fn_type;
112
113   if (!gcov_type_node)
114     {
115       gcov_type_node = get_gcov_type ();
116       gcov_type_ptr = build_pointer_type (gcov_type_node);
117
118       /* void (*) (gcov_type *, gcov_type, int, unsigned)  */
119       interval_profiler_fn_type
120               = build_function_type_list (void_type_node,
121                                           gcov_type_ptr, gcov_type_node,
122                                           integer_type_node,
123                                           unsigned_type_node, NULL_TREE);
124       tree_interval_profiler_fn
125               = build_fn_decl ("__gcov_interval_profiler",
126                                      interval_profiler_fn_type);
127       TREE_NOTHROW (tree_interval_profiler_fn) = 1;
128       DECL_ATTRIBUTES (tree_interval_profiler_fn)
129         = tree_cons (get_identifier ("leaf"), NULL,
130                      DECL_ATTRIBUTES (tree_interval_profiler_fn));
131
132       /* void (*) (gcov_type *, gcov_type)  */
133       pow2_profiler_fn_type
134               = build_function_type_list (void_type_node,
135                                           gcov_type_ptr, gcov_type_node,
136                                           NULL_TREE);
137       tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler",
138                                                    pow2_profiler_fn_type);
139       TREE_NOTHROW (tree_pow2_profiler_fn) = 1;
140       DECL_ATTRIBUTES (tree_pow2_profiler_fn)
141         = tree_cons (get_identifier ("leaf"), NULL,
142                      DECL_ATTRIBUTES (tree_pow2_profiler_fn));
143
144       /* void (*) (gcov_type *, gcov_type)  */
145       one_value_profiler_fn_type
146               = build_function_type_list (void_type_node,
147                                           gcov_type_ptr, gcov_type_node,
148                                           NULL_TREE);
149       tree_one_value_profiler_fn
150               = build_fn_decl ("__gcov_one_value_profiler",
151                                      one_value_profiler_fn_type);
152       TREE_NOTHROW (tree_one_value_profiler_fn) = 1;
153       DECL_ATTRIBUTES (tree_one_value_profiler_fn)
154         = tree_cons (get_identifier ("leaf"), NULL,
155                      DECL_ATTRIBUTES (tree_one_value_profiler_fn));
156
157       init_ic_make_global_vars ();
158
159       /* void (*) (gcov_type *, gcov_type, void *, void *)  */
160       ic_profiler_fn_type
161                = build_function_type_list (void_type_node,
162                                           gcov_type_ptr, gcov_type_node,
163                                           ptr_void,
164                                           ptr_void, NULL_TREE);
165       tree_indirect_call_profiler_fn
166               = build_fn_decl ("__gcov_indirect_call_profiler",
167                                      ic_profiler_fn_type);
168       TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
169       DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
170         = tree_cons (get_identifier ("leaf"), NULL,
171                      DECL_ATTRIBUTES (tree_indirect_call_profiler_fn));
172
173       /* void (*) (gcov_type *, gcov_type)  */
174       average_profiler_fn_type
175               = build_function_type_list (void_type_node,
176                                           gcov_type_ptr, gcov_type_node, NULL_TREE);
177       tree_average_profiler_fn
178               = build_fn_decl ("__gcov_average_profiler",
179                                      average_profiler_fn_type);
180       TREE_NOTHROW (tree_average_profiler_fn) = 1;
181       DECL_ATTRIBUTES (tree_average_profiler_fn)
182         = tree_cons (get_identifier ("leaf"), NULL,
183                      DECL_ATTRIBUTES (tree_average_profiler_fn));
184       tree_ior_profiler_fn
185               = build_fn_decl ("__gcov_ior_profiler",
186                                      average_profiler_fn_type);
187       TREE_NOTHROW (tree_ior_profiler_fn) = 1;
188       DECL_ATTRIBUTES (tree_ior_profiler_fn)
189         = tree_cons (get_identifier ("leaf"), NULL,
190                      DECL_ATTRIBUTES (tree_ior_profiler_fn));
191
192       /* LTO streamer needs assembler names.  Because we create these decls
193          late, we need to initialize them by hand.  */
194       DECL_ASSEMBLER_NAME (tree_interval_profiler_fn);
195       DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn);
196       DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn);
197       DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn);
198       DECL_ASSEMBLER_NAME (tree_average_profiler_fn);
199       DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
200     }
201 }
202
203 /* Output instructions as GIMPLE trees to increment the edge
204    execution count, and insert them on E.  We rely on
205    gsi_insert_on_edge to preserve the order.  */
206
207 void
208 gimple_gen_edge_profiler (int edgeno, edge e)
209 {
210   tree ref, one;
211   gimple stmt1, stmt2, stmt3;
212
213   /* We share one temporary variable declaration per function.  This
214      gets re-set in tree_profiling.  */
215   if (gcov_type_tmp_var == NULL_TREE)
216     gcov_type_tmp_var = create_tmp_reg (gcov_type_node, "PROF_edge_counter");
217   ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
218   one = build_int_cst (gcov_type_node, 1);
219   stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
220   gimple_assign_set_lhs (stmt1, make_ssa_name (gcov_type_tmp_var, stmt1));
221   find_referenced_vars_in (stmt1);
222   stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, gcov_type_tmp_var,
223                                         gimple_assign_lhs (stmt1), one);
224   gimple_assign_set_lhs (stmt2, make_ssa_name (gcov_type_tmp_var, stmt2));
225   stmt3 = gimple_build_assign (unshare_expr (ref), gimple_assign_lhs (stmt2));
226   gsi_insert_on_edge (e, stmt1);
227   gsi_insert_on_edge (e, stmt2);
228   gsi_insert_on_edge (e, stmt3);
229 }
230
231 /* Emits code to get VALUE to instrument at GSI, and returns the
232    variable containing the value.  */
233
234 static tree
235 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
236 {
237   tree val = value->hvalue.value;
238   if (POINTER_TYPE_P (TREE_TYPE (val)))
239     val = fold_convert (build_nonstandard_integer_type
240                           (TYPE_PRECISION (TREE_TYPE (val)), 1), val);
241   return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
242                                    true, NULL_TREE, true, GSI_SAME_STMT);
243 }
244
245 /* Output instructions as GIMPLE trees to increment the interval histogram
246    counter.  VALUE is the expression whose value is profiled.  TAG is the
247    tag of the section for counters, BASE is offset of the counter position.  */
248
249 void
250 gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
251 {
252   gimple stmt = value->hvalue.stmt;
253   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
254   tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
255   gimple call;
256   tree val;
257   tree start = build_int_cst_type (integer_type_node,
258                                    value->hdata.intvl.int_start);
259   tree steps = build_int_cst_type (unsigned_type_node,
260                                    value->hdata.intvl.steps);
261
262   ref_ptr = force_gimple_operand_gsi (&gsi,
263                                       build_addr (ref, current_function_decl),
264                                       true, NULL_TREE, true, GSI_SAME_STMT);
265   val = prepare_instrumented_value (&gsi, value);
266   call = gimple_build_call (tree_interval_profiler_fn, 4,
267                             ref_ptr, val, start, steps);
268   find_referenced_vars_in (call);
269   gsi_insert_before (&gsi, call, GSI_NEW_STMT);
270 }
271
272 /* Output instructions as GIMPLE trees to increment the power of two histogram
273    counter.  VALUE is the expression whose value is profiled.  TAG is the tag
274    of the section for counters, BASE is offset of the counter position.  */
275
276 void
277 gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
278 {
279   gimple stmt = value->hvalue.stmt;
280   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
281   tree ref_ptr = tree_coverage_counter_addr (tag, base);
282   gimple call;
283   tree val;
284
285   ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
286                                       true, NULL_TREE, true, GSI_SAME_STMT);
287   val = prepare_instrumented_value (&gsi, value);
288   call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val);
289   find_referenced_vars_in (call);
290   gsi_insert_before (&gsi, call, GSI_NEW_STMT);
291 }
292
293 /* Output instructions as GIMPLE trees for code to find the most common value.
294    VALUE is the expression whose value is profiled.  TAG is the tag of the
295    section for counters, BASE is offset of the counter position.  */
296
297 void
298 gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
299 {
300   gimple stmt = value->hvalue.stmt;
301   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
302   tree ref_ptr = tree_coverage_counter_addr (tag, base);
303   gimple call;
304   tree val;
305
306   ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
307                                       true, NULL_TREE, true, GSI_SAME_STMT);
308   val = prepare_instrumented_value (&gsi, value);
309   call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val);
310   find_referenced_vars_in (call);
311   gsi_insert_before (&gsi, call, GSI_NEW_STMT);
312 }
313
314
315 /* Output instructions as GIMPLE trees for code to find the most
316    common called function in indirect call.
317    VALUE is the call expression whose indirect callee is profiled.
318    TAG is the tag of the section for counters, BASE is offset of the
319    counter position.  */
320
321 void
322 gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
323 {
324   tree tmp1;
325   gimple stmt1, stmt2, stmt3;
326   gimple stmt = value->hvalue.stmt;
327   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
328   tree ref_ptr = tree_coverage_counter_addr (tag, base);
329
330   ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
331                                       true, NULL_TREE, true, GSI_SAME_STMT);
332
333   /* Insert code:
334
335     __gcov_indirect_call_counters = get_relevant_counter_ptr ();
336     __gcov_indirect_call_callee = (void *) indirect call argument;
337    */
338
339   tmp1 = create_tmp_reg (ptr_void, "PROF");
340   stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr);
341   find_referenced_vars_in (stmt1);
342   stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
343   gimple_assign_set_lhs (stmt2, make_ssa_name (tmp1, stmt2));
344   find_referenced_vars_in (stmt2);
345   stmt3 = gimple_build_assign (ic_void_ptr_var, gimple_assign_lhs (stmt2));
346
347   gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
348   gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
349   gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
350 }
351
352
353 /* Output instructions as GIMPLE trees for code to find the most
354    common called function in indirect call. Insert instructions at the
355    beginning of every possible called function.
356   */
357
358 void
359 gimple_gen_ic_func_profiler (void)
360 {
361   struct cgraph_node * c_node = cgraph_get_node (current_function_decl);
362   gimple_stmt_iterator gsi;
363   gimple stmt1, stmt2;
364   tree tree_uid, cur_func, counter_ptr, ptr_var, void0;
365
366   if (cgraph_only_called_directly_p (c_node))
367     return;
368
369   gimple_init_edge_profiler ();
370
371   gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR));
372
373   cur_func = force_gimple_operand_gsi (&gsi,
374                                        build_addr (current_function_decl,
375                                                    current_function_decl),
376                                        true, NULL_TREE,
377                                        true, GSI_SAME_STMT);
378   counter_ptr = force_gimple_operand_gsi (&gsi, ic_gcov_type_ptr_var,
379                                           true, NULL_TREE, true,
380                                           GSI_SAME_STMT);
381   ptr_var = force_gimple_operand_gsi (&gsi, ic_void_ptr_var,
382                                       true, NULL_TREE, true,
383                                       GSI_SAME_STMT);
384   tree_uid = build_int_cst (gcov_type_node, current_function_funcdef_no);
385   stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 4,
386                              counter_ptr, tree_uid, cur_func, ptr_var);
387   gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
388
389   /* Set __gcov_indirect_call_callee to 0,
390      so that calls from other modules won't get misattributed
391      to the last caller of the current callee. */
392   void0 = build_int_cst (build_pointer_type (void_type_node), 0);
393   stmt2 = gimple_build_assign (ic_void_ptr_var, void0);
394   gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
395 }
396
397 /* Output instructions as GIMPLE trees for code to find the most common value
398    of a difference between two evaluations of an expression.
399    VALUE is the expression whose value is profiled.  TAG is the tag of the
400    section for counters, BASE is offset of the counter position.  */
401
402 void
403 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
404                                unsigned tag ATTRIBUTE_UNUSED,
405                                unsigned base ATTRIBUTE_UNUSED)
406 {
407   /* FIXME implement this.  */
408 #ifdef ENABLE_CHECKING
409   internal_error ("unimplemented functionality");
410 #endif
411   gcc_unreachable ();
412 }
413
414 /* Output instructions as GIMPLE trees to increment the average histogram
415    counter.  VALUE is the expression whose value is profiled.  TAG is the
416    tag of the section for counters, BASE is offset of the counter position.  */
417
418 void
419 gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
420 {
421   gimple stmt = value->hvalue.stmt;
422   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
423   tree ref_ptr = tree_coverage_counter_addr (tag, base);
424   gimple call;
425   tree val;
426
427   ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
428                                       true, NULL_TREE,
429                                       true, GSI_SAME_STMT);
430   val = prepare_instrumented_value (&gsi, value);
431   call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
432   find_referenced_vars_in (call);
433   gsi_insert_before (&gsi, call, GSI_NEW_STMT);
434 }
435
436 /* Output instructions as GIMPLE trees to increment the ior histogram
437    counter.  VALUE is the expression whose value is profiled.  TAG is the
438    tag of the section for counters, BASE is offset of the counter position.  */
439
440 void
441 gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
442 {
443   gimple stmt = value->hvalue.stmt;
444   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
445   tree ref_ptr = tree_coverage_counter_addr (tag, base);
446   gimple call;
447   tree val;
448
449   ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
450                                       true, NULL_TREE, true, GSI_SAME_STMT);
451   val = prepare_instrumented_value (&gsi, value);
452   call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
453   find_referenced_vars_in (call);
454   gsi_insert_before (&gsi, call, GSI_NEW_STMT);
455 }
456
457 /* Profile all functions in the callgraph.  */
458
459 static unsigned int
460 tree_profiling (void)
461 {
462   struct cgraph_node *node;
463
464   /* Don't profile functions produced at destruction time, particularly
465      the gcov datastructure initializer.  Don't profile if it has been
466      already instrumented either (when OpenMP expansion creates
467      child function from already instrumented body).  */
468   if (cgraph_state == CGRAPH_STATE_FINISHED)
469     return 0;
470
471   init_node_map();
472
473   FOR_EACH_DEFINED_FUNCTION (node)
474     {
475       if (!gimple_has_body_p (node->symbol.decl))
476         continue;
477
478       /* Don't profile functions produced for builtin stuff.  */
479       if (DECL_SOURCE_LOCATION (node->symbol.decl) == BUILTINS_LOCATION
480           || DECL_STRUCT_FUNCTION (node->symbol.decl)->after_tree_profile)
481         continue;
482
483       push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl));
484       current_function_decl = node->symbol.decl;
485
486       /* Re-set global shared temporary variable for edge-counters.  */
487       gcov_type_tmp_var = NULL_TREE;
488
489       /* Local pure-const may imply need to fixup the cfg.  */
490       if (execute_fixup_cfg () & TODO_cleanup_cfg)
491         cleanup_tree_cfg ();
492       branch_prob ();
493
494       if (! flag_branch_probabilities
495           && flag_profile_values)
496         gimple_gen_ic_func_profiler ();
497
498       if (flag_branch_probabilities
499           && flag_profile_values
500           && flag_value_profile_transformations)
501         gimple_value_profile_transformations ();
502
503       /* The above could hose dominator info.  Currently there is
504          none coming in, this is a safety valve.  It should be
505          easy to adjust it, if and when there is some.  */
506       free_dominance_info (CDI_DOMINATORS);
507       free_dominance_info (CDI_POST_DOMINATORS);
508
509       current_function_decl = NULL;
510       pop_cfun ();
511     }
512
513   /* Drop pure/const flags from instrumented functions.  */
514   FOR_EACH_DEFINED_FUNCTION (node)
515     {
516       if (!gimple_has_body_p (node->symbol.decl)
517           || !(!node->clone_of
518           || node->symbol.decl != node->clone_of->symbol.decl))
519         continue;
520
521       /* Don't profile functions produced for builtin stuff.  */
522       if (DECL_SOURCE_LOCATION (node->symbol.decl) == BUILTINS_LOCATION
523           || DECL_STRUCT_FUNCTION (node->symbol.decl)->after_tree_profile)
524         continue;
525
526       cgraph_set_const_flag (node, false, false);
527       cgraph_set_pure_flag (node, false, false);
528     }
529
530   /* Update call statements and rebuild the cgraph.  */
531   FOR_EACH_DEFINED_FUNCTION (node)
532     {
533       basic_block bb;
534
535       if (!gimple_has_body_p (node->symbol.decl)
536           || !(!node->clone_of
537           || node->symbol.decl != node->clone_of->symbol.decl))
538         continue;
539
540       /* Don't profile functions produced for builtin stuff.  */
541       if (DECL_SOURCE_LOCATION (node->symbol.decl) == BUILTINS_LOCATION
542           || DECL_STRUCT_FUNCTION (node->symbol.decl)->after_tree_profile)
543         continue;
544
545       push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl));
546       current_function_decl = node->symbol.decl;
547
548       FOR_EACH_BB (bb)
549         {
550           gimple_stmt_iterator gsi;
551           for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
552             {
553               gimple stmt = gsi_stmt (gsi);
554               if (is_gimple_call (stmt))
555                 update_stmt (stmt);
556             }
557         }
558
559       cfun->after_tree_profile = 1;
560       update_ssa (TODO_update_ssa);
561
562       rebuild_cgraph_edges ();
563
564       current_function_decl = NULL;
565       pop_cfun ();
566     }
567
568   del_node_map();
569   return 0;
570 }
571
572 /* When profile instrumentation, use or test coverage shall be performed.  */
573
574 static bool
575 gate_tree_profile_ipa (void)
576 {
577   return (!in_lto_p
578           && (flag_branch_probabilities || flag_test_coverage
579               || profile_arc_flag));
580 }
581
582 struct simple_ipa_opt_pass pass_ipa_tree_profile =
583 {
584  {
585   SIMPLE_IPA_PASS,
586   "profile",                           /* name */
587   gate_tree_profile_ipa,               /* gate */
588   tree_profiling,                      /* execute */
589   NULL,                                /* sub */
590   NULL,                                /* next */
591   0,                                   /* static_pass_number */
592   TV_IPA_PROFILE,                      /* tv_id */
593   0,                                   /* properties_required */
594   0,                                   /* properties_provided */
595   0,                                   /* properties_destroyed */
596   0,                                   /* todo_flags_start */
597   0                                    /* todo_flags_finish */
598  }
599 };
600
601 #include "gt-tree-profile.h"