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 DECL_TLS_MODEL (ic_void_ptr_var
) =
114 decl_default_tls_model (ic_void_ptr_var
);
116 varpool_finalize_decl (ic_void_ptr_var
);
118 gcov_type_ptr
= build_pointer_type (get_gcov_type ());
119 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
123 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
124 get_identifier ("__gcov_indirect_call_counters_ltopriv"),
126 TREE_PUBLIC (ic_gcov_type_ptr_var
) = 1;
127 DECL_COMMON (ic_gcov_type_ptr_var
) = 1;
128 DECL_VISIBILITY (ic_gcov_type_ptr_var
) = VISIBILITY_HIDDEN
;
129 DECL_VISIBILITY_SPECIFIED (ic_gcov_type_ptr_var
) = true;
134 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
135 get_identifier ("__gcov_indirect_call_counters"),
137 TREE_PUBLIC (ic_gcov_type_ptr_var
) = 1;
138 DECL_EXTERNAL (ic_gcov_type_ptr_var
) = 1;
140 TREE_STATIC (ic_gcov_type_ptr_var
) = 1;
141 DECL_ARTIFICIAL (ic_gcov_type_ptr_var
) = 1;
142 DECL_INITIAL (ic_gcov_type_ptr_var
) = NULL
;
143 if (targetm
.have_tls
)
144 DECL_TLS_MODEL (ic_gcov_type_ptr_var
) =
145 decl_default_tls_model (ic_gcov_type_ptr_var
);
147 varpool_finalize_decl (ic_gcov_type_ptr_var
);
150 /* Create the type and function decls for the interface with gcov. */
153 gimple_init_edge_profiler (void)
155 tree interval_profiler_fn_type
;
156 tree pow2_profiler_fn_type
;
157 tree one_value_profiler_fn_type
;
159 tree ic_profiler_fn_type
;
160 tree average_profiler_fn_type
;
161 tree time_profiler_fn_type
;
165 gcov_type_node
= get_gcov_type ();
166 gcov_type_ptr
= build_pointer_type (gcov_type_node
);
168 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
169 interval_profiler_fn_type
170 = build_function_type_list (void_type_node
,
171 gcov_type_ptr
, gcov_type_node
,
173 unsigned_type_node
, NULL_TREE
);
174 tree_interval_profiler_fn
175 = build_fn_decl ("__gcov_interval_profiler",
176 interval_profiler_fn_type
);
177 TREE_NOTHROW (tree_interval_profiler_fn
) = 1;
178 DECL_ATTRIBUTES (tree_interval_profiler_fn
)
179 = tree_cons (get_identifier ("leaf"), NULL
,
180 DECL_ATTRIBUTES (tree_interval_profiler_fn
));
182 /* void (*) (gcov_type *, gcov_type) */
183 pow2_profiler_fn_type
184 = build_function_type_list (void_type_node
,
185 gcov_type_ptr
, gcov_type_node
,
187 tree_pow2_profiler_fn
= build_fn_decl ("__gcov_pow2_profiler",
188 pow2_profiler_fn_type
);
189 TREE_NOTHROW (tree_pow2_profiler_fn
) = 1;
190 DECL_ATTRIBUTES (tree_pow2_profiler_fn
)
191 = tree_cons (get_identifier ("leaf"), NULL
,
192 DECL_ATTRIBUTES (tree_pow2_profiler_fn
));
194 /* void (*) (gcov_type *, gcov_type) */
195 one_value_profiler_fn_type
196 = build_function_type_list (void_type_node
,
197 gcov_type_ptr
, gcov_type_node
,
199 tree_one_value_profiler_fn
200 = build_fn_decl ("__gcov_one_value_profiler",
201 one_value_profiler_fn_type
);
202 TREE_NOTHROW (tree_one_value_profiler_fn
) = 1;
203 DECL_ATTRIBUTES (tree_one_value_profiler_fn
)
204 = tree_cons (get_identifier ("leaf"), NULL
,
205 DECL_ATTRIBUTES (tree_one_value_profiler_fn
));
207 init_ic_make_global_vars ();
209 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
212 /* void (*) (gcov_type, void *) */
214 = build_function_type_list (void_type_node
,
215 gcov_type_ptr
, gcov_type_node
,
218 tree_indirect_call_profiler_fn
219 = build_fn_decl ("__gcov_indirect_call_profiler",
220 ic_profiler_fn_type
);
224 /* void (*) (gcov_type, void *) */
226 = build_function_type_list (void_type_node
,
230 tree_indirect_call_profiler_fn
231 = build_fn_decl ("__gcov_indirect_call_profiler_v2",
232 ic_profiler_fn_type
);
234 TREE_NOTHROW (tree_indirect_call_profiler_fn
) = 1;
235 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn
)
236 = tree_cons (get_identifier ("leaf"), NULL
,
237 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn
));
239 /* void (*) (gcov_type *, gcov_type, void *) */
240 time_profiler_fn_type
241 = build_function_type_list (void_type_node
,
242 gcov_type_ptr
, NULL_TREE
);
243 tree_time_profiler_fn
244 = build_fn_decl ("__gcov_time_profiler",
245 time_profiler_fn_type
);
246 TREE_NOTHROW (tree_time_profiler_fn
) = 1;
247 DECL_ATTRIBUTES (tree_time_profiler_fn
)
248 = tree_cons (get_identifier ("leaf"), NULL
,
249 DECL_ATTRIBUTES (tree_time_profiler_fn
));
251 /* void (*) (gcov_type *, gcov_type) */
252 average_profiler_fn_type
253 = build_function_type_list (void_type_node
,
254 gcov_type_ptr
, gcov_type_node
, NULL_TREE
);
255 tree_average_profiler_fn
256 = build_fn_decl ("__gcov_average_profiler",
257 average_profiler_fn_type
);
258 TREE_NOTHROW (tree_average_profiler_fn
) = 1;
259 DECL_ATTRIBUTES (tree_average_profiler_fn
)
260 = tree_cons (get_identifier ("leaf"), NULL
,
261 DECL_ATTRIBUTES (tree_average_profiler_fn
));
263 = build_fn_decl ("__gcov_ior_profiler",
264 average_profiler_fn_type
);
265 TREE_NOTHROW (tree_ior_profiler_fn
) = 1;
266 DECL_ATTRIBUTES (tree_ior_profiler_fn
)
267 = tree_cons (get_identifier ("leaf"), NULL
,
268 DECL_ATTRIBUTES (tree_ior_profiler_fn
));
270 /* LTO streamer needs assembler names. Because we create these decls
271 late, we need to initialize them by hand. */
272 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn
);
273 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn
);
274 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn
);
275 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn
);
276 DECL_ASSEMBLER_NAME (tree_time_profiler_fn
);
277 DECL_ASSEMBLER_NAME (tree_average_profiler_fn
);
278 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn
);
282 /* Output instructions as GIMPLE trees to increment the edge
283 execution count, and insert them on E. We rely on
284 gsi_insert_on_edge to preserve the order. */
287 gimple_gen_edge_profiler (int edgeno
, edge e
)
289 tree ref
, one
, gcov_type_tmp_var
;
290 gimple stmt1
, stmt2
, stmt3
;
292 ref
= tree_coverage_counter_ref (GCOV_COUNTER_ARCS
, edgeno
);
293 one
= build_int_cst (gcov_type_node
, 1);
294 gcov_type_tmp_var
= make_temp_ssa_name (gcov_type_node
,
295 NULL
, "PROF_edge_counter");
296 stmt1
= gimple_build_assign (gcov_type_tmp_var
, ref
);
297 gcov_type_tmp_var
= make_temp_ssa_name (gcov_type_node
,
298 NULL
, "PROF_edge_counter");
299 stmt2
= gimple_build_assign_with_ops (PLUS_EXPR
, gcov_type_tmp_var
,
300 gimple_assign_lhs (stmt1
), one
);
301 stmt3
= gimple_build_assign (unshare_expr (ref
), gimple_assign_lhs (stmt2
));
302 gsi_insert_on_edge (e
, stmt1
);
303 gsi_insert_on_edge (e
, stmt2
);
304 gsi_insert_on_edge (e
, stmt3
);
307 /* Emits code to get VALUE to instrument at GSI, and returns the
308 variable containing the value. */
311 prepare_instrumented_value (gimple_stmt_iterator
*gsi
, histogram_value value
)
313 tree val
= value
->hvalue
.value
;
314 if (POINTER_TYPE_P (TREE_TYPE (val
)))
315 val
= fold_convert (build_nonstandard_integer_type
316 (TYPE_PRECISION (TREE_TYPE (val
)), 1), val
);
317 return force_gimple_operand_gsi (gsi
, fold_convert (gcov_type_node
, val
),
318 true, NULL_TREE
, true, GSI_SAME_STMT
);
321 /* Output instructions as GIMPLE trees to increment the interval histogram
322 counter. VALUE is the expression whose value is profiled. TAG is the
323 tag of the section for counters, BASE is offset of the counter position. */
326 gimple_gen_interval_profiler (histogram_value value
, unsigned tag
, unsigned base
)
328 gimple stmt
= value
->hvalue
.stmt
;
329 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
330 tree ref
= tree_coverage_counter_ref (tag
, base
), ref_ptr
;
333 tree start
= build_int_cst_type (integer_type_node
,
334 value
->hdata
.intvl
.int_start
);
335 tree steps
= build_int_cst_type (unsigned_type_node
,
336 value
->hdata
.intvl
.steps
);
338 ref_ptr
= force_gimple_operand_gsi (&gsi
,
339 build_addr (ref
, current_function_decl
),
340 true, NULL_TREE
, true, GSI_SAME_STMT
);
341 val
= prepare_instrumented_value (&gsi
, value
);
342 call
= gimple_build_call (tree_interval_profiler_fn
, 4,
343 ref_ptr
, val
, start
, steps
);
344 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
347 /* Output instructions as GIMPLE trees to increment the power of two histogram
348 counter. VALUE is the expression whose value is profiled. TAG is the tag
349 of the section for counters, BASE is offset of the counter position. */
352 gimple_gen_pow2_profiler (histogram_value value
, unsigned tag
, unsigned base
)
354 gimple stmt
= value
->hvalue
.stmt
;
355 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
356 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
360 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
361 true, NULL_TREE
, true, GSI_SAME_STMT
);
362 val
= prepare_instrumented_value (&gsi
, value
);
363 call
= gimple_build_call (tree_pow2_profiler_fn
, 2, ref_ptr
, val
);
364 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
367 /* Output instructions as GIMPLE trees for code to find the most common value.
368 VALUE is the expression whose value is profiled. TAG is the tag of the
369 section for counters, BASE is offset of the counter position. */
372 gimple_gen_one_value_profiler (histogram_value value
, unsigned tag
, unsigned base
)
374 gimple stmt
= value
->hvalue
.stmt
;
375 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
376 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
380 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
381 true, NULL_TREE
, true, GSI_SAME_STMT
);
382 val
= prepare_instrumented_value (&gsi
, value
);
383 call
= gimple_build_call (tree_one_value_profiler_fn
, 2, ref_ptr
, val
);
384 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
388 /* Output instructions as GIMPLE trees for code to find the most
389 common called function in indirect call.
390 VALUE is the call expression whose indirect callee is profiled.
391 TAG is the tag of the section for counters, BASE is offset of the
395 gimple_gen_ic_profiler (histogram_value value
, unsigned tag
, unsigned base
)
398 gimple stmt1
, stmt2
, stmt3
;
399 gimple stmt
= value
->hvalue
.stmt
;
400 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
401 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
403 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
404 true, NULL_TREE
, true, GSI_SAME_STMT
);
408 stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
409 stmt2: tmp1 = (void *) (indirect call argument value)
410 stmt3: __gcov_indirect_call_callee = tmp1;
413 stmt1
= gimple_build_assign (ic_gcov_type_ptr_var
, ref_ptr
);
414 tmp1
= make_temp_ssa_name (ptr_void
, NULL
, "PROF");
415 stmt2
= gimple_build_assign (tmp1
, unshare_expr (value
->hvalue
.value
));
416 stmt3
= gimple_build_assign (ic_void_ptr_var
, gimple_assign_lhs (stmt2
));
418 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
419 gsi_insert_before (&gsi
, stmt2
, GSI_SAME_STMT
);
420 gsi_insert_before (&gsi
, stmt3
, GSI_SAME_STMT
);
424 /* Output instructions as GIMPLE trees for code to find the most
425 common called function in indirect call. Insert instructions at the
426 beginning of every possible called function.
430 gimple_gen_ic_func_profiler (void)
432 struct cgraph_node
* c_node
= cgraph_get_node (current_function_decl
);
433 gimple_stmt_iterator gsi
;
435 tree tree_uid
, cur_func
, void0
;
437 if (cgraph_only_called_directly_p (c_node
))
440 gimple_init_edge_profiler ();
444 stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
445 ¤t_function_decl)
448 gsi_after_labels (split_edge (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun
))));
450 cur_func
= force_gimple_operand_gsi (&gsi
,
451 build_addr (current_function_decl
,
452 current_function_decl
),
454 true, GSI_SAME_STMT
);
455 tree_uid
= build_int_cst
456 (gcov_type_node
, cgraph_get_node (current_function_decl
)->profile_id
);
457 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
460 tree counter_ptr
, ptr_var
;
461 counter_ptr
= force_gimple_operand_gsi (&gsi
, ic_gcov_type_ptr_var
,
462 true, NULL_TREE
, true,
464 ptr_var
= force_gimple_operand_gsi (&gsi
, ic_void_ptr_var
,
465 true, NULL_TREE
, true,
468 stmt1
= gimple_build_call (tree_indirect_call_profiler_fn
, 4,
469 counter_ptr
, tree_uid
, cur_func
, ptr_var
);
473 stmt1
= gimple_build_call (tree_indirect_call_profiler_fn
, 2,
476 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
478 /* Set __gcov_indirect_call_callee to 0,
479 so that calls from other modules won't get misattributed
480 to the last caller of the current callee. */
481 void0
= build_int_cst (build_pointer_type (void_type_node
), 0);
482 stmt2
= gimple_build_assign (ic_void_ptr_var
, void0
);
483 gsi_insert_before (&gsi
, stmt2
, GSI_SAME_STMT
);
486 /* Output instructions as GIMPLE tree at the beginning for each function.
487 TAG is the tag of the section for counters, BASE is offset of the
488 counter position and GSI is the iterator we place the counter. */
491 gimple_gen_time_profiler (unsigned tag
, unsigned base
,
492 gimple_stmt_iterator
&gsi
)
494 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
497 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
498 true, NULL_TREE
, true, GSI_SAME_STMT
);
499 call
= gimple_build_call (tree_time_profiler_fn
, 1, ref_ptr
);
500 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
503 /* Output instructions as GIMPLE trees for code to find the most common value
504 of a difference between two evaluations of an expression.
505 VALUE is the expression whose value is profiled. TAG is the tag of the
506 section for counters, BASE is offset of the counter position. */
509 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED
,
510 unsigned tag ATTRIBUTE_UNUSED
,
511 unsigned base ATTRIBUTE_UNUSED
)
513 /* FIXME implement this. */
514 #ifdef ENABLE_CHECKING
515 internal_error ("unimplemented functionality");
520 /* Output instructions as GIMPLE trees to increment the average histogram
521 counter. VALUE is the expression whose value is profiled. TAG is the
522 tag of the section for counters, BASE is offset of the counter position. */
525 gimple_gen_average_profiler (histogram_value value
, unsigned tag
, unsigned base
)
527 gimple stmt
= value
->hvalue
.stmt
;
528 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
529 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
533 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
535 true, GSI_SAME_STMT
);
536 val
= prepare_instrumented_value (&gsi
, value
);
537 call
= gimple_build_call (tree_average_profiler_fn
, 2, ref_ptr
, val
);
538 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
541 /* Output instructions as GIMPLE trees to increment the ior histogram
542 counter. VALUE is the expression whose value is profiled. TAG is the
543 tag of the section for counters, BASE is offset of the counter position. */
546 gimple_gen_ior_profiler (histogram_value value
, unsigned tag
, unsigned base
)
548 gimple stmt
= value
->hvalue
.stmt
;
549 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
550 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
554 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
555 true, NULL_TREE
, true, GSI_SAME_STMT
);
556 val
= prepare_instrumented_value (&gsi
, value
);
557 call
= gimple_build_call (tree_ior_profiler_fn
, 2, ref_ptr
, val
);
558 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
561 /* Profile all functions in the callgraph. */
564 tree_profiling (void)
566 struct cgraph_node
*node
;
568 /* This is a small-ipa pass that gets called only once, from
569 cgraphunit.c:ipa_passes(). */
570 gcc_assert (cgraph_state
== CGRAPH_STATE_IPA_SSA
);
572 init_node_map (true);
574 FOR_EACH_DEFINED_FUNCTION (node
)
576 if (!gimple_has_body_p (node
->decl
))
579 /* Don't profile functions produced for builtin stuff. */
580 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
)
583 push_cfun (DECL_STRUCT_FUNCTION (node
->decl
));
585 /* Local pure-const may imply need to fixup the cfg. */
586 if (execute_fixup_cfg () & TODO_cleanup_cfg
)
591 if (! flag_branch_probabilities
592 && flag_profile_values
)
593 gimple_gen_ic_func_profiler ();
595 if (flag_branch_probabilities
596 && flag_profile_values
597 && flag_value_profile_transformations
)
598 gimple_value_profile_transformations ();
600 /* The above could hose dominator info. Currently there is
601 none coming in, this is a safety valve. It should be
602 easy to adjust it, if and when there is some. */
603 free_dominance_info (CDI_DOMINATORS
);
604 free_dominance_info (CDI_POST_DOMINATORS
);
608 /* Drop pure/const flags from instrumented functions. */
609 FOR_EACH_DEFINED_FUNCTION (node
)
611 if (!gimple_has_body_p (node
->decl
)
613 || node
->decl
!= node
->clone_of
->decl
))
616 /* Don't profile functions produced for builtin stuff. */
617 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
)
620 cgraph_set_const_flag (node
, false, false);
621 cgraph_set_pure_flag (node
, false, false);
624 /* Update call statements and rebuild the cgraph. */
625 FOR_EACH_DEFINED_FUNCTION (node
)
629 if (!gimple_has_body_p (node
->decl
)
631 || node
->decl
!= node
->clone_of
->decl
))
634 /* Don't profile functions produced for builtin stuff. */
635 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
)
638 push_cfun (DECL_STRUCT_FUNCTION (node
->decl
));
640 FOR_EACH_BB_FN (bb
, cfun
)
642 gimple_stmt_iterator gsi
;
643 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
645 gimple stmt
= gsi_stmt (gsi
);
646 if (is_gimple_call (stmt
))
651 /* re-merge split blocks. */
653 update_ssa (TODO_update_ssa
);
655 rebuild_cgraph_edges ();
660 handle_missing_profiles ();
668 const pass_data pass_data_ipa_tree_profile
=
670 SIMPLE_IPA_PASS
, /* type */
671 "profile", /* name */
672 OPTGROUP_NONE
, /* optinfo_flags */
673 true, /* has_execute */
674 TV_IPA_PROFILE
, /* tv_id */
675 0, /* properties_required */
676 0, /* properties_provided */
677 0, /* properties_destroyed */
678 0, /* todo_flags_start */
679 0, /* todo_flags_finish */
682 class pass_ipa_tree_profile
: public simple_ipa_opt_pass
685 pass_ipa_tree_profile (gcc::context
*ctxt
)
686 : simple_ipa_opt_pass (pass_data_ipa_tree_profile
, ctxt
)
689 /* opt_pass methods: */
690 virtual bool gate (function
*);
691 virtual unsigned int execute (function
*) { return tree_profiling (); }
693 }; // class pass_ipa_tree_profile
696 pass_ipa_tree_profile::gate (function
*)
698 /* When profile instrumentation, use or test coverage shall be performed. */
700 && (flag_branch_probabilities
|| flag_test_coverage
701 || profile_arc_flag
));
706 simple_ipa_opt_pass
*
707 make_pass_ipa_tree_profile (gcc::context
*ctxt
)
709 return new pass_ipa_tree_profile (ctxt
);
712 #include "gt-tree-profile.h"