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"
33 #include "hard-reg-set.h"
36 #include "diagnostic-core.h"
39 #include "fold-const.h"
40 #include "internal-fn.h"
42 #include "tree-nested.h"
44 #include "gimple-iterator.h"
45 #include "gimplify-me.h"
48 #include "tree-into-ssa.h"
49 #include "tree-pass.h"
50 #include "value-prof.h"
53 #include "tree-cfgcleanup.h"
54 #include "tree-nested.h"
57 static GTY(()) tree gcov_type_node
;
58 static GTY(()) tree tree_interval_profiler_fn
;
59 static GTY(()) tree tree_pow2_profiler_fn
;
60 static GTY(()) tree tree_one_value_profiler_fn
;
61 static GTY(()) tree tree_indirect_call_profiler_fn
;
62 static GTY(()) tree tree_time_profiler_fn
;
63 static GTY(()) tree tree_average_profiler_fn
;
64 static GTY(()) tree tree_ior_profiler_fn
;
67 static GTY(()) tree ic_void_ptr_var
;
68 static GTY(()) tree ic_gcov_type_ptr_var
;
69 static GTY(()) tree ptr_void
;
71 /* Do initialization work for the edge profiler. */
74 __thread gcov* __gcov_indirect_call_counters; // pointer to actual counter
75 __thread void* __gcov_indirect_call_callee; // actual callee address
76 __thread int __gcov_function_counter; // time profiler function counter
79 init_ic_make_global_vars (void)
83 ptr_void
= build_pointer_type (void_type_node
);
86 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
88 (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE
) ?
89 "__gcov_indirect_call_topn_callee" :
90 "__gcov_indirect_call_callee")),
92 TREE_PUBLIC (ic_void_ptr_var
) = 1;
93 DECL_EXTERNAL (ic_void_ptr_var
) = 1;
94 TREE_STATIC (ic_void_ptr_var
) = 1;
95 DECL_ARTIFICIAL (ic_void_ptr_var
) = 1;
96 DECL_INITIAL (ic_void_ptr_var
) = NULL
;
98 set_decl_tls_model (ic_void_ptr_var
, decl_default_tls_model (ic_void_ptr_var
));
100 varpool_node::finalize_decl (ic_void_ptr_var
);
102 gcov_type_ptr
= build_pointer_type (get_gcov_type ());
105 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
107 (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE
) ?
108 "__gcov_indirect_call_topn_counters" :
109 "__gcov_indirect_call_counters")),
111 TREE_PUBLIC (ic_gcov_type_ptr_var
) = 1;
112 DECL_EXTERNAL (ic_gcov_type_ptr_var
) = 1;
113 TREE_STATIC (ic_gcov_type_ptr_var
) = 1;
114 DECL_ARTIFICIAL (ic_gcov_type_ptr_var
) = 1;
115 DECL_INITIAL (ic_gcov_type_ptr_var
) = NULL
;
116 if (targetm
.have_tls
)
117 set_decl_tls_model (ic_gcov_type_ptr_var
, decl_default_tls_model (ic_gcov_type_ptr_var
));
119 varpool_node::finalize_decl (ic_gcov_type_ptr_var
);
122 /* Create the type and function decls for the interface with gcov. */
125 gimple_init_edge_profiler (void)
127 tree interval_profiler_fn_type
;
128 tree pow2_profiler_fn_type
;
129 tree one_value_profiler_fn_type
;
131 tree ic_profiler_fn_type
;
132 tree average_profiler_fn_type
;
133 tree time_profiler_fn_type
;
137 gcov_type_node
= get_gcov_type ();
138 gcov_type_ptr
= build_pointer_type (gcov_type_node
);
140 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
141 interval_profiler_fn_type
142 = build_function_type_list (void_type_node
,
143 gcov_type_ptr
, gcov_type_node
,
145 unsigned_type_node
, NULL_TREE
);
146 tree_interval_profiler_fn
147 = build_fn_decl ("__gcov_interval_profiler",
148 interval_profiler_fn_type
);
149 TREE_NOTHROW (tree_interval_profiler_fn
) = 1;
150 DECL_ATTRIBUTES (tree_interval_profiler_fn
)
151 = tree_cons (get_identifier ("leaf"), NULL
,
152 DECL_ATTRIBUTES (tree_interval_profiler_fn
));
154 /* void (*) (gcov_type *, gcov_type) */
155 pow2_profiler_fn_type
156 = build_function_type_list (void_type_node
,
157 gcov_type_ptr
, gcov_type_node
,
159 tree_pow2_profiler_fn
= build_fn_decl ("__gcov_pow2_profiler",
160 pow2_profiler_fn_type
);
161 TREE_NOTHROW (tree_pow2_profiler_fn
) = 1;
162 DECL_ATTRIBUTES (tree_pow2_profiler_fn
)
163 = tree_cons (get_identifier ("leaf"), NULL
,
164 DECL_ATTRIBUTES (tree_pow2_profiler_fn
));
166 /* void (*) (gcov_type *, gcov_type) */
167 one_value_profiler_fn_type
168 = build_function_type_list (void_type_node
,
169 gcov_type_ptr
, gcov_type_node
,
171 tree_one_value_profiler_fn
172 = build_fn_decl ("__gcov_one_value_profiler",
173 one_value_profiler_fn_type
);
174 TREE_NOTHROW (tree_one_value_profiler_fn
) = 1;
175 DECL_ATTRIBUTES (tree_one_value_profiler_fn
)
176 = tree_cons (get_identifier ("leaf"), NULL
,
177 DECL_ATTRIBUTES (tree_one_value_profiler_fn
));
179 init_ic_make_global_vars ();
181 /* void (*) (gcov_type, void *) */
183 = build_function_type_list (void_type_node
,
187 tree_indirect_call_profiler_fn
188 = build_fn_decl ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE
) ?
189 "__gcov_indirect_call_topn_profiler":
190 "__gcov_indirect_call_profiler_v2"),
191 ic_profiler_fn_type
);
193 TREE_NOTHROW (tree_indirect_call_profiler_fn
) = 1;
194 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn
)
195 = tree_cons (get_identifier ("leaf"), NULL
,
196 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn
));
198 /* void (*) (gcov_type *, gcov_type, void *) */
199 time_profiler_fn_type
200 = build_function_type_list (void_type_node
,
201 gcov_type_ptr
, NULL_TREE
);
202 tree_time_profiler_fn
203 = build_fn_decl ("__gcov_time_profiler",
204 time_profiler_fn_type
);
205 TREE_NOTHROW (tree_time_profiler_fn
) = 1;
206 DECL_ATTRIBUTES (tree_time_profiler_fn
)
207 = tree_cons (get_identifier ("leaf"), NULL
,
208 DECL_ATTRIBUTES (tree_time_profiler_fn
));
210 /* void (*) (gcov_type *, gcov_type) */
211 average_profiler_fn_type
212 = build_function_type_list (void_type_node
,
213 gcov_type_ptr
, gcov_type_node
, NULL_TREE
);
214 tree_average_profiler_fn
215 = build_fn_decl ("__gcov_average_profiler",
216 average_profiler_fn_type
);
217 TREE_NOTHROW (tree_average_profiler_fn
) = 1;
218 DECL_ATTRIBUTES (tree_average_profiler_fn
)
219 = tree_cons (get_identifier ("leaf"), NULL
,
220 DECL_ATTRIBUTES (tree_average_profiler_fn
));
222 = build_fn_decl ("__gcov_ior_profiler",
223 average_profiler_fn_type
);
224 TREE_NOTHROW (tree_ior_profiler_fn
) = 1;
225 DECL_ATTRIBUTES (tree_ior_profiler_fn
)
226 = tree_cons (get_identifier ("leaf"), NULL
,
227 DECL_ATTRIBUTES (tree_ior_profiler_fn
));
229 /* LTO streamer needs assembler names. Because we create these decls
230 late, we need to initialize them by hand. */
231 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn
);
232 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn
);
233 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn
);
234 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn
);
235 DECL_ASSEMBLER_NAME (tree_time_profiler_fn
);
236 DECL_ASSEMBLER_NAME (tree_average_profiler_fn
);
237 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn
);
241 /* Output instructions as GIMPLE trees to increment the edge
242 execution count, and insert them on E. We rely on
243 gsi_insert_on_edge to preserve the order. */
246 gimple_gen_edge_profiler (int edgeno
, edge e
)
248 tree ref
, one
, gcov_type_tmp_var
;
249 gassign
*stmt1
, *stmt2
, *stmt3
;
251 ref
= tree_coverage_counter_ref (GCOV_COUNTER_ARCS
, edgeno
);
252 one
= build_int_cst (gcov_type_node
, 1);
253 gcov_type_tmp_var
= make_temp_ssa_name (gcov_type_node
,
254 NULL
, "PROF_edge_counter");
255 stmt1
= gimple_build_assign (gcov_type_tmp_var
, ref
);
256 gcov_type_tmp_var
= make_temp_ssa_name (gcov_type_node
,
257 NULL
, "PROF_edge_counter");
258 stmt2
= gimple_build_assign (gcov_type_tmp_var
, PLUS_EXPR
,
259 gimple_assign_lhs (stmt1
), one
);
260 stmt3
= gimple_build_assign (unshare_expr (ref
), gimple_assign_lhs (stmt2
));
261 gsi_insert_on_edge (e
, stmt1
);
262 gsi_insert_on_edge (e
, stmt2
);
263 gsi_insert_on_edge (e
, stmt3
);
266 /* Emits code to get VALUE to instrument at GSI, and returns the
267 variable containing the value. */
270 prepare_instrumented_value (gimple_stmt_iterator
*gsi
, histogram_value value
)
272 tree val
= value
->hvalue
.value
;
273 if (POINTER_TYPE_P (TREE_TYPE (val
)))
274 val
= fold_convert (build_nonstandard_integer_type
275 (TYPE_PRECISION (TREE_TYPE (val
)), 1), val
);
276 return force_gimple_operand_gsi (gsi
, fold_convert (gcov_type_node
, val
),
277 true, NULL_TREE
, true, GSI_SAME_STMT
);
280 /* Output instructions as GIMPLE trees to increment the interval histogram
281 counter. VALUE is the expression whose value is profiled. TAG is the
282 tag of the section for counters, BASE is offset of the counter position. */
285 gimple_gen_interval_profiler (histogram_value value
, unsigned tag
, unsigned base
)
287 gimple stmt
= value
->hvalue
.stmt
;
288 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
289 tree ref
= tree_coverage_counter_ref (tag
, base
), ref_ptr
;
292 tree start
= build_int_cst_type (integer_type_node
,
293 value
->hdata
.intvl
.int_start
);
294 tree steps
= build_int_cst_type (unsigned_type_node
,
295 value
->hdata
.intvl
.steps
);
297 ref_ptr
= force_gimple_operand_gsi (&gsi
,
298 build_addr (ref
, current_function_decl
),
299 true, NULL_TREE
, true, GSI_SAME_STMT
);
300 val
= prepare_instrumented_value (&gsi
, value
);
301 call
= gimple_build_call (tree_interval_profiler_fn
, 4,
302 ref_ptr
, val
, start
, steps
);
303 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
306 /* Output instructions as GIMPLE trees to increment the power of two histogram
307 counter. VALUE is the expression whose value is profiled. TAG is the tag
308 of the section for counters, BASE is offset of the counter position. */
311 gimple_gen_pow2_profiler (histogram_value value
, unsigned tag
, unsigned base
)
313 gimple stmt
= value
->hvalue
.stmt
;
314 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
315 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
319 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
320 true, NULL_TREE
, true, GSI_SAME_STMT
);
321 val
= prepare_instrumented_value (&gsi
, value
);
322 call
= gimple_build_call (tree_pow2_profiler_fn
, 2, ref_ptr
, val
);
323 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
326 /* Output instructions as GIMPLE trees for code to find the most common value.
327 VALUE is the expression whose value is profiled. TAG is the tag of the
328 section for counters, BASE is offset of the counter position. */
331 gimple_gen_one_value_profiler (histogram_value value
, unsigned tag
, unsigned base
)
333 gimple stmt
= value
->hvalue
.stmt
;
334 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
335 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
339 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
340 true, NULL_TREE
, true, GSI_SAME_STMT
);
341 val
= prepare_instrumented_value (&gsi
, value
);
342 call
= gimple_build_call (tree_one_value_profiler_fn
, 2, ref_ptr
, val
);
343 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
347 /* Output instructions as GIMPLE trees for code to find the most
348 common called function in indirect call.
349 VALUE is the call expression whose indirect callee is profiled.
350 TAG is the tag of the section for counters, BASE is offset of the
354 gimple_gen_ic_profiler (histogram_value value
, unsigned tag
, unsigned base
)
357 gassign
*stmt1
, *stmt2
, *stmt3
;
358 gimple stmt
= value
->hvalue
.stmt
;
359 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
360 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
362 if ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE
) &&
363 tag
== GCOV_COUNTER_V_INDIR
) ||
364 (!PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE
) &&
365 tag
== GCOV_COUNTER_ICALL_TOPNV
))
368 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
369 true, NULL_TREE
, true, GSI_SAME_STMT
);
373 stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
374 stmt2: tmp1 = (void *) (indirect call argument value)
375 stmt3: __gcov_indirect_call_callee = tmp1;
378 stmt1
= gimple_build_assign (ic_gcov_type_ptr_var
, ref_ptr
);
379 tmp1
= make_temp_ssa_name (ptr_void
, NULL
, "PROF");
380 stmt2
= gimple_build_assign (tmp1
, unshare_expr (value
->hvalue
.value
));
381 stmt3
= gimple_build_assign (ic_void_ptr_var
, gimple_assign_lhs (stmt2
));
383 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
384 gsi_insert_before (&gsi
, stmt2
, GSI_SAME_STMT
);
385 gsi_insert_before (&gsi
, stmt3
, GSI_SAME_STMT
);
389 /* Output instructions as GIMPLE trees for code to find the most
390 common called function in indirect call. Insert instructions at the
391 beginning of every possible called function.
395 gimple_gen_ic_func_profiler (void)
397 struct cgraph_node
* c_node
= cgraph_node::get (current_function_decl
);
398 gimple_stmt_iterator gsi
;
401 tree tree_uid
, cur_func
, void0
;
403 if (c_node
->only_called_directly_p ())
406 gimple_init_edge_profiler ();
410 stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
411 ¤t_function_decl)
413 gsi
= gsi_after_labels (split_edge (single_succ_edge
414 (ENTRY_BLOCK_PTR_FOR_FN (cfun
))));
416 cur_func
= force_gimple_operand_gsi (&gsi
,
417 build_addr (current_function_decl
,
418 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. */
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 (symtab
->state
== IPA_SSA
);
522 init_node_map (true);
524 FOR_EACH_DEFINED_FUNCTION (node
)
526 if (!gimple_has_body_p (node
->decl
))
529 /* Don't profile functions produced for builtin stuff. */
530 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
)
533 /* Do not instrument extern inline functions when testing coverage.
534 While this is not perfectly consistent (early inlined extern inlines
535 will get acocunted), testsuite expects that. */
536 if (DECL_EXTERNAL (node
->decl
)
537 && flag_test_coverage
)
540 push_cfun (DECL_STRUCT_FUNCTION (node
->decl
));
542 /* Local pure-const may imply need to fixup the cfg. */
543 if (execute_fixup_cfg () & TODO_cleanup_cfg
)
548 if (! flag_branch_probabilities
549 && flag_profile_values
)
550 gimple_gen_ic_func_profiler ();
552 if (flag_branch_probabilities
553 && flag_profile_values
554 && flag_value_profile_transformations
)
555 gimple_value_profile_transformations ();
557 /* The above could hose dominator info. Currently there is
558 none coming in, this is a safety valve. It should be
559 easy to adjust it, if and when there is some. */
560 free_dominance_info (CDI_DOMINATORS
);
561 free_dominance_info (CDI_POST_DOMINATORS
);
565 /* Drop pure/const flags from instrumented functions. */
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 0, /* 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"