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