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"
32 #include "hard-reg-set.h"
35 #include "dominance.h"
37 #include "basic-block.h"
38 #include "diagnostic-core.h"
43 #include "fold-const.h"
44 #include "tree-ssa-alias.h"
45 #include "internal-fn.h"
46 #include "gimple-expr.h"
49 #include "tree-nested.h"
51 #include "gimple-iterator.h"
52 #include "gimplify-me.h"
53 #include "gimple-ssa.h"
56 #include "stringpool.h"
57 #include "tree-ssanames.h"
58 #include "tree-into-ssa.h"
59 #include "tree-pass.h"
60 #include "value-prof.h"
63 #include "tree-cfgcleanup.h"
64 #include "tree-nested.h"
67 static GTY(()) tree gcov_type_node
;
68 static GTY(()) tree tree_interval_profiler_fn
;
69 static GTY(()) tree tree_pow2_profiler_fn
;
70 static GTY(()) tree tree_one_value_profiler_fn
;
71 static GTY(()) tree tree_indirect_call_profiler_fn
;
72 static GTY(()) tree tree_time_profiler_fn
;
73 static GTY(()) tree tree_average_profiler_fn
;
74 static GTY(()) tree tree_ior_profiler_fn
;
77 static GTY(()) tree ic_void_ptr_var
;
78 static GTY(()) tree ic_gcov_type_ptr_var
;
79 static GTY(()) tree ptr_void
;
81 /* Do initialization work for the edge profiler. */
84 __thread gcov* __gcov_indirect_call_counters; // pointer to actual counter
85 __thread void* __gcov_indirect_call_callee; // actual callee address
86 __thread int __gcov_function_counter; // time profiler function counter
89 init_ic_make_global_vars (void)
93 ptr_void
= build_pointer_type (void_type_node
);
96 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
98 (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE
) ?
99 "__gcov_indirect_call_topn_callee" :
100 "__gcov_indirect_call_callee")),
102 TREE_PUBLIC (ic_void_ptr_var
) = 1;
103 DECL_EXTERNAL (ic_void_ptr_var
) = 1;
104 TREE_STATIC (ic_void_ptr_var
) = 1;
105 DECL_ARTIFICIAL (ic_void_ptr_var
) = 1;
106 DECL_INITIAL (ic_void_ptr_var
) = NULL
;
107 if (targetm
.have_tls
)
108 set_decl_tls_model (ic_void_ptr_var
, decl_default_tls_model (ic_void_ptr_var
));
110 varpool_node::finalize_decl (ic_void_ptr_var
);
112 gcov_type_ptr
= build_pointer_type (get_gcov_type ());
115 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
117 (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE
) ?
118 "__gcov_indirect_call_topn_counters" :
119 "__gcov_indirect_call_counters")),
121 TREE_PUBLIC (ic_gcov_type_ptr_var
) = 1;
122 DECL_EXTERNAL (ic_gcov_type_ptr_var
) = 1;
123 TREE_STATIC (ic_gcov_type_ptr_var
) = 1;
124 DECL_ARTIFICIAL (ic_gcov_type_ptr_var
) = 1;
125 DECL_INITIAL (ic_gcov_type_ptr_var
) = NULL
;
126 if (targetm
.have_tls
)
127 set_decl_tls_model (ic_gcov_type_ptr_var
, decl_default_tls_model (ic_gcov_type_ptr_var
));
129 varpool_node::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
;
143 tree time_profiler_fn_type
;
147 gcov_type_node
= get_gcov_type ();
148 gcov_type_ptr
= build_pointer_type (gcov_type_node
);
150 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
151 interval_profiler_fn_type
152 = build_function_type_list (void_type_node
,
153 gcov_type_ptr
, gcov_type_node
,
155 unsigned_type_node
, NULL_TREE
);
156 tree_interval_profiler_fn
157 = build_fn_decl ("__gcov_interval_profiler",
158 interval_profiler_fn_type
);
159 TREE_NOTHROW (tree_interval_profiler_fn
) = 1;
160 DECL_ATTRIBUTES (tree_interval_profiler_fn
)
161 = tree_cons (get_identifier ("leaf"), NULL
,
162 DECL_ATTRIBUTES (tree_interval_profiler_fn
));
164 /* void (*) (gcov_type *, gcov_type) */
165 pow2_profiler_fn_type
166 = build_function_type_list (void_type_node
,
167 gcov_type_ptr
, gcov_type_node
,
169 tree_pow2_profiler_fn
= build_fn_decl ("__gcov_pow2_profiler",
170 pow2_profiler_fn_type
);
171 TREE_NOTHROW (tree_pow2_profiler_fn
) = 1;
172 DECL_ATTRIBUTES (tree_pow2_profiler_fn
)
173 = tree_cons (get_identifier ("leaf"), NULL
,
174 DECL_ATTRIBUTES (tree_pow2_profiler_fn
));
176 /* void (*) (gcov_type *, gcov_type) */
177 one_value_profiler_fn_type
178 = build_function_type_list (void_type_node
,
179 gcov_type_ptr
, gcov_type_node
,
181 tree_one_value_profiler_fn
182 = build_fn_decl ("__gcov_one_value_profiler",
183 one_value_profiler_fn_type
);
184 TREE_NOTHROW (tree_one_value_profiler_fn
) = 1;
185 DECL_ATTRIBUTES (tree_one_value_profiler_fn
)
186 = tree_cons (get_identifier ("leaf"), NULL
,
187 DECL_ATTRIBUTES (tree_one_value_profiler_fn
));
189 init_ic_make_global_vars ();
191 /* void (*) (gcov_type, void *) */
193 = build_function_type_list (void_type_node
,
197 tree_indirect_call_profiler_fn
198 = build_fn_decl ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE
) ?
199 "__gcov_indirect_call_topn_profiler":
200 "__gcov_indirect_call_profiler_v2"),
201 ic_profiler_fn_type
);
203 TREE_NOTHROW (tree_indirect_call_profiler_fn
) = 1;
204 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn
)
205 = tree_cons (get_identifier ("leaf"), NULL
,
206 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn
));
208 /* void (*) (gcov_type *, gcov_type, void *) */
209 time_profiler_fn_type
210 = build_function_type_list (void_type_node
,
211 gcov_type_ptr
, NULL_TREE
);
212 tree_time_profiler_fn
213 = build_fn_decl ("__gcov_time_profiler",
214 time_profiler_fn_type
);
215 TREE_NOTHROW (tree_time_profiler_fn
) = 1;
216 DECL_ATTRIBUTES (tree_time_profiler_fn
)
217 = tree_cons (get_identifier ("leaf"), NULL
,
218 DECL_ATTRIBUTES (tree_time_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_time_profiler_fn
);
246 DECL_ASSEMBLER_NAME (tree_average_profiler_fn
);
247 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn
);
251 /* Output instructions as GIMPLE trees to increment the edge
252 execution count, and insert them on E. We rely on
253 gsi_insert_on_edge to preserve the order. */
256 gimple_gen_edge_profiler (int edgeno
, edge e
)
258 tree ref
, one
, gcov_type_tmp_var
;
259 gassign
*stmt1
, *stmt2
, *stmt3
;
261 ref
= tree_coverage_counter_ref (GCOV_COUNTER_ARCS
, edgeno
);
262 one
= build_int_cst (gcov_type_node
, 1);
263 gcov_type_tmp_var
= make_temp_ssa_name (gcov_type_node
,
264 NULL
, "PROF_edge_counter");
265 stmt1
= gimple_build_assign (gcov_type_tmp_var
, ref
);
266 gcov_type_tmp_var
= make_temp_ssa_name (gcov_type_node
,
267 NULL
, "PROF_edge_counter");
268 stmt2
= gimple_build_assign (gcov_type_tmp_var
, PLUS_EXPR
,
269 gimple_assign_lhs (stmt1
), one
);
270 stmt3
= gimple_build_assign (unshare_expr (ref
), gimple_assign_lhs (stmt2
));
271 gsi_insert_on_edge (e
, stmt1
);
272 gsi_insert_on_edge (e
, stmt2
);
273 gsi_insert_on_edge (e
, stmt3
);
276 /* Emits code to get VALUE to instrument at GSI, and returns the
277 variable containing the value. */
280 prepare_instrumented_value (gimple_stmt_iterator
*gsi
, histogram_value value
)
282 tree val
= value
->hvalue
.value
;
283 if (POINTER_TYPE_P (TREE_TYPE (val
)))
284 val
= fold_convert (build_nonstandard_integer_type
285 (TYPE_PRECISION (TREE_TYPE (val
)), 1), val
);
286 return force_gimple_operand_gsi (gsi
, fold_convert (gcov_type_node
, val
),
287 true, NULL_TREE
, true, GSI_SAME_STMT
);
290 /* Output instructions as GIMPLE trees to increment the interval histogram
291 counter. VALUE is the expression whose value is profiled. TAG is the
292 tag of the section for counters, BASE is offset of the counter position. */
295 gimple_gen_interval_profiler (histogram_value value
, unsigned tag
, unsigned base
)
297 gimple stmt
= value
->hvalue
.stmt
;
298 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
299 tree ref
= tree_coverage_counter_ref (tag
, base
), ref_ptr
;
302 tree start
= build_int_cst_type (integer_type_node
,
303 value
->hdata
.intvl
.int_start
);
304 tree steps
= build_int_cst_type (unsigned_type_node
,
305 value
->hdata
.intvl
.steps
);
307 ref_ptr
= force_gimple_operand_gsi (&gsi
,
308 build_addr (ref
, current_function_decl
),
309 true, NULL_TREE
, true, GSI_SAME_STMT
);
310 val
= prepare_instrumented_value (&gsi
, value
);
311 call
= gimple_build_call (tree_interval_profiler_fn
, 4,
312 ref_ptr
, val
, start
, steps
);
313 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
316 /* Output instructions as GIMPLE trees to increment the power of two histogram
317 counter. VALUE is the expression whose value is profiled. TAG is the tag
318 of the section for counters, BASE is offset of the counter position. */
321 gimple_gen_pow2_profiler (histogram_value value
, unsigned tag
, unsigned base
)
323 gimple stmt
= value
->hvalue
.stmt
;
324 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
325 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
329 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
330 true, NULL_TREE
, true, GSI_SAME_STMT
);
331 val
= prepare_instrumented_value (&gsi
, value
);
332 call
= gimple_build_call (tree_pow2_profiler_fn
, 2, ref_ptr
, val
);
333 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
336 /* Output instructions as GIMPLE trees for code to find the most common value.
337 VALUE is the expression whose value is profiled. TAG is the tag of the
338 section for counters, BASE is offset of the counter position. */
341 gimple_gen_one_value_profiler (histogram_value value
, unsigned tag
, unsigned base
)
343 gimple stmt
= value
->hvalue
.stmt
;
344 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
345 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
349 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
350 true, NULL_TREE
, true, GSI_SAME_STMT
);
351 val
= prepare_instrumented_value (&gsi
, value
);
352 call
= gimple_build_call (tree_one_value_profiler_fn
, 2, ref_ptr
, val
);
353 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
357 /* Output instructions as GIMPLE trees for code to find the most
358 common called function in indirect call.
359 VALUE is the call expression whose indirect callee is profiled.
360 TAG is the tag of the section for counters, BASE is offset of the
364 gimple_gen_ic_profiler (histogram_value value
, unsigned tag
, unsigned base
)
367 gassign
*stmt1
, *stmt2
, *stmt3
;
368 gimple stmt
= value
->hvalue
.stmt
;
369 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
370 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
372 if ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE
) &&
373 tag
== GCOV_COUNTER_V_INDIR
) ||
374 (!PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE
) &&
375 tag
== GCOV_COUNTER_ICALL_TOPNV
))
378 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
379 true, NULL_TREE
, true, GSI_SAME_STMT
);
383 stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
384 stmt2: tmp1 = (void *) (indirect call argument value)
385 stmt3: __gcov_indirect_call_callee = tmp1;
388 stmt1
= gimple_build_assign (ic_gcov_type_ptr_var
, ref_ptr
);
389 tmp1
= make_temp_ssa_name (ptr_void
, NULL
, "PROF");
390 stmt2
= gimple_build_assign (tmp1
, unshare_expr (value
->hvalue
.value
));
391 stmt3
= gimple_build_assign (ic_void_ptr_var
, gimple_assign_lhs (stmt2
));
393 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
394 gsi_insert_before (&gsi
, stmt2
, GSI_SAME_STMT
);
395 gsi_insert_before (&gsi
, stmt3
, GSI_SAME_STMT
);
399 /* Output instructions as GIMPLE trees for code to find the most
400 common called function in indirect call. Insert instructions at the
401 beginning of every possible called function.
405 gimple_gen_ic_func_profiler (void)
407 struct cgraph_node
* c_node
= cgraph_node::get (current_function_decl
);
408 gimple_stmt_iterator gsi
;
411 tree tree_uid
, cur_func
, void0
;
413 if (c_node
->only_called_directly_p ())
416 gimple_init_edge_profiler ();
420 stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
421 ¤t_function_decl)
423 gsi
= gsi_after_labels (split_edge (single_succ_edge
424 (ENTRY_BLOCK_PTR_FOR_FN (cfun
))));
426 cur_func
= force_gimple_operand_gsi (&gsi
,
427 build_addr (current_function_decl
,
428 current_function_decl
),
430 true, GSI_SAME_STMT
);
431 tree_uid
= build_int_cst
433 cgraph_node::get (current_function_decl
)->profile_id
);
434 stmt1
= gimple_build_call (tree_indirect_call_profiler_fn
, 2,
436 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
438 /* Set __gcov_indirect_call_callee to 0,
439 so that calls from other modules won't get misattributed
440 to the last caller of the current callee. */
441 void0
= build_int_cst (build_pointer_type (void_type_node
), 0);
442 stmt2
= gimple_build_assign (ic_void_ptr_var
, void0
);
443 gsi_insert_before (&gsi
, stmt2
, GSI_SAME_STMT
);
446 /* Output instructions as GIMPLE tree at the beginning for each function.
447 TAG is the tag of the section for counters, BASE is offset of the
448 counter position and GSI is the iterator we place the counter. */
451 gimple_gen_time_profiler (unsigned tag
, unsigned base
,
452 gimple_stmt_iterator
&gsi
)
454 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
457 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
458 true, NULL_TREE
, true, GSI_SAME_STMT
);
459 call
= gimple_build_call (tree_time_profiler_fn
, 1, ref_ptr
);
460 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
463 /* Output instructions as GIMPLE trees for code to find the most common value
464 of a difference between two evaluations of an expression.
465 VALUE is the expression whose value is profiled. TAG is the tag of the
466 section for counters, BASE is offset of the counter position. */
469 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED
,
470 unsigned tag ATTRIBUTE_UNUSED
,
471 unsigned base ATTRIBUTE_UNUSED
)
473 /* FIXME implement this. */
474 #ifdef ENABLE_CHECKING
475 internal_error ("unimplemented functionality");
480 /* Output instructions as GIMPLE trees to increment the average histogram
481 counter. VALUE is the expression whose value is profiled. TAG is the
482 tag of the section for counters, BASE is offset of the counter position. */
485 gimple_gen_average_profiler (histogram_value value
, unsigned tag
, unsigned base
)
487 gimple stmt
= value
->hvalue
.stmt
;
488 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
489 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
493 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
495 true, GSI_SAME_STMT
);
496 val
= prepare_instrumented_value (&gsi
, value
);
497 call
= gimple_build_call (tree_average_profiler_fn
, 2, ref_ptr
, val
);
498 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
501 /* Output instructions as GIMPLE trees to increment the ior histogram
502 counter. VALUE is the expression whose value is profiled. TAG is the
503 tag of the section for counters, BASE is offset of the counter position. */
506 gimple_gen_ior_profiler (histogram_value value
, unsigned tag
, unsigned base
)
508 gimple stmt
= value
->hvalue
.stmt
;
509 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
510 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
514 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
515 true, NULL_TREE
, true, GSI_SAME_STMT
);
516 val
= prepare_instrumented_value (&gsi
, value
);
517 call
= gimple_build_call (tree_ior_profiler_fn
, 2, ref_ptr
, val
);
518 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
521 /* Profile all functions in the callgraph. */
524 tree_profiling (void)
526 struct cgraph_node
*node
;
528 /* This is a small-ipa pass that gets called only once, from
529 cgraphunit.c:ipa_passes(). */
530 gcc_assert (symtab
->state
== IPA_SSA
);
532 init_node_map (true);
534 FOR_EACH_DEFINED_FUNCTION (node
)
536 if (!gimple_has_body_p (node
->decl
))
539 /* Don't profile functions produced for builtin stuff. */
540 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
)
543 /* Do not instrument extern inline functions when testing coverage.
544 While this is not perfectly consistent (early inlined extern inlines
545 will get acocunted), testsuite expects that. */
546 if (DECL_EXTERNAL (node
->decl
)
547 && flag_test_coverage
)
550 push_cfun (DECL_STRUCT_FUNCTION (node
->decl
));
552 /* Local pure-const may imply need to fixup the cfg. */
553 if (execute_fixup_cfg () & TODO_cleanup_cfg
)
558 if (! flag_branch_probabilities
559 && flag_profile_values
)
560 gimple_gen_ic_func_profiler ();
562 if (flag_branch_probabilities
563 && flag_profile_values
564 && flag_value_profile_transformations
)
565 gimple_value_profile_transformations ();
567 /* The above could hose dominator info. Currently there is
568 none coming in, this is a safety valve. It should be
569 easy to adjust it, if and when there is some. */
570 free_dominance_info (CDI_DOMINATORS
);
571 free_dominance_info (CDI_POST_DOMINATORS
);
575 /* Drop pure/const flags from instrumented functions. */
576 FOR_EACH_DEFINED_FUNCTION (node
)
578 if (!gimple_has_body_p (node
->decl
)
580 || node
->decl
!= node
->clone_of
->decl
))
583 /* Don't profile functions produced for builtin stuff. */
584 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
)
587 node
->set_const_flag (false, false);
588 node
->set_pure_flag (false, false);
591 /* Update call statements and rebuild the cgraph. */
592 FOR_EACH_DEFINED_FUNCTION (node
)
596 if (!gimple_has_body_p (node
->decl
)
598 || node
->decl
!= node
->clone_of
->decl
))
601 /* Don't profile functions produced for builtin stuff. */
602 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
)
605 push_cfun (DECL_STRUCT_FUNCTION (node
->decl
));
607 FOR_EACH_BB_FN (bb
, cfun
)
609 gimple_stmt_iterator gsi
;
610 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
612 gimple stmt
= gsi_stmt (gsi
);
613 if (is_gimple_call (stmt
))
618 /* re-merge split blocks. */
620 update_ssa (TODO_update_ssa
);
622 cgraph_edge::rebuild_edges ();
627 handle_missing_profiles ();
635 const pass_data pass_data_ipa_tree_profile
=
637 SIMPLE_IPA_PASS
, /* type */
638 "profile", /* name */
639 OPTGROUP_NONE
, /* optinfo_flags */
640 TV_IPA_PROFILE
, /* tv_id */
641 0, /* properties_required */
642 0, /* properties_provided */
643 0, /* properties_destroyed */
644 0, /* todo_flags_start */
645 0, /* todo_flags_finish */
648 class pass_ipa_tree_profile
: public simple_ipa_opt_pass
651 pass_ipa_tree_profile (gcc::context
*ctxt
)
652 : simple_ipa_opt_pass (pass_data_ipa_tree_profile
, ctxt
)
655 /* opt_pass methods: */
656 virtual bool gate (function
*);
657 virtual unsigned int execute (function
*) { return tree_profiling (); }
659 }; // class pass_ipa_tree_profile
662 pass_ipa_tree_profile::gate (function
*)
664 /* When profile instrumentation, use or test coverage shall be performed.
665 But for AutoFDO, this there is no instrumentation, thus this pass is
667 return (!in_lto_p
&& !flag_auto_profile
668 && (flag_branch_probabilities
|| flag_test_coverage
669 || profile_arc_flag
));
674 simple_ipa_opt_pass
*
675 make_pass_ipa_tree_profile (gcc::context
*ctxt
)
677 return new pass_ipa_tree_profile (ctxt
);
680 #include "gt-tree-profile.h"