OSDN Git Service

use tls for ic vars
[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           || !(!node->clone_of || node->decl != node->clone_of->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       branch_prob ();
489
490       if (! flag_branch_probabilities
491           && flag_profile_values)
492         gimple_gen_ic_func_profiler ();
493
494       if (flag_branch_probabilities
495           && flag_profile_values
496           && flag_value_profile_transformations)
497         gimple_value_profile_transformations ();
498
499       /* The above could hose dominator info.  Currently there is
500          none coming in, this is a safety valve.  It should be
501          easy to adjust it, if and when there is some.  */
502       free_dominance_info (CDI_DOMINATORS);
503       free_dominance_info (CDI_POST_DOMINATORS);
504
505       current_function_decl = NULL;
506       pop_cfun ();
507     }
508
509   /* Drop pure/const flags from instrumented functions.  */
510   for (node = cgraph_nodes; node; node = node->next)
511     {
512       if (!node->analyzed
513           || !gimple_has_body_p (node->decl)
514           || !(!node->clone_of || node->decl != node->clone_of->decl))
515         continue;
516
517       /* Don't profile functions produced for builtin stuff.  */
518       if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION
519           || DECL_STRUCT_FUNCTION (node->decl)->after_tree_profile)
520         continue;
521
522       cgraph_set_const_flag (node, false, false);
523       cgraph_set_pure_flag (node, false, false);
524     }
525
526   /* Update call statements and rebuild the cgraph.  */
527   for (node = cgraph_nodes; node; node = node->next)
528     {
529       basic_block bb;
530
531       if (!node->analyzed
532           || !gimple_has_body_p (node->decl)
533           || !(!node->clone_of || node->decl != node->clone_of->decl))
534         continue;
535
536       /* Don't profile functions produced for builtin stuff.  */
537       if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION
538           || DECL_STRUCT_FUNCTION (node->decl)->after_tree_profile)
539         continue;
540
541       push_cfun (DECL_STRUCT_FUNCTION (node->decl));
542       current_function_decl = node->decl;
543
544       FOR_EACH_BB (bb)
545         {
546           gimple_stmt_iterator gsi;
547           for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
548             {
549               gimple stmt = gsi_stmt (gsi);
550               if (is_gimple_call (stmt))
551                 update_stmt (stmt);
552             }
553         }
554
555       cfun->after_tree_profile = 1;
556       update_ssa (TODO_update_ssa);
557
558       rebuild_cgraph_edges ();
559
560       current_function_decl = NULL;
561       pop_cfun ();
562     }
563
564   del_node_map();
565   return 0;
566 }
567
568 /* When profile instrumentation, use or test coverage shall be performed.  */
569
570 static bool
571 gate_tree_profile_ipa (void)
572 {
573   return (!in_lto_p
574           && (flag_branch_probabilities || flag_test_coverage
575               || profile_arc_flag));
576 }
577
578 struct simple_ipa_opt_pass pass_ipa_tree_profile =
579 {
580  {
581   SIMPLE_IPA_PASS,
582   "tree_profile_ipa",                  /* name */
583   gate_tree_profile_ipa,               /* gate */
584   tree_profiling,                      /* execute */
585   NULL,                                /* sub */
586   NULL,                                /* next */
587   0,                                   /* static_pass_number */
588   TV_IPA_PROFILE,                      /* tv_id */
589   0,                                   /* properties_required */
590   0,                                   /* properties_provided */
591   0,                                   /* properties_destroyed */
592   0,                                   /* todo_flags_start */
593   TODO_dump_func                       /* todo_flags_finish */
594  }
595 };
596
597 #include "gt-tree-profile.h"