1 /* Calculate branch probabilities, and basic block execution counts.
2 Copyright (C) 1990-2013 Free Software Foundation, Inc.
3 Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
4 based on some ideas from Dain Samples of UC Berkeley.
5 Further mangling by Bob Manson, Cygnus Support.
6 Converted to use trees by Dale Johannesen, Apple Computer.
8 This file is part of GCC.
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3. If not see
22 <http://www.gnu.org/licenses/>. */
24 /* Generate basic block profile instrumentation and auxiliary files.
25 Tree-based version. See profile.c for overview. */
29 #include "coretypes.h"
33 #include "basic-block.h"
34 #include "diagnostic-core.h"
37 #include "tree-flow.h"
38 #include "tree-pass.h"
39 #include "value-prof.h"
44 static GTY(()) tree gcov_type_node
;
45 static GTY(()) tree tree_interval_profiler_fn
;
46 static GTY(()) tree tree_pow2_profiler_fn
;
47 static GTY(()) tree tree_one_value_profiler_fn
;
48 static GTY(()) tree tree_indirect_call_profiler_fn
;
49 static GTY(()) tree tree_average_profiler_fn
;
50 static GTY(()) tree tree_ior_profiler_fn
;
53 static GTY(()) tree ic_void_ptr_var
;
54 static GTY(()) tree ic_gcov_type_ptr_var
;
55 static GTY(()) tree ptr_void
;
57 /* Do initialization work for the edge profiler. */
60 __thread gcov* __gcov_indirect_call_counters; // pointer to actual counter
61 __thread void* __gcov_indirect_call_callee; // actual callee address
64 init_ic_make_global_vars (void)
68 ptr_void
= build_pointer_type (void_type_node
);
70 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
74 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
75 get_identifier ("__gcov_indirect_call_callee_ltopriv"),
77 TREE_PUBLIC (ic_void_ptr_var
) = 1;
78 DECL_COMMON (ic_void_ptr_var
) = 1;
79 DECL_VISIBILITY (ic_void_ptr_var
) = VISIBILITY_HIDDEN
;
80 DECL_VISIBILITY_SPECIFIED (ic_void_ptr_var
) = true;
85 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
86 get_identifier ("__gcov_indirect_call_callee"),
88 TREE_PUBLIC (ic_void_ptr_var
) = 1;
89 DECL_EXTERNAL (ic_void_ptr_var
) = 1;
91 TREE_STATIC (ic_void_ptr_var
) = 1;
92 DECL_ARTIFICIAL (ic_void_ptr_var
) = 1;
93 DECL_INITIAL (ic_void_ptr_var
) = NULL
;
95 DECL_TLS_MODEL (ic_void_ptr_var
) =
96 decl_default_tls_model (ic_void_ptr_var
);
98 varpool_finalize_decl (ic_void_ptr_var
);
100 gcov_type_ptr
= build_pointer_type (get_gcov_type ());
101 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
105 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
106 get_identifier ("__gcov_indirect_call_counters_ltopriv"),
108 TREE_PUBLIC (ic_gcov_type_ptr_var
) = 1;
109 DECL_COMMON (ic_gcov_type_ptr_var
) = 1;
110 DECL_VISIBILITY (ic_gcov_type_ptr_var
) = VISIBILITY_HIDDEN
;
111 DECL_VISIBILITY_SPECIFIED (ic_gcov_type_ptr_var
) = true;
116 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
117 get_identifier ("__gcov_indirect_call_counters"),
119 TREE_PUBLIC (ic_gcov_type_ptr_var
) = 1;
120 DECL_EXTERNAL (ic_gcov_type_ptr_var
) = 1;
122 TREE_STATIC (ic_gcov_type_ptr_var
) = 1;
123 DECL_ARTIFICIAL (ic_gcov_type_ptr_var
) = 1;
124 DECL_INITIAL (ic_gcov_type_ptr_var
) = NULL
;
125 if (targetm
.have_tls
)
126 DECL_TLS_MODEL (ic_gcov_type_ptr_var
) =
127 decl_default_tls_model (ic_gcov_type_ptr_var
);
129 varpool_finalize_decl (ic_gcov_type_ptr_var
);
132 /* Create the type and function decls for the interface with gcov. */
135 gimple_init_edge_profiler (void)
137 tree interval_profiler_fn_type
;
138 tree pow2_profiler_fn_type
;
139 tree one_value_profiler_fn_type
;
141 tree ic_profiler_fn_type
;
142 tree average_profiler_fn_type
;
146 gcov_type_node
= get_gcov_type ();
147 gcov_type_ptr
= build_pointer_type (gcov_type_node
);
149 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
150 interval_profiler_fn_type
151 = build_function_type_list (void_type_node
,
152 gcov_type_ptr
, gcov_type_node
,
154 unsigned_type_node
, NULL_TREE
);
155 tree_interval_profiler_fn
156 = build_fn_decl ("__gcov_interval_profiler",
157 interval_profiler_fn_type
);
158 TREE_NOTHROW (tree_interval_profiler_fn
) = 1;
159 DECL_ATTRIBUTES (tree_interval_profiler_fn
)
160 = tree_cons (get_identifier ("leaf"), NULL
,
161 DECL_ATTRIBUTES (tree_interval_profiler_fn
));
163 /* void (*) (gcov_type *, gcov_type) */
164 pow2_profiler_fn_type
165 = build_function_type_list (void_type_node
,
166 gcov_type_ptr
, gcov_type_node
,
168 tree_pow2_profiler_fn
= build_fn_decl ("__gcov_pow2_profiler",
169 pow2_profiler_fn_type
);
170 TREE_NOTHROW (tree_pow2_profiler_fn
) = 1;
171 DECL_ATTRIBUTES (tree_pow2_profiler_fn
)
172 = tree_cons (get_identifier ("leaf"), NULL
,
173 DECL_ATTRIBUTES (tree_pow2_profiler_fn
));
175 /* void (*) (gcov_type *, gcov_type) */
176 one_value_profiler_fn_type
177 = build_function_type_list (void_type_node
,
178 gcov_type_ptr
, gcov_type_node
,
180 tree_one_value_profiler_fn
181 = build_fn_decl ("__gcov_one_value_profiler",
182 one_value_profiler_fn_type
);
183 TREE_NOTHROW (tree_one_value_profiler_fn
) = 1;
184 DECL_ATTRIBUTES (tree_one_value_profiler_fn
)
185 = tree_cons (get_identifier ("leaf"), NULL
,
186 DECL_ATTRIBUTES (tree_one_value_profiler_fn
));
188 init_ic_make_global_vars ();
190 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
193 /* void (*) (gcov_type, void *) */
195 = build_function_type_list (void_type_node
,
196 gcov_type_ptr
, gcov_type_node
,
199 tree_indirect_call_profiler_fn
200 = build_fn_decl ("__gcov_indirect_call_profiler",
201 ic_profiler_fn_type
);
205 /* void (*) (gcov_type, void *) */
207 = build_function_type_list (void_type_node
,
211 tree_indirect_call_profiler_fn
212 = build_fn_decl ("__gcov_indirect_call_profiler_v2",
213 ic_profiler_fn_type
);
215 TREE_NOTHROW (tree_indirect_call_profiler_fn
) = 1;
216 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn
)
217 = tree_cons (get_identifier ("leaf"), NULL
,
218 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn
));
220 /* void (*) (gcov_type *, gcov_type) */
221 average_profiler_fn_type
222 = build_function_type_list (void_type_node
,
223 gcov_type_ptr
, gcov_type_node
, NULL_TREE
);
224 tree_average_profiler_fn
225 = build_fn_decl ("__gcov_average_profiler",
226 average_profiler_fn_type
);
227 TREE_NOTHROW (tree_average_profiler_fn
) = 1;
228 DECL_ATTRIBUTES (tree_average_profiler_fn
)
229 = tree_cons (get_identifier ("leaf"), NULL
,
230 DECL_ATTRIBUTES (tree_average_profiler_fn
));
232 = build_fn_decl ("__gcov_ior_profiler",
233 average_profiler_fn_type
);
234 TREE_NOTHROW (tree_ior_profiler_fn
) = 1;
235 DECL_ATTRIBUTES (tree_ior_profiler_fn
)
236 = tree_cons (get_identifier ("leaf"), NULL
,
237 DECL_ATTRIBUTES (tree_ior_profiler_fn
));
239 /* LTO streamer needs assembler names. Because we create these decls
240 late, we need to initialize them by hand. */
241 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn
);
242 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn
);
243 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn
);
244 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn
);
245 DECL_ASSEMBLER_NAME (tree_average_profiler_fn
);
246 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn
);
250 /* Output instructions as GIMPLE trees to increment the edge
251 execution count, and insert them on E. We rely on
252 gsi_insert_on_edge to preserve the order. */
255 gimple_gen_edge_profiler (int edgeno
, edge e
)
257 tree ref
, one
, gcov_type_tmp_var
;
258 gimple stmt1
, stmt2
, stmt3
;
260 ref
= tree_coverage_counter_ref (GCOV_COUNTER_ARCS
, edgeno
);
261 one
= build_int_cst (gcov_type_node
, 1);
262 gcov_type_tmp_var
= make_temp_ssa_name (gcov_type_node
,
263 NULL
, "PROF_edge_counter");
264 stmt1
= gimple_build_assign (gcov_type_tmp_var
, ref
);
265 gcov_type_tmp_var
= make_temp_ssa_name (gcov_type_node
,
266 NULL
, "PROF_edge_counter");
267 stmt2
= gimple_build_assign_with_ops (PLUS_EXPR
, gcov_type_tmp_var
,
268 gimple_assign_lhs (stmt1
), one
);
269 stmt3
= gimple_build_assign (unshare_expr (ref
), gimple_assign_lhs (stmt2
));
270 gsi_insert_on_edge (e
, stmt1
);
271 gsi_insert_on_edge (e
, stmt2
);
272 gsi_insert_on_edge (e
, stmt3
);
275 /* Emits code to get VALUE to instrument at GSI, and returns the
276 variable containing the value. */
279 prepare_instrumented_value (gimple_stmt_iterator
*gsi
, histogram_value value
)
281 tree val
= value
->hvalue
.value
;
282 if (POINTER_TYPE_P (TREE_TYPE (val
)))
283 val
= fold_convert (build_nonstandard_integer_type
284 (TYPE_PRECISION (TREE_TYPE (val
)), 1), val
);
285 return force_gimple_operand_gsi (gsi
, fold_convert (gcov_type_node
, val
),
286 true, NULL_TREE
, true, GSI_SAME_STMT
);
289 /* Output instructions as GIMPLE trees to increment the interval histogram
290 counter. VALUE is the expression whose value is profiled. TAG is the
291 tag of the section for counters, BASE is offset of the counter position. */
294 gimple_gen_interval_profiler (histogram_value value
, unsigned tag
, unsigned base
)
296 gimple stmt
= value
->hvalue
.stmt
;
297 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
298 tree ref
= tree_coverage_counter_ref (tag
, base
), ref_ptr
;
301 tree start
= build_int_cst_type (integer_type_node
,
302 value
->hdata
.intvl
.int_start
);
303 tree steps
= build_int_cst_type (unsigned_type_node
,
304 value
->hdata
.intvl
.steps
);
306 ref_ptr
= force_gimple_operand_gsi (&gsi
,
307 build_addr (ref
, current_function_decl
),
308 true, NULL_TREE
, true, GSI_SAME_STMT
);
309 val
= prepare_instrumented_value (&gsi
, value
);
310 call
= gimple_build_call (tree_interval_profiler_fn
, 4,
311 ref_ptr
, val
, start
, steps
);
312 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
315 /* Output instructions as GIMPLE trees to increment the power of two histogram
316 counter. VALUE is the expression whose value is profiled. TAG is the tag
317 of the section for counters, BASE is offset of the counter position. */
320 gimple_gen_pow2_profiler (histogram_value value
, unsigned tag
, unsigned base
)
322 gimple stmt
= value
->hvalue
.stmt
;
323 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
324 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
328 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
329 true, NULL_TREE
, true, GSI_SAME_STMT
);
330 val
= prepare_instrumented_value (&gsi
, value
);
331 call
= gimple_build_call (tree_pow2_profiler_fn
, 2, ref_ptr
, val
);
332 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
335 /* Output instructions as GIMPLE trees for code to find the most common value.
336 VALUE is the expression whose value is profiled. TAG is the tag of the
337 section for counters, BASE is offset of the counter position. */
340 gimple_gen_one_value_profiler (histogram_value value
, unsigned tag
, unsigned base
)
342 gimple stmt
= value
->hvalue
.stmt
;
343 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
344 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
348 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
349 true, NULL_TREE
, true, GSI_SAME_STMT
);
350 val
= prepare_instrumented_value (&gsi
, value
);
351 call
= gimple_build_call (tree_one_value_profiler_fn
, 2, ref_ptr
, val
);
352 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
356 /* Output instructions as GIMPLE trees for code to find the most
357 common called function in indirect call.
358 VALUE is the call expression whose indirect callee is profiled.
359 TAG is the tag of the section for counters, BASE is offset of the
363 gimple_gen_ic_profiler (histogram_value value
, unsigned tag
, unsigned base
)
366 gimple stmt1
, stmt2
, stmt3
;
367 gimple stmt
= value
->hvalue
.stmt
;
368 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
369 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
371 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
372 true, NULL_TREE
, true, GSI_SAME_STMT
);
376 stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
377 stmt2: tmp1 = (void *) (indirect call argument value)
378 stmt3: __gcov_indirect_call_callee = tmp1;
381 stmt1
= gimple_build_assign (ic_gcov_type_ptr_var
, ref_ptr
);
382 tmp1
= make_temp_ssa_name (ptr_void
, NULL
, "PROF");
383 stmt2
= gimple_build_assign (tmp1
, unshare_expr (value
->hvalue
.value
));
384 stmt3
= gimple_build_assign (ic_void_ptr_var
, gimple_assign_lhs (stmt2
));
386 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
387 gsi_insert_before (&gsi
, stmt2
, GSI_SAME_STMT
);
388 gsi_insert_before (&gsi
, stmt3
, GSI_SAME_STMT
);
392 /* Output instructions as GIMPLE trees for code to find the most
393 common called function in indirect call. Insert instructions at the
394 beginning of every possible called function.
398 gimple_gen_ic_func_profiler (void)
400 struct cgraph_node
* c_node
= cgraph_get_node (current_function_decl
);
401 gimple_stmt_iterator gsi
;
403 tree tree_uid
, cur_func
, void0
;
405 if (cgraph_only_called_directly_p (c_node
))
408 gimple_init_edge_profiler ();
412 stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
413 ¤t_function_decl)
415 gsi
= gsi_after_labels (split_edge (single_succ_edge (ENTRY_BLOCK_PTR
)));
417 cur_func
= force_gimple_operand_gsi (&gsi
,
418 build_addr (current_function_decl
,
419 current_function_decl
),
421 true, GSI_SAME_STMT
);
422 tree_uid
= build_int_cst
423 (gcov_type_node
, cgraph_get_node (current_function_decl
)->profile_id
);
424 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
427 tree counter_ptr
, ptr_var
;
428 counter_ptr
= force_gimple_operand_gsi (&gsi
, ic_gcov_type_ptr_var
,
429 true, NULL_TREE
, true,
431 ptr_var
= force_gimple_operand_gsi (&gsi
, ic_void_ptr_var
,
432 true, NULL_TREE
, true,
435 stmt1
= gimple_build_call (tree_indirect_call_profiler_fn
, 4,
436 counter_ptr
, tree_uid
, cur_func
, ptr_var
);
440 stmt1
= gimple_build_call (tree_indirect_call_profiler_fn
, 2,
443 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
445 /* Set __gcov_indirect_call_callee to 0,
446 so that calls from other modules won't get misattributed
447 to the last caller of the current callee. */
448 void0
= build_int_cst (build_pointer_type (void_type_node
), 0);
449 stmt2
= gimple_build_assign (ic_void_ptr_var
, void0
);
450 gsi_insert_before (&gsi
, stmt2
, GSI_SAME_STMT
);
453 /* Output instructions as GIMPLE trees for code to find the most common value
454 of a difference between two evaluations of an expression.
455 VALUE is the expression whose value is profiled. TAG is the tag of the
456 section for counters, BASE is offset of the counter position. */
459 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED
,
460 unsigned tag ATTRIBUTE_UNUSED
,
461 unsigned base ATTRIBUTE_UNUSED
)
463 /* FIXME implement this. */
464 #ifdef ENABLE_CHECKING
465 internal_error ("unimplemented functionality");
470 /* Output instructions as GIMPLE trees to increment the average histogram
471 counter. VALUE is the expression whose value is profiled. TAG is the
472 tag of the section for counters, BASE is offset of the counter position. */
475 gimple_gen_average_profiler (histogram_value value
, unsigned tag
, unsigned base
)
477 gimple stmt
= value
->hvalue
.stmt
;
478 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
479 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
483 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
485 true, GSI_SAME_STMT
);
486 val
= prepare_instrumented_value (&gsi
, value
);
487 call
= gimple_build_call (tree_average_profiler_fn
, 2, ref_ptr
, val
);
488 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
491 /* Output instructions as GIMPLE trees to increment the ior histogram
492 counter. VALUE is the expression whose value is profiled. TAG is the
493 tag of the section for counters, BASE is offset of the counter position. */
496 gimple_gen_ior_profiler (histogram_value value
, unsigned tag
, unsigned base
)
498 gimple stmt
= value
->hvalue
.stmt
;
499 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
500 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
504 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
505 true, NULL_TREE
, true, GSI_SAME_STMT
);
506 val
= prepare_instrumented_value (&gsi
, value
);
507 call
= gimple_build_call (tree_ior_profiler_fn
, 2, ref_ptr
, val
);
508 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
511 /* Profile all functions in the callgraph. */
514 tree_profiling (void)
516 struct cgraph_node
*node
;
518 /* This is a small-ipa pass that gets called only once, from
519 cgraphunit.c:ipa_passes(). */
520 gcc_assert (cgraph_state
== CGRAPH_STATE_IPA_SSA
);
522 init_node_map (true);
524 FOR_EACH_DEFINED_FUNCTION (node
)
526 if (!gimple_has_body_p (node
->symbol
.decl
))
529 /* Don't profile functions produced for builtin stuff. */
530 if (DECL_SOURCE_LOCATION (node
->symbol
.decl
) == BUILTINS_LOCATION
)
533 push_cfun (DECL_STRUCT_FUNCTION (node
->symbol
.decl
));
535 /* Local pure-const may imply need to fixup the cfg. */
536 if (execute_fixup_cfg () & TODO_cleanup_cfg
)
541 if (! flag_branch_probabilities
542 && flag_profile_values
)
543 gimple_gen_ic_func_profiler ();
545 if (flag_branch_probabilities
546 && flag_profile_values
547 && flag_value_profile_transformations
)
548 gimple_value_profile_transformations ();
550 /* The above could hose dominator info. Currently there is
551 none coming in, this is a safety valve. It should be
552 easy to adjust it, if and when there is some. */
553 free_dominance_info (CDI_DOMINATORS
);
554 free_dominance_info (CDI_POST_DOMINATORS
);
558 /* Drop pure/const flags from instrumented functions. */
559 FOR_EACH_DEFINED_FUNCTION (node
)
561 if (!gimple_has_body_p (node
->symbol
.decl
)
563 || node
->symbol
.decl
!= node
->clone_of
->symbol
.decl
))
566 /* Don't profile functions produced for builtin stuff. */
567 if (DECL_SOURCE_LOCATION (node
->symbol
.decl
) == BUILTINS_LOCATION
)
570 cgraph_set_const_flag (node
, false, false);
571 cgraph_set_pure_flag (node
, false, false);
574 /* Update call statements and rebuild the cgraph. */
575 FOR_EACH_DEFINED_FUNCTION (node
)
579 if (!gimple_has_body_p (node
->symbol
.decl
)
581 || node
->symbol
.decl
!= node
->clone_of
->symbol
.decl
))
584 /* Don't profile functions produced for builtin stuff. */
585 if (DECL_SOURCE_LOCATION (node
->symbol
.decl
) == BUILTINS_LOCATION
)
588 push_cfun (DECL_STRUCT_FUNCTION (node
->symbol
.decl
));
592 gimple_stmt_iterator gsi
;
593 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
595 gimple stmt
= gsi_stmt (gsi
);
596 if (is_gimple_call (stmt
))
601 update_ssa (TODO_update_ssa
);
603 rebuild_cgraph_edges ();
612 /* When profile instrumentation, use or test coverage shall be performed. */
615 gate_tree_profile_ipa (void)
618 && (flag_branch_probabilities
|| flag_test_coverage
619 || profile_arc_flag
));
624 const pass_data pass_data_ipa_tree_profile
=
626 SIMPLE_IPA_PASS
, /* type */
627 "profile", /* name */
628 OPTGROUP_NONE
, /* optinfo_flags */
630 true, /* has_execute */
631 TV_IPA_PROFILE
, /* tv_id */
632 0, /* properties_required */
633 0, /* properties_provided */
634 0, /* properties_destroyed */
635 0, /* todo_flags_start */
636 0, /* todo_flags_finish */
639 class pass_ipa_tree_profile
: public simple_ipa_opt_pass
642 pass_ipa_tree_profile(gcc::context
*ctxt
)
643 : simple_ipa_opt_pass(pass_data_ipa_tree_profile
, ctxt
)
646 /* opt_pass methods: */
647 bool gate () { return gate_tree_profile_ipa (); }
648 unsigned int execute () { return tree_profiling (); }
650 }; // class pass_ipa_tree_profile
654 simple_ipa_opt_pass
*
655 make_pass_ipa_tree_profile (gcc::context
*ctxt
)
657 return new pass_ipa_tree_profile (ctxt
);
660 #include "gt-tree-profile.h"