OSDN Git Service

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