1 /* Calculate branch probabilities, and basic block execution counts.
2 Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010
4 Free Software Foundation, Inc.
5 Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
6 based on some ideas from Dain Samples of UC Berkeley.
7 Further mangling by Bob Manson, Cygnus Support.
8 Converted to use trees by Dale Johannesen, Apple Computer.
10 This file is part of GCC.
12 GCC is free software; you can redistribute it and/or modify it under
13 the terms of the GNU General Public License as published by the Free
14 Software Foundation; either version 3, or (at your option) any later
17 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
18 WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 You should have received a copy of the GNU General Public License
23 along with GCC; see the file COPYING3. If not see
24 <http://www.gnu.org/licenses/>. */
26 /* Generate basic block profile instrumentation and auxiliary files.
27 Tree-based version. See profile.c for overview. */
31 #include "coretypes.h"
36 #include "basic-block.h"
37 #include "diagnostic-core.h"
40 #include "tree-flow.h"
41 #include "tree-dump.h"
42 #include "tree-pass.h"
44 #include "value-prof.h"
50 static GTY(()) tree gcov_type_node
;
51 static GTY(()) tree gcov_type_tmp_var
;
52 static GTY(()) tree tree_interval_profiler_fn
;
53 static GTY(()) tree tree_pow2_profiler_fn
;
54 static GTY(()) tree tree_one_value_profiler_fn
;
55 static GTY(()) tree tree_indirect_call_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 static gcov* __gcov_indirect_call_counters; // pointer to actual counter
68 static void* __gcov_indirect_call_callee; // actual callee address
71 init_ic_make_global_vars (void)
75 ptr_void
= build_pointer_type (void_type_node
);
78 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
79 get_identifier ("__gcov_indirect_call_callee"),
81 TREE_STATIC (ic_void_ptr_var
) = 1;
82 TREE_PUBLIC (ic_void_ptr_var
) = 0;
83 DECL_ARTIFICIAL (ic_void_ptr_var
) = 1;
84 DECL_INITIAL (ic_void_ptr_var
) = NULL
;
86 DECL_TLS_MODEL (ic_void_ptr_var
) =
87 decl_default_tls_model (ic_void_ptr_var
);
89 varpool_finalize_decl (ic_void_ptr_var
);
90 varpool_mark_needed_node (varpool_node (ic_void_ptr_var
));
92 gcov_type_ptr
= build_pointer_type (get_gcov_type ());
94 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
95 get_identifier ("__gcov_indirect_call_counters"),
97 TREE_STATIC (ic_gcov_type_ptr_var
) = 1;
98 TREE_PUBLIC (ic_gcov_type_ptr_var
) = 0;
99 DECL_ARTIFICIAL (ic_gcov_type_ptr_var
) = 1;
100 DECL_INITIAL (ic_gcov_type_ptr_var
) = NULL
;
101 if (targetm
.have_tls
)
102 DECL_TLS_MODEL (ic_gcov_type_ptr_var
) =
103 decl_default_tls_model (ic_gcov_type_ptr_var
);
105 varpool_finalize_decl (ic_gcov_type_ptr_var
);
106 varpool_mark_needed_node (varpool_node (ic_gcov_type_ptr_var
));
110 gimple_init_edge_profiler (void)
112 tree interval_profiler_fn_type
;
113 tree pow2_profiler_fn_type
;
114 tree one_value_profiler_fn_type
;
116 tree ic_profiler_fn_type
;
117 tree average_profiler_fn_type
;
121 gcov_type_node
= get_gcov_type ();
122 gcov_type_ptr
= build_pointer_type (gcov_type_node
);
124 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
125 interval_profiler_fn_type
126 = build_function_type_list (void_type_node
,
127 gcov_type_ptr
, gcov_type_node
,
129 unsigned_type_node
, NULL_TREE
);
130 tree_interval_profiler_fn
131 = build_fn_decl ("__gcov_interval_profiler",
132 interval_profiler_fn_type
);
133 TREE_NOTHROW (tree_interval_profiler_fn
) = 1;
134 DECL_ATTRIBUTES (tree_interval_profiler_fn
)
135 = tree_cons (get_identifier ("leaf"), NULL
,
136 DECL_ATTRIBUTES (tree_interval_profiler_fn
));
138 /* void (*) (gcov_type *, gcov_type) */
139 pow2_profiler_fn_type
140 = build_function_type_list (void_type_node
,
141 gcov_type_ptr
, gcov_type_node
,
143 tree_pow2_profiler_fn
= build_fn_decl ("__gcov_pow2_profiler",
144 pow2_profiler_fn_type
);
145 TREE_NOTHROW (tree_pow2_profiler_fn
) = 1;
146 DECL_ATTRIBUTES (tree_pow2_profiler_fn
)
147 = tree_cons (get_identifier ("leaf"), NULL
,
148 DECL_ATTRIBUTES (tree_pow2_profiler_fn
));
150 /* void (*) (gcov_type *, gcov_type) */
151 one_value_profiler_fn_type
152 = build_function_type_list (void_type_node
,
153 gcov_type_ptr
, gcov_type_node
,
155 tree_one_value_profiler_fn
156 = build_fn_decl ("__gcov_one_value_profiler",
157 one_value_profiler_fn_type
);
158 TREE_NOTHROW (tree_one_value_profiler_fn
) = 1;
159 DECL_ATTRIBUTES (tree_one_value_profiler_fn
)
160 = tree_cons (get_identifier ("leaf"), NULL
,
161 DECL_ATTRIBUTES (tree_one_value_profiler_fn
));
163 init_ic_make_global_vars ();
165 /* void (*) (gcov_type *, gcov_type, void *, void *) */
167 = build_function_type_list (void_type_node
,
168 gcov_type_ptr
, gcov_type_node
,
170 ptr_void
, NULL_TREE
);
171 tree_indirect_call_profiler_fn
172 = build_fn_decl ("__gcov_indirect_call_profiler",
173 ic_profiler_fn_type
);
174 TREE_NOTHROW (tree_indirect_call_profiler_fn
) = 1;
175 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn
)
176 = tree_cons (get_identifier ("leaf"), NULL
,
177 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn
));
179 /* void (*) (gcov_type *, gcov_type) */
180 average_profiler_fn_type
181 = build_function_type_list (void_type_node
,
182 gcov_type_ptr
, gcov_type_node
, NULL_TREE
);
183 tree_average_profiler_fn
184 = build_fn_decl ("__gcov_average_profiler",
185 average_profiler_fn_type
);
186 TREE_NOTHROW (tree_average_profiler_fn
) = 1;
187 DECL_ATTRIBUTES (tree_average_profiler_fn
)
188 = tree_cons (get_identifier ("leaf"), NULL
,
189 DECL_ATTRIBUTES (tree_average_profiler_fn
));
191 = build_fn_decl ("__gcov_ior_profiler",
192 average_profiler_fn_type
);
193 TREE_NOTHROW (tree_ior_profiler_fn
) = 1;
194 DECL_ATTRIBUTES (tree_ior_profiler_fn
)
195 = tree_cons (get_identifier ("leaf"), NULL
,
196 DECL_ATTRIBUTES (tree_ior_profiler_fn
));
198 /* LTO streamer needs assembler names. Because we create these decls
199 late, we need to initialize them by hand. */
200 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn
);
201 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn
);
202 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn
);
203 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn
);
204 DECL_ASSEMBLER_NAME (tree_average_profiler_fn
);
205 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn
);
209 /* Output instructions as GIMPLE trees to increment the edge
210 execution count, and insert them on E. We rely on
211 gsi_insert_on_edge to preserve the order. */
214 gimple_gen_edge_profiler (int edgeno
, edge e
)
217 gimple stmt1
, stmt2
, stmt3
;
219 /* We share one temporary variable declaration per function. This
220 gets re-set in tree_profiling. */
221 if (gcov_type_tmp_var
== NULL_TREE
)
222 gcov_type_tmp_var
= create_tmp_reg (gcov_type_node
, "PROF_edge_counter");
223 ref
= tree_coverage_counter_ref (GCOV_COUNTER_ARCS
, edgeno
);
224 one
= build_int_cst (gcov_type_node
, 1);
225 stmt1
= gimple_build_assign (gcov_type_tmp_var
, ref
);
226 gimple_assign_set_lhs (stmt1
, make_ssa_name (gcov_type_tmp_var
, stmt1
));
227 find_referenced_vars_in (stmt1
);
228 stmt2
= gimple_build_assign_with_ops (PLUS_EXPR
, gcov_type_tmp_var
,
229 gimple_assign_lhs (stmt1
), one
);
230 gimple_assign_set_lhs (stmt2
, make_ssa_name (gcov_type_tmp_var
, stmt2
));
231 stmt3
= gimple_build_assign (unshare_expr (ref
), gimple_assign_lhs (stmt2
));
232 gsi_insert_on_edge (e
, stmt1
);
233 gsi_insert_on_edge (e
, stmt2
);
234 gsi_insert_on_edge (e
, stmt3
);
237 /* Emits code to get VALUE to instrument at GSI, and returns the
238 variable containing the value. */
241 prepare_instrumented_value (gimple_stmt_iterator
*gsi
, histogram_value value
)
243 tree val
= value
->hvalue
.value
;
244 if (POINTER_TYPE_P (TREE_TYPE (val
)))
245 val
= fold_convert (build_nonstandard_integer_type
246 (TYPE_PRECISION (TREE_TYPE (val
)), 1), val
);
247 return force_gimple_operand_gsi (gsi
, fold_convert (gcov_type_node
, val
),
248 true, NULL_TREE
, true, GSI_SAME_STMT
);
251 /* Output instructions as GIMPLE trees to increment the interval histogram
252 counter. VALUE is the expression whose value is profiled. TAG is the
253 tag of the section for counters, BASE is offset of the counter position. */
256 gimple_gen_interval_profiler (histogram_value value
, unsigned tag
, unsigned base
)
258 gimple stmt
= value
->hvalue
.stmt
;
259 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
260 tree ref
= tree_coverage_counter_ref (tag
, base
), ref_ptr
;
263 tree start
= build_int_cst_type (integer_type_node
,
264 value
->hdata
.intvl
.int_start
);
265 tree steps
= build_int_cst_type (unsigned_type_node
,
266 value
->hdata
.intvl
.steps
);
268 ref_ptr
= force_gimple_operand_gsi (&gsi
,
269 build_addr (ref
, current_function_decl
),
270 true, NULL_TREE
, true, GSI_SAME_STMT
);
271 val
= prepare_instrumented_value (&gsi
, value
);
272 call
= gimple_build_call (tree_interval_profiler_fn
, 4,
273 ref_ptr
, val
, start
, steps
);
274 find_referenced_vars_in (call
);
275 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
278 /* Output instructions as GIMPLE trees to increment the power of two histogram
279 counter. VALUE is the expression whose value is profiled. TAG is the tag
280 of the section for counters, BASE is offset of the counter position. */
283 gimple_gen_pow2_profiler (histogram_value value
, unsigned tag
, unsigned base
)
285 gimple stmt
= value
->hvalue
.stmt
;
286 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
287 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
291 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
292 true, NULL_TREE
, true, GSI_SAME_STMT
);
293 val
= prepare_instrumented_value (&gsi
, value
);
294 call
= gimple_build_call (tree_pow2_profiler_fn
, 2, ref_ptr
, val
);
295 find_referenced_vars_in (call
);
296 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
299 /* Output instructions as GIMPLE trees for code to find the most common value.
300 VALUE is the expression whose value is profiled. TAG is the tag of the
301 section for counters, BASE is offset of the counter position. */
304 gimple_gen_one_value_profiler (histogram_value value
, unsigned tag
, unsigned base
)
306 gimple stmt
= value
->hvalue
.stmt
;
307 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
308 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
312 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
313 true, NULL_TREE
, true, GSI_SAME_STMT
);
314 val
= prepare_instrumented_value (&gsi
, value
);
315 call
= gimple_build_call (tree_one_value_profiler_fn
, 2, ref_ptr
, val
);
316 find_referenced_vars_in (call
);
317 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
321 /* Output instructions as GIMPLE trees for code to find the most
322 common called function in indirect call.
323 VALUE is the call expression whose indirect callee is profiled.
324 TAG is the tag of the section for counters, BASE is offset of the
328 gimple_gen_ic_profiler (histogram_value value
, unsigned tag
, unsigned base
)
331 gimple stmt1
, stmt2
, stmt3
;
332 gimple stmt
= value
->hvalue
.stmt
;
333 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
334 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
336 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
337 true, NULL_TREE
, true, GSI_SAME_STMT
);
341 __gcov_indirect_call_counters = get_relevant_counter_ptr ();
342 __gcov_indirect_call_callee = (void *) indirect call argument;
345 tmp1
= create_tmp_reg (ptr_void
, "PROF");
346 stmt1
= gimple_build_assign (ic_gcov_type_ptr_var
, ref_ptr
);
347 find_referenced_vars_in (stmt1
);
348 stmt2
= gimple_build_assign (tmp1
, unshare_expr (value
->hvalue
.value
));
349 gimple_assign_set_lhs (stmt2
, make_ssa_name (tmp1
, stmt2
));
350 find_referenced_vars_in (stmt2
);
351 stmt3
= gimple_build_assign (ic_void_ptr_var
, gimple_assign_lhs (stmt2
));
352 add_referenced_var (ic_void_ptr_var
);
354 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
355 gsi_insert_before (&gsi
, stmt2
, GSI_SAME_STMT
);
356 gsi_insert_before (&gsi
, stmt3
, GSI_SAME_STMT
);
360 /* Output instructions as GIMPLE trees for code to find the most
361 common called function in indirect call. Insert instructions at the
362 beginning of every possible called function.
366 gimple_gen_ic_func_profiler (void)
368 struct cgraph_node
* c_node
= cgraph_get_node (current_function_decl
);
369 gimple_stmt_iterator gsi
;
371 tree tree_uid
, cur_func
, counter_ptr
, ptr_var
, void0
;
373 if (cgraph_only_called_directly_p (c_node
))
376 gimple_init_edge_profiler ();
378 gsi
= gsi_after_labels (single_succ (ENTRY_BLOCK_PTR
));
380 cur_func
= force_gimple_operand_gsi (&gsi
,
381 build_addr (current_function_decl
,
382 current_function_decl
),
384 true, GSI_SAME_STMT
);
385 counter_ptr
= force_gimple_operand_gsi (&gsi
, ic_gcov_type_ptr_var
,
386 true, NULL_TREE
, true,
388 add_referenced_var (ic_gcov_type_ptr_var
);
389 ptr_var
= force_gimple_operand_gsi (&gsi
, ic_void_ptr_var
,
390 true, NULL_TREE
, true,
392 add_referenced_var (ic_void_ptr_var
);
393 tree_uid
= build_int_cst (gcov_type_node
, current_function_funcdef_no
);
394 stmt1
= gimple_build_call (tree_indirect_call_profiler_fn
, 4,
395 counter_ptr
, tree_uid
, cur_func
, ptr_var
);
396 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
398 /* Set __gcov_indirect_call_callee to 0,
399 so that calls from other modules won't get misattributed
400 to the last caller of the current callee. */
401 void0
= build_int_cst (build_pointer_type (void_type_node
), 0);
402 stmt2
= gimple_build_assign (ic_void_ptr_var
, void0
);
403 gsi_insert_before (&gsi
, stmt2
, GSI_SAME_STMT
);
406 /* Output instructions as GIMPLE trees for code to find the most common value
407 of a difference between two evaluations of an expression.
408 VALUE is the expression whose value is profiled. TAG is the tag of the
409 section for counters, BASE is offset of the counter position. */
412 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED
,
413 unsigned tag ATTRIBUTE_UNUSED
,
414 unsigned base ATTRIBUTE_UNUSED
)
416 /* FIXME implement this. */
417 #ifdef ENABLE_CHECKING
418 internal_error ("unimplemented functionality");
423 /* Output instructions as GIMPLE trees to increment the average histogram
424 counter. VALUE is the expression whose value is profiled. TAG is the
425 tag of the section for counters, BASE is offset of the counter position. */
428 gimple_gen_average_profiler (histogram_value value
, unsigned tag
, unsigned base
)
430 gimple stmt
= value
->hvalue
.stmt
;
431 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
432 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
436 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
438 true, GSI_SAME_STMT
);
439 val
= prepare_instrumented_value (&gsi
, value
);
440 call
= gimple_build_call (tree_average_profiler_fn
, 2, ref_ptr
, val
);
441 find_referenced_vars_in (call
);
442 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
445 /* Output instructions as GIMPLE trees to increment the ior histogram
446 counter. VALUE is the expression whose value is profiled. TAG is the
447 tag of the section for counters, BASE is offset of the counter position. */
450 gimple_gen_ior_profiler (histogram_value value
, unsigned tag
, unsigned base
)
452 gimple stmt
= value
->hvalue
.stmt
;
453 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
454 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
458 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
459 true, NULL_TREE
, true, GSI_SAME_STMT
);
460 val
= prepare_instrumented_value (&gsi
, value
);
461 call
= gimple_build_call (tree_ior_profiler_fn
, 2, ref_ptr
, val
);
462 find_referenced_vars_in (call
);
463 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
466 /* Profile all functions in the callgraph. */
469 tree_profiling (void)
471 struct cgraph_node
*node
;
473 /* Don't profile functions produced at destruction time, particularly
474 the gcov datastructure initializer. Don't profile if it has been
475 already instrumented either (when OpenMP expansion creates
476 child function from already instrumented body). */
477 if (cgraph_state
== CGRAPH_STATE_FINISHED
)
482 for (node
= cgraph_nodes
; node
; node
= node
->next
)
485 || !gimple_has_body_p (node
->decl
))
488 /* Don't profile functions produced for builtin stuff. */
489 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
490 || DECL_STRUCT_FUNCTION (node
->decl
)->after_tree_profile
)
493 push_cfun (DECL_STRUCT_FUNCTION (node
->decl
));
494 current_function_decl
= node
->decl
;
496 /* Re-set global shared temporary variable for edge-counters. */
497 gcov_type_tmp_var
= NULL_TREE
;
499 /* Local pure-const may imply need to fixup the cfg. */
500 execute_fixup_cfg ();
503 if (! flag_branch_probabilities
504 && flag_profile_values
)
505 gimple_gen_ic_func_profiler ();
507 if (flag_branch_probabilities
508 && flag_profile_values
509 && flag_value_profile_transformations
)
510 gimple_value_profile_transformations ();
512 /* The above could hose dominator info. Currently there is
513 none coming in, this is a safety valve. It should be
514 easy to adjust it, if and when there is some. */
515 free_dominance_info (CDI_DOMINATORS
);
516 free_dominance_info (CDI_POST_DOMINATORS
);
518 current_function_decl
= NULL
;
522 /* Drop pure/const flags from instrumented functions. */
523 for (node
= cgraph_nodes
; node
; node
= node
->next
)
526 || !gimple_has_body_p (node
->decl
)
527 || !(!node
->clone_of
|| node
->decl
!= node
->clone_of
->decl
))
530 /* Don't profile functions produced for builtin stuff. */
531 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
532 || DECL_STRUCT_FUNCTION (node
->decl
)->after_tree_profile
)
535 cgraph_set_const_flag (node
, false, false);
536 cgraph_set_pure_flag (node
, false, false);
539 /* Update call statements and rebuild the cgraph. */
540 for (node
= cgraph_nodes
; node
; node
= node
->next
)
545 || !gimple_has_body_p (node
->decl
)
546 || !(!node
->clone_of
|| node
->decl
!= node
->clone_of
->decl
))
549 /* Don't profile functions produced for builtin stuff. */
550 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
551 || DECL_STRUCT_FUNCTION (node
->decl
)->after_tree_profile
)
554 push_cfun (DECL_STRUCT_FUNCTION (node
->decl
));
555 current_function_decl
= node
->decl
;
559 gimple_stmt_iterator gsi
;
560 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
562 gimple stmt
= gsi_stmt (gsi
);
563 if (is_gimple_call (stmt
))
568 cfun
->after_tree_profile
= 1;
569 update_ssa (TODO_update_ssa
);
571 rebuild_cgraph_edges ();
573 current_function_decl
= NULL
;
581 /* When profile instrumentation, use or test coverage shall be performed. */
584 gate_tree_profile_ipa (void)
587 && (flag_branch_probabilities
|| flag_test_coverage
588 || profile_arc_flag
));
591 struct simple_ipa_opt_pass pass_ipa_tree_profile
=
595 "profile", /* name */
596 gate_tree_profile_ipa
, /* gate */
597 tree_profiling
, /* execute */
600 0, /* static_pass_number */
601 TV_IPA_PROFILE
, /* tv_id */
602 0, /* properties_required */
603 0, /* properties_provided */
604 0, /* properties_destroyed */
605 0, /* todo_flags_start */
606 0 /* todo_flags_finish */
610 #include "gt-tree-profile.h"