1 /* Calculate branch probabilities, and basic block execution counts.
2 Copyright (C) 1990-2013 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"
38 #include "gimple-iterator.h"
39 #include "gimple-ssa.h"
42 #include "tree-ssanames.h"
43 #include "tree-into-ssa.h"
44 #include "tree-pass.h"
45 #include "value-prof.h"
48 #include "tree-cfgcleanup.h"
50 static GTY(()) tree gcov_type_node
;
51 static GTY(()) tree tree_interval_profiler_fn
;
52 static GTY(()) tree tree_pow2_profiler_fn
;
53 static GTY(()) tree tree_one_value_profiler_fn
;
54 static GTY(()) tree tree_indirect_call_profiler_fn
;
55 static GTY(()) tree tree_time_profiler_fn
;
56 static GTY(()) tree tree_average_profiler_fn
;
57 static GTY(()) tree tree_ior_profiler_fn
;
60 static GTY(()) tree ic_void_ptr_var
;
61 static GTY(()) tree ic_gcov_type_ptr_var
;
62 static GTY(()) tree ptr_void
;
64 /* Do initialization work for the edge profiler. */
67 __thread gcov* __gcov_indirect_call_counters; // pointer to actual counter
68 __thread void* __gcov_indirect_call_callee; // actual callee address
69 __thread int __gcov_function_counter; // time profiler function counter
72 init_ic_make_global_vars (void)
76 ptr_void
= build_pointer_type (void_type_node
);
78 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
82 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
83 get_identifier ("__gcov_indirect_call_callee_ltopriv"),
85 TREE_PUBLIC (ic_void_ptr_var
) = 1;
86 DECL_COMMON (ic_void_ptr_var
) = 1;
87 DECL_VISIBILITY (ic_void_ptr_var
) = VISIBILITY_HIDDEN
;
88 DECL_VISIBILITY_SPECIFIED (ic_void_ptr_var
) = true;
93 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
94 get_identifier ("__gcov_indirect_call_callee"),
96 TREE_PUBLIC (ic_void_ptr_var
) = 1;
97 DECL_EXTERNAL (ic_void_ptr_var
) = 1;
99 TREE_STATIC (ic_void_ptr_var
) = 1;
100 DECL_ARTIFICIAL (ic_void_ptr_var
) = 1;
101 DECL_INITIAL (ic_void_ptr_var
) = NULL
;
102 if (targetm
.have_tls
)
103 DECL_TLS_MODEL (ic_void_ptr_var
) =
104 decl_default_tls_model (ic_void_ptr_var
);
106 varpool_finalize_decl (ic_void_ptr_var
);
108 gcov_type_ptr
= build_pointer_type (get_gcov_type ());
109 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
113 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
114 get_identifier ("__gcov_indirect_call_counters_ltopriv"),
116 TREE_PUBLIC (ic_gcov_type_ptr_var
) = 1;
117 DECL_COMMON (ic_gcov_type_ptr_var
) = 1;
118 DECL_VISIBILITY (ic_gcov_type_ptr_var
) = VISIBILITY_HIDDEN
;
119 DECL_VISIBILITY_SPECIFIED (ic_gcov_type_ptr_var
) = true;
124 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
125 get_identifier ("__gcov_indirect_call_counters"),
127 TREE_PUBLIC (ic_gcov_type_ptr_var
) = 1;
128 DECL_EXTERNAL (ic_gcov_type_ptr_var
) = 1;
130 TREE_STATIC (ic_gcov_type_ptr_var
) = 1;
131 DECL_ARTIFICIAL (ic_gcov_type_ptr_var
) = 1;
132 DECL_INITIAL (ic_gcov_type_ptr_var
) = NULL
;
133 if (targetm
.have_tls
)
134 DECL_TLS_MODEL (ic_gcov_type_ptr_var
) =
135 decl_default_tls_model (ic_gcov_type_ptr_var
);
137 varpool_finalize_decl (ic_gcov_type_ptr_var
);
140 /* Create the type and function decls for the interface with gcov. */
143 gimple_init_edge_profiler (void)
145 tree interval_profiler_fn_type
;
146 tree pow2_profiler_fn_type
;
147 tree one_value_profiler_fn_type
;
149 tree ic_profiler_fn_type
;
150 tree average_profiler_fn_type
;
151 tree time_profiler_fn_type
;
155 gcov_type_node
= get_gcov_type ();
156 gcov_type_ptr
= build_pointer_type (gcov_type_node
);
158 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
159 interval_profiler_fn_type
160 = build_function_type_list (void_type_node
,
161 gcov_type_ptr
, gcov_type_node
,
163 unsigned_type_node
, NULL_TREE
);
164 tree_interval_profiler_fn
165 = build_fn_decl ("__gcov_interval_profiler",
166 interval_profiler_fn_type
);
167 TREE_NOTHROW (tree_interval_profiler_fn
) = 1;
168 DECL_ATTRIBUTES (tree_interval_profiler_fn
)
169 = tree_cons (get_identifier ("leaf"), NULL
,
170 DECL_ATTRIBUTES (tree_interval_profiler_fn
));
172 /* void (*) (gcov_type *, gcov_type) */
173 pow2_profiler_fn_type
174 = build_function_type_list (void_type_node
,
175 gcov_type_ptr
, gcov_type_node
,
177 tree_pow2_profiler_fn
= build_fn_decl ("__gcov_pow2_profiler",
178 pow2_profiler_fn_type
);
179 TREE_NOTHROW (tree_pow2_profiler_fn
) = 1;
180 DECL_ATTRIBUTES (tree_pow2_profiler_fn
)
181 = tree_cons (get_identifier ("leaf"), NULL
,
182 DECL_ATTRIBUTES (tree_pow2_profiler_fn
));
184 /* void (*) (gcov_type *, gcov_type) */
185 one_value_profiler_fn_type
186 = build_function_type_list (void_type_node
,
187 gcov_type_ptr
, gcov_type_node
,
189 tree_one_value_profiler_fn
190 = build_fn_decl ("__gcov_one_value_profiler",
191 one_value_profiler_fn_type
);
192 TREE_NOTHROW (tree_one_value_profiler_fn
) = 1;
193 DECL_ATTRIBUTES (tree_one_value_profiler_fn
)
194 = tree_cons (get_identifier ("leaf"), NULL
,
195 DECL_ATTRIBUTES (tree_one_value_profiler_fn
));
197 init_ic_make_global_vars ();
199 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
202 /* void (*) (gcov_type, void *) */
204 = build_function_type_list (void_type_node
,
205 gcov_type_ptr
, gcov_type_node
,
208 tree_indirect_call_profiler_fn
209 = build_fn_decl ("__gcov_indirect_call_profiler",
210 ic_profiler_fn_type
);
214 /* void (*) (gcov_type, void *) */
216 = build_function_type_list (void_type_node
,
220 tree_indirect_call_profiler_fn
221 = build_fn_decl ("__gcov_indirect_call_profiler_v2",
222 ic_profiler_fn_type
);
224 TREE_NOTHROW (tree_indirect_call_profiler_fn
) = 1;
225 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn
)
226 = tree_cons (get_identifier ("leaf"), NULL
,
227 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn
));
229 /* void (*) (gcov_type *, gcov_type, void *) */
230 time_profiler_fn_type
231 = build_function_type_list (void_type_node
,
232 gcov_type_ptr
, NULL_TREE
);
233 tree_time_profiler_fn
234 = build_fn_decl ("__gcov_time_profiler",
235 time_profiler_fn_type
);
236 TREE_NOTHROW (tree_time_profiler_fn
) = 1;
237 DECL_ATTRIBUTES (tree_time_profiler_fn
)
238 = tree_cons (get_identifier ("leaf"), NULL
,
239 DECL_ATTRIBUTES (tree_time_profiler_fn
));
241 /* void (*) (gcov_type *, gcov_type) */
242 average_profiler_fn_type
243 = build_function_type_list (void_type_node
,
244 gcov_type_ptr
, gcov_type_node
, NULL_TREE
);
245 tree_average_profiler_fn
246 = build_fn_decl ("__gcov_average_profiler",
247 average_profiler_fn_type
);
248 TREE_NOTHROW (tree_average_profiler_fn
) = 1;
249 DECL_ATTRIBUTES (tree_average_profiler_fn
)
250 = tree_cons (get_identifier ("leaf"), NULL
,
251 DECL_ATTRIBUTES (tree_average_profiler_fn
));
253 = build_fn_decl ("__gcov_ior_profiler",
254 average_profiler_fn_type
);
255 TREE_NOTHROW (tree_ior_profiler_fn
) = 1;
256 DECL_ATTRIBUTES (tree_ior_profiler_fn
)
257 = tree_cons (get_identifier ("leaf"), NULL
,
258 DECL_ATTRIBUTES (tree_ior_profiler_fn
));
260 /* LTO streamer needs assembler names. Because we create these decls
261 late, we need to initialize them by hand. */
262 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn
);
263 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn
);
264 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn
);
265 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn
);
266 DECL_ASSEMBLER_NAME (tree_time_profiler_fn
);
267 DECL_ASSEMBLER_NAME (tree_average_profiler_fn
);
268 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn
);
272 /* Output instructions as GIMPLE trees to increment the edge
273 execution count, and insert them on E. We rely on
274 gsi_insert_on_edge to preserve the order. */
277 gimple_gen_edge_profiler (int edgeno
, edge e
)
279 tree ref
, one
, gcov_type_tmp_var
;
280 gimple stmt1
, stmt2
, stmt3
;
282 ref
= tree_coverage_counter_ref (GCOV_COUNTER_ARCS
, edgeno
);
283 one
= build_int_cst (gcov_type_node
, 1);
284 gcov_type_tmp_var
= make_temp_ssa_name (gcov_type_node
,
285 NULL
, "PROF_edge_counter");
286 stmt1
= gimple_build_assign (gcov_type_tmp_var
, ref
);
287 gcov_type_tmp_var
= make_temp_ssa_name (gcov_type_node
,
288 NULL
, "PROF_edge_counter");
289 stmt2
= gimple_build_assign_with_ops (PLUS_EXPR
, gcov_type_tmp_var
,
290 gimple_assign_lhs (stmt1
), one
);
291 stmt3
= gimple_build_assign (unshare_expr (ref
), gimple_assign_lhs (stmt2
));
292 gsi_insert_on_edge (e
, stmt1
);
293 gsi_insert_on_edge (e
, stmt2
);
294 gsi_insert_on_edge (e
, stmt3
);
297 /* Emits code to get VALUE to instrument at GSI, and returns the
298 variable containing the value. */
301 prepare_instrumented_value (gimple_stmt_iterator
*gsi
, histogram_value value
)
303 tree val
= value
->hvalue
.value
;
304 if (POINTER_TYPE_P (TREE_TYPE (val
)))
305 val
= fold_convert (build_nonstandard_integer_type
306 (TYPE_PRECISION (TREE_TYPE (val
)), 1), val
);
307 return force_gimple_operand_gsi (gsi
, fold_convert (gcov_type_node
, val
),
308 true, NULL_TREE
, true, GSI_SAME_STMT
);
311 /* Output instructions as GIMPLE trees to increment the interval histogram
312 counter. VALUE is the expression whose value is profiled. TAG is the
313 tag of the section for counters, BASE is offset of the counter position. */
316 gimple_gen_interval_profiler (histogram_value value
, unsigned tag
, unsigned base
)
318 gimple stmt
= value
->hvalue
.stmt
;
319 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
320 tree ref
= tree_coverage_counter_ref (tag
, base
), ref_ptr
;
323 tree start
= build_int_cst_type (integer_type_node
,
324 value
->hdata
.intvl
.int_start
);
325 tree steps
= build_int_cst_type (unsigned_type_node
,
326 value
->hdata
.intvl
.steps
);
328 ref_ptr
= force_gimple_operand_gsi (&gsi
,
329 build_addr (ref
, current_function_decl
),
330 true, NULL_TREE
, true, GSI_SAME_STMT
);
331 val
= prepare_instrumented_value (&gsi
, value
);
332 call
= gimple_build_call (tree_interval_profiler_fn
, 4,
333 ref_ptr
, val
, start
, steps
);
334 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
337 /* Output instructions as GIMPLE trees to increment the power of two histogram
338 counter. VALUE is the expression whose value is profiled. TAG is the tag
339 of the section for counters, BASE is offset of the counter position. */
342 gimple_gen_pow2_profiler (histogram_value value
, unsigned tag
, unsigned base
)
344 gimple stmt
= value
->hvalue
.stmt
;
345 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
346 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
350 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
351 true, NULL_TREE
, true, GSI_SAME_STMT
);
352 val
= prepare_instrumented_value (&gsi
, value
);
353 call
= gimple_build_call (tree_pow2_profiler_fn
, 2, ref_ptr
, val
);
354 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
357 /* Output instructions as GIMPLE trees for code to find the most common value.
358 VALUE is the expression whose value is profiled. TAG is the tag of the
359 section for counters, BASE is offset of the counter position. */
362 gimple_gen_one_value_profiler (histogram_value value
, unsigned tag
, unsigned base
)
364 gimple stmt
= value
->hvalue
.stmt
;
365 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
366 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
370 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
371 true, NULL_TREE
, true, GSI_SAME_STMT
);
372 val
= prepare_instrumented_value (&gsi
, value
);
373 call
= gimple_build_call (tree_one_value_profiler_fn
, 2, ref_ptr
, val
);
374 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
378 /* Output instructions as GIMPLE trees for code to find the most
379 common called function in indirect call.
380 VALUE is the call expression whose indirect callee is profiled.
381 TAG is the tag of the section for counters, BASE is offset of the
385 gimple_gen_ic_profiler (histogram_value value
, unsigned tag
, unsigned base
)
388 gimple stmt1
, stmt2
, stmt3
;
389 gimple stmt
= value
->hvalue
.stmt
;
390 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
391 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
393 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
394 true, NULL_TREE
, true, GSI_SAME_STMT
);
398 stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
399 stmt2: tmp1 = (void *) (indirect call argument value)
400 stmt3: __gcov_indirect_call_callee = tmp1;
403 stmt1
= gimple_build_assign (ic_gcov_type_ptr_var
, ref_ptr
);
404 tmp1
= make_temp_ssa_name (ptr_void
, NULL
, "PROF");
405 stmt2
= gimple_build_assign (tmp1
, unshare_expr (value
->hvalue
.value
));
406 stmt3
= gimple_build_assign (ic_void_ptr_var
, gimple_assign_lhs (stmt2
));
408 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
409 gsi_insert_before (&gsi
, stmt2
, GSI_SAME_STMT
);
410 gsi_insert_before (&gsi
, stmt3
, GSI_SAME_STMT
);
414 /* Output instructions as GIMPLE trees for code to find the most
415 common called function in indirect call. Insert instructions at the
416 beginning of every possible called function.
420 gimple_gen_ic_func_profiler (void)
422 struct cgraph_node
* c_node
= cgraph_get_node (current_function_decl
);
423 gimple_stmt_iterator gsi
;
425 tree tree_uid
, cur_func
, void0
;
427 if (cgraph_only_called_directly_p (c_node
))
430 gimple_init_edge_profiler ();
434 stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
435 ¤t_function_decl)
437 gsi
= gsi_after_labels (split_edge (single_succ_edge (ENTRY_BLOCK_PTR
)));
439 cur_func
= force_gimple_operand_gsi (&gsi
,
440 build_addr (current_function_decl
,
441 current_function_decl
),
443 true, GSI_SAME_STMT
);
444 tree_uid
= build_int_cst
445 (gcov_type_node
, cgraph_get_node (current_function_decl
)->profile_id
);
446 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
449 tree counter_ptr
, ptr_var
;
450 counter_ptr
= force_gimple_operand_gsi (&gsi
, ic_gcov_type_ptr_var
,
451 true, NULL_TREE
, true,
453 ptr_var
= force_gimple_operand_gsi (&gsi
, ic_void_ptr_var
,
454 true, NULL_TREE
, true,
457 stmt1
= gimple_build_call (tree_indirect_call_profiler_fn
, 4,
458 counter_ptr
, tree_uid
, cur_func
, ptr_var
);
462 stmt1
= gimple_build_call (tree_indirect_call_profiler_fn
, 2,
465 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
467 /* Set __gcov_indirect_call_callee to 0,
468 so that calls from other modules won't get misattributed
469 to the last caller of the current callee. */
470 void0
= build_int_cst (build_pointer_type (void_type_node
), 0);
471 stmt2
= gimple_build_assign (ic_void_ptr_var
, void0
);
472 gsi_insert_before (&gsi
, stmt2
, GSI_SAME_STMT
);
475 /* Output instructions as GIMPLE tree at the beginning for each function.
476 TAG is the tag of the section for counters, BASE is offset of the
477 counter position and GSI is the iterator we place the counter. */
480 gimple_gen_time_profiler (unsigned tag
, unsigned base
,
481 gimple_stmt_iterator
&gsi
)
483 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
486 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
487 true, NULL_TREE
, true, GSI_SAME_STMT
);
488 call
= gimple_build_call (tree_time_profiler_fn
, 1, ref_ptr
);
489 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
492 /* Output instructions as GIMPLE trees for code to find the most common value
493 of a difference between two evaluations of an expression.
494 VALUE is the expression whose value is profiled. TAG is the tag of the
495 section for counters, BASE is offset of the counter position. */
498 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED
,
499 unsigned tag ATTRIBUTE_UNUSED
,
500 unsigned base ATTRIBUTE_UNUSED
)
502 /* FIXME implement this. */
503 #ifdef ENABLE_CHECKING
504 internal_error ("unimplemented functionality");
509 /* Output instructions as GIMPLE trees to increment the average histogram
510 counter. VALUE is the expression whose value is profiled. TAG is the
511 tag of the section for counters, BASE is offset of the counter position. */
514 gimple_gen_average_profiler (histogram_value value
, unsigned tag
, unsigned base
)
516 gimple stmt
= value
->hvalue
.stmt
;
517 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
518 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
522 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
524 true, GSI_SAME_STMT
);
525 val
= prepare_instrumented_value (&gsi
, value
);
526 call
= gimple_build_call (tree_average_profiler_fn
, 2, ref_ptr
, val
);
527 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
530 /* Output instructions as GIMPLE trees to increment the ior histogram
531 counter. VALUE is the expression whose value is profiled. TAG is the
532 tag of the section for counters, BASE is offset of the counter position. */
535 gimple_gen_ior_profiler (histogram_value value
, unsigned tag
, unsigned base
)
537 gimple stmt
= value
->hvalue
.stmt
;
538 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
539 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
543 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
544 true, NULL_TREE
, true, GSI_SAME_STMT
);
545 val
= prepare_instrumented_value (&gsi
, value
);
546 call
= gimple_build_call (tree_ior_profiler_fn
, 2, ref_ptr
, val
);
547 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
550 /* Profile all functions in the callgraph. */
553 tree_profiling (void)
555 struct cgraph_node
*node
;
557 /* This is a small-ipa pass that gets called only once, from
558 cgraphunit.c:ipa_passes(). */
559 gcc_assert (cgraph_state
== CGRAPH_STATE_IPA_SSA
);
561 init_node_map (true);
563 FOR_EACH_DEFINED_FUNCTION (node
)
565 if (!gimple_has_body_p (node
->decl
))
568 /* Don't profile functions produced for builtin stuff. */
569 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
)
572 push_cfun (DECL_STRUCT_FUNCTION (node
->decl
));
574 /* Local pure-const may imply need to fixup the cfg. */
575 if (execute_fixup_cfg () & TODO_cleanup_cfg
)
580 if (! flag_branch_probabilities
581 && flag_profile_values
)
582 gimple_gen_ic_func_profiler ();
584 if (flag_branch_probabilities
585 && flag_profile_values
586 && flag_value_profile_transformations
)
587 gimple_value_profile_transformations ();
589 /* The above could hose dominator info. Currently there is
590 none coming in, this is a safety valve. It should be
591 easy to adjust it, if and when there is some. */
592 free_dominance_info (CDI_DOMINATORS
);
593 free_dominance_info (CDI_POST_DOMINATORS
);
597 /* Drop pure/const flags from instrumented functions. */
598 FOR_EACH_DEFINED_FUNCTION (node
)
600 if (!gimple_has_body_p (node
->decl
)
602 || node
->decl
!= node
->clone_of
->decl
))
605 /* Don't profile functions produced for builtin stuff. */
606 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
)
609 cgraph_set_const_flag (node
, false, false);
610 cgraph_set_pure_flag (node
, false, false);
613 /* Update call statements and rebuild the cgraph. */
614 FOR_EACH_DEFINED_FUNCTION (node
)
618 if (!gimple_has_body_p (node
->decl
)
620 || node
->decl
!= node
->clone_of
->decl
))
623 /* Don't profile functions produced for builtin stuff. */
624 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
)
627 push_cfun (DECL_STRUCT_FUNCTION (node
->decl
));
631 gimple_stmt_iterator gsi
;
632 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
634 gimple stmt
= gsi_stmt (gsi
);
635 if (is_gimple_call (stmt
))
640 /* re-merge split blocks. */
642 update_ssa (TODO_update_ssa
);
644 rebuild_cgraph_edges ();
649 handle_missing_profiles ();
655 /* When profile instrumentation, use or test coverage shall be performed. */
658 gate_tree_profile_ipa (void)
661 && (flag_branch_probabilities
|| flag_test_coverage
662 || profile_arc_flag
));
667 const pass_data pass_data_ipa_tree_profile
=
669 SIMPLE_IPA_PASS
, /* type */
670 "profile", /* name */
671 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 bool gate () { return gate_tree_profile_ipa (); }
691 unsigned int execute () { return tree_profiling (); }
693 }; // class pass_ipa_tree_profile
697 simple_ipa_opt_pass
*
698 make_pass_ipa_tree_profile (gcc::context
*ctxt
)
700 return new pass_ipa_tree_profile (ctxt
);
703 #include "gt-tree-profile.h"