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
,
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
),
420 true, GSI_SAME_STMT
);
421 tree_uid
= build_int_cst
423 cgraph_node::get (current_function_decl
)->profile_id
);
424 stmt1
= gimple_build_call (tree_indirect_call_profiler_fn
, 2,
426 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
428 /* Set __gcov_indirect_call_callee to 0,
429 so that calls from other modules won't get misattributed
430 to the last caller of the current callee. */
431 void0
= build_int_cst (build_pointer_type (void_type_node
), 0);
432 stmt2
= gimple_build_assign (ic_void_ptr_var
, void0
);
433 gsi_insert_before (&gsi
, stmt2
, GSI_SAME_STMT
);
436 /* Output instructions as GIMPLE tree at the beginning for each function.
437 TAG is the tag of the section for counters, BASE is offset of the
438 counter position and GSI is the iterator we place the counter. */
441 gimple_gen_time_profiler (unsigned tag
, unsigned base
,
442 gimple_stmt_iterator
&gsi
)
444 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
447 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
448 true, NULL_TREE
, true, GSI_SAME_STMT
);
449 call
= gimple_build_call (tree_time_profiler_fn
, 1, ref_ptr
);
450 gsi_insert_before (&gsi
, call
, GSI_NEW_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. */
465 internal_error ("unimplemented functionality");
469 /* Output instructions as GIMPLE trees to increment the average histogram
470 counter. VALUE is the expression whose value is profiled. TAG is the
471 tag of the section for counters, BASE is offset of the counter position. */
474 gimple_gen_average_profiler (histogram_value value
, unsigned tag
, unsigned base
)
476 gimple
*stmt
= value
->hvalue
.stmt
;
477 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
478 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
482 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
484 true, GSI_SAME_STMT
);
485 val
= prepare_instrumented_value (&gsi
, value
);
486 call
= gimple_build_call (tree_average_profiler_fn
, 2, ref_ptr
, val
);
487 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
490 /* Output instructions as GIMPLE trees to increment the ior histogram
491 counter. VALUE is the expression whose value is profiled. TAG is the
492 tag of the section for counters, BASE is offset of the counter position. */
495 gimple_gen_ior_profiler (histogram_value value
, unsigned tag
, unsigned base
)
497 gimple
*stmt
= value
->hvalue
.stmt
;
498 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
499 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
503 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
504 true, NULL_TREE
, true, GSI_SAME_STMT
);
505 val
= prepare_instrumented_value (&gsi
, value
);
506 call
= gimple_build_call (tree_ior_profiler_fn
, 2, ref_ptr
, val
);
507 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
510 /* Profile all functions in the callgraph. */
513 tree_profiling (void)
515 struct cgraph_node
*node
;
517 /* This is a small-ipa pass that gets called only once, from
518 cgraphunit.c:ipa_passes(). */
519 gcc_assert (symtab
->state
== IPA_SSA
);
521 init_node_map (true);
523 FOR_EACH_DEFINED_FUNCTION (node
)
525 if (!gimple_has_body_p (node
->decl
))
528 /* Don't profile functions produced for builtin stuff. */
529 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
)
532 /* Do not instrument extern inline functions when testing coverage.
533 While this is not perfectly consistent (early inlined extern inlines
534 will get acocunted), testsuite expects that. */
535 if (DECL_EXTERNAL (node
->decl
)
536 && flag_test_coverage
)
539 push_cfun (DECL_STRUCT_FUNCTION (node
->decl
));
541 /* Local pure-const may imply need to fixup the cfg. */
542 if (execute_fixup_cfg () & TODO_cleanup_cfg
)
547 if (! flag_branch_probabilities
548 && flag_profile_values
)
549 gimple_gen_ic_func_profiler ();
551 if (flag_branch_probabilities
552 && flag_profile_values
553 && flag_value_profile_transformations
)
554 gimple_value_profile_transformations ();
556 /* The above could hose dominator info. Currently there is
557 none coming in, this is a safety valve. It should be
558 easy to adjust it, if and when there is some. */
559 free_dominance_info (CDI_DOMINATORS
);
560 free_dominance_info (CDI_POST_DOMINATORS
);
564 /* Drop pure/const flags from instrumented functions. */
565 if (profile_arc_flag
|| flag_test_coverage
)
566 FOR_EACH_DEFINED_FUNCTION (node
)
568 if (!gimple_has_body_p (node
->decl
)
570 || node
->decl
!= node
->clone_of
->decl
))
573 /* Don't profile functions produced for builtin stuff. */
574 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
)
577 node
->set_const_flag (false, false);
578 node
->set_pure_flag (false, false);
581 /* Update call statements and rebuild the cgraph. */
582 FOR_EACH_DEFINED_FUNCTION (node
)
586 if (!gimple_has_body_p (node
->decl
)
588 || node
->decl
!= node
->clone_of
->decl
))
591 /* Don't profile functions produced for builtin stuff. */
592 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
)
595 push_cfun (DECL_STRUCT_FUNCTION (node
->decl
));
597 FOR_EACH_BB_FN (bb
, cfun
)
599 gimple_stmt_iterator gsi
;
600 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
602 gimple
*stmt
= gsi_stmt (gsi
);
603 if (is_gimple_call (stmt
))
608 /* re-merge split blocks. */
610 update_ssa (TODO_update_ssa
);
612 cgraph_edge::rebuild_edges ();
617 handle_missing_profiles ();
625 const pass_data pass_data_ipa_tree_profile
=
627 SIMPLE_IPA_PASS
, /* type */
628 "profile", /* name */
629 OPTGROUP_NONE
, /* optinfo_flags */
630 TV_IPA_PROFILE
, /* tv_id */
631 0, /* properties_required */
632 0, /* properties_provided */
633 0, /* properties_destroyed */
634 0, /* todo_flags_start */
635 TODO_dump_symtab
, /* todo_flags_finish */
638 class pass_ipa_tree_profile
: public simple_ipa_opt_pass
641 pass_ipa_tree_profile (gcc::context
*ctxt
)
642 : simple_ipa_opt_pass (pass_data_ipa_tree_profile
, ctxt
)
645 /* opt_pass methods: */
646 virtual bool gate (function
*);
647 virtual unsigned int execute (function
*) { return tree_profiling (); }
649 }; // class pass_ipa_tree_profile
652 pass_ipa_tree_profile::gate (function
*)
654 /* When profile instrumentation, use or test coverage shall be performed.
655 But for AutoFDO, this there is no instrumentation, thus this pass is
657 return (!in_lto_p
&& !flag_auto_profile
658 && (flag_branch_probabilities
|| flag_test_coverage
659 || profile_arc_flag
));
664 simple_ipa_opt_pass
*
665 make_pass_ipa_tree_profile (gcc::context
*ctxt
)
667 return new pass_ipa_tree_profile (ctxt
);
670 #include "gt-tree-profile.h"