1 /* Calculate branch probabilities, and basic block execution counts.
2 Copyright (C) 1990-2014 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 "basic-block.h"
34 #include "diagnostic-core.h"
37 #include "tree-ssa-alias.h"
38 #include "internal-fn.h"
39 #include "gimple-expr.h"
43 #include "tree-nested.h"
45 #include "gimple-iterator.h"
46 #include "gimplify-me.h"
47 #include "gimple-ssa.h"
50 #include "stringpool.h"
51 #include "tree-ssanames.h"
52 #include "tree-into-ssa.h"
53 #include "tree-pass.h"
54 #include "value-prof.h"
57 #include "tree-cfgcleanup.h"
58 #include "tree-nested.h"
60 static GTY(()) tree gcov_type_node
;
61 static GTY(()) tree tree_interval_profiler_fn
;
62 static GTY(()) tree tree_pow2_profiler_fn
;
63 static GTY(()) tree tree_one_value_profiler_fn
;
64 static GTY(()) tree tree_indirect_call_profiler_fn
;
65 static GTY(()) tree tree_time_profiler_fn
;
66 static GTY(()) tree tree_average_profiler_fn
;
67 static GTY(()) tree tree_ior_profiler_fn
;
70 static GTY(()) tree ic_void_ptr_var
;
71 static GTY(()) tree ic_gcov_type_ptr_var
;
72 static GTY(()) tree ptr_void
;
74 /* Do initialization work for the edge profiler. */
77 __thread gcov* __gcov_indirect_call_counters; // pointer to actual counter
78 __thread void* __gcov_indirect_call_callee; // actual callee address
79 __thread int __gcov_function_counter; // time profiler function counter
82 init_ic_make_global_vars (void)
86 ptr_void
= build_pointer_type (void_type_node
);
88 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
92 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
93 get_identifier ("__gcov_indirect_call_callee_ltopriv"),
95 TREE_PUBLIC (ic_void_ptr_var
) = 1;
96 DECL_COMMON (ic_void_ptr_var
) = 1;
97 DECL_VISIBILITY (ic_void_ptr_var
) = VISIBILITY_HIDDEN
;
98 DECL_VISIBILITY_SPECIFIED (ic_void_ptr_var
) = true;
103 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
104 get_identifier ("__gcov_indirect_call_callee"),
106 TREE_PUBLIC (ic_void_ptr_var
) = 1;
107 DECL_EXTERNAL (ic_void_ptr_var
) = 1;
109 TREE_STATIC (ic_void_ptr_var
) = 1;
110 DECL_ARTIFICIAL (ic_void_ptr_var
) = 1;
111 DECL_INITIAL (ic_void_ptr_var
) = NULL
;
112 if (targetm
.have_tls
)
113 set_decl_tls_model (ic_void_ptr_var
, decl_default_tls_model (ic_void_ptr_var
));
115 varpool_node::finalize_decl (ic_void_ptr_var
);
117 gcov_type_ptr
= build_pointer_type (get_gcov_type ());
118 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
122 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
123 get_identifier ("__gcov_indirect_call_counters_ltopriv"),
125 TREE_PUBLIC (ic_gcov_type_ptr_var
) = 1;
126 DECL_COMMON (ic_gcov_type_ptr_var
) = 1;
127 DECL_VISIBILITY (ic_gcov_type_ptr_var
) = VISIBILITY_HIDDEN
;
128 DECL_VISIBILITY_SPECIFIED (ic_gcov_type_ptr_var
) = true;
133 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
134 get_identifier ("__gcov_indirect_call_counters"),
136 TREE_PUBLIC (ic_gcov_type_ptr_var
) = 1;
137 DECL_EXTERNAL (ic_gcov_type_ptr_var
) = 1;
139 TREE_STATIC (ic_gcov_type_ptr_var
) = 1;
140 DECL_ARTIFICIAL (ic_gcov_type_ptr_var
) = 1;
141 DECL_INITIAL (ic_gcov_type_ptr_var
) = NULL
;
142 if (targetm
.have_tls
)
143 set_decl_tls_model (ic_gcov_type_ptr_var
, decl_default_tls_model (ic_gcov_type_ptr_var
));
145 varpool_node::finalize_decl (ic_gcov_type_ptr_var
);
148 /* Create the type and function decls for the interface with gcov. */
151 gimple_init_edge_profiler (void)
153 tree interval_profiler_fn_type
;
154 tree pow2_profiler_fn_type
;
155 tree one_value_profiler_fn_type
;
157 tree ic_profiler_fn_type
;
158 tree average_profiler_fn_type
;
159 tree time_profiler_fn_type
;
163 gcov_type_node
= get_gcov_type ();
164 gcov_type_ptr
= build_pointer_type (gcov_type_node
);
166 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
167 interval_profiler_fn_type
168 = build_function_type_list (void_type_node
,
169 gcov_type_ptr
, gcov_type_node
,
171 unsigned_type_node
, NULL_TREE
);
172 tree_interval_profiler_fn
173 = build_fn_decl ("__gcov_interval_profiler",
174 interval_profiler_fn_type
);
175 TREE_NOTHROW (tree_interval_profiler_fn
) = 1;
176 DECL_ATTRIBUTES (tree_interval_profiler_fn
)
177 = tree_cons (get_identifier ("leaf"), NULL
,
178 DECL_ATTRIBUTES (tree_interval_profiler_fn
));
180 /* void (*) (gcov_type *, gcov_type) */
181 pow2_profiler_fn_type
182 = build_function_type_list (void_type_node
,
183 gcov_type_ptr
, gcov_type_node
,
185 tree_pow2_profiler_fn
= build_fn_decl ("__gcov_pow2_profiler",
186 pow2_profiler_fn_type
);
187 TREE_NOTHROW (tree_pow2_profiler_fn
) = 1;
188 DECL_ATTRIBUTES (tree_pow2_profiler_fn
)
189 = tree_cons (get_identifier ("leaf"), NULL
,
190 DECL_ATTRIBUTES (tree_pow2_profiler_fn
));
192 /* void (*) (gcov_type *, gcov_type) */
193 one_value_profiler_fn_type
194 = build_function_type_list (void_type_node
,
195 gcov_type_ptr
, gcov_type_node
,
197 tree_one_value_profiler_fn
198 = build_fn_decl ("__gcov_one_value_profiler",
199 one_value_profiler_fn_type
);
200 TREE_NOTHROW (tree_one_value_profiler_fn
) = 1;
201 DECL_ATTRIBUTES (tree_one_value_profiler_fn
)
202 = tree_cons (get_identifier ("leaf"), NULL
,
203 DECL_ATTRIBUTES (tree_one_value_profiler_fn
));
205 init_ic_make_global_vars ();
207 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
210 /* void (*) (gcov_type, void *) */
212 = build_function_type_list (void_type_node
,
213 gcov_type_ptr
, gcov_type_node
,
216 tree_indirect_call_profiler_fn
217 = build_fn_decl ("__gcov_indirect_call_profiler",
218 ic_profiler_fn_type
);
222 /* void (*) (gcov_type, void *) */
224 = build_function_type_list (void_type_node
,
228 tree_indirect_call_profiler_fn
229 = build_fn_decl ("__gcov_indirect_call_profiler_v2",
230 ic_profiler_fn_type
);
232 TREE_NOTHROW (tree_indirect_call_profiler_fn
) = 1;
233 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn
)
234 = tree_cons (get_identifier ("leaf"), NULL
,
235 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn
));
237 /* void (*) (gcov_type *, gcov_type, void *) */
238 time_profiler_fn_type
239 = build_function_type_list (void_type_node
,
240 gcov_type_ptr
, NULL_TREE
);
241 tree_time_profiler_fn
242 = build_fn_decl ("__gcov_time_profiler",
243 time_profiler_fn_type
);
244 TREE_NOTHROW (tree_time_profiler_fn
) = 1;
245 DECL_ATTRIBUTES (tree_time_profiler_fn
)
246 = tree_cons (get_identifier ("leaf"), NULL
,
247 DECL_ATTRIBUTES (tree_time_profiler_fn
));
249 /* void (*) (gcov_type *, gcov_type) */
250 average_profiler_fn_type
251 = build_function_type_list (void_type_node
,
252 gcov_type_ptr
, gcov_type_node
, NULL_TREE
);
253 tree_average_profiler_fn
254 = build_fn_decl ("__gcov_average_profiler",
255 average_profiler_fn_type
);
256 TREE_NOTHROW (tree_average_profiler_fn
) = 1;
257 DECL_ATTRIBUTES (tree_average_profiler_fn
)
258 = tree_cons (get_identifier ("leaf"), NULL
,
259 DECL_ATTRIBUTES (tree_average_profiler_fn
));
261 = build_fn_decl ("__gcov_ior_profiler",
262 average_profiler_fn_type
);
263 TREE_NOTHROW (tree_ior_profiler_fn
) = 1;
264 DECL_ATTRIBUTES (tree_ior_profiler_fn
)
265 = tree_cons (get_identifier ("leaf"), NULL
,
266 DECL_ATTRIBUTES (tree_ior_profiler_fn
));
268 /* LTO streamer needs assembler names. Because we create these decls
269 late, we need to initialize them by hand. */
270 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn
);
271 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn
);
272 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn
);
273 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn
);
274 DECL_ASSEMBLER_NAME (tree_time_profiler_fn
);
275 DECL_ASSEMBLER_NAME (tree_average_profiler_fn
);
276 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn
);
280 /* Output instructions as GIMPLE trees to increment the edge
281 execution count, and insert them on E. We rely on
282 gsi_insert_on_edge to preserve the order. */
285 gimple_gen_edge_profiler (int edgeno
, edge e
)
287 tree ref
, one
, gcov_type_tmp_var
;
288 gimple stmt1
, stmt2
, stmt3
;
290 ref
= tree_coverage_counter_ref (GCOV_COUNTER_ARCS
, edgeno
);
291 one
= build_int_cst (gcov_type_node
, 1);
292 gcov_type_tmp_var
= make_temp_ssa_name (gcov_type_node
,
293 NULL
, "PROF_edge_counter");
294 stmt1
= gimple_build_assign (gcov_type_tmp_var
, ref
);
295 gcov_type_tmp_var
= make_temp_ssa_name (gcov_type_node
,
296 NULL
, "PROF_edge_counter");
297 stmt2
= gimple_build_assign_with_ops (PLUS_EXPR
, gcov_type_tmp_var
,
298 gimple_assign_lhs (stmt1
), one
);
299 stmt3
= gimple_build_assign (unshare_expr (ref
), gimple_assign_lhs (stmt2
));
300 gsi_insert_on_edge (e
, stmt1
);
301 gsi_insert_on_edge (e
, stmt2
);
302 gsi_insert_on_edge (e
, stmt3
);
305 /* Emits code to get VALUE to instrument at GSI, and returns the
306 variable containing the value. */
309 prepare_instrumented_value (gimple_stmt_iterator
*gsi
, histogram_value value
)
311 tree val
= value
->hvalue
.value
;
312 if (POINTER_TYPE_P (TREE_TYPE (val
)))
313 val
= fold_convert (build_nonstandard_integer_type
314 (TYPE_PRECISION (TREE_TYPE (val
)), 1), val
);
315 return force_gimple_operand_gsi (gsi
, fold_convert (gcov_type_node
, val
),
316 true, NULL_TREE
, true, GSI_SAME_STMT
);
319 /* Output instructions as GIMPLE trees to increment the interval histogram
320 counter. VALUE is the expression whose value is profiled. TAG is the
321 tag of the section for counters, BASE is offset of the counter position. */
324 gimple_gen_interval_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
= tree_coverage_counter_ref (tag
, base
), ref_ptr
;
331 tree start
= build_int_cst_type (integer_type_node
,
332 value
->hdata
.intvl
.int_start
);
333 tree steps
= build_int_cst_type (unsigned_type_node
,
334 value
->hdata
.intvl
.steps
);
336 ref_ptr
= force_gimple_operand_gsi (&gsi
,
337 build_addr (ref
, current_function_decl
),
338 true, NULL_TREE
, true, GSI_SAME_STMT
);
339 val
= prepare_instrumented_value (&gsi
, value
);
340 call
= gimple_build_call (tree_interval_profiler_fn
, 4,
341 ref_ptr
, val
, start
, steps
);
342 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
345 /* Output instructions as GIMPLE trees to increment the power of two histogram
346 counter. VALUE is the expression whose value is profiled. TAG is the tag
347 of the section for counters, BASE is offset of the counter position. */
350 gimple_gen_pow2_profiler (histogram_value value
, unsigned tag
, unsigned base
)
352 gimple stmt
= value
->hvalue
.stmt
;
353 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
354 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
358 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
359 true, NULL_TREE
, true, GSI_SAME_STMT
);
360 val
= prepare_instrumented_value (&gsi
, value
);
361 call
= gimple_build_call (tree_pow2_profiler_fn
, 2, ref_ptr
, val
);
362 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
365 /* Output instructions as GIMPLE trees for code to find the most common value.
366 VALUE is the expression whose value is profiled. TAG is the tag of the
367 section for counters, BASE is offset of the counter position. */
370 gimple_gen_one_value_profiler (histogram_value value
, unsigned tag
, unsigned base
)
372 gimple stmt
= value
->hvalue
.stmt
;
373 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
374 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
378 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
379 true, NULL_TREE
, true, GSI_SAME_STMT
);
380 val
= prepare_instrumented_value (&gsi
, value
);
381 call
= gimple_build_call (tree_one_value_profiler_fn
, 2, ref_ptr
, val
);
382 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
386 /* Output instructions as GIMPLE trees for code to find the most
387 common called function in indirect call.
388 VALUE is the call expression whose indirect callee is profiled.
389 TAG is the tag of the section for counters, BASE is offset of the
393 gimple_gen_ic_profiler (histogram_value value
, unsigned tag
, unsigned base
)
396 gimple stmt1
, stmt2
, stmt3
;
397 gimple stmt
= value
->hvalue
.stmt
;
398 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
399 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
401 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
402 true, NULL_TREE
, true, GSI_SAME_STMT
);
406 stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
407 stmt2: tmp1 = (void *) (indirect call argument value)
408 stmt3: __gcov_indirect_call_callee = tmp1;
411 stmt1
= gimple_build_assign (ic_gcov_type_ptr_var
, ref_ptr
);
412 tmp1
= make_temp_ssa_name (ptr_void
, NULL
, "PROF");
413 stmt2
= gimple_build_assign (tmp1
, unshare_expr (value
->hvalue
.value
));
414 stmt3
= gimple_build_assign (ic_void_ptr_var
, gimple_assign_lhs (stmt2
));
416 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
417 gsi_insert_before (&gsi
, stmt2
, GSI_SAME_STMT
);
418 gsi_insert_before (&gsi
, stmt3
, GSI_SAME_STMT
);
422 /* Output instructions as GIMPLE trees for code to find the most
423 common called function in indirect call. Insert instructions at the
424 beginning of every possible called function.
428 gimple_gen_ic_func_profiler (void)
430 struct cgraph_node
* c_node
= cgraph_node::get (current_function_decl
);
431 gimple_stmt_iterator gsi
;
433 tree tree_uid
, cur_func
, void0
;
435 if (c_node
->only_called_directly_p ())
438 gimple_init_edge_profiler ();
442 stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
443 ¤t_function_decl)
446 gsi_after_labels (split_edge (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun
))));
448 cur_func
= force_gimple_operand_gsi (&gsi
,
449 build_addr (current_function_decl
,
450 current_function_decl
),
452 true, GSI_SAME_STMT
);
453 tree_uid
= build_int_cst
454 (gcov_type_node
, cgraph_node::get (current_function_decl
)->profile_id
);
455 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
458 tree counter_ptr
, ptr_var
;
459 counter_ptr
= force_gimple_operand_gsi (&gsi
, ic_gcov_type_ptr_var
,
460 true, NULL_TREE
, true,
462 ptr_var
= force_gimple_operand_gsi (&gsi
, ic_void_ptr_var
,
463 true, NULL_TREE
, true,
466 stmt1
= gimple_build_call (tree_indirect_call_profiler_fn
, 4,
467 counter_ptr
, tree_uid
, cur_func
, ptr_var
);
471 stmt1
= gimple_build_call (tree_indirect_call_profiler_fn
, 2,
474 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
476 /* Set __gcov_indirect_call_callee to 0,
477 so that calls from other modules won't get misattributed
478 to the last caller of the current callee. */
479 void0
= build_int_cst (build_pointer_type (void_type_node
), 0);
480 stmt2
= gimple_build_assign (ic_void_ptr_var
, void0
);
481 gsi_insert_before (&gsi
, stmt2
, GSI_SAME_STMT
);
484 /* Output instructions as GIMPLE tree at the beginning for each function.
485 TAG is the tag of the section for counters, BASE is offset of the
486 counter position and GSI is the iterator we place the counter. */
489 gimple_gen_time_profiler (unsigned tag
, unsigned base
,
490 gimple_stmt_iterator
&gsi
)
492 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
495 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
496 true, NULL_TREE
, true, GSI_SAME_STMT
);
497 call
= gimple_build_call (tree_time_profiler_fn
, 1, ref_ptr
);
498 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
501 /* Output instructions as GIMPLE trees for code to find the most common value
502 of a difference between two evaluations of an expression.
503 VALUE is the expression whose value is profiled. TAG is the tag of the
504 section for counters, BASE is offset of the counter position. */
507 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED
,
508 unsigned tag ATTRIBUTE_UNUSED
,
509 unsigned base ATTRIBUTE_UNUSED
)
511 /* FIXME implement this. */
512 #ifdef ENABLE_CHECKING
513 internal_error ("unimplemented functionality");
518 /* Output instructions as GIMPLE trees to increment the average histogram
519 counter. VALUE is the expression whose value is profiled. TAG is the
520 tag of the section for counters, BASE is offset of the counter position. */
523 gimple_gen_average_profiler (histogram_value value
, unsigned tag
, unsigned base
)
525 gimple stmt
= value
->hvalue
.stmt
;
526 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
527 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
531 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
533 true, GSI_SAME_STMT
);
534 val
= prepare_instrumented_value (&gsi
, value
);
535 call
= gimple_build_call (tree_average_profiler_fn
, 2, ref_ptr
, val
);
536 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
539 /* Output instructions as GIMPLE trees to increment the ior histogram
540 counter. VALUE is the expression whose value is profiled. TAG is the
541 tag of the section for counters, BASE is offset of the counter position. */
544 gimple_gen_ior_profiler (histogram_value value
, unsigned tag
, unsigned base
)
546 gimple stmt
= value
->hvalue
.stmt
;
547 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
548 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
552 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
553 true, NULL_TREE
, true, GSI_SAME_STMT
);
554 val
= prepare_instrumented_value (&gsi
, value
);
555 call
= gimple_build_call (tree_ior_profiler_fn
, 2, ref_ptr
, val
);
556 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
559 /* Profile all functions in the callgraph. */
562 tree_profiling (void)
564 struct cgraph_node
*node
;
566 /* This is a small-ipa pass that gets called only once, from
567 cgraphunit.c:ipa_passes(). */
568 gcc_assert (symtab
->state
== IPA_SSA
);
570 init_node_map (true);
572 FOR_EACH_DEFINED_FUNCTION (node
)
574 if (!gimple_has_body_p (node
->decl
))
577 /* Don't profile functions produced for builtin stuff. */
578 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
)
581 /* Do not instrument extern inline functions when testing coverage.
582 While this is not perfectly consistent (early inlined extern inlines
583 will get acocunted), testsuite expects that. */
584 if (DECL_EXTERNAL (node
->decl
)
585 && flag_test_coverage
)
588 push_cfun (DECL_STRUCT_FUNCTION (node
->decl
));
590 /* Local pure-const may imply need to fixup the cfg. */
591 if (execute_fixup_cfg () & TODO_cleanup_cfg
)
596 if (! flag_branch_probabilities
597 && flag_profile_values
)
598 gimple_gen_ic_func_profiler ();
600 if (flag_branch_probabilities
601 && flag_profile_values
602 && flag_value_profile_transformations
)
603 gimple_value_profile_transformations ();
605 /* The above could hose dominator info. Currently there is
606 none coming in, this is a safety valve. It should be
607 easy to adjust it, if and when there is some. */
608 free_dominance_info (CDI_DOMINATORS
);
609 free_dominance_info (CDI_POST_DOMINATORS
);
613 /* Drop pure/const flags from instrumented functions. */
614 FOR_EACH_DEFINED_FUNCTION (node
)
616 if (!gimple_has_body_p (node
->decl
)
618 || node
->decl
!= node
->clone_of
->decl
))
621 /* Don't profile functions produced for builtin stuff. */
622 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
)
625 node
->set_const_flag (false, false);
626 node
->set_pure_flag (false, false);
629 /* Update call statements and rebuild the cgraph. */
630 FOR_EACH_DEFINED_FUNCTION (node
)
634 if (!gimple_has_body_p (node
->decl
)
636 || node
->decl
!= node
->clone_of
->decl
))
639 /* Don't profile functions produced for builtin stuff. */
640 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
)
643 push_cfun (DECL_STRUCT_FUNCTION (node
->decl
));
645 FOR_EACH_BB_FN (bb
, cfun
)
647 gimple_stmt_iterator gsi
;
648 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
650 gimple stmt
= gsi_stmt (gsi
);
651 if (is_gimple_call (stmt
))
656 /* re-merge split blocks. */
658 update_ssa (TODO_update_ssa
);
660 cgraph_edge::rebuild_edges ();
665 handle_missing_profiles ();
673 const pass_data pass_data_ipa_tree_profile
=
675 SIMPLE_IPA_PASS
, /* type */
676 "profile", /* name */
677 OPTGROUP_NONE
, /* optinfo_flags */
678 TV_IPA_PROFILE
, /* tv_id */
679 0, /* properties_required */
680 0, /* properties_provided */
681 0, /* properties_destroyed */
682 0, /* todo_flags_start */
683 0, /* todo_flags_finish */
686 class pass_ipa_tree_profile
: public simple_ipa_opt_pass
689 pass_ipa_tree_profile (gcc::context
*ctxt
)
690 : simple_ipa_opt_pass (pass_data_ipa_tree_profile
, ctxt
)
693 /* opt_pass methods: */
694 virtual bool gate (function
*);
695 virtual unsigned int execute (function
*) { return tree_profiling (); }
697 }; // class pass_ipa_tree_profile
700 pass_ipa_tree_profile::gate (function
*)
702 /* When profile instrumentation, use or test coverage shall be performed. */
704 && (flag_branch_probabilities
|| flag_test_coverage
705 || profile_arc_flag
));
710 simple_ipa_opt_pass
*
711 make_pass_ipa_tree_profile (gcc::context
*ctxt
)
713 return new pass_ipa_tree_profile (ctxt
);
716 #include "gt-tree-profile.h"