OSDN Git Service

dumping cleanup phase 1 -- Removing TODO_dump_func
[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   stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, gcov_type_tmp_var,
228                                         gimple_assign_lhs (stmt1), one);
229   gimple_assign_set_lhs (stmt2, make_ssa_name (gcov_type_tmp_var, stmt2));
230   stmt3 = gimple_build_assign (unshare_expr (ref), gimple_assign_lhs (stmt2));
231   gsi_insert_on_edge (e, stmt1);
232   gsi_insert_on_edge (e, stmt2);
233   gsi_insert_on_edge (e, stmt3);
234 }
235
236 /* Emits code to get VALUE to instrument at GSI, and returns the
237    variable containing the value.  */
238
239 static tree
240 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
241 {
242   tree val = value->hvalue.value;
243   if (POINTER_TYPE_P (TREE_TYPE (val)))
244     val = fold_convert (sizetype, 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   gsi_insert_before (&gsi, call, GSI_NEW_STMT);
273 }
274
275 /* Output instructions as GIMPLE trees to increment the power of two histogram
276    counter.  VALUE is the expression whose value is profiled.  TAG is the tag
277    of the section for counters, BASE is offset of the counter position.  */
278
279 void
280 gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
281 {
282   gimple stmt = value->hvalue.stmt;
283   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
284   tree ref_ptr = tree_coverage_counter_addr (tag, base);
285   gimple call;
286   tree val;
287
288   ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
289                                       true, NULL_TREE, true, GSI_SAME_STMT);
290   val = prepare_instrumented_value (&gsi, value);
291   call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val);
292   gsi_insert_before (&gsi, call, GSI_NEW_STMT);
293 }
294
295 /* Output instructions as GIMPLE trees for code to find the most common value.
296    VALUE is the expression whose value is profiled.  TAG is the tag of the
297    section for counters, BASE is offset of the counter position.  */
298
299 void
300 gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
301 {
302   gimple stmt = value->hvalue.stmt;
303   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
304   tree ref_ptr = tree_coverage_counter_addr (tag, base);
305   gimple call;
306   tree val;
307
308   ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
309                                       true, NULL_TREE, true, GSI_SAME_STMT);
310   val = prepare_instrumented_value (&gsi, value);
311   call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val);
312   gsi_insert_before (&gsi, call, GSI_NEW_STMT);
313 }
314
315
316 /* Output instructions as GIMPLE trees for code to find the most
317    common called function in indirect call.
318    VALUE is the call expression whose indirect callee is profiled.
319    TAG is the tag of the section for counters, BASE is offset of the
320    counter position.  */
321
322 void
323 gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
324 {
325   tree tmp1;
326   gimple stmt1, stmt2, stmt3;
327   gimple stmt = value->hvalue.stmt;
328   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
329   tree ref_ptr = tree_coverage_counter_addr (tag, base);
330
331   ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
332                                       true, NULL_TREE, true, GSI_SAME_STMT);
333
334   /* Insert code:
335
336     __gcov_indirect_call_counters = get_relevant_counter_ptr ();
337     __gcov_indirect_call_callee = (void *) indirect call argument;
338    */
339
340   tmp1 = create_tmp_reg (ptr_void, "PROF");
341   stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr);
342   stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
343   gimple_assign_set_lhs (stmt2, make_ssa_name (tmp1, stmt2));
344   stmt3 = gimple_build_assign (ic_void_ptr_var, gimple_assign_lhs (stmt2));
345
346   gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
347   gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
348   gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
349 }
350
351
352 /* Output instructions as GIMPLE trees for code to find the most
353    common called function in indirect call. Insert instructions at the
354    beginning of every possible called function.
355   */
356
357 void
358 gimple_gen_ic_func_profiler (void)
359 {
360   struct cgraph_node * c_node = cgraph_get_node (current_function_decl);
361   gimple_stmt_iterator gsi;
362   gimple stmt1, stmt2;
363   tree tree_uid, cur_func, counter_ptr, ptr_var, void0;
364
365   if (cgraph_only_called_directly_p (c_node))
366     return;
367
368   gimple_init_edge_profiler ();
369
370   gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR));
371
372   cur_func = force_gimple_operand_gsi (&gsi,
373                                        build_addr (current_function_decl,
374                                                    current_function_decl),
375                                        true, NULL_TREE,
376                                        true, GSI_SAME_STMT);
377   counter_ptr = force_gimple_operand_gsi (&gsi, ic_gcov_type_ptr_var,
378                                           true, NULL_TREE, true,
379                                           GSI_SAME_STMT);
380   ptr_var = force_gimple_operand_gsi (&gsi, ic_void_ptr_var,
381                                       true, NULL_TREE, true,
382                                       GSI_SAME_STMT);
383   tree_uid = build_int_cst (gcov_type_node, current_function_funcdef_no);
384   stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 4,
385                              counter_ptr, tree_uid, cur_func, ptr_var);
386   gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
387
388   /* Set __gcov_indirect_call_callee to 0,
389      so that calls from other modules won't get misattributed
390      to the last caller of the current callee. */
391   void0 = build_int_cst (build_pointer_type (void_type_node), 0);
392   stmt2 = gimple_build_assign (ic_void_ptr_var, void0);
393   gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
394 }
395
396 /* Output instructions as GIMPLE trees for code to find the most common value
397    of a difference between two evaluations of an expression.
398    VALUE is the expression whose value is profiled.  TAG is the tag of the
399    section for counters, BASE is offset of the counter position.  */
400
401 void
402 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
403                                unsigned tag ATTRIBUTE_UNUSED,
404                                unsigned base ATTRIBUTE_UNUSED)
405 {
406   /* FIXME implement this.  */
407 #ifdef ENABLE_CHECKING
408   internal_error ("unimplemented functionality");
409 #endif
410   gcc_unreachable ();
411 }
412
413 /* Output instructions as GIMPLE trees to increment the average histogram
414    counter.  VALUE is the expression whose value is profiled.  TAG is the
415    tag of the section for counters, BASE is offset of the counter position.  */
416
417 void
418 gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
419 {
420   gimple stmt = value->hvalue.stmt;
421   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
422   tree ref_ptr = tree_coverage_counter_addr (tag, base);
423   gimple call;
424   tree val;
425
426   ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
427                                       true, NULL_TREE,
428                                       true, GSI_SAME_STMT);
429   val = prepare_instrumented_value (&gsi, value);
430   call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
431   gsi_insert_before (&gsi, call, GSI_NEW_STMT);
432 }
433
434 /* Output instructions as GIMPLE trees to increment the ior histogram
435    counter.  VALUE is the expression whose value is profiled.  TAG is the
436    tag of the section for counters, BASE is offset of the counter position.  */
437
438 void
439 gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
440 {
441   gimple stmt = value->hvalue.stmt;
442   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
443   tree ref_ptr = tree_coverage_counter_addr (tag, base);
444   gimple call;
445   tree val;
446
447   ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
448                                       true, NULL_TREE, true, GSI_SAME_STMT);
449   val = prepare_instrumented_value (&gsi, value);
450   call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
451   gsi_insert_before (&gsi, call, GSI_NEW_STMT);
452 }
453
454 /* Profile all functions in the callgraph.  */
455
456 static unsigned int
457 tree_profiling (void)
458 {
459   struct cgraph_node *node;
460
461   /* Don't profile functions produced at destruction time, particularly
462      the gcov datastructure initializer.  Don't profile if it has been
463      already instrumented either (when OpenMP expansion creates
464      child function from already instrumented body).  */
465   if (cgraph_state == CGRAPH_STATE_FINISHED)
466     return 0;
467
468   init_node_map();
469
470   for (node = cgraph_nodes; node; node = node->next)
471     {
472       if (!node->analyzed
473           || !gimple_has_body_p (node->decl))
474         continue;
475
476       /* Don't profile functions produced for builtin stuff.  */
477       if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION
478           || DECL_STRUCT_FUNCTION (node->decl)->after_tree_profile)
479         continue;
480
481       push_cfun (DECL_STRUCT_FUNCTION (node->decl));
482       current_function_decl = node->decl;
483
484       /* Re-set global shared temporary variable for edge-counters.  */
485       gcov_type_tmp_var = NULL_TREE;
486
487       /* Local pure-const may imply need to fixup the cfg.  */
488       execute_fixup_cfg ();
489       branch_prob ();
490
491       if (! flag_branch_probabilities
492           && flag_profile_values)
493         gimple_gen_ic_func_profiler ();
494
495       if (flag_branch_probabilities
496           && flag_profile_values
497           && flag_value_profile_transformations)
498         gimple_value_profile_transformations ();
499
500       /* The above could hose dominator info.  Currently there is
501          none coming in, this is a safety valve.  It should be
502          easy to adjust it, if and when there is some.  */
503       free_dominance_info (CDI_DOMINATORS);
504       free_dominance_info (CDI_POST_DOMINATORS);
505
506       current_function_decl = NULL;
507       pop_cfun ();
508     }
509
510   /* Drop pure/const flags from instrumented functions.  */
511   for (node = cgraph_nodes; node; node = node->next)
512     {
513       if (!node->analyzed
514           || !gimple_has_body_p (node->decl)
515           || !(!node->clone_of || node->decl != node->clone_of->decl))
516         continue;
517
518       /* Don't profile functions produced for builtin stuff.  */
519       if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION
520           || DECL_STRUCT_FUNCTION (node->decl)->after_tree_profile)
521         continue;
522
523       cgraph_set_const_flag (node, false, false);
524       cgraph_set_pure_flag (node, false, false);
525     }
526
527   /* Update call statements and rebuild the cgraph.  */
528   for (node = cgraph_nodes; node; node = node->next)
529     {
530       basic_block bb;
531
532       if (!node->analyzed
533           || !gimple_has_body_p (node->decl)
534           || !(!node->clone_of || node->decl != node->clone_of->decl))
535         continue;
536
537       /* Don't profile functions produced for builtin stuff.  */
538       if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION
539           || DECL_STRUCT_FUNCTION (node->decl)->after_tree_profile)
540         continue;
541
542       push_cfun (DECL_STRUCT_FUNCTION (node->decl));
543       current_function_decl = node->decl;
544
545       FOR_EACH_BB (bb)
546         {
547           gimple_stmt_iterator gsi;
548           for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
549             {
550               gimple stmt = gsi_stmt (gsi);
551               if (is_gimple_call (stmt))
552                 update_stmt (stmt);
553             }
554         }
555
556       cfun->after_tree_profile = 1;
557       update_ssa (TODO_update_ssa);
558
559       rebuild_cgraph_edges ();
560
561       current_function_decl = NULL;
562       pop_cfun ();
563     }
564
565   del_node_map();
566   return 0;
567 }
568
569 /* When profile instrumentation, use or test coverage shall be performed.  */
570
571 static bool
572 gate_tree_profile_ipa (void)
573 {
574   return (!in_lto_p
575           && (flag_branch_probabilities || flag_test_coverage
576               || profile_arc_flag));
577 }
578
579 struct simple_ipa_opt_pass pass_ipa_tree_profile =
580 {
581  {
582   SIMPLE_IPA_PASS,
583   "profile",                           /* name */
584   gate_tree_profile_ipa,               /* gate */
585   tree_profiling,                      /* execute */
586   NULL,                                /* sub */
587   NULL,                                /* next */
588   0,                                   /* static_pass_number */
589   TV_IPA_PROFILE,                      /* tv_id */
590   0,                                   /* properties_required */
591   0,                                   /* properties_provided */
592   0,                                   /* properties_destroyed */
593   0,                                   /* todo_flags_start */
594   0                                    /* todo_flags_finish */
595  }
596 };
597
598 #include "gt-tree-profile.h"