In gcc/testsuite/: 2010-12-19 Nicola Pero <nicola.pero@meta-innovation.com>
[gcc.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"