OSDN Git Service

Fix r179381: add missing period in testsuite/Changelog.
[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 (build_nonstandard_integer_type
245                           (TYPE_PRECISION (TREE_TYPE (val)), 1), val);
246   return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
247                                    true, NULL_TREE, true, GSI_SAME_STMT);
248 }
249
250 /* Output instructions as GIMPLE trees to increment the interval histogram
251    counter.  VALUE is the expression whose value is profiled.  TAG is the
252    tag of the section for counters, BASE is offset of the counter position.  */
253
254 void
255 gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
256 {
257   gimple stmt = value->hvalue.stmt;
258   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
259   tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
260   gimple call;
261   tree val;
262   tree start = build_int_cst_type (integer_type_node,
263                                    value->hdata.intvl.int_start);
264   tree steps = build_int_cst_type (unsigned_type_node,
265                                    value->hdata.intvl.steps);
266
267   ref_ptr = force_gimple_operand_gsi (&gsi,
268                                       build_addr (ref, current_function_decl),
269                                       true, NULL_TREE, true, GSI_SAME_STMT);
270   val = prepare_instrumented_value (&gsi, value);
271   call = gimple_build_call (tree_interval_profiler_fn, 4,
272                             ref_ptr, val, start, steps);
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   gsi_insert_before (&gsi, call, GSI_NEW_STMT);
294 }
295
296 /* Output instructions as GIMPLE trees for code to find the most common value.
297    VALUE is the expression whose value is profiled.  TAG is the tag of the
298    section for counters, BASE is offset of the counter position.  */
299
300 void
301 gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
302 {
303   gimple stmt = value->hvalue.stmt;
304   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
305   tree ref_ptr = tree_coverage_counter_addr (tag, base);
306   gimple call;
307   tree val;
308
309   ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
310                                       true, NULL_TREE, true, GSI_SAME_STMT);
311   val = prepare_instrumented_value (&gsi, value);
312   call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val);
313   gsi_insert_before (&gsi, call, GSI_NEW_STMT);
314 }
315
316
317 /* Output instructions as GIMPLE trees for code to find the most
318    common called function in indirect call.
319    VALUE is the call expression whose indirect callee is profiled.
320    TAG is the tag of the section for counters, BASE is offset of the
321    counter position.  */
322
323 void
324 gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
325 {
326   tree tmp1;
327   gimple stmt1, stmt2, stmt3;
328   gimple stmt = value->hvalue.stmt;
329   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
330   tree ref_ptr = tree_coverage_counter_addr (tag, base);
331
332   ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
333                                       true, NULL_TREE, true, GSI_SAME_STMT);
334
335   /* Insert code:
336
337     __gcov_indirect_call_counters = get_relevant_counter_ptr ();
338     __gcov_indirect_call_callee = (void *) indirect call argument;
339    */
340
341   tmp1 = create_tmp_reg (ptr_void, "PROF");
342   stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr);
343   stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
344   gimple_assign_set_lhs (stmt2, make_ssa_name (tmp1, 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   gsi_insert_before (&gsi, call, GSI_NEW_STMT);
433 }
434
435 /* Output instructions as GIMPLE trees to increment the ior histogram
436    counter.  VALUE is the expression whose value is profiled.  TAG is the
437    tag of the section for counters, BASE is offset of the counter position.  */
438
439 void
440 gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
441 {
442   gimple stmt = value->hvalue.stmt;
443   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
444   tree ref_ptr = tree_coverage_counter_addr (tag, base);
445   gimple call;
446   tree val;
447
448   ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
449                                       true, NULL_TREE, true, GSI_SAME_STMT);
450   val = prepare_instrumented_value (&gsi, value);
451   call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
452   gsi_insert_before (&gsi, call, GSI_NEW_STMT);
453 }
454
455 /* Profile all functions in the callgraph.  */
456
457 static unsigned int
458 tree_profiling (void)
459 {
460   struct cgraph_node *node;
461
462   /* Don't profile functions produced at destruction time, particularly
463      the gcov datastructure initializer.  Don't profile if it has been
464      already instrumented either (when OpenMP expansion creates
465      child function from already instrumented body).  */
466   if (cgraph_state == CGRAPH_STATE_FINISHED)
467     return 0;
468
469   init_node_map();
470
471   for (node = cgraph_nodes; node; node = node->next)
472     {
473       if (!node->analyzed
474           || !gimple_has_body_p (node->decl))
475         continue;
476
477       /* Don't profile functions produced for builtin stuff.  */
478       if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION
479           || DECL_STRUCT_FUNCTION (node->decl)->after_tree_profile)
480         continue;
481
482       push_cfun (DECL_STRUCT_FUNCTION (node->decl));
483       current_function_decl = node->decl;
484
485       /* Re-set global shared temporary variable for edge-counters.  */
486       gcov_type_tmp_var = NULL_TREE;
487
488       /* Local pure-const may imply need to fixup the cfg.  */
489       execute_fixup_cfg ();
490       branch_prob ();
491
492       if (! flag_branch_probabilities
493           && flag_profile_values)
494         gimple_gen_ic_func_profiler ();
495
496       if (flag_branch_probabilities
497           && flag_profile_values
498           && flag_value_profile_transformations)
499         gimple_value_profile_transformations ();
500
501       /* The above could hose dominator info.  Currently there is
502          none coming in, this is a safety valve.  It should be
503          easy to adjust it, if and when there is some.  */
504       free_dominance_info (CDI_DOMINATORS);
505       free_dominance_info (CDI_POST_DOMINATORS);
506
507       current_function_decl = NULL;
508       pop_cfun ();
509     }
510
511   /* Drop pure/const flags from instrumented functions.  */
512   for (node = cgraph_nodes; node; node = node->next)
513     {
514       if (!node->analyzed
515           || !gimple_has_body_p (node->decl)
516           || !(!node->clone_of || node->decl != node->clone_of->decl))
517         continue;
518
519       /* Don't profile functions produced for builtin stuff.  */
520       if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION
521           || DECL_STRUCT_FUNCTION (node->decl)->after_tree_profile)
522         continue;
523
524       cgraph_set_const_flag (node, false, false);
525       cgraph_set_pure_flag (node, false, false);
526     }
527
528   /* Update call statements and rebuild the cgraph.  */
529   for (node = cgraph_nodes; node; node = node->next)
530     {
531       basic_block bb;
532
533       if (!node->analyzed
534           || !gimple_has_body_p (node->decl)
535           || !(!node->clone_of || node->decl != node->clone_of->decl))
536         continue;
537
538       /* Don't profile functions produced for builtin stuff.  */
539       if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION
540           || DECL_STRUCT_FUNCTION (node->decl)->after_tree_profile)
541         continue;
542
543       push_cfun (DECL_STRUCT_FUNCTION (node->decl));
544       current_function_decl = node->decl;
545
546       FOR_EACH_BB (bb)
547         {
548           gimple_stmt_iterator gsi;
549           for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
550             {
551               gimple stmt = gsi_stmt (gsi);
552               if (is_gimple_call (stmt))
553                 update_stmt (stmt);
554             }
555         }
556
557       cfun->after_tree_profile = 1;
558       update_ssa (TODO_update_ssa);
559
560       rebuild_cgraph_edges ();
561
562       current_function_decl = NULL;
563       pop_cfun ();
564     }
565
566   del_node_map();
567   return 0;
568 }
569
570 /* When profile instrumentation, use or test coverage shall be performed.  */
571
572 static bool
573 gate_tree_profile_ipa (void)
574 {
575   return (!in_lto_p
576           && (flag_branch_probabilities || flag_test_coverage
577               || profile_arc_flag));
578 }
579
580 struct simple_ipa_opt_pass pass_ipa_tree_profile =
581 {
582  {
583   SIMPLE_IPA_PASS,
584   "profile",                           /* name */
585   gate_tree_profile_ipa,               /* gate */
586   tree_profiling,                      /* execute */
587   NULL,                                /* sub */
588   NULL,                                /* next */
589   0,                                   /* static_pass_number */
590   TV_IPA_PROFILE,                      /* tv_id */
591   0,                                   /* properties_required */
592   0,                                   /* properties_provided */
593   0,                                   /* properties_destroyed */
594   0,                                   /* todo_flags_start */
595   0                                    /* todo_flags_finish */
596  }
597 };
598
599 #include "gt-tree-profile.h"