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 "gimple-iterator.h"
40 #include "gimplify-me.h"
41 #include "gimple-ssa.h"
44 #include "tree-ssanames.h"
45 #include "tree-into-ssa.h"
46 #include "tree-pass.h"
47 #include "value-prof.h"
50 #include "tree-cfgcleanup.h"
52 static GTY(()) tree gcov_type_node
;
53 static GTY(()) tree tree_interval_profiler_fn
;
54 static GTY(()) tree tree_pow2_profiler_fn
;
55 static GTY(()) tree tree_one_value_profiler_fn
;
56 static GTY(()) tree tree_indirect_call_profiler_fn
;
57 static GTY(()) tree tree_time_profiler_fn
;
58 static GTY(()) tree tree_average_profiler_fn
;
59 static GTY(()) tree tree_ior_profiler_fn
;
62 static GTY(()) tree ic_void_ptr_var
;
63 static GTY(()) tree ic_gcov_type_ptr_var
;
64 static GTY(()) tree ptr_void
;
66 /* Do initialization work for the edge profiler. */
69 __thread gcov* __gcov_indirect_call_counters; // pointer to actual counter
70 __thread void* __gcov_indirect_call_callee; // actual callee address
71 __thread int __gcov_function_counter; // time profiler function counter
74 init_ic_make_global_vars (void)
78 ptr_void
= build_pointer_type (void_type_node
);
80 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
84 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
85 get_identifier ("__gcov_indirect_call_callee_ltopriv"),
87 TREE_PUBLIC (ic_void_ptr_var
) = 1;
88 DECL_COMMON (ic_void_ptr_var
) = 1;
89 DECL_VISIBILITY (ic_void_ptr_var
) = VISIBILITY_HIDDEN
;
90 DECL_VISIBILITY_SPECIFIED (ic_void_ptr_var
) = true;
95 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
96 get_identifier ("__gcov_indirect_call_callee"),
98 TREE_PUBLIC (ic_void_ptr_var
) = 1;
99 DECL_EXTERNAL (ic_void_ptr_var
) = 1;
101 TREE_STATIC (ic_void_ptr_var
) = 1;
102 DECL_ARTIFICIAL (ic_void_ptr_var
) = 1;
103 DECL_INITIAL (ic_void_ptr_var
) = NULL
;
104 if (targetm
.have_tls
)
105 DECL_TLS_MODEL (ic_void_ptr_var
) =
106 decl_default_tls_model (ic_void_ptr_var
);
108 varpool_finalize_decl (ic_void_ptr_var
);
110 gcov_type_ptr
= build_pointer_type (get_gcov_type ());
111 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
115 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
116 get_identifier ("__gcov_indirect_call_counters_ltopriv"),
118 TREE_PUBLIC (ic_gcov_type_ptr_var
) = 1;
119 DECL_COMMON (ic_gcov_type_ptr_var
) = 1;
120 DECL_VISIBILITY (ic_gcov_type_ptr_var
) = VISIBILITY_HIDDEN
;
121 DECL_VISIBILITY_SPECIFIED (ic_gcov_type_ptr_var
) = true;
126 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
127 get_identifier ("__gcov_indirect_call_counters"),
129 TREE_PUBLIC (ic_gcov_type_ptr_var
) = 1;
130 DECL_EXTERNAL (ic_gcov_type_ptr_var
) = 1;
132 TREE_STATIC (ic_gcov_type_ptr_var
) = 1;
133 DECL_ARTIFICIAL (ic_gcov_type_ptr_var
) = 1;
134 DECL_INITIAL (ic_gcov_type_ptr_var
) = NULL
;
135 if (targetm
.have_tls
)
136 DECL_TLS_MODEL (ic_gcov_type_ptr_var
) =
137 decl_default_tls_model (ic_gcov_type_ptr_var
);
139 varpool_finalize_decl (ic_gcov_type_ptr_var
);
142 /* Create the type and function decls for the interface with gcov. */
145 gimple_init_edge_profiler (void)
147 tree interval_profiler_fn_type
;
148 tree pow2_profiler_fn_type
;
149 tree one_value_profiler_fn_type
;
151 tree ic_profiler_fn_type
;
152 tree average_profiler_fn_type
;
153 tree time_profiler_fn_type
;
157 gcov_type_node
= get_gcov_type ();
158 gcov_type_ptr
= build_pointer_type (gcov_type_node
);
160 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
161 interval_profiler_fn_type
162 = build_function_type_list (void_type_node
,
163 gcov_type_ptr
, gcov_type_node
,
165 unsigned_type_node
, NULL_TREE
);
166 tree_interval_profiler_fn
167 = build_fn_decl ("__gcov_interval_profiler",
168 interval_profiler_fn_type
);
169 TREE_NOTHROW (tree_interval_profiler_fn
) = 1;
170 DECL_ATTRIBUTES (tree_interval_profiler_fn
)
171 = tree_cons (get_identifier ("leaf"), NULL
,
172 DECL_ATTRIBUTES (tree_interval_profiler_fn
));
174 /* void (*) (gcov_type *, gcov_type) */
175 pow2_profiler_fn_type
176 = build_function_type_list (void_type_node
,
177 gcov_type_ptr
, gcov_type_node
,
179 tree_pow2_profiler_fn
= build_fn_decl ("__gcov_pow2_profiler",
180 pow2_profiler_fn_type
);
181 TREE_NOTHROW (tree_pow2_profiler_fn
) = 1;
182 DECL_ATTRIBUTES (tree_pow2_profiler_fn
)
183 = tree_cons (get_identifier ("leaf"), NULL
,
184 DECL_ATTRIBUTES (tree_pow2_profiler_fn
));
186 /* void (*) (gcov_type *, gcov_type) */
187 one_value_profiler_fn_type
188 = build_function_type_list (void_type_node
,
189 gcov_type_ptr
, gcov_type_node
,
191 tree_one_value_profiler_fn
192 = build_fn_decl ("__gcov_one_value_profiler",
193 one_value_profiler_fn_type
);
194 TREE_NOTHROW (tree_one_value_profiler_fn
) = 1;
195 DECL_ATTRIBUTES (tree_one_value_profiler_fn
)
196 = tree_cons (get_identifier ("leaf"), NULL
,
197 DECL_ATTRIBUTES (tree_one_value_profiler_fn
));
199 init_ic_make_global_vars ();
201 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
204 /* void (*) (gcov_type, void *) */
206 = build_function_type_list (void_type_node
,
207 gcov_type_ptr
, gcov_type_node
,
210 tree_indirect_call_profiler_fn
211 = build_fn_decl ("__gcov_indirect_call_profiler",
212 ic_profiler_fn_type
);
216 /* void (*) (gcov_type, void *) */
218 = build_function_type_list (void_type_node
,
222 tree_indirect_call_profiler_fn
223 = build_fn_decl ("__gcov_indirect_call_profiler_v2",
224 ic_profiler_fn_type
);
226 TREE_NOTHROW (tree_indirect_call_profiler_fn
) = 1;
227 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn
)
228 = tree_cons (get_identifier ("leaf"), NULL
,
229 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn
));
231 /* void (*) (gcov_type *, gcov_type, void *) */
232 time_profiler_fn_type
233 = build_function_type_list (void_type_node
,
234 gcov_type_ptr
, NULL_TREE
);
235 tree_time_profiler_fn
236 = build_fn_decl ("__gcov_time_profiler",
237 time_profiler_fn_type
);
238 TREE_NOTHROW (tree_time_profiler_fn
) = 1;
239 DECL_ATTRIBUTES (tree_time_profiler_fn
)
240 = tree_cons (get_identifier ("leaf"), NULL
,
241 DECL_ATTRIBUTES (tree_time_profiler_fn
));
243 /* void (*) (gcov_type *, gcov_type) */
244 average_profiler_fn_type
245 = build_function_type_list (void_type_node
,
246 gcov_type_ptr
, gcov_type_node
, NULL_TREE
);
247 tree_average_profiler_fn
248 = build_fn_decl ("__gcov_average_profiler",
249 average_profiler_fn_type
);
250 TREE_NOTHROW (tree_average_profiler_fn
) = 1;
251 DECL_ATTRIBUTES (tree_average_profiler_fn
)
252 = tree_cons (get_identifier ("leaf"), NULL
,
253 DECL_ATTRIBUTES (tree_average_profiler_fn
));
255 = build_fn_decl ("__gcov_ior_profiler",
256 average_profiler_fn_type
);
257 TREE_NOTHROW (tree_ior_profiler_fn
) = 1;
258 DECL_ATTRIBUTES (tree_ior_profiler_fn
)
259 = tree_cons (get_identifier ("leaf"), NULL
,
260 DECL_ATTRIBUTES (tree_ior_profiler_fn
));
262 /* LTO streamer needs assembler names. Because we create these decls
263 late, we need to initialize them by hand. */
264 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn
);
265 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn
);
266 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn
);
267 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn
);
268 DECL_ASSEMBLER_NAME (tree_time_profiler_fn
);
269 DECL_ASSEMBLER_NAME (tree_average_profiler_fn
);
270 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn
);
274 /* Output instructions as GIMPLE trees to increment the edge
275 execution count, and insert them on E. We rely on
276 gsi_insert_on_edge to preserve the order. */
279 gimple_gen_edge_profiler (int edgeno
, edge e
)
281 tree ref
, one
, gcov_type_tmp_var
;
282 gimple stmt1
, stmt2
, stmt3
;
284 ref
= tree_coverage_counter_ref (GCOV_COUNTER_ARCS
, edgeno
);
285 one
= build_int_cst (gcov_type_node
, 1);
286 gcov_type_tmp_var
= make_temp_ssa_name (gcov_type_node
,
287 NULL
, "PROF_edge_counter");
288 stmt1
= gimple_build_assign (gcov_type_tmp_var
, ref
);
289 gcov_type_tmp_var
= make_temp_ssa_name (gcov_type_node
,
290 NULL
, "PROF_edge_counter");
291 stmt2
= gimple_build_assign_with_ops (PLUS_EXPR
, gcov_type_tmp_var
,
292 gimple_assign_lhs (stmt1
), one
);
293 stmt3
= gimple_build_assign (unshare_expr (ref
), gimple_assign_lhs (stmt2
));
294 gsi_insert_on_edge (e
, stmt1
);
295 gsi_insert_on_edge (e
, stmt2
);
296 gsi_insert_on_edge (e
, stmt3
);
299 /* Emits code to get VALUE to instrument at GSI, and returns the
300 variable containing the value. */
303 prepare_instrumented_value (gimple_stmt_iterator
*gsi
, histogram_value value
)
305 tree val
= value
->hvalue
.value
;
306 if (POINTER_TYPE_P (TREE_TYPE (val
)))
307 val
= fold_convert (build_nonstandard_integer_type
308 (TYPE_PRECISION (TREE_TYPE (val
)), 1), val
);
309 return force_gimple_operand_gsi (gsi
, fold_convert (gcov_type_node
, val
),
310 true, NULL_TREE
, true, GSI_SAME_STMT
);
313 /* Output instructions as GIMPLE trees to increment the interval histogram
314 counter. VALUE is the expression whose value is profiled. TAG is the
315 tag of the section for counters, BASE is offset of the counter position. */
318 gimple_gen_interval_profiler (histogram_value value
, unsigned tag
, unsigned base
)
320 gimple stmt
= value
->hvalue
.stmt
;
321 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
322 tree ref
= tree_coverage_counter_ref (tag
, base
), ref_ptr
;
325 tree start
= build_int_cst_type (integer_type_node
,
326 value
->hdata
.intvl
.int_start
);
327 tree steps
= build_int_cst_type (unsigned_type_node
,
328 value
->hdata
.intvl
.steps
);
330 ref_ptr
= force_gimple_operand_gsi (&gsi
,
331 build_addr (ref
, current_function_decl
),
332 true, NULL_TREE
, true, GSI_SAME_STMT
);
333 val
= prepare_instrumented_value (&gsi
, value
);
334 call
= gimple_build_call (tree_interval_profiler_fn
, 4,
335 ref_ptr
, val
, start
, steps
);
336 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
339 /* Output instructions as GIMPLE trees to increment the power of two histogram
340 counter. VALUE is the expression whose value is profiled. TAG is the tag
341 of the section for counters, BASE is offset of the counter position. */
344 gimple_gen_pow2_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_pow2_profiler_fn
, 2, ref_ptr
, val
);
356 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
359 /* Output instructions as GIMPLE trees for code to find the most common value.
360 VALUE is the expression whose value is profiled. TAG is the tag of the
361 section for counters, BASE is offset of the counter position. */
364 gimple_gen_one_value_profiler (histogram_value value
, unsigned tag
, unsigned base
)
366 gimple stmt
= value
->hvalue
.stmt
;
367 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
368 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
372 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
373 true, NULL_TREE
, true, GSI_SAME_STMT
);
374 val
= prepare_instrumented_value (&gsi
, value
);
375 call
= gimple_build_call (tree_one_value_profiler_fn
, 2, ref_ptr
, val
);
376 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
380 /* Output instructions as GIMPLE trees for code to find the most
381 common called function in indirect call.
382 VALUE is the call expression whose indirect callee is profiled.
383 TAG is the tag of the section for counters, BASE is offset of the
387 gimple_gen_ic_profiler (histogram_value value
, unsigned tag
, unsigned base
)
390 gimple stmt1
, stmt2
, stmt3
;
391 gimple stmt
= value
->hvalue
.stmt
;
392 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
393 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
395 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
396 true, NULL_TREE
, true, GSI_SAME_STMT
);
400 stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
401 stmt2: tmp1 = (void *) (indirect call argument value)
402 stmt3: __gcov_indirect_call_callee = tmp1;
405 stmt1
= gimple_build_assign (ic_gcov_type_ptr_var
, ref_ptr
);
406 tmp1
= make_temp_ssa_name (ptr_void
, NULL
, "PROF");
407 stmt2
= gimple_build_assign (tmp1
, unshare_expr (value
->hvalue
.value
));
408 stmt3
= gimple_build_assign (ic_void_ptr_var
, gimple_assign_lhs (stmt2
));
410 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
411 gsi_insert_before (&gsi
, stmt2
, GSI_SAME_STMT
);
412 gsi_insert_before (&gsi
, stmt3
, GSI_SAME_STMT
);
416 /* Output instructions as GIMPLE trees for code to find the most
417 common called function in indirect call. Insert instructions at the
418 beginning of every possible called function.
422 gimple_gen_ic_func_profiler (void)
424 struct cgraph_node
* c_node
= cgraph_get_node (current_function_decl
);
425 gimple_stmt_iterator gsi
;
427 tree tree_uid
, cur_func
, void0
;
429 if (cgraph_only_called_directly_p (c_node
))
432 gimple_init_edge_profiler ();
436 stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
437 ¤t_function_decl)
439 gsi
= gsi_after_labels (split_edge (single_succ_edge (ENTRY_BLOCK_PTR
)));
441 cur_func
= force_gimple_operand_gsi (&gsi
,
442 build_addr (current_function_decl
,
443 current_function_decl
),
445 true, GSI_SAME_STMT
);
446 tree_uid
= build_int_cst
447 (gcov_type_node
, cgraph_get_node (current_function_decl
)->profile_id
);
448 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
451 tree counter_ptr
, ptr_var
;
452 counter_ptr
= force_gimple_operand_gsi (&gsi
, ic_gcov_type_ptr_var
,
453 true, NULL_TREE
, true,
455 ptr_var
= force_gimple_operand_gsi (&gsi
, ic_void_ptr_var
,
456 true, NULL_TREE
, true,
459 stmt1
= gimple_build_call (tree_indirect_call_profiler_fn
, 4,
460 counter_ptr
, tree_uid
, cur_func
, ptr_var
);
464 stmt1
= gimple_build_call (tree_indirect_call_profiler_fn
, 2,
467 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
469 /* Set __gcov_indirect_call_callee to 0,
470 so that calls from other modules won't get misattributed
471 to the last caller of the current callee. */
472 void0
= build_int_cst (build_pointer_type (void_type_node
), 0);
473 stmt2
= gimple_build_assign (ic_void_ptr_var
, void0
);
474 gsi_insert_before (&gsi
, stmt2
, GSI_SAME_STMT
);
477 /* Output instructions as GIMPLE tree at the beginning for each function.
478 TAG is the tag of the section for counters, BASE is offset of the
479 counter position and GSI is the iterator we place the counter. */
482 gimple_gen_time_profiler (unsigned tag
, unsigned base
,
483 gimple_stmt_iterator
&gsi
)
485 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
488 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
489 true, NULL_TREE
, true, GSI_SAME_STMT
);
490 call
= gimple_build_call (tree_time_profiler_fn
, 1, ref_ptr
);
491 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
494 /* Output instructions as GIMPLE trees for code to find the most common value
495 of a difference between two evaluations of an expression.
496 VALUE is the expression whose value is profiled. TAG is the tag of the
497 section for counters, BASE is offset of the counter position. */
500 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED
,
501 unsigned tag ATTRIBUTE_UNUSED
,
502 unsigned base ATTRIBUTE_UNUSED
)
504 /* FIXME implement this. */
505 #ifdef ENABLE_CHECKING
506 internal_error ("unimplemented functionality");
511 /* Output instructions as GIMPLE trees to increment the average histogram
512 counter. VALUE is the expression whose value is profiled. TAG is the
513 tag of the section for counters, BASE is offset of the counter position. */
516 gimple_gen_average_profiler (histogram_value value
, unsigned tag
, unsigned base
)
518 gimple stmt
= value
->hvalue
.stmt
;
519 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
520 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
524 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
526 true, GSI_SAME_STMT
);
527 val
= prepare_instrumented_value (&gsi
, value
);
528 call
= gimple_build_call (tree_average_profiler_fn
, 2, ref_ptr
, val
);
529 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
532 /* Output instructions as GIMPLE trees to increment the ior histogram
533 counter. VALUE is the expression whose value is profiled. TAG is the
534 tag of the section for counters, BASE is offset of the counter position. */
537 gimple_gen_ior_profiler (histogram_value value
, unsigned tag
, unsigned base
)
539 gimple stmt
= value
->hvalue
.stmt
;
540 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
541 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
545 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
546 true, NULL_TREE
, true, GSI_SAME_STMT
);
547 val
= prepare_instrumented_value (&gsi
, value
);
548 call
= gimple_build_call (tree_ior_profiler_fn
, 2, ref_ptr
, val
);
549 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
552 /* Profile all functions in the callgraph. */
555 tree_profiling (void)
557 struct cgraph_node
*node
;
559 /* This is a small-ipa pass that gets called only once, from
560 cgraphunit.c:ipa_passes(). */
561 gcc_assert (cgraph_state
== CGRAPH_STATE_IPA_SSA
);
563 init_node_map (true);
565 FOR_EACH_DEFINED_FUNCTION (node
)
567 if (!gimple_has_body_p (node
->decl
))
570 /* Don't profile functions produced for builtin stuff. */
571 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
)
574 push_cfun (DECL_STRUCT_FUNCTION (node
->decl
));
576 /* Local pure-const may imply need to fixup the cfg. */
577 if (execute_fixup_cfg () & TODO_cleanup_cfg
)
582 if (! flag_branch_probabilities
583 && flag_profile_values
)
584 gimple_gen_ic_func_profiler ();
586 if (flag_branch_probabilities
587 && flag_profile_values
588 && flag_value_profile_transformations
)
589 gimple_value_profile_transformations ();
591 /* The above could hose dominator info. Currently there is
592 none coming in, this is a safety valve. It should be
593 easy to adjust it, if and when there is some. */
594 free_dominance_info (CDI_DOMINATORS
);
595 free_dominance_info (CDI_POST_DOMINATORS
);
599 /* Drop pure/const flags from instrumented functions. */
600 FOR_EACH_DEFINED_FUNCTION (node
)
602 if (!gimple_has_body_p (node
->decl
)
604 || node
->decl
!= node
->clone_of
->decl
))
607 /* Don't profile functions produced for builtin stuff. */
608 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
)
611 cgraph_set_const_flag (node
, false, false);
612 cgraph_set_pure_flag (node
, false, false);
615 /* Update call statements and rebuild the cgraph. */
616 FOR_EACH_DEFINED_FUNCTION (node
)
620 if (!gimple_has_body_p (node
->decl
)
622 || node
->decl
!= node
->clone_of
->decl
))
625 /* Don't profile functions produced for builtin stuff. */
626 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
)
629 push_cfun (DECL_STRUCT_FUNCTION (node
->decl
));
633 gimple_stmt_iterator gsi
;
634 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
636 gimple stmt
= gsi_stmt (gsi
);
637 if (is_gimple_call (stmt
))
642 /* re-merge split blocks. */
644 update_ssa (TODO_update_ssa
);
646 rebuild_cgraph_edges ();
651 handle_missing_profiles ();
657 /* When profile instrumentation, use or test coverage shall be performed. */
660 gate_tree_profile_ipa (void)
663 && (flag_branch_probabilities
|| flag_test_coverage
664 || profile_arc_flag
));
669 const pass_data pass_data_ipa_tree_profile
=
671 SIMPLE_IPA_PASS
, /* type */
672 "profile", /* name */
673 OPTGROUP_NONE
, /* optinfo_flags */
675 true, /* has_execute */
676 TV_IPA_PROFILE
, /* tv_id */
677 0, /* properties_required */
678 0, /* properties_provided */
679 0, /* properties_destroyed */
680 0, /* todo_flags_start */
681 0, /* todo_flags_finish */
684 class pass_ipa_tree_profile
: public simple_ipa_opt_pass
687 pass_ipa_tree_profile (gcc::context
*ctxt
)
688 : simple_ipa_opt_pass (pass_data_ipa_tree_profile
, ctxt
)
691 /* opt_pass methods: */
692 bool gate () { return gate_tree_profile_ipa (); }
693 unsigned int execute () { return tree_profiling (); }
695 }; // class pass_ipa_tree_profile
699 simple_ipa_opt_pass
*
700 make_pass_ipa_tree_profile (gcc::context
*ctxt
)
702 return new pass_ipa_tree_profile (ctxt
);
705 #include "gt-tree-profile.h"