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"
39 #include "tree-nested.h"
41 #include "gimple-iterator.h"
42 #include "gimplify-me.h"
43 #include "gimple-ssa.h"
46 #include "stringpool.h"
47 #include "tree-ssanames.h"
48 #include "tree-into-ssa.h"
49 #include "tree-pass.h"
50 #include "value-prof.h"
53 #include "tree-cfgcleanup.h"
54 #include "tree-nested.h"
56 static GTY(()) tree gcov_type_node
;
57 static GTY(()) tree tree_interval_profiler_fn
;
58 static GTY(()) tree tree_pow2_profiler_fn
;
59 static GTY(()) tree tree_one_value_profiler_fn
;
60 static GTY(()) tree tree_indirect_call_profiler_fn
;
61 static GTY(()) tree tree_time_profiler_fn
;
62 static GTY(()) tree tree_average_profiler_fn
;
63 static GTY(()) tree tree_ior_profiler_fn
;
66 static GTY(()) tree ic_void_ptr_var
;
67 static GTY(()) tree ic_gcov_type_ptr_var
;
68 static GTY(()) tree ptr_void
;
70 /* Do initialization work for the edge profiler. */
73 __thread gcov* __gcov_indirect_call_counters; // pointer to actual counter
74 __thread void* __gcov_indirect_call_callee; // actual callee address
75 __thread int __gcov_function_counter; // time profiler function counter
78 init_ic_make_global_vars (void)
82 ptr_void
= build_pointer_type (void_type_node
);
84 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
88 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
89 get_identifier ("__gcov_indirect_call_callee_ltopriv"),
91 TREE_PUBLIC (ic_void_ptr_var
) = 1;
92 DECL_COMMON (ic_void_ptr_var
) = 1;
93 DECL_VISIBILITY (ic_void_ptr_var
) = VISIBILITY_HIDDEN
;
94 DECL_VISIBILITY_SPECIFIED (ic_void_ptr_var
) = true;
99 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
100 get_identifier ("__gcov_indirect_call_callee"),
102 TREE_PUBLIC (ic_void_ptr_var
) = 1;
103 DECL_EXTERNAL (ic_void_ptr_var
) = 1;
105 TREE_STATIC (ic_void_ptr_var
) = 1;
106 DECL_ARTIFICIAL (ic_void_ptr_var
) = 1;
107 DECL_INITIAL (ic_void_ptr_var
) = NULL
;
108 if (targetm
.have_tls
)
109 DECL_TLS_MODEL (ic_void_ptr_var
) =
110 decl_default_tls_model (ic_void_ptr_var
);
112 varpool_finalize_decl (ic_void_ptr_var
);
114 gcov_type_ptr
= build_pointer_type (get_gcov_type ());
115 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
119 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
120 get_identifier ("__gcov_indirect_call_counters_ltopriv"),
122 TREE_PUBLIC (ic_gcov_type_ptr_var
) = 1;
123 DECL_COMMON (ic_gcov_type_ptr_var
) = 1;
124 DECL_VISIBILITY (ic_gcov_type_ptr_var
) = VISIBILITY_HIDDEN
;
125 DECL_VISIBILITY_SPECIFIED (ic_gcov_type_ptr_var
) = true;
130 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
131 get_identifier ("__gcov_indirect_call_counters"),
133 TREE_PUBLIC (ic_gcov_type_ptr_var
) = 1;
134 DECL_EXTERNAL (ic_gcov_type_ptr_var
) = 1;
136 TREE_STATIC (ic_gcov_type_ptr_var
) = 1;
137 DECL_ARTIFICIAL (ic_gcov_type_ptr_var
) = 1;
138 DECL_INITIAL (ic_gcov_type_ptr_var
) = NULL
;
139 if (targetm
.have_tls
)
140 DECL_TLS_MODEL (ic_gcov_type_ptr_var
) =
141 decl_default_tls_model (ic_gcov_type_ptr_var
);
143 varpool_finalize_decl (ic_gcov_type_ptr_var
);
146 /* Create the type and function decls for the interface with gcov. */
149 gimple_init_edge_profiler (void)
151 tree interval_profiler_fn_type
;
152 tree pow2_profiler_fn_type
;
153 tree one_value_profiler_fn_type
;
155 tree ic_profiler_fn_type
;
156 tree average_profiler_fn_type
;
157 tree time_profiler_fn_type
;
161 gcov_type_node
= get_gcov_type ();
162 gcov_type_ptr
= build_pointer_type (gcov_type_node
);
164 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
165 interval_profiler_fn_type
166 = build_function_type_list (void_type_node
,
167 gcov_type_ptr
, gcov_type_node
,
169 unsigned_type_node
, NULL_TREE
);
170 tree_interval_profiler_fn
171 = build_fn_decl ("__gcov_interval_profiler",
172 interval_profiler_fn_type
);
173 TREE_NOTHROW (tree_interval_profiler_fn
) = 1;
174 DECL_ATTRIBUTES (tree_interval_profiler_fn
)
175 = tree_cons (get_identifier ("leaf"), NULL
,
176 DECL_ATTRIBUTES (tree_interval_profiler_fn
));
178 /* void (*) (gcov_type *, gcov_type) */
179 pow2_profiler_fn_type
180 = build_function_type_list (void_type_node
,
181 gcov_type_ptr
, gcov_type_node
,
183 tree_pow2_profiler_fn
= build_fn_decl ("__gcov_pow2_profiler",
184 pow2_profiler_fn_type
);
185 TREE_NOTHROW (tree_pow2_profiler_fn
) = 1;
186 DECL_ATTRIBUTES (tree_pow2_profiler_fn
)
187 = tree_cons (get_identifier ("leaf"), NULL
,
188 DECL_ATTRIBUTES (tree_pow2_profiler_fn
));
190 /* void (*) (gcov_type *, gcov_type) */
191 one_value_profiler_fn_type
192 = build_function_type_list (void_type_node
,
193 gcov_type_ptr
, gcov_type_node
,
195 tree_one_value_profiler_fn
196 = build_fn_decl ("__gcov_one_value_profiler",
197 one_value_profiler_fn_type
);
198 TREE_NOTHROW (tree_one_value_profiler_fn
) = 1;
199 DECL_ATTRIBUTES (tree_one_value_profiler_fn
)
200 = tree_cons (get_identifier ("leaf"), NULL
,
201 DECL_ATTRIBUTES (tree_one_value_profiler_fn
));
203 init_ic_make_global_vars ();
205 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
208 /* void (*) (gcov_type, void *) */
210 = build_function_type_list (void_type_node
,
211 gcov_type_ptr
, gcov_type_node
,
214 tree_indirect_call_profiler_fn
215 = build_fn_decl ("__gcov_indirect_call_profiler",
216 ic_profiler_fn_type
);
220 /* void (*) (gcov_type, void *) */
222 = build_function_type_list (void_type_node
,
226 tree_indirect_call_profiler_fn
227 = build_fn_decl ("__gcov_indirect_call_profiler_v2",
228 ic_profiler_fn_type
);
230 TREE_NOTHROW (tree_indirect_call_profiler_fn
) = 1;
231 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn
)
232 = tree_cons (get_identifier ("leaf"), NULL
,
233 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn
));
235 /* void (*) (gcov_type *, gcov_type, void *) */
236 time_profiler_fn_type
237 = build_function_type_list (void_type_node
,
238 gcov_type_ptr
, NULL_TREE
);
239 tree_time_profiler_fn
240 = build_fn_decl ("__gcov_time_profiler",
241 time_profiler_fn_type
);
242 TREE_NOTHROW (tree_time_profiler_fn
) = 1;
243 DECL_ATTRIBUTES (tree_time_profiler_fn
)
244 = tree_cons (get_identifier ("leaf"), NULL
,
245 DECL_ATTRIBUTES (tree_time_profiler_fn
));
247 /* void (*) (gcov_type *, gcov_type) */
248 average_profiler_fn_type
249 = build_function_type_list (void_type_node
,
250 gcov_type_ptr
, gcov_type_node
, NULL_TREE
);
251 tree_average_profiler_fn
252 = build_fn_decl ("__gcov_average_profiler",
253 average_profiler_fn_type
);
254 TREE_NOTHROW (tree_average_profiler_fn
) = 1;
255 DECL_ATTRIBUTES (tree_average_profiler_fn
)
256 = tree_cons (get_identifier ("leaf"), NULL
,
257 DECL_ATTRIBUTES (tree_average_profiler_fn
));
259 = build_fn_decl ("__gcov_ior_profiler",
260 average_profiler_fn_type
);
261 TREE_NOTHROW (tree_ior_profiler_fn
) = 1;
262 DECL_ATTRIBUTES (tree_ior_profiler_fn
)
263 = tree_cons (get_identifier ("leaf"), NULL
,
264 DECL_ATTRIBUTES (tree_ior_profiler_fn
));
266 /* LTO streamer needs assembler names. Because we create these decls
267 late, we need to initialize them by hand. */
268 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn
);
269 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn
);
270 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn
);
271 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn
);
272 DECL_ASSEMBLER_NAME (tree_time_profiler_fn
);
273 DECL_ASSEMBLER_NAME (tree_average_profiler_fn
);
274 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn
);
278 /* Output instructions as GIMPLE trees to increment the edge
279 execution count, and insert them on E. We rely on
280 gsi_insert_on_edge to preserve the order. */
283 gimple_gen_edge_profiler (int edgeno
, edge e
)
285 tree ref
, one
, gcov_type_tmp_var
;
286 gimple stmt1
, stmt2
, stmt3
;
288 ref
= tree_coverage_counter_ref (GCOV_COUNTER_ARCS
, edgeno
);
289 one
= build_int_cst (gcov_type_node
, 1);
290 gcov_type_tmp_var
= make_temp_ssa_name (gcov_type_node
,
291 NULL
, "PROF_edge_counter");
292 stmt1
= gimple_build_assign (gcov_type_tmp_var
, ref
);
293 gcov_type_tmp_var
= make_temp_ssa_name (gcov_type_node
,
294 NULL
, "PROF_edge_counter");
295 stmt2
= gimple_build_assign_with_ops (PLUS_EXPR
, gcov_type_tmp_var
,
296 gimple_assign_lhs (stmt1
), one
);
297 stmt3
= gimple_build_assign (unshare_expr (ref
), gimple_assign_lhs (stmt2
));
298 gsi_insert_on_edge (e
, stmt1
);
299 gsi_insert_on_edge (e
, stmt2
);
300 gsi_insert_on_edge (e
, stmt3
);
303 /* Emits code to get VALUE to instrument at GSI, and returns the
304 variable containing the value. */
307 prepare_instrumented_value (gimple_stmt_iterator
*gsi
, histogram_value value
)
309 tree val
= value
->hvalue
.value
;
310 if (POINTER_TYPE_P (TREE_TYPE (val
)))
311 val
= fold_convert (build_nonstandard_integer_type
312 (TYPE_PRECISION (TREE_TYPE (val
)), 1), val
);
313 return force_gimple_operand_gsi (gsi
, fold_convert (gcov_type_node
, val
),
314 true, NULL_TREE
, true, GSI_SAME_STMT
);
317 /* Output instructions as GIMPLE trees to increment the interval histogram
318 counter. VALUE is the expression whose value is profiled. TAG is the
319 tag of the section for counters, BASE is offset of the counter position. */
322 gimple_gen_interval_profiler (histogram_value value
, unsigned tag
, unsigned base
)
324 gimple stmt
= value
->hvalue
.stmt
;
325 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
326 tree ref
= tree_coverage_counter_ref (tag
, base
), ref_ptr
;
329 tree start
= build_int_cst_type (integer_type_node
,
330 value
->hdata
.intvl
.int_start
);
331 tree steps
= build_int_cst_type (unsigned_type_node
,
332 value
->hdata
.intvl
.steps
);
334 ref_ptr
= force_gimple_operand_gsi (&gsi
,
335 build_addr (ref
, current_function_decl
),
336 true, NULL_TREE
, true, GSI_SAME_STMT
);
337 val
= prepare_instrumented_value (&gsi
, value
);
338 call
= gimple_build_call (tree_interval_profiler_fn
, 4,
339 ref_ptr
, val
, start
, steps
);
340 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
343 /* Output instructions as GIMPLE trees to increment the power of two histogram
344 counter. VALUE is the expression whose value is profiled. TAG is the tag
345 of the section for counters, BASE is offset of the counter position. */
348 gimple_gen_pow2_profiler (histogram_value value
, unsigned tag
, unsigned base
)
350 gimple stmt
= value
->hvalue
.stmt
;
351 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
352 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
356 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
357 true, NULL_TREE
, true, GSI_SAME_STMT
);
358 val
= prepare_instrumented_value (&gsi
, value
);
359 call
= gimple_build_call (tree_pow2_profiler_fn
, 2, ref_ptr
, val
);
360 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
363 /* Output instructions as GIMPLE trees for code to find the most common value.
364 VALUE is the expression whose value is profiled. TAG is the tag of the
365 section for counters, BASE is offset of the counter position. */
368 gimple_gen_one_value_profiler (histogram_value value
, unsigned tag
, unsigned base
)
370 gimple stmt
= value
->hvalue
.stmt
;
371 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
372 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
376 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
377 true, NULL_TREE
, true, GSI_SAME_STMT
);
378 val
= prepare_instrumented_value (&gsi
, value
);
379 call
= gimple_build_call (tree_one_value_profiler_fn
, 2, ref_ptr
, val
);
380 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
384 /* Output instructions as GIMPLE trees for code to find the most
385 common called function in indirect call.
386 VALUE is the call expression whose indirect callee is profiled.
387 TAG is the tag of the section for counters, BASE is offset of the
391 gimple_gen_ic_profiler (histogram_value value
, unsigned tag
, unsigned base
)
394 gimple stmt1
, stmt2
, stmt3
;
395 gimple stmt
= value
->hvalue
.stmt
;
396 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
397 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
399 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
400 true, NULL_TREE
, true, GSI_SAME_STMT
);
404 stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
405 stmt2: tmp1 = (void *) (indirect call argument value)
406 stmt3: __gcov_indirect_call_callee = tmp1;
409 stmt1
= gimple_build_assign (ic_gcov_type_ptr_var
, ref_ptr
);
410 tmp1
= make_temp_ssa_name (ptr_void
, NULL
, "PROF");
411 stmt2
= gimple_build_assign (tmp1
, unshare_expr (value
->hvalue
.value
));
412 stmt3
= gimple_build_assign (ic_void_ptr_var
, gimple_assign_lhs (stmt2
));
414 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
415 gsi_insert_before (&gsi
, stmt2
, GSI_SAME_STMT
);
416 gsi_insert_before (&gsi
, stmt3
, GSI_SAME_STMT
);
420 /* Output instructions as GIMPLE trees for code to find the most
421 common called function in indirect call. Insert instructions at the
422 beginning of every possible called function.
426 gimple_gen_ic_func_profiler (void)
428 struct cgraph_node
* c_node
= cgraph_get_node (current_function_decl
);
429 gimple_stmt_iterator gsi
;
431 tree tree_uid
, cur_func
, void0
;
433 if (cgraph_only_called_directly_p (c_node
))
436 gimple_init_edge_profiler ();
440 stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
441 ¤t_function_decl)
444 gsi_after_labels (split_edge (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun
))));
446 cur_func
= force_gimple_operand_gsi (&gsi
,
447 build_addr (current_function_decl
,
448 current_function_decl
),
450 true, GSI_SAME_STMT
);
451 tree_uid
= build_int_cst
452 (gcov_type_node
, cgraph_get_node (current_function_decl
)->profile_id
);
453 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
456 tree counter_ptr
, ptr_var
;
457 counter_ptr
= force_gimple_operand_gsi (&gsi
, ic_gcov_type_ptr_var
,
458 true, NULL_TREE
, true,
460 ptr_var
= force_gimple_operand_gsi (&gsi
, ic_void_ptr_var
,
461 true, NULL_TREE
, true,
464 stmt1
= gimple_build_call (tree_indirect_call_profiler_fn
, 4,
465 counter_ptr
, tree_uid
, cur_func
, ptr_var
);
469 stmt1
= gimple_build_call (tree_indirect_call_profiler_fn
, 2,
472 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
474 /* Set __gcov_indirect_call_callee to 0,
475 so that calls from other modules won't get misattributed
476 to the last caller of the current callee. */
477 void0
= build_int_cst (build_pointer_type (void_type_node
), 0);
478 stmt2
= gimple_build_assign (ic_void_ptr_var
, void0
);
479 gsi_insert_before (&gsi
, stmt2
, GSI_SAME_STMT
);
482 /* Output instructions as GIMPLE tree at the beginning for each function.
483 TAG is the tag of the section for counters, BASE is offset of the
484 counter position and GSI is the iterator we place the counter. */
487 gimple_gen_time_profiler (unsigned tag
, unsigned base
,
488 gimple_stmt_iterator
&gsi
)
490 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
493 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
494 true, NULL_TREE
, true, GSI_SAME_STMT
);
495 call
= gimple_build_call (tree_time_profiler_fn
, 1, ref_ptr
);
496 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
499 /* Output instructions as GIMPLE trees for code to find the most common value
500 of a difference between two evaluations of an expression.
501 VALUE is the expression whose value is profiled. TAG is the tag of the
502 section for counters, BASE is offset of the counter position. */
505 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED
,
506 unsigned tag ATTRIBUTE_UNUSED
,
507 unsigned base ATTRIBUTE_UNUSED
)
509 /* FIXME implement this. */
510 #ifdef ENABLE_CHECKING
511 internal_error ("unimplemented functionality");
516 /* Output instructions as GIMPLE trees to increment the average histogram
517 counter. VALUE is the expression whose value is profiled. TAG is the
518 tag of the section for counters, BASE is offset of the counter position. */
521 gimple_gen_average_profiler (histogram_value value
, unsigned tag
, unsigned base
)
523 gimple stmt
= value
->hvalue
.stmt
;
524 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
525 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
529 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
531 true, GSI_SAME_STMT
);
532 val
= prepare_instrumented_value (&gsi
, value
);
533 call
= gimple_build_call (tree_average_profiler_fn
, 2, ref_ptr
, val
);
534 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
537 /* Output instructions as GIMPLE trees to increment the ior histogram
538 counter. VALUE is the expression whose value is profiled. TAG is the
539 tag of the section for counters, BASE is offset of the counter position. */
542 gimple_gen_ior_profiler (histogram_value value
, unsigned tag
, unsigned base
)
544 gimple stmt
= value
->hvalue
.stmt
;
545 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
546 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
550 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
551 true, NULL_TREE
, true, GSI_SAME_STMT
);
552 val
= prepare_instrumented_value (&gsi
, value
);
553 call
= gimple_build_call (tree_ior_profiler_fn
, 2, ref_ptr
, val
);
554 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
557 /* Profile all functions in the callgraph. */
560 tree_profiling (void)
562 struct cgraph_node
*node
;
564 /* This is a small-ipa pass that gets called only once, from
565 cgraphunit.c:ipa_passes(). */
566 gcc_assert (cgraph_state
== CGRAPH_STATE_IPA_SSA
);
568 init_node_map (true);
570 FOR_EACH_DEFINED_FUNCTION (node
)
572 if (!gimple_has_body_p (node
->decl
))
575 /* Don't profile functions produced for builtin stuff. */
576 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
)
579 push_cfun (DECL_STRUCT_FUNCTION (node
->decl
));
581 /* Local pure-const may imply need to fixup the cfg. */
582 if (execute_fixup_cfg () & TODO_cleanup_cfg
)
587 if (! flag_branch_probabilities
588 && flag_profile_values
)
589 gimple_gen_ic_func_profiler ();
591 if (flag_branch_probabilities
592 && flag_profile_values
593 && flag_value_profile_transformations
)
594 gimple_value_profile_transformations ();
596 /* The above could hose dominator info. Currently there is
597 none coming in, this is a safety valve. It should be
598 easy to adjust it, if and when there is some. */
599 free_dominance_info (CDI_DOMINATORS
);
600 free_dominance_info (CDI_POST_DOMINATORS
);
604 /* Drop pure/const flags from instrumented functions. */
605 FOR_EACH_DEFINED_FUNCTION (node
)
607 if (!gimple_has_body_p (node
->decl
)
609 || node
->decl
!= node
->clone_of
->decl
))
612 /* Don't profile functions produced for builtin stuff. */
613 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
)
616 cgraph_set_const_flag (node
, false, false);
617 cgraph_set_pure_flag (node
, false, false);
620 /* Update call statements and rebuild the cgraph. */
621 FOR_EACH_DEFINED_FUNCTION (node
)
625 if (!gimple_has_body_p (node
->decl
)
627 || node
->decl
!= node
->clone_of
->decl
))
630 /* Don't profile functions produced for builtin stuff. */
631 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
)
634 push_cfun (DECL_STRUCT_FUNCTION (node
->decl
));
638 gimple_stmt_iterator gsi
;
639 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
641 gimple stmt
= gsi_stmt (gsi
);
642 if (is_gimple_call (stmt
))
647 /* re-merge split blocks. */
649 update_ssa (TODO_update_ssa
);
651 rebuild_cgraph_edges ();
656 handle_missing_profiles ();
662 /* When profile instrumentation, use or test coverage shall be performed. */
665 gate_tree_profile_ipa (void)
668 && (flag_branch_probabilities
|| flag_test_coverage
669 || profile_arc_flag
));
674 const pass_data pass_data_ipa_tree_profile
=
676 SIMPLE_IPA_PASS
, /* type */
677 "profile", /* name */
678 OPTGROUP_NONE
, /* optinfo_flags */
680 true, /* has_execute */
681 TV_IPA_PROFILE
, /* tv_id */
682 0, /* properties_required */
683 0, /* properties_provided */
684 0, /* properties_destroyed */
685 0, /* todo_flags_start */
686 0, /* todo_flags_finish */
689 class pass_ipa_tree_profile
: public simple_ipa_opt_pass
692 pass_ipa_tree_profile (gcc::context
*ctxt
)
693 : simple_ipa_opt_pass (pass_data_ipa_tree_profile
, ctxt
)
696 /* opt_pass methods: */
697 bool gate () { return gate_tree_profile_ipa (); }
698 unsigned int execute () { return tree_profiling (); }
700 }; // class pass_ipa_tree_profile
704 simple_ipa_opt_pass
*
705 make_pass_ipa_tree_profile (gcc::context
*ctxt
)
707 return new pass_ipa_tree_profile (ctxt
);
710 #include "gt-tree-profile.h"