OSDN Git Service

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