OSDN Git Service

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