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