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
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"
42 #include "tree-flow.h"
43 #include "tree-dump.h"
44 #include "tree-pass.h"
46 #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 tree_init_ic_make_global_vars (void)
75 ptr_void
= build_pointer_type (void_type_node
);
78 = build_decl (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
;
85 assemble_variable (ic_void_ptr_var
, 0, 0, 0);
87 gcov_type_ptr
= build_pointer_type (get_gcov_type ());
89 = build_decl (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
;
96 assemble_variable (ic_gcov_type_ptr_var
, 0, 0, 0);
100 tree_init_edge_profiler (void)
102 tree interval_profiler_fn_type
;
103 tree pow2_profiler_fn_type
;
104 tree one_value_profiler_fn_type
;
106 tree ic_profiler_fn_type
;
107 tree average_profiler_fn_type
;
111 gcov_type_node
= get_gcov_type ();
112 gcov_type_ptr
= build_pointer_type (gcov_type_node
);
114 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
115 interval_profiler_fn_type
116 = build_function_type_list (void_type_node
,
117 gcov_type_ptr
, gcov_type_node
,
119 unsigned_type_node
, NULL_TREE
);
120 tree_interval_profiler_fn
121 = build_fn_decl ("__gcov_interval_profiler",
122 interval_profiler_fn_type
);
124 /* void (*) (gcov_type *, gcov_type) */
125 pow2_profiler_fn_type
126 = build_function_type_list (void_type_node
,
127 gcov_type_ptr
, gcov_type_node
,
129 tree_pow2_profiler_fn
= build_fn_decl ("__gcov_pow2_profiler",
130 pow2_profiler_fn_type
);
132 /* void (*) (gcov_type *, gcov_type) */
133 one_value_profiler_fn_type
134 = build_function_type_list (void_type_node
,
135 gcov_type_ptr
, gcov_type_node
,
137 tree_one_value_profiler_fn
138 = build_fn_decl ("__gcov_one_value_profiler",
139 one_value_profiler_fn_type
);
141 tree_init_ic_make_global_vars ();
143 /* void (*) (gcov_type *, gcov_type, void *, void *) */
145 = build_function_type_list (void_type_node
,
146 gcov_type_ptr
, gcov_type_node
,
148 ptr_void
, NULL_TREE
);
149 tree_indirect_call_profiler_fn
150 = build_fn_decl ("__gcov_indirect_call_profiler",
151 ic_profiler_fn_type
);
152 /* void (*) (gcov_type *, gcov_type) */
153 average_profiler_fn_type
154 = build_function_type_list (void_type_node
,
155 gcov_type_ptr
, gcov_type_node
, NULL_TREE
);
156 tree_average_profiler_fn
157 = build_fn_decl ("__gcov_average_profiler",
158 average_profiler_fn_type
);
160 = build_fn_decl ("__gcov_ior_profiler",
161 average_profiler_fn_type
);
165 /* New call was added, make goto call edges if neccesary. */
168 add_abnormal_goto_call_edges (gimple_stmt_iterator gsi
)
170 gimple stmt
= gsi_stmt (gsi
);
172 if (!stmt_can_make_abnormal_goto (stmt
))
174 if (!gsi_end_p (gsi
))
175 split_block (gimple_bb (stmt
), stmt
);
176 make_abnormal_goto_edges (gimple_bb (stmt
), true);
179 /* Output instructions as GIMPLE trees to increment the edge
180 execution count, and insert them on E. We rely on
181 gsi_insert_on_edge to preserve the order. */
184 tree_gen_edge_profiler (int edgeno
, edge e
)
187 gimple stmt1
, stmt2
, stmt3
;
189 /* We share one temporary variable declaration per function. This
190 gets re-set in tree_profiling. */
191 if (gcov_type_tmp_var
== NULL_TREE
)
192 gcov_type_tmp_var
= create_tmp_var (gcov_type_node
, "PROF_edge_counter");
193 ref
= tree_coverage_counter_ref (GCOV_COUNTER_ARCS
, edgeno
);
194 one
= build_int_cst (gcov_type_node
, 1);
195 stmt1
= gimple_build_assign (gcov_type_tmp_var
, ref
);
196 stmt2
= gimple_build_assign_with_ops (PLUS_EXPR
, gcov_type_tmp_var
,
197 gcov_type_tmp_var
, one
);
198 stmt3
= gimple_build_assign (unshare_expr (ref
), gcov_type_tmp_var
);
199 gsi_insert_on_edge (e
, stmt1
);
200 gsi_insert_on_edge (e
, stmt2
);
201 gsi_insert_on_edge (e
, stmt3
);
204 /* Emits code to get VALUE to instrument at GSI, and returns the
205 variable containing the value. */
208 prepare_instrumented_value (gimple_stmt_iterator
*gsi
, histogram_value value
)
210 tree val
= value
->hvalue
.value
;
211 return force_gimple_operand_gsi (gsi
, fold_convert (gcov_type_node
, val
),
212 true, NULL_TREE
, true, GSI_SAME_STMT
);
215 /* Output instructions as GIMPLE trees to increment the interval histogram
216 counter. VALUE is the expression whose value is profiled. TAG is the
217 tag of the section for counters, BASE is offset of the counter position. */
220 tree_gen_interval_profiler (histogram_value value
, unsigned tag
, unsigned base
)
222 gimple stmt
= value
->hvalue
.stmt
;
223 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
224 tree ref
= tree_coverage_counter_ref (tag
, base
), ref_ptr
;
227 tree start
= build_int_cst_type (integer_type_node
,
228 value
->hdata
.intvl
.int_start
);
229 tree steps
= build_int_cst_type (unsigned_type_node
,
230 value
->hdata
.intvl
.steps
);
232 ref_ptr
= force_gimple_operand_gsi (&gsi
,
233 build_addr (ref
, current_function_decl
),
234 true, NULL_TREE
, true, GSI_SAME_STMT
);
235 val
= prepare_instrumented_value (&gsi
, value
);
236 call
= gimple_build_call (tree_interval_profiler_fn
, 4,
237 ref_ptr
, val
, start
, steps
);
238 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
239 add_abnormal_goto_call_edges (gsi
);
242 /* Output instructions as GIMPLE trees to increment the power of two histogram
243 counter. VALUE is the expression whose value is profiled. TAG is the tag
244 of the section for counters, BASE is offset of the counter position. */
247 tree_gen_pow2_profiler (histogram_value value
, unsigned tag
, unsigned base
)
249 gimple stmt
= value
->hvalue
.stmt
;
250 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
251 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
255 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
256 true, NULL_TREE
, true, GSI_SAME_STMT
);
257 val
= prepare_instrumented_value (&gsi
, value
);
258 call
= gimple_build_call (tree_pow2_profiler_fn
, 2, ref_ptr
, val
);
259 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
260 add_abnormal_goto_call_edges (gsi
);
263 /* Output instructions as GIMPLE trees for code to find the most common value.
264 VALUE is the expression whose value is profiled. TAG is the tag of the
265 section for counters, BASE is offset of the counter position. */
268 tree_gen_one_value_profiler (histogram_value value
, unsigned tag
, unsigned base
)
270 gimple stmt
= value
->hvalue
.stmt
;
271 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
272 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
276 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
277 true, NULL_TREE
, true, GSI_SAME_STMT
);
278 val
= prepare_instrumented_value (&gsi
, value
);
279 call
= gimple_build_call (tree_one_value_profiler_fn
, 2, ref_ptr
, val
);
280 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
281 add_abnormal_goto_call_edges (gsi
);
285 /* Output instructions as GIMPLE trees for code to find the most
286 common called function in indirect call.
287 VALUE is the call expression whose indirect callee is profiled.
288 TAG is the tag of the section for counters, BASE is offset of the
292 tree_gen_ic_profiler (histogram_value value
, unsigned tag
, unsigned base
)
295 gimple stmt1
, stmt2
, stmt3
;
296 gimple stmt
= value
->hvalue
.stmt
;
297 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
298 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
300 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
301 true, NULL_TREE
, true, GSI_SAME_STMT
);
305 __gcov_indirect_call_counters = get_relevant_counter_ptr ();
306 __gcov_indirect_call_callee = (void *) indirect call argument;
309 tmp1
= create_tmp_var (ptr_void
, "PROF");
310 stmt1
= gimple_build_assign (ic_gcov_type_ptr_var
, ref_ptr
);
311 stmt2
= gimple_build_assign (tmp1
, unshare_expr (value
->hvalue
.value
));
312 stmt3
= gimple_build_assign (ic_void_ptr_var
, tmp1
);
314 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
315 gsi_insert_before (&gsi
, stmt2
, GSI_SAME_STMT
);
316 gsi_insert_before (&gsi
, stmt3
, GSI_SAME_STMT
);
320 /* Output instructions as GIMPLE trees for code to find the most
321 common called function in indirect call. Insert instructions at the
322 beginning of every possible called function.
326 tree_gen_ic_func_profiler (void)
328 struct cgraph_node
* c_node
= cgraph_node (current_function_decl
);
329 gimple_stmt_iterator gsi
;
334 tree tree_uid
, cur_func
;
339 tree_init_edge_profiler ();
341 FOR_EACH_EDGE (e
, ei
, ENTRY_BLOCK_PTR
->succs
)
346 gsi
= gsi_start_bb (bb
);
348 cur_func
= force_gimple_operand_gsi (&gsi
,
349 build_addr (current_function_decl
,
350 current_function_decl
),
352 true, GSI_SAME_STMT
);
353 tree_uid
= build_int_cst (gcov_type_node
, c_node
->pid
);
354 stmt1
= gimple_build_call (tree_indirect_call_profiler_fn
, 4,
355 ic_gcov_type_ptr_var
,
359 gsi_insert_after (&gsi
, stmt1
, GSI_NEW_STMT
);
360 gcc_assert (EDGE_COUNT (bb
->succs
) == 1);
361 bb
= split_edge (EDGE_I (bb
->succs
, 0));
362 add_abnormal_goto_call_edges (gsi
);
364 gsi
= gsi_start_bb (bb
);
365 /* Set __gcov_indirect_call_callee to 0,
366 so that calls from other modules won't get misattributed
367 to the last caller of the current callee. */
368 void0
= build_int_cst (build_pointer_type (void_type_node
), 0);
369 stmt2
= gimple_build_assign (ic_void_ptr_var
, void0
);
370 gsi_insert_after (&gsi
, stmt2
, GSI_NEW_STMT
);
374 /* Output instructions as GIMPLE trees for code to find the most common value
375 of a difference between two evaluations of an expression.
376 VALUE is the expression whose value is profiled. TAG is the tag of the
377 section for counters, BASE is offset of the counter position. */
380 tree_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED
,
381 unsigned tag ATTRIBUTE_UNUSED
,
382 unsigned base ATTRIBUTE_UNUSED
)
384 /* FIXME implement this. */
385 #ifdef ENABLE_CHECKING
386 internal_error ("unimplemented functionality");
391 /* Output instructions as GIMPLE trees to increment the average histogram
392 counter. VALUE is the expression whose value is profiled. TAG is the
393 tag of the section for counters, BASE is offset of the counter position. */
396 tree_gen_average_profiler (histogram_value value
, unsigned tag
, unsigned base
)
398 gimple stmt
= value
->hvalue
.stmt
;
399 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
400 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
404 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
406 true, GSI_SAME_STMT
);
407 val
= prepare_instrumented_value (&gsi
, value
);
408 call
= gimple_build_call (tree_average_profiler_fn
, 2, ref_ptr
, val
);
409 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
410 add_abnormal_goto_call_edges (gsi
);
413 /* Output instructions as GIMPLE trees to increment the ior histogram
414 counter. VALUE is the expression whose value is profiled. TAG is the
415 tag of the section for counters, BASE is offset of the counter position. */
418 tree_gen_ior_profiler (histogram_value value
, unsigned tag
, unsigned base
)
420 gimple stmt
= value
->hvalue
.stmt
;
421 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
422 tree ref_ptr
= tree_coverage_counter_addr (tag
, base
);
426 ref_ptr
= force_gimple_operand_gsi (&gsi
, ref_ptr
,
427 true, NULL_TREE
, true, GSI_SAME_STMT
);
428 val
= prepare_instrumented_value (&gsi
, value
);
429 call
= gimple_build_call (tree_ior_profiler_fn
, 2, ref_ptr
, val
);
430 gsi_insert_before (&gsi
, call
, GSI_NEW_STMT
);
431 add_abnormal_goto_call_edges (gsi
);
434 /* Return 1 if tree-based profiling is in effect, else 0.
435 If it is, set up hooks for tree-based profiling.
436 Gate for pass_tree_profile. */
439 do_tree_profiling (void)
441 if (profile_arc_flag
|| flag_test_coverage
|| flag_branch_probabilities
)
443 tree_register_profile_hooks ();
444 gimple_register_value_prof_hooks ();
451 tree_profiling (void)
453 /* Don't profile functions produced at destruction time, particularly
454 the gcov datastructure initializer. Don't profile if it has been
455 already instrumented either (when OpenMP expansion creates
456 child function from already instrumented body). */
457 if (cgraph_state
== CGRAPH_STATE_FINISHED
458 || cfun
->after_tree_profile
)
461 /* Re-set global shared temporary variable for edge-counters. */
462 gcov_type_tmp_var
= NULL_TREE
;
466 if (! flag_branch_probabilities
467 && flag_profile_values
)
468 tree_gen_ic_func_profiler ();
470 if (flag_branch_probabilities
471 && flag_profile_values
472 && flag_value_profile_transformations
)
473 value_profile_transformations ();
474 /* The above could hose dominator info. Currently there is
475 none coming in, this is a safety valve. It should be
476 easy to adjust it, if and when there is some. */
477 free_dominance_info (CDI_DOMINATORS
);
478 free_dominance_info (CDI_POST_DOMINATORS
);
479 cfun
->after_tree_profile
= 1;
483 struct gimple_opt_pass pass_tree_profile
=
487 "tree_profile", /* name */
488 do_tree_profiling
, /* gate */
489 tree_profiling
, /* execute */
492 0, /* static_pass_number */
493 TV_BRANCH_PROB
, /* tv_id */
494 PROP_gimple_leh
| PROP_cfg
, /* properties_required */
495 PROP_gimple_leh
| PROP_cfg
, /* properties_provided */
496 0, /* properties_destroyed */
497 0, /* todo_flags_start */
498 TODO_verify_stmts
| TODO_dump_func
/* todo_flags_finish */
502 struct profile_hooks tree_profile_hooks
=
504 tree_init_edge_profiler
, /* init_edge_profiler */
505 tree_gen_edge_profiler
, /* gen_edge_profiler */
506 tree_gen_interval_profiler
, /* gen_interval_profiler */
507 tree_gen_pow2_profiler
, /* gen_pow2_profiler */
508 tree_gen_one_value_profiler
, /* gen_one_value_profiler */
509 tree_gen_const_delta_profiler
, /* gen_const_delta_profiler */
510 tree_gen_ic_profiler
, /* gen_ic_profiler */
511 tree_gen_average_profiler
, /* gen_average_profiler */
512 tree_gen_ior_profiler
/* gen_ior_profiler */
515 #include "gt-tree-profile.h"