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"
35 #include "basic-block.h"
36 #include "diagnostic-core.h"
39 #include "tree-flow.h"
40 #include "tree-pass.h"
41 #include "value-prof.h"
46 static GTY(()) tree gcov_type_node
;
47 static GTY(()) tree gcov_type_tmp_var
;
48 static GTY(()) tree tree_interval_profiler_fn
;
49 static GTY(()) tree tree_pow2_profiler_fn
;
50 static GTY(()) tree tree_one_value_profiler_fn
;
51 static GTY(()) tree tree_indirect_call_profiler_fn
;
52 static GTY(()) tree tree_average_profiler_fn
;
53 static GTY(()) tree tree_ior_profiler_fn
;
56 static GTY(()) tree ic_void_ptr_var
;
57 static GTY(()) tree ic_gcov_type_ptr_var
;
58 static GTY(()) tree ptr_void
;
60 /* Do initialization work for the edge profiler. */
63 static gcov* __gcov_indirect_call_counters; // pointer to actual counter
64 static void* __gcov_indirect_call_callee; // actual callee address
67 init_ic_make_global_vars (void)
71 ptr_void
= build_pointer_type (void_type_node
);
74 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
75 get_identifier ("__gcov_indirect_call_callee"),
77 TREE_STATIC (ic_void_ptr_var
) = 1;
78 TREE_PUBLIC (ic_void_ptr_var
) = 0;
79 DECL_ARTIFICIAL (ic_void_ptr_var
) = 1;
80 DECL_INITIAL (ic_void_ptr_var
) = NULL
;
82 DECL_TLS_MODEL (ic_void_ptr_var
) =
83 decl_default_tls_model (ic_void_ptr_var
);
85 varpool_finalize_decl (ic_void_ptr_var
);
87 gcov_type_ptr
= build_pointer_type (get_gcov_type ());
89 = build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
90 get_identifier ("__gcov_indirect_call_counters"),
92 TREE_STATIC (ic_gcov_type_ptr_var
) = 1;
93 TREE_PUBLIC (ic_gcov_type_ptr_var
) = 0;
94 DECL_ARTIFICIAL (ic_gcov_type_ptr_var
) = 1;
95 DECL_INITIAL (ic_gcov_type_ptr_var
) = NULL
;
97 DECL_TLS_MODEL (ic_gcov_type_ptr_var
) =
98 decl_default_tls_model (ic_gcov_type_ptr_var
);
100 varpool_finalize_decl (ic_gcov_type_ptr_var
);
103 /* Create the type and function decls for the interface with gcov. */
106 gimple_init_edge_profiler (void)
108 tree interval_profiler_fn_type
;
109 tree pow2_profiler_fn_type
;
110 tree one_value_profiler_fn_type
;
112 tree ic_profiler_fn_type
;
113 tree average_profiler_fn_type
;
117 gcov_type_node
= get_gcov_type ();
118 gcov_type_ptr
= build_pointer_type (gcov_type_node
);
120 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
121 interval_profiler_fn_type
122 = build_function_type_list (void_type_node
,
123 gcov_type_ptr
, gcov_type_node
,
125 unsigned_type_node
, NULL_TREE
);
126 tree_interval_profiler_fn
127 = build_fn_decl ("__gcov_interval_profiler",
128 interval_profiler_fn_type
);
129 TREE_NOTHROW (tree_interval_profiler_fn
) = 1;
130 DECL_ATTRIBUTES (tree_interval_profiler_fn
)
131 = tree_cons (get_identifier ("leaf"), NULL
,
132 DECL_ATTRIBUTES (tree_interval_profiler_fn
));
134 /* void (*) (gcov_type *, gcov_type) */
135 pow2_profiler_fn_type
136 = build_function_type_list (void_type_node
,
137 gcov_type_ptr
, gcov_type_node
,
139 tree_pow2_profiler_fn
= build_fn_decl ("__gcov_pow2_profiler",
140 pow2_profiler_fn_type
);
141 TREE_NOTHROW (tree_pow2_profiler_fn
) = 1;
142 DECL_ATTRIBUTES (tree_pow2_profiler_fn
)
143 = tree_cons (get_identifier ("leaf"), NULL
,
144 DECL_ATTRIBUTES (tree_pow2_profiler_fn
));
146 /* void (*) (gcov_type *, gcov_type) */
147 one_value_profiler_fn_type
148 = build_function_type_list (void_type_node
,
149 gcov_type_ptr
, gcov_type_node
,
151 tree_one_value_profiler_fn
152 = build_fn_decl ("__gcov_one_value_profiler",
153 one_value_profiler_fn_type
);
154 TREE_NOTHROW (tree_one_value_profiler_fn
) = 1;
155 DECL_ATTRIBUTES (tree_one_value_profiler_fn
)
156 = tree_cons (get_identifier ("leaf"), NULL
,
157 DECL_ATTRIBUTES (tree_one_value_profiler_fn
));
159 init_ic_make_global_vars ();
161 /* void (*) (gcov_type *, gcov_type, void *, void *) */
163 = build_function_type_list (void_type_node
,
164 gcov_type_ptr
, gcov_type_node
,
166 ptr_void
, NULL_TREE
);
167 tree_indirect_call_profiler_fn
168 = build_fn_decl ("__gcov_indirect_call_profiler",
169 ic_profiler_fn_type
);
170 TREE_NOTHROW (tree_indirect_call_profiler_fn
) = 1;
171 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn
)
172 = tree_cons (get_identifier ("leaf"), NULL
,
173 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn
));
175 /* void (*) (gcov_type *, gcov_type) */
176 average_profiler_fn_type
177 = build_function_type_list (void_type_node
,
178 gcov_type_ptr
, gcov_type_node
, NULL_TREE
);
179 tree_average_profiler_fn
180 = build_fn_decl ("__gcov_average_profiler",
181 average_profiler_fn_type
);
182 TREE_NOTHROW (tree_average_profiler_fn
) = 1;
183 DECL_ATTRIBUTES (tree_average_profiler_fn
)
184 = tree_cons (get_identifier ("leaf"), NULL
,
185 DECL_ATTRIBUTES (tree_average_profiler_fn
));
187 = build_fn_decl ("__gcov_ior_profiler",
188 average_profiler_fn_type
);
189 TREE_NOTHROW (tree_ior_profiler_fn
) = 1;
190 DECL_ATTRIBUTES (tree_ior_profiler_fn
)
191 = tree_cons (get_identifier ("leaf"), NULL
,
192 DECL_ATTRIBUTES (tree_ior_profiler_fn
));
194 /* LTO streamer needs assembler names. Because we create these decls
195 late, we need to initialize them by hand. */
196 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn
);
197 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn
);
198 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn
);
199 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn
);
200 DECL_ASSEMBLER_NAME (tree_average_profiler_fn
);
201 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn
);
205 /* Output instructions as GIMPLE trees to increment the edge
206 execution count, and insert them on E. We rely on
207 gsi_insert_on_edge to preserve the order. */
210 gimple_gen_edge_profiler (int edgeno
, edge e
)
213 gimple stmt1
, stmt2
, stmt3
;
215 /* We share one temporary variable declaration per function. This
216 gets re-set in tree_profiling. */
217 if (gcov_type_tmp_var
== NULL_TREE
)
218 gcov_type_tmp_var
= create_tmp_reg (gcov_type_node
, "PROF_edge_counter");
219 ref
= tree_coverage_counter_ref (GCOV_COUNTER_ARCS
, edgeno
);
220 one
= build_int_cst (gcov_type_node
, 1);
221 stmt1
= gimple_build_assign (gcov_type_tmp_var
, ref
);
222 gimple_assign_set_lhs (stmt1
, make_ssa_name (gcov_type_tmp_var
, stmt1
));
223 find_referenced_vars_in (stmt1
);
224 stmt2
= gimple_build_assign_with_ops (PLUS_EXPR
, gcov_type_tmp_var
,
225 gimple_assign_lhs (stmt1
), one
);
226 gimple_assign_set_lhs (stmt2
, make_ssa_name (gcov_type_tmp_var
, stmt2
));
227 stmt3
= gimple_build_assign (unshare_expr (ref
), gimple_assign_lhs (stmt2
));
228 gsi_insert_on_edge (e
, stmt1
);
229 gsi_insert_on_edge (e
, stmt2
);
230 gsi_insert_on_edge (e
, stmt3
);
233 /* Emits code to get VALUE to instrument at GSI, and returns the
234 variable containing the value. */
237 prepare_instrumented_value (gimple_stmt_iterator
*gsi
, histogram_value value
)
239 tree val
= value
->hvalue
.value
;
240 if (POINTER_TYPE_P (TREE_TYPE (val
)))
241 val
= fold_convert (build_nonstandard_integer_type
242 (TYPE_PRECISION (TREE_TYPE (val
)), 1), val
);
243 return force_gimple_operand_gsi (gsi
, fold_convert (gcov_type_node
, val
),
244 true, NULL_TREE
, true, GSI_SAME_STMT
);
247 /* Output instructions as GIMPLE trees to increment the interval histogram
248 counter. VALUE is the expression whose value is profiled. TAG is the
249 tag of the section for counters, BASE is offset of the counter position. */
252 gimple_gen_interval_profiler (histogram_value value
, unsigned tag
, unsigned base
)
254 gimple stmt
= value
->hvalue
.stmt
;
255 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
256 tree ref
= tree_coverage_counter_ref (tag
, base
), ref_ptr
;
259 tree start
= build_int_cst_type (integer_type_node
,
260 value
->hdata
.intvl
.int_start
);
261 tree steps
= build_int_cst_type (unsigned_type_node
,
262 value
->hdata
.intvl
.steps
);
264 ref_ptr
= force_gimple_operand_gsi (&gsi
,
265 build_addr (ref
, current_function_decl
),
266 true, NULL_TREE
, true, GSI_SAME_STMT
);
267 val
= prepare_instrumented_value (&gsi
, value
);
268 call
= gimple_build_call (tree_interval_profiler_fn
, 4,
269 ref_ptr
, val
, start
, steps
);
270 find_referenced_vars_in (call
);
271 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
274 /* Output instructions as GIMPLE trees to increment the power of two histogram
275 counter. VALUE is the expression whose value is profiled. TAG is the tag
276 of the section for counters, BASE is offset of the counter position. */
279 gimple_gen_pow2_profiler (histogram_value value
, unsigned tag
, unsigned base
)
281 gimple stmt
= value
->hvalue
.stmt
;
282 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
283 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
287 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
288 true, NULL_TREE
, true, GSI_SAME_STMT
);
289 val
= prepare_instrumented_value (&gsi
, value
);
290 call
= gimple_build_call (tree_pow2_profiler_fn
, 2, ref_ptr
, val
);
291 find_referenced_vars_in (call
);
292 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
295 /* Output instructions as GIMPLE trees for code to find the most common value.
296 VALUE is the expression whose value is profiled. TAG is the tag of the
297 section for counters, BASE is offset of the counter position. */
300 gimple_gen_one_value_profiler (histogram_value value
, unsigned tag
, unsigned base
)
302 gimple stmt
= value
->hvalue
.stmt
;
303 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
304 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
308 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
309 true, NULL_TREE
, true, GSI_SAME_STMT
);
310 val
= prepare_instrumented_value (&gsi
, value
);
311 call
= gimple_build_call (tree_one_value_profiler_fn
, 2, ref_ptr
, val
);
312 find_referenced_vars_in (call
);
313 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
317 /* Output instructions as GIMPLE trees for code to find the most
318 common called function in indirect call.
319 VALUE is the call expression whose indirect callee is profiled.
320 TAG is the tag of the section for counters, BASE is offset of the
324 gimple_gen_ic_profiler (histogram_value value
, unsigned tag
, unsigned base
)
327 gimple stmt1
, stmt2
, stmt3
;
328 gimple stmt
= value
->hvalue
.stmt
;
329 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
330 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
332 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
333 true, NULL_TREE
, true, GSI_SAME_STMT
);
337 stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
338 stmt2: tmp1 = (void *) (indirect call argument value)
339 stmt3: __gcov_indirect_call_callee = tmp1;
342 tmp1
= create_tmp_reg (ptr_void
, "PROF");
343 stmt1
= gimple_build_assign (ic_gcov_type_ptr_var
, ref_ptr
);
344 find_referenced_vars_in (stmt1
);
345 stmt2
= gimple_build_assign (tmp1
, unshare_expr (value
->hvalue
.value
));
346 gimple_assign_set_lhs (stmt2
, make_ssa_name (tmp1
, stmt2
));
347 find_referenced_vars_in (stmt2
);
348 stmt3
= gimple_build_assign (ic_void_ptr_var
, gimple_assign_lhs (stmt2
));
350 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
351 gsi_insert_before (&gsi
, stmt2
, GSI_SAME_STMT
);
352 gsi_insert_before (&gsi
, stmt3
, GSI_SAME_STMT
);
356 /* Output instructions as GIMPLE trees for code to find the most
357 common called function in indirect call. Insert instructions at the
358 beginning of every possible called function.
362 gimple_gen_ic_func_profiler (void)
364 struct cgraph_node
* c_node
= cgraph_get_node (current_function_decl
);
365 gimple_stmt_iterator gsi
;
367 tree tree_uid
, cur_func
, counter_ptr
, ptr_var
, void0
;
369 if (cgraph_only_called_directly_p (c_node
))
372 gimple_init_edge_profiler ();
376 stmt1: __gcov_indirect_call_profiler (__gcov_indirect_call_counters,
377 current_function_funcdef_no,
378 ¤t_function_decl,
379 __gcov_indirect_call_callee);
381 gsi
= gsi_after_labels (single_succ (ENTRY_BLOCK_PTR
));
383 cur_func
= force_gimple_operand_gsi (&gsi
,
384 build_addr (current_function_decl
,
385 current_function_decl
),
387 true, GSI_SAME_STMT
);
388 counter_ptr
= force_gimple_operand_gsi (&gsi
, ic_gcov_type_ptr_var
,
389 true, NULL_TREE
, true,
391 ptr_var
= force_gimple_operand_gsi (&gsi
, ic_void_ptr_var
,
392 true, NULL_TREE
, true,
394 tree_uid
= build_int_cst (gcov_type_node
, current_function_funcdef_no
);
395 stmt1
= gimple_build_call (tree_indirect_call_profiler_fn
, 4,
396 counter_ptr
, tree_uid
, cur_func
, ptr_var
);
397 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
399 /* Set __gcov_indirect_call_callee to 0,
400 so that calls from other modules won't get misattributed
401 to the last caller of the current callee. */
402 void0
= build_int_cst (build_pointer_type (void_type_node
), 0);
403 stmt2
= gimple_build_assign (ic_void_ptr_var
, void0
);
404 gsi_insert_before (&gsi
, stmt2
, GSI_SAME_STMT
);
407 /* Output instructions as GIMPLE trees for code to find the most common value
408 of a difference between two evaluations of an expression.
409 VALUE is the expression whose value is profiled. TAG is the tag of the
410 section for counters, BASE is offset of the counter position. */
413 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED
,
414 unsigned tag ATTRIBUTE_UNUSED
,
415 unsigned base ATTRIBUTE_UNUSED
)
417 /* FIXME implement this. */
418 #ifdef ENABLE_CHECKING
419 internal_error ("unimplemented functionality");
424 /* Output instructions as GIMPLE trees to increment the average histogram
425 counter. VALUE is the expression whose value is profiled. TAG is the
426 tag of the section for counters, BASE is offset of the counter position. */
429 gimple_gen_average_profiler (histogram_value value
, unsigned tag
, unsigned base
)
431 gimple stmt
= value
->hvalue
.stmt
;
432 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
433 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
437 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
439 true, GSI_SAME_STMT
);
440 val
= prepare_instrumented_value (&gsi
, value
);
441 call
= gimple_build_call (tree_average_profiler_fn
, 2, ref_ptr
, val
);
442 find_referenced_vars_in (call
);
443 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
446 /* Output instructions as GIMPLE trees to increment the ior histogram
447 counter. VALUE is the expression whose value is profiled. TAG is the
448 tag of the section for counters, BASE is offset of the counter position. */
451 gimple_gen_ior_profiler (histogram_value value
, unsigned tag
, unsigned base
)
453 gimple stmt
= value
->hvalue
.stmt
;
454 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
455 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
459 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
460 true, NULL_TREE
, true, GSI_SAME_STMT
);
461 val
= prepare_instrumented_value (&gsi
, value
);
462 call
= gimple_build_call (tree_ior_profiler_fn
, 2, ref_ptr
, val
);
463 find_referenced_vars_in (call
);
464 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
467 /* Profile all functions in the callgraph. */
470 tree_profiling (void)
472 struct cgraph_node
*node
;
474 /* This is a small-ipa pass that gets called only once, from
475 cgraphunit.c:ipa_passes(). */
476 gcc_assert (cgraph_state
== CGRAPH_STATE_IPA_SSA
);
480 FOR_EACH_DEFINED_FUNCTION (node
)
482 if (!gimple_has_body_p (node
->symbol
.decl
))
485 /* Don't profile functions produced for builtin stuff. */
486 if (DECL_SOURCE_LOCATION (node
->symbol
.decl
) == BUILTINS_LOCATION
)
489 push_cfun (DECL_STRUCT_FUNCTION (node
->symbol
.decl
));
490 current_function_decl
= node
->symbol
.decl
;
492 /* Re-set global shared temporary variable for edge-counters. */
493 gcov_type_tmp_var
= NULL_TREE
;
495 /* Local pure-const may imply need to fixup the cfg. */
496 if (execute_fixup_cfg () & TODO_cleanup_cfg
)
501 if (! flag_branch_probabilities
502 && flag_profile_values
)
503 gimple_gen_ic_func_profiler ();
505 if (flag_branch_probabilities
506 && flag_profile_values
507 && flag_value_profile_transformations
)
508 gimple_value_profile_transformations ();
510 /* The above could hose dominator info. Currently there is
511 none coming in, this is a safety valve. It should be
512 easy to adjust it, if and when there is some. */
513 free_dominance_info (CDI_DOMINATORS
);
514 free_dominance_info (CDI_POST_DOMINATORS
);
516 current_function_decl
= NULL
;
520 /* Drop pure/const flags from instrumented functions. */
521 FOR_EACH_DEFINED_FUNCTION (node
)
523 if (!gimple_has_body_p (node
->symbol
.decl
)
525 || node
->symbol
.decl
!= node
->clone_of
->symbol
.decl
))
528 /* Don't profile functions produced for builtin stuff. */
529 if (DECL_SOURCE_LOCATION (node
->symbol
.decl
) == BUILTINS_LOCATION
)
532 cgraph_set_const_flag (node
, false, false);
533 cgraph_set_pure_flag (node
, false, false);
536 /* Update call statements and rebuild the cgraph. */
537 FOR_EACH_DEFINED_FUNCTION (node
)
541 if (!gimple_has_body_p (node
->symbol
.decl
)
543 || node
->symbol
.decl
!= node
->clone_of
->symbol
.decl
))
546 /* Don't profile functions produced for builtin stuff. */
547 if (DECL_SOURCE_LOCATION (node
->symbol
.decl
) == BUILTINS_LOCATION
)
550 push_cfun (DECL_STRUCT_FUNCTION (node
->symbol
.decl
));
551 current_function_decl
= node
->symbol
.decl
;
555 gimple_stmt_iterator gsi
;
556 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
558 gimple stmt
= gsi_stmt (gsi
);
559 if (is_gimple_call (stmt
))
564 update_ssa (TODO_update_ssa
);
566 rebuild_cgraph_edges ();
568 current_function_decl
= NULL
;
576 /* When profile instrumentation, use or test coverage shall be performed. */
579 gate_tree_profile_ipa (void)
582 && (flag_branch_probabilities
|| flag_test_coverage
583 || profile_arc_flag
));
586 struct simple_ipa_opt_pass pass_ipa_tree_profile
=
590 "profile", /* name */
591 gate_tree_profile_ipa
, /* gate */
592 tree_profiling
, /* execute */
595 0, /* static_pass_number */
596 TV_IPA_PROFILE
, /* tv_id */
597 0, /* properties_required */
598 0, /* properties_provided */
599 0, /* properties_destroyed */
600 0, /* todo_flags_start */
601 0 /* todo_flags_finish */
605 #include "gt-tree-profile.h"