1 /* Calculate branch probabilities, and basic block execution counts.
2 Copyright (C) 1990-2016 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"
35 #include "tree-pass.h"
39 #include "diagnostic-core.h"
40 #include "fold-const.h"
42 #include "tree-nested.h"
44 #include "gimple-iterator.h"
45 #include "gimplify-me.h"
47 #include "tree-into-ssa.h"
48 #include "value-prof.h"
50 #include "tree-cfgcleanup.h"
53 static GTY(()) tree gcov_type_node
;
54 static GTY(()) tree tree_interval_profiler_fn
;
55 static GTY(()) tree tree_pow2_profiler_fn
;
56 static GTY(()) tree tree_one_value_profiler_fn
;
57 static GTY(()) tree tree_indirect_call_profiler_fn
;
58 static GTY(()) tree tree_time_profiler_fn
;
59 static GTY(()) tree tree_average_profiler_fn
;
60 static GTY(()) tree tree_ior_profiler_fn
;
63 static GTY(()) tree ic_void_ptr_var
;
64 static GTY(()) tree ic_gcov_type_ptr_var
;
65 static GTY(()) tree ptr_void
;
67 /* Do initialization work for the edge profiler. */
70 __thread gcov* __gcov_indirect_call_counters; // pointer to actual counter
71 __thread void* __gcov_indirect_call_callee; // actual callee address
72 __thread int __gcov_function_counter; // time profiler function counter
75 init_ic_make_global_vars (void)
79 ptr_void
= build_pointer_type (void_type_node
);
82 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
84 (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE
) ?
85 "__gcov_indirect_call_topn_callee" :
86 "__gcov_indirect_call_callee")),
88 TREE_PUBLIC (ic_void_ptr_var
) = 1;
89 DECL_EXTERNAL (ic_void_ptr_var
) = 1;
90 TREE_STATIC (ic_void_ptr_var
) = 1;
91 DECL_ARTIFICIAL (ic_void_ptr_var
) = 1;
92 DECL_INITIAL (ic_void_ptr_var
) = NULL
;
94 set_decl_tls_model (ic_void_ptr_var
, decl_default_tls_model (ic_void_ptr_var
));
96 varpool_node::finalize_decl (ic_void_ptr_var
);
98 gcov_type_ptr
= build_pointer_type (get_gcov_type ());
101 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
103 (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE
) ?
104 "__gcov_indirect_call_topn_counters" :
105 "__gcov_indirect_call_counters")),
107 TREE_PUBLIC (ic_gcov_type_ptr_var
) = 1;
108 DECL_EXTERNAL (ic_gcov_type_ptr_var
) = 1;
109 TREE_STATIC (ic_gcov_type_ptr_var
) = 1;
110 DECL_ARTIFICIAL (ic_gcov_type_ptr_var
) = 1;
111 DECL_INITIAL (ic_gcov_type_ptr_var
) = NULL
;
112 if (targetm
.have_tls
)
113 set_decl_tls_model (ic_gcov_type_ptr_var
, decl_default_tls_model (ic_gcov_type_ptr_var
));
115 varpool_node::finalize_decl (ic_gcov_type_ptr_var
);
118 /* Create the type and function decls for the interface with gcov. */
121 gimple_init_edge_profiler (void)
123 tree interval_profiler_fn_type
;
124 tree pow2_profiler_fn_type
;
125 tree one_value_profiler_fn_type
;
127 tree ic_profiler_fn_type
;
128 tree average_profiler_fn_type
;
129 tree time_profiler_fn_type
;
130 const char *profiler_fn_name
;
134 gcov_type_node
= get_gcov_type ();
135 gcov_type_ptr
= build_pointer_type (gcov_type_node
);
137 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
138 interval_profiler_fn_type
139 = build_function_type_list (void_type_node
,
140 gcov_type_ptr
, gcov_type_node
,
142 unsigned_type_node
, NULL_TREE
);
143 tree_interval_profiler_fn
144 = build_fn_decl ("__gcov_interval_profiler",
145 interval_profiler_fn_type
);
146 TREE_NOTHROW (tree_interval_profiler_fn
) = 1;
147 DECL_ATTRIBUTES (tree_interval_profiler_fn
)
148 = tree_cons (get_identifier ("leaf"), NULL
,
149 DECL_ATTRIBUTES (tree_interval_profiler_fn
));
151 /* void (*) (gcov_type *, gcov_type) */
152 pow2_profiler_fn_type
153 = build_function_type_list (void_type_node
,
154 gcov_type_ptr
, gcov_type_node
,
156 tree_pow2_profiler_fn
= build_fn_decl ("__gcov_pow2_profiler",
157 pow2_profiler_fn_type
);
158 TREE_NOTHROW (tree_pow2_profiler_fn
) = 1;
159 DECL_ATTRIBUTES (tree_pow2_profiler_fn
)
160 = tree_cons (get_identifier ("leaf"), NULL
,
161 DECL_ATTRIBUTES (tree_pow2_profiler_fn
));
163 /* void (*) (gcov_type *, gcov_type) */
164 one_value_profiler_fn_type
165 = build_function_type_list (void_type_node
,
166 gcov_type_ptr
, gcov_type_node
,
168 tree_one_value_profiler_fn
169 = build_fn_decl ("__gcov_one_value_profiler",
170 one_value_profiler_fn_type
);
171 TREE_NOTHROW (tree_one_value_profiler_fn
) = 1;
172 DECL_ATTRIBUTES (tree_one_value_profiler_fn
)
173 = tree_cons (get_identifier ("leaf"), NULL
,
174 DECL_ATTRIBUTES (tree_one_value_profiler_fn
));
176 init_ic_make_global_vars ();
178 /* void (*) (gcov_type, void *) */
180 = build_function_type_list (void_type_node
,
184 profiler_fn_name
= "__gcov_indirect_call_profiler_v2";
185 if (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE
))
186 profiler_fn_name
= "__gcov_indirect_call_topn_profiler";
188 tree_indirect_call_profiler_fn
189 = build_fn_decl (profiler_fn_name
, ic_profiler_fn_type
);
191 TREE_NOTHROW (tree_indirect_call_profiler_fn
) = 1;
192 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn
)
193 = tree_cons (get_identifier ("leaf"), NULL
,
194 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn
));
196 /* void (*) (gcov_type *, gcov_type, void *) */
197 time_profiler_fn_type
198 = build_function_type_list (void_type_node
,
199 gcov_type_ptr
, NULL_TREE
);
200 tree_time_profiler_fn
201 = build_fn_decl ("__gcov_time_profiler",
202 time_profiler_fn_type
);
203 TREE_NOTHROW (tree_time_profiler_fn
) = 1;
204 DECL_ATTRIBUTES (tree_time_profiler_fn
)
205 = tree_cons (get_identifier ("leaf"), NULL
,
206 DECL_ATTRIBUTES (tree_time_profiler_fn
));
208 /* void (*) (gcov_type *, gcov_type) */
209 average_profiler_fn_type
210 = build_function_type_list (void_type_node
,
211 gcov_type_ptr
, gcov_type_node
, NULL_TREE
);
212 tree_average_profiler_fn
213 = build_fn_decl ("__gcov_average_profiler",
214 average_profiler_fn_type
);
215 TREE_NOTHROW (tree_average_profiler_fn
) = 1;
216 DECL_ATTRIBUTES (tree_average_profiler_fn
)
217 = tree_cons (get_identifier ("leaf"), NULL
,
218 DECL_ATTRIBUTES (tree_average_profiler_fn
));
220 = build_fn_decl ("__gcov_ior_profiler",
221 average_profiler_fn_type
);
222 TREE_NOTHROW (tree_ior_profiler_fn
) = 1;
223 DECL_ATTRIBUTES (tree_ior_profiler_fn
)
224 = tree_cons (get_identifier ("leaf"), NULL
,
225 DECL_ATTRIBUTES (tree_ior_profiler_fn
));
227 /* LTO streamer needs assembler names. Because we create these decls
228 late, we need to initialize them by hand. */
229 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn
);
230 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn
);
231 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn
);
232 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn
);
233 DECL_ASSEMBLER_NAME (tree_time_profiler_fn
);
234 DECL_ASSEMBLER_NAME (tree_average_profiler_fn
);
235 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn
);
239 /* Output instructions as GIMPLE trees to increment the edge
240 execution count, and insert them on E. We rely on
241 gsi_insert_on_edge to preserve the order. */
244 gimple_gen_edge_profiler (int edgeno
, edge e
)
248 one
= build_int_cst (gcov_type_node
, 1);
250 if (flag_profile_update
== PROFILE_UPDATE_ATOMIC
)
252 /* __atomic_fetch_add (&counter, 1, MEMMODEL_RELAXED); */
253 tree addr
= tree_coverage_counter_addr (GCOV_COUNTER_ARCS
, edgeno
);
255 = gimple_build_call (builtin_decl_explicit (GCOV_TYPE_ATOMIC_FETCH_ADD
),
257 build_int_cst (integer_type_node
,
259 gsi_insert_on_edge (e
, stmt
);
263 tree ref
= tree_coverage_counter_ref (GCOV_COUNTER_ARCS
, edgeno
);
264 tree gcov_type_tmp_var
= make_temp_ssa_name (gcov_type_node
,
265 NULL
, "PROF_edge_counter");
266 gassign
*stmt1
= gimple_build_assign (gcov_type_tmp_var
, ref
);
267 gcov_type_tmp_var
= make_temp_ssa_name (gcov_type_node
,
268 NULL
, "PROF_edge_counter");
269 gassign
*stmt2
= gimple_build_assign (gcov_type_tmp_var
, PLUS_EXPR
,
270 gimple_assign_lhs (stmt1
), one
);
271 gassign
*stmt3
= gimple_build_assign (unshare_expr (ref
),
272 gimple_assign_lhs (stmt2
));
273 gsi_insert_on_edge (e
, stmt1
);
274 gsi_insert_on_edge (e
, stmt2
);
275 gsi_insert_on_edge (e
, stmt3
);
279 /* Emits code to get VALUE to instrument at GSI, and returns the
280 variable containing the value. */
283 prepare_instrumented_value (gimple_stmt_iterator
*gsi
, histogram_value value
)
285 tree val
= value
->hvalue
.value
;
286 if (POINTER_TYPE_P (TREE_TYPE (val
)))
287 val
= fold_convert (build_nonstandard_integer_type
288 (TYPE_PRECISION (TREE_TYPE (val
)), 1), val
);
289 return force_gimple_operand_gsi (gsi
, fold_convert (gcov_type_node
, val
),
290 true, NULL_TREE
, true, GSI_SAME_STMT
);
293 /* Output instructions as GIMPLE trees to increment the interval histogram
294 counter. VALUE is the expression whose value is profiled. TAG is the
295 tag of the section for counters, BASE is offset of the counter position. */
298 gimple_gen_interval_profiler (histogram_value value
, unsigned tag
, unsigned base
)
300 gimple
*stmt
= value
->hvalue
.stmt
;
301 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
302 tree ref
= tree_coverage_counter_ref (tag
, base
), ref_ptr
;
305 tree start
= build_int_cst_type (integer_type_node
,
306 value
->hdata
.intvl
.int_start
);
307 tree steps
= build_int_cst_type (unsigned_type_node
,
308 value
->hdata
.intvl
.steps
);
310 ref_ptr
= force_gimple_operand_gsi (&gsi
,
312 true, NULL_TREE
, true, GSI_SAME_STMT
);
313 val
= prepare_instrumented_value (&gsi
, value
);
314 call
= gimple_build_call (tree_interval_profiler_fn
, 4,
315 ref_ptr
, val
, start
, steps
);
316 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
319 /* Output instructions as GIMPLE trees to increment the power of two histogram
320 counter. VALUE is the expression whose value is profiled. TAG is the tag
321 of the section for counters, BASE is offset of the counter position. */
324 gimple_gen_pow2_profiler (histogram_value value
, unsigned tag
, unsigned base
)
326 gimple
*stmt
= value
->hvalue
.stmt
;
327 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
328 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
332 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
333 true, NULL_TREE
, true, GSI_SAME_STMT
);
334 val
= prepare_instrumented_value (&gsi
, value
);
335 call
= gimple_build_call (tree_pow2_profiler_fn
, 2, ref_ptr
, val
);
336 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
339 /* Output instructions as GIMPLE trees for code to find the most common value.
340 VALUE is the expression whose value is profiled. TAG is the tag of the
341 section for counters, BASE is offset of the counter position. */
344 gimple_gen_one_value_profiler (histogram_value value
, unsigned tag
, unsigned base
)
346 gimple
*stmt
= value
->hvalue
.stmt
;
347 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
348 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
352 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
353 true, NULL_TREE
, true, GSI_SAME_STMT
);
354 val
= prepare_instrumented_value (&gsi
, value
);
355 call
= gimple_build_call (tree_one_value_profiler_fn
, 2, ref_ptr
, val
);
356 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
360 /* Output instructions as GIMPLE trees for code to find the most
361 common called function in indirect call.
362 VALUE is the call expression whose indirect callee is profiled.
363 TAG is the tag of the section for counters, BASE is offset of the
367 gimple_gen_ic_profiler (histogram_value value
, unsigned tag
, unsigned base
)
370 gassign
*stmt1
, *stmt2
, *stmt3
;
371 gimple
*stmt
= value
->hvalue
.stmt
;
372 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
373 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
375 if ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE
) &&
376 tag
== GCOV_COUNTER_V_INDIR
) ||
377 (!PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE
) &&
378 tag
== GCOV_COUNTER_ICALL_TOPNV
))
381 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
382 true, NULL_TREE
, true, GSI_SAME_STMT
);
386 stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
387 stmt2: tmp1 = (void *) (indirect call argument value)
388 stmt3: __gcov_indirect_call_callee = tmp1;
391 stmt1
= gimple_build_assign (ic_gcov_type_ptr_var
, ref_ptr
);
392 tmp1
= make_temp_ssa_name (ptr_void
, NULL
, "PROF");
393 stmt2
= gimple_build_assign (tmp1
, unshare_expr (value
->hvalue
.value
));
394 stmt3
= gimple_build_assign (ic_void_ptr_var
, gimple_assign_lhs (stmt2
));
396 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
397 gsi_insert_before (&gsi
, stmt2
, GSI_SAME_STMT
);
398 gsi_insert_before (&gsi
, stmt3
, GSI_SAME_STMT
);
402 /* Output instructions as GIMPLE trees for code to find the most
403 common called function in indirect call. Insert instructions at the
404 beginning of every possible called function.
408 gimple_gen_ic_func_profiler (void)
410 struct cgraph_node
* c_node
= cgraph_node::get (current_function_decl
);
411 gimple_stmt_iterator gsi
;
414 tree tree_uid
, cur_func
, void0
;
416 if (c_node
->only_called_directly_p ())
419 gimple_init_edge_profiler ();
423 stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
424 ¤t_function_decl)
426 gsi
= gsi_after_labels (split_edge (single_succ_edge
427 (ENTRY_BLOCK_PTR_FOR_FN (cfun
))));
429 cur_func
= force_gimple_operand_gsi (&gsi
,
430 build_addr (current_function_decl
),
432 true, GSI_SAME_STMT
);
433 tree_uid
= build_int_cst
435 cgraph_node::get (current_function_decl
)->profile_id
);
436 stmt1
= gimple_build_call (tree_indirect_call_profiler_fn
, 2,
438 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
440 /* Set __gcov_indirect_call_callee to 0,
441 so that calls from other modules won't get misattributed
442 to the last caller of the current callee. */
443 void0
= build_int_cst (build_pointer_type (void_type_node
), 0);
444 stmt2
= gimple_build_assign (ic_void_ptr_var
, void0
);
445 gsi_insert_before (&gsi
, stmt2
, GSI_SAME_STMT
);
448 /* Output instructions as GIMPLE tree at the beginning for each function.
449 TAG is the tag of the section for counters, BASE is offset of the
450 counter position and GSI is the iterator we place the counter. */
453 gimple_gen_time_profiler (unsigned tag
, unsigned base
,
454 gimple_stmt_iterator
&gsi
)
456 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
459 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
460 true, NULL_TREE
, true, GSI_SAME_STMT
);
461 call
= gimple_build_call (tree_time_profiler_fn
, 1, ref_ptr
);
462 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
465 /* Output instructions as GIMPLE trees for code to find the most common value
466 of a difference between two evaluations of an expression.
467 VALUE is the expression whose value is profiled. TAG is the tag of the
468 section for counters, BASE is offset of the counter position. */
471 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED
,
472 unsigned tag ATTRIBUTE_UNUSED
,
473 unsigned base ATTRIBUTE_UNUSED
)
475 /* FIXME implement this. */
477 internal_error ("unimplemented functionality");
481 /* Output instructions as GIMPLE trees to increment the average histogram
482 counter. VALUE is the expression whose value is profiled. TAG is the
483 tag of the section for counters, BASE is offset of the counter position. */
486 gimple_gen_average_profiler (histogram_value value
, unsigned tag
, unsigned base
)
488 gimple
*stmt
= value
->hvalue
.stmt
;
489 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
490 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
494 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
496 true, GSI_SAME_STMT
);
497 val
= prepare_instrumented_value (&gsi
, value
);
498 call
= gimple_build_call (tree_average_profiler_fn
, 2, ref_ptr
, val
);
499 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
502 /* Output instructions as GIMPLE trees to increment the ior histogram
503 counter. VALUE is the expression whose value is profiled. TAG is the
504 tag of the section for counters, BASE is offset of the counter position. */
507 gimple_gen_ior_profiler (histogram_value value
, unsigned tag
, unsigned base
)
509 gimple
*stmt
= value
->hvalue
.stmt
;
510 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
511 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
515 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
516 true, NULL_TREE
, true, GSI_SAME_STMT
);
517 val
= prepare_instrumented_value (&gsi
, value
);
518 call
= gimple_build_call (tree_ior_profiler_fn
, 2, ref_ptr
, val
);
519 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
522 /* Profile all functions in the callgraph. */
525 tree_profiling (void)
527 struct cgraph_node
*node
;
529 /* This is a small-ipa pass that gets called only once, from
530 cgraphunit.c:ipa_passes(). */
531 gcc_assert (symtab
->state
== IPA_SSA
);
533 init_node_map (true);
535 FOR_EACH_DEFINED_FUNCTION (node
)
537 if (!gimple_has_body_p (node
->decl
))
540 /* Don't profile functions produced for builtin stuff. */
541 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
)
544 if (lookup_attribute ("no_profile_instrument_function",
545 DECL_ATTRIBUTES (node
->decl
)))
547 /* Do not instrument extern inline functions when testing coverage.
548 While this is not perfectly consistent (early inlined extern inlines
549 will get acocunted), testsuite expects that. */
550 if (DECL_EXTERNAL (node
->decl
)
551 && flag_test_coverage
)
554 push_cfun (DECL_STRUCT_FUNCTION (node
->decl
));
556 /* Local pure-const may imply need to fixup the cfg. */
557 if (execute_fixup_cfg () & TODO_cleanup_cfg
)
562 if (! flag_branch_probabilities
563 && flag_profile_values
)
564 gimple_gen_ic_func_profiler ();
566 if (flag_branch_probabilities
567 && flag_profile_values
568 && flag_value_profile_transformations
)
569 gimple_value_profile_transformations ();
571 /* The above could hose dominator info. Currently there is
572 none coming in, this is a safety valve. It should be
573 easy to adjust it, if and when there is some. */
574 free_dominance_info (CDI_DOMINATORS
);
575 free_dominance_info (CDI_POST_DOMINATORS
);
579 /* Drop pure/const flags from instrumented functions. */
580 if (profile_arc_flag
|| flag_test_coverage
)
581 FOR_EACH_DEFINED_FUNCTION (node
)
583 if (!gimple_has_body_p (node
->decl
)
585 || node
->decl
!= node
->clone_of
->decl
))
588 /* Don't profile functions produced for builtin stuff. */
589 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
)
592 node
->set_const_flag (false, false);
593 node
->set_pure_flag (false, false);
596 /* Update call statements and rebuild the cgraph. */
597 FOR_EACH_DEFINED_FUNCTION (node
)
601 if (!gimple_has_body_p (node
->decl
)
603 || node
->decl
!= node
->clone_of
->decl
))
606 /* Don't profile functions produced for builtin stuff. */
607 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
)
610 push_cfun (DECL_STRUCT_FUNCTION (node
->decl
));
612 FOR_EACH_BB_FN (bb
, cfun
)
614 gimple_stmt_iterator gsi
;
615 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
617 gimple
*stmt
= gsi_stmt (gsi
);
618 if (is_gimple_call (stmt
))
623 /* re-merge split blocks. */
625 update_ssa (TODO_update_ssa
);
627 cgraph_edge::rebuild_edges ();
632 handle_missing_profiles ();
640 const pass_data pass_data_ipa_tree_profile
=
642 SIMPLE_IPA_PASS
, /* type */
643 "profile", /* name */
644 OPTGROUP_NONE
, /* optinfo_flags */
645 TV_IPA_PROFILE
, /* tv_id */
646 0, /* properties_required */
647 0, /* properties_provided */
648 0, /* properties_destroyed */
649 0, /* todo_flags_start */
650 TODO_dump_symtab
, /* todo_flags_finish */
653 class pass_ipa_tree_profile
: public simple_ipa_opt_pass
656 pass_ipa_tree_profile (gcc::context
*ctxt
)
657 : simple_ipa_opt_pass (pass_data_ipa_tree_profile
, ctxt
)
660 /* opt_pass methods: */
661 virtual bool gate (function
*);
662 virtual unsigned int execute (function
*) { return tree_profiling (); }
664 }; // class pass_ipa_tree_profile
667 pass_ipa_tree_profile::gate (function
*)
669 /* When profile instrumentation, use or test coverage shall be performed.
670 But for AutoFDO, this there is no instrumentation, thus this pass is
672 return (!in_lto_p
&& !flag_auto_profile
673 && (flag_branch_probabilities
|| flag_test_coverage
674 || profile_arc_flag
));
679 simple_ipa_opt_pass
*
680 make_pass_ipa_tree_profile (gcc::context
*ctxt
)
682 return new pass_ipa_tree_profile (ctxt
);
685 #include "gt-tree-profile.h"