1 /* Calculate branch probabilities, and basic block execution counts.
2 Copyright (C) 1990-2015 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"
34 #include "hard-reg-set.h"
37 #include "diagnostic-core.h"
40 #include "fold-const.h"
41 #include "internal-fn.h"
43 #include "tree-nested.h"
45 #include "gimple-iterator.h"
46 #include "gimplify-me.h"
49 #include "tree-into-ssa.h"
50 #include "tree-pass.h"
51 #include "value-prof.h"
54 #include "tree-cfgcleanup.h"
55 #include "tree-nested.h"
58 static GTY(()) tree gcov_type_node
;
59 static GTY(()) tree tree_interval_profiler_fn
;
60 static GTY(()) tree tree_pow2_profiler_fn
;
61 static GTY(()) tree tree_one_value_profiler_fn
;
62 static GTY(()) tree tree_indirect_call_profiler_fn
;
63 static GTY(()) tree tree_time_profiler_fn
;
64 static GTY(()) tree tree_average_profiler_fn
;
65 static GTY(()) tree tree_ior_profiler_fn
;
68 static GTY(()) tree ic_void_ptr_var
;
69 static GTY(()) tree ic_gcov_type_ptr_var
;
70 static GTY(()) tree ptr_void
;
72 /* Do initialization work for the edge profiler. */
75 __thread gcov* __gcov_indirect_call_counters; // pointer to actual counter
76 __thread void* __gcov_indirect_call_callee; // actual callee address
77 __thread int __gcov_function_counter; // time profiler function counter
80 init_ic_make_global_vars (void)
84 ptr_void
= build_pointer_type (void_type_node
);
87 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
89 (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE
) ?
90 "__gcov_indirect_call_topn_callee" :
91 "__gcov_indirect_call_callee")),
93 TREE_PUBLIC (ic_void_ptr_var
) = 1;
94 DECL_EXTERNAL (ic_void_ptr_var
) = 1;
95 TREE_STATIC (ic_void_ptr_var
) = 1;
96 DECL_ARTIFICIAL (ic_void_ptr_var
) = 1;
97 DECL_INITIAL (ic_void_ptr_var
) = NULL
;
99 set_decl_tls_model (ic_void_ptr_var
, decl_default_tls_model (ic_void_ptr_var
));
101 varpool_node::finalize_decl (ic_void_ptr_var
);
103 gcov_type_ptr
= build_pointer_type (get_gcov_type ());
106 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
108 (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE
) ?
109 "__gcov_indirect_call_topn_counters" :
110 "__gcov_indirect_call_counters")),
112 TREE_PUBLIC (ic_gcov_type_ptr_var
) = 1;
113 DECL_EXTERNAL (ic_gcov_type_ptr_var
) = 1;
114 TREE_STATIC (ic_gcov_type_ptr_var
) = 1;
115 DECL_ARTIFICIAL (ic_gcov_type_ptr_var
) = 1;
116 DECL_INITIAL (ic_gcov_type_ptr_var
) = NULL
;
117 if (targetm
.have_tls
)
118 set_decl_tls_model (ic_gcov_type_ptr_var
, decl_default_tls_model (ic_gcov_type_ptr_var
));
120 varpool_node::finalize_decl (ic_gcov_type_ptr_var
);
123 /* Create the type and function decls for the interface with gcov. */
126 gimple_init_edge_profiler (void)
128 tree interval_profiler_fn_type
;
129 tree pow2_profiler_fn_type
;
130 tree one_value_profiler_fn_type
;
132 tree ic_profiler_fn_type
;
133 tree average_profiler_fn_type
;
134 tree time_profiler_fn_type
;
138 gcov_type_node
= get_gcov_type ();
139 gcov_type_ptr
= build_pointer_type (gcov_type_node
);
141 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
142 interval_profiler_fn_type
143 = build_function_type_list (void_type_node
,
144 gcov_type_ptr
, gcov_type_node
,
146 unsigned_type_node
, NULL_TREE
);
147 tree_interval_profiler_fn
148 = build_fn_decl ("__gcov_interval_profiler",
149 interval_profiler_fn_type
);
150 TREE_NOTHROW (tree_interval_profiler_fn
) = 1;
151 DECL_ATTRIBUTES (tree_interval_profiler_fn
)
152 = tree_cons (get_identifier ("leaf"), NULL
,
153 DECL_ATTRIBUTES (tree_interval_profiler_fn
));
155 /* void (*) (gcov_type *, gcov_type) */
156 pow2_profiler_fn_type
157 = build_function_type_list (void_type_node
,
158 gcov_type_ptr
, gcov_type_node
,
160 tree_pow2_profiler_fn
= build_fn_decl ("__gcov_pow2_profiler",
161 pow2_profiler_fn_type
);
162 TREE_NOTHROW (tree_pow2_profiler_fn
) = 1;
163 DECL_ATTRIBUTES (tree_pow2_profiler_fn
)
164 = tree_cons (get_identifier ("leaf"), NULL
,
165 DECL_ATTRIBUTES (tree_pow2_profiler_fn
));
167 /* void (*) (gcov_type *, gcov_type) */
168 one_value_profiler_fn_type
169 = build_function_type_list (void_type_node
,
170 gcov_type_ptr
, gcov_type_node
,
172 tree_one_value_profiler_fn
173 = build_fn_decl ("__gcov_one_value_profiler",
174 one_value_profiler_fn_type
);
175 TREE_NOTHROW (tree_one_value_profiler_fn
) = 1;
176 DECL_ATTRIBUTES (tree_one_value_profiler_fn
)
177 = tree_cons (get_identifier ("leaf"), NULL
,
178 DECL_ATTRIBUTES (tree_one_value_profiler_fn
));
180 init_ic_make_global_vars ();
182 /* void (*) (gcov_type, void *) */
184 = build_function_type_list (void_type_node
,
188 tree_indirect_call_profiler_fn
189 = build_fn_decl ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE
) ?
190 "__gcov_indirect_call_topn_profiler":
191 "__gcov_indirect_call_profiler_v2"),
192 ic_profiler_fn_type
);
194 TREE_NOTHROW (tree_indirect_call_profiler_fn
) = 1;
195 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn
)
196 = tree_cons (get_identifier ("leaf"), NULL
,
197 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn
));
199 /* void (*) (gcov_type *, gcov_type, void *) */
200 time_profiler_fn_type
201 = build_function_type_list (void_type_node
,
202 gcov_type_ptr
, NULL_TREE
);
203 tree_time_profiler_fn
204 = build_fn_decl ("__gcov_time_profiler",
205 time_profiler_fn_type
);
206 TREE_NOTHROW (tree_time_profiler_fn
) = 1;
207 DECL_ATTRIBUTES (tree_time_profiler_fn
)
208 = tree_cons (get_identifier ("leaf"), NULL
,
209 DECL_ATTRIBUTES (tree_time_profiler_fn
));
211 /* void (*) (gcov_type *, gcov_type) */
212 average_profiler_fn_type
213 = build_function_type_list (void_type_node
,
214 gcov_type_ptr
, gcov_type_node
, NULL_TREE
);
215 tree_average_profiler_fn
216 = build_fn_decl ("__gcov_average_profiler",
217 average_profiler_fn_type
);
218 TREE_NOTHROW (tree_average_profiler_fn
) = 1;
219 DECL_ATTRIBUTES (tree_average_profiler_fn
)
220 = tree_cons (get_identifier ("leaf"), NULL
,
221 DECL_ATTRIBUTES (tree_average_profiler_fn
));
223 = build_fn_decl ("__gcov_ior_profiler",
224 average_profiler_fn_type
);
225 TREE_NOTHROW (tree_ior_profiler_fn
) = 1;
226 DECL_ATTRIBUTES (tree_ior_profiler_fn
)
227 = tree_cons (get_identifier ("leaf"), NULL
,
228 DECL_ATTRIBUTES (tree_ior_profiler_fn
));
230 /* LTO streamer needs assembler names. Because we create these decls
231 late, we need to initialize them by hand. */
232 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn
);
233 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn
);
234 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn
);
235 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn
);
236 DECL_ASSEMBLER_NAME (tree_time_profiler_fn
);
237 DECL_ASSEMBLER_NAME (tree_average_profiler_fn
);
238 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn
);
242 /* Output instructions as GIMPLE trees to increment the edge
243 execution count, and insert them on E. We rely on
244 gsi_insert_on_edge to preserve the order. */
247 gimple_gen_edge_profiler (int edgeno
, edge e
)
249 tree ref
, one
, gcov_type_tmp_var
;
250 gassign
*stmt1
, *stmt2
, *stmt3
;
252 ref
= tree_coverage_counter_ref (GCOV_COUNTER_ARCS
, edgeno
);
253 one
= build_int_cst (gcov_type_node
, 1);
254 gcov_type_tmp_var
= make_temp_ssa_name (gcov_type_node
,
255 NULL
, "PROF_edge_counter");
256 stmt1
= gimple_build_assign (gcov_type_tmp_var
, ref
);
257 gcov_type_tmp_var
= make_temp_ssa_name (gcov_type_node
,
258 NULL
, "PROF_edge_counter");
259 stmt2
= gimple_build_assign (gcov_type_tmp_var
, PLUS_EXPR
,
260 gimple_assign_lhs (stmt1
), one
);
261 stmt3
= gimple_build_assign (unshare_expr (ref
), gimple_assign_lhs (stmt2
));
262 gsi_insert_on_edge (e
, stmt1
);
263 gsi_insert_on_edge (e
, stmt2
);
264 gsi_insert_on_edge (e
, stmt3
);
267 /* Emits code to get VALUE to instrument at GSI, and returns the
268 variable containing the value. */
271 prepare_instrumented_value (gimple_stmt_iterator
*gsi
, histogram_value value
)
273 tree val
= value
->hvalue
.value
;
274 if (POINTER_TYPE_P (TREE_TYPE (val
)))
275 val
= fold_convert (build_nonstandard_integer_type
276 (TYPE_PRECISION (TREE_TYPE (val
)), 1), val
);
277 return force_gimple_operand_gsi (gsi
, fold_convert (gcov_type_node
, val
),
278 true, NULL_TREE
, true, GSI_SAME_STMT
);
281 /* Output instructions as GIMPLE trees to increment the interval histogram
282 counter. VALUE is the expression whose value is profiled. TAG is the
283 tag of the section for counters, BASE is offset of the counter position. */
286 gimple_gen_interval_profiler (histogram_value value
, unsigned tag
, unsigned base
)
288 gimple stmt
= value
->hvalue
.stmt
;
289 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
290 tree ref
= tree_coverage_counter_ref (tag
, base
), ref_ptr
;
293 tree start
= build_int_cst_type (integer_type_node
,
294 value
->hdata
.intvl
.int_start
);
295 tree steps
= build_int_cst_type (unsigned_type_node
,
296 value
->hdata
.intvl
.steps
);
298 ref_ptr
= force_gimple_operand_gsi (&gsi
,
299 build_addr (ref
, current_function_decl
),
300 true, NULL_TREE
, true, GSI_SAME_STMT
);
301 val
= prepare_instrumented_value (&gsi
, value
);
302 call
= gimple_build_call (tree_interval_profiler_fn
, 4,
303 ref_ptr
, val
, start
, steps
);
304 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
307 /* Output instructions as GIMPLE trees to increment the power of two histogram
308 counter. VALUE is the expression whose value is profiled. TAG is the tag
309 of the section for counters, BASE is offset of the counter position. */
312 gimple_gen_pow2_profiler (histogram_value value
, unsigned tag
, unsigned base
)
314 gimple stmt
= value
->hvalue
.stmt
;
315 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
316 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
320 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
321 true, NULL_TREE
, true, GSI_SAME_STMT
);
322 val
= prepare_instrumented_value (&gsi
, value
);
323 call
= gimple_build_call (tree_pow2_profiler_fn
, 2, ref_ptr
, val
);
324 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
327 /* Output instructions as GIMPLE trees for code to find the most common value.
328 VALUE is the expression whose value is profiled. TAG is the tag of the
329 section for counters, BASE is offset of the counter position. */
332 gimple_gen_one_value_profiler (histogram_value value
, unsigned tag
, unsigned base
)
334 gimple stmt
= value
->hvalue
.stmt
;
335 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
336 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
340 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
341 true, NULL_TREE
, true, GSI_SAME_STMT
);
342 val
= prepare_instrumented_value (&gsi
, value
);
343 call
= gimple_build_call (tree_one_value_profiler_fn
, 2, ref_ptr
, val
);
344 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
348 /* Output instructions as GIMPLE trees for code to find the most
349 common called function in indirect call.
350 VALUE is the call expression whose indirect callee is profiled.
351 TAG is the tag of the section for counters, BASE is offset of the
355 gimple_gen_ic_profiler (histogram_value value
, unsigned tag
, unsigned base
)
358 gassign
*stmt1
, *stmt2
, *stmt3
;
359 gimple stmt
= value
->hvalue
.stmt
;
360 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
361 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
363 if ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE
) &&
364 tag
== GCOV_COUNTER_V_INDIR
) ||
365 (!PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE
) &&
366 tag
== GCOV_COUNTER_ICALL_TOPNV
))
369 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
370 true, NULL_TREE
, true, GSI_SAME_STMT
);
374 stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
375 stmt2: tmp1 = (void *) (indirect call argument value)
376 stmt3: __gcov_indirect_call_callee = tmp1;
379 stmt1
= gimple_build_assign (ic_gcov_type_ptr_var
, ref_ptr
);
380 tmp1
= make_temp_ssa_name (ptr_void
, NULL
, "PROF");
381 stmt2
= gimple_build_assign (tmp1
, unshare_expr (value
->hvalue
.value
));
382 stmt3
= gimple_build_assign (ic_void_ptr_var
, gimple_assign_lhs (stmt2
));
384 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
385 gsi_insert_before (&gsi
, stmt2
, GSI_SAME_STMT
);
386 gsi_insert_before (&gsi
, stmt3
, GSI_SAME_STMT
);
390 /* Output instructions as GIMPLE trees for code to find the most
391 common called function in indirect call. Insert instructions at the
392 beginning of every possible called function.
396 gimple_gen_ic_func_profiler (void)
398 struct cgraph_node
* c_node
= cgraph_node::get (current_function_decl
);
399 gimple_stmt_iterator gsi
;
402 tree tree_uid
, cur_func
, void0
;
404 if (c_node
->only_called_directly_p ())
407 gimple_init_edge_profiler ();
411 stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
412 ¤t_function_decl)
414 gsi
= gsi_after_labels (split_edge (single_succ_edge
415 (ENTRY_BLOCK_PTR_FOR_FN (cfun
))));
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
424 cgraph_node::get (current_function_decl
)->profile_id
);
425 stmt1
= gimple_build_call (tree_indirect_call_profiler_fn
, 2,
427 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
429 /* Set __gcov_indirect_call_callee to 0,
430 so that calls from other modules won't get misattributed
431 to the last caller of the current callee. */
432 void0
= build_int_cst (build_pointer_type (void_type_node
), 0);
433 stmt2
= gimple_build_assign (ic_void_ptr_var
, void0
);
434 gsi_insert_before (&gsi
, stmt2
, GSI_SAME_STMT
);
437 /* Output instructions as GIMPLE tree at the beginning for each function.
438 TAG is the tag of the section for counters, BASE is offset of the
439 counter position and GSI is the iterator we place the counter. */
442 gimple_gen_time_profiler (unsigned tag
, unsigned base
,
443 gimple_stmt_iterator
&gsi
)
445 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
448 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
449 true, NULL_TREE
, true, GSI_SAME_STMT
);
450 call
= gimple_build_call (tree_time_profiler_fn
, 1, ref_ptr
);
451 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
454 /* Output instructions as GIMPLE trees for code to find the most common value
455 of a difference between two evaluations of an expression.
456 VALUE is the expression whose value is profiled. TAG is the tag of the
457 section for counters, BASE is offset of the counter position. */
460 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED
,
461 unsigned tag ATTRIBUTE_UNUSED
,
462 unsigned base ATTRIBUTE_UNUSED
)
464 /* FIXME implement this. */
465 #ifdef ENABLE_CHECKING
466 internal_error ("unimplemented functionality");
471 /* Output instructions as GIMPLE trees to increment the average histogram
472 counter. VALUE is the expression whose value is profiled. TAG is the
473 tag of the section for counters, BASE is offset of the counter position. */
476 gimple_gen_average_profiler (histogram_value value
, unsigned tag
, unsigned base
)
478 gimple stmt
= value
->hvalue
.stmt
;
479 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
480 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
484 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
486 true, GSI_SAME_STMT
);
487 val
= prepare_instrumented_value (&gsi
, value
);
488 call
= gimple_build_call (tree_average_profiler_fn
, 2, ref_ptr
, val
);
489 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
492 /* Output instructions as GIMPLE trees to increment the ior histogram
493 counter. VALUE is the expression whose value is profiled. TAG is the
494 tag of the section for counters, BASE is offset of the counter position. */
497 gimple_gen_ior_profiler (histogram_value value
, unsigned tag
, unsigned base
)
499 gimple stmt
= value
->hvalue
.stmt
;
500 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
501 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
505 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
506 true, NULL_TREE
, true, GSI_SAME_STMT
);
507 val
= prepare_instrumented_value (&gsi
, value
);
508 call
= gimple_build_call (tree_ior_profiler_fn
, 2, ref_ptr
, val
);
509 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
512 /* Profile all functions in the callgraph. */
515 tree_profiling (void)
517 struct cgraph_node
*node
;
519 /* This is a small-ipa pass that gets called only once, from
520 cgraphunit.c:ipa_passes(). */
521 gcc_assert (symtab
->state
== IPA_SSA
);
523 init_node_map (true);
525 FOR_EACH_DEFINED_FUNCTION (node
)
527 if (!gimple_has_body_p (node
->decl
))
530 /* Don't profile functions produced for builtin stuff. */
531 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
)
534 /* Do not instrument extern inline functions when testing coverage.
535 While this is not perfectly consistent (early inlined extern inlines
536 will get acocunted), testsuite expects that. */
537 if (DECL_EXTERNAL (node
->decl
)
538 && flag_test_coverage
)
541 push_cfun (DECL_STRUCT_FUNCTION (node
->decl
));
543 /* Local pure-const may imply need to fixup the cfg. */
544 if (execute_fixup_cfg () & TODO_cleanup_cfg
)
549 if (! flag_branch_probabilities
550 && flag_profile_values
)
551 gimple_gen_ic_func_profiler ();
553 if (flag_branch_probabilities
554 && flag_profile_values
555 && flag_value_profile_transformations
)
556 gimple_value_profile_transformations ();
558 /* The above could hose dominator info. Currently there is
559 none coming in, this is a safety valve. It should be
560 easy to adjust it, if and when there is some. */
561 free_dominance_info (CDI_DOMINATORS
);
562 free_dominance_info (CDI_POST_DOMINATORS
);
566 /* Drop pure/const flags from instrumented functions. */
567 FOR_EACH_DEFINED_FUNCTION (node
)
569 if (!gimple_has_body_p (node
->decl
)
571 || node
->decl
!= node
->clone_of
->decl
))
574 /* Don't profile functions produced for builtin stuff. */
575 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
)
578 node
->set_const_flag (false, false);
579 node
->set_pure_flag (false, false);
582 /* Update call statements and rebuild the cgraph. */
583 FOR_EACH_DEFINED_FUNCTION (node
)
587 if (!gimple_has_body_p (node
->decl
)
589 || node
->decl
!= node
->clone_of
->decl
))
592 /* Don't profile functions produced for builtin stuff. */
593 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
)
596 push_cfun (DECL_STRUCT_FUNCTION (node
->decl
));
598 FOR_EACH_BB_FN (bb
, cfun
)
600 gimple_stmt_iterator gsi
;
601 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
603 gimple stmt
= gsi_stmt (gsi
);
604 if (is_gimple_call (stmt
))
609 /* re-merge split blocks. */
611 update_ssa (TODO_update_ssa
);
613 cgraph_edge::rebuild_edges ();
618 handle_missing_profiles ();
626 const pass_data pass_data_ipa_tree_profile
=
628 SIMPLE_IPA_PASS
, /* type */
629 "profile", /* name */
630 OPTGROUP_NONE
, /* optinfo_flags */
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 virtual bool gate (function
*);
648 virtual unsigned int execute (function
*) { return tree_profiling (); }
650 }; // class pass_ipa_tree_profile
653 pass_ipa_tree_profile::gate (function
*)
655 /* When profile instrumentation, use or test coverage shall be performed.
656 But for AutoFDO, this there is no instrumentation, thus this pass is
658 return (!in_lto_p
&& !flag_auto_profile
659 && (flag_branch_probabilities
|| flag_test_coverage
660 || profile_arc_flag
));
665 simple_ipa_opt_pass
*
666 make_pass_ipa_tree_profile (gcc::context
*ctxt
)
668 return new pass_ipa_tree_profile (ctxt
);
671 #include "gt-tree-profile.h"