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 /* Output instructions as GIMPLE trees to increment the edge
166 execution count, and insert them on E. We rely on
167 gsi_insert_on_edge to preserve the order. */
170 tree_gen_edge_profiler (int edgeno, edge e)
173 gimple stmt1, stmt2, stmt3;
175 /* We share one temporary variable declaration per function. This
176 gets re-set in tree_profiling. */
177 if (gcov_type_tmp_var == NULL_TREE)
178 gcov_type_tmp_var = create_tmp_var (gcov_type_node, "PROF_edge_counter");
179 ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
180 one = build_int_cst (gcov_type_node, 1);
181 stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
182 stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, gcov_type_tmp_var,
183 gcov_type_tmp_var, one);
184 stmt3 = gimple_build_assign (unshare_expr (ref), gcov_type_tmp_var);
185 gsi_insert_on_edge (e, stmt1);
186 gsi_insert_on_edge (e, stmt2);
187 gsi_insert_on_edge (e, stmt3);
190 /* Emits code to get VALUE to instrument at GSI, and returns the
191 variable containing the value. */
194 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
196 tree val = value->hvalue.value;
197 return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
198 true, NULL_TREE, true, GSI_SAME_STMT);
201 /* Output instructions as GIMPLE trees to increment the interval histogram
202 counter. VALUE is the expression whose value is profiled. TAG is the
203 tag of the section for counters, BASE is offset of the counter position. */
206 tree_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
208 gimple stmt = value->hvalue.stmt;
209 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
210 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
213 tree start = build_int_cst_type (integer_type_node,
214 value->hdata.intvl.int_start);
215 tree steps = build_int_cst_type (unsigned_type_node,
216 value->hdata.intvl.steps);
218 ref_ptr = force_gimple_operand_gsi (&gsi,
219 build_addr (ref, current_function_decl),
220 true, NULL_TREE, true, GSI_SAME_STMT);
221 val = prepare_instrumented_value (&gsi, value);
222 call = gimple_build_call (tree_interval_profiler_fn, 4,
223 ref_ptr, val, start, steps);
224 gsi_insert_before (&gsi, call, GSI_SAME_STMT);
227 /* Output instructions as GIMPLE trees to increment the power of two histogram
228 counter. VALUE is the expression whose value is profiled. TAG is the tag
229 of the section for counters, BASE is offset of the counter position. */
232 tree_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
234 gimple stmt = value->hvalue.stmt;
235 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
236 tree ref_ptr = tree_coverage_counter_addr (tag, base);
240 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
241 true, NULL_TREE, true, GSI_SAME_STMT);
242 val = prepare_instrumented_value (&gsi, value);
243 call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val);
244 gsi_insert_before (&gsi, call, GSI_SAME_STMT);
247 /* Output instructions as GIMPLE trees for code to find the most common value.
248 VALUE is the expression whose value is profiled. TAG is the tag of the
249 section for counters, BASE is offset of the counter position. */
252 tree_gen_one_value_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_ptr = tree_coverage_counter_addr (tag, base);
260 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
261 true, NULL_TREE, true, GSI_SAME_STMT);
262 val = prepare_instrumented_value (&gsi, value);
263 call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val);
264 gsi_insert_before (&gsi, call, GSI_SAME_STMT);
268 /* Output instructions as GIMPLE trees for code to find the most
269 common called function in indirect call.
270 VALUE is the call expression whose indirect callee is profiled.
271 TAG is the tag of the section for counters, BASE is offset of the
275 tree_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
278 gimple stmt1, stmt2, stmt3;
279 gimple stmt = value->hvalue.stmt;
280 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
281 tree ref_ptr = tree_coverage_counter_addr (tag, base);
283 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
284 true, NULL_TREE, true, GSI_SAME_STMT);
288 __gcov_indirect_call_counters = get_relevant_counter_ptr ();
289 __gcov_indirect_call_callee = (void *) indirect call argument;
292 tmp1 = create_tmp_var (ptr_void, "PROF");
293 stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr);
294 stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
295 stmt3 = gimple_build_assign (ic_void_ptr_var, tmp1);
297 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
298 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
299 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
303 /* Output instructions as GIMPLE trees for code to find the most
304 common called function in indirect call. Insert instructions at the
305 beginning of every possible called function.
309 tree_gen_ic_func_profiler (void)
311 struct cgraph_node * c_node = cgraph_node (current_function_decl);
312 gimple_stmt_iterator gsi;
317 tree tree_uid, cur_func;
322 tree_init_edge_profiler ();
324 FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
329 gsi = gsi_start_bb (bb);
331 cur_func = force_gimple_operand_gsi (&gsi,
332 build_addr (current_function_decl,
333 current_function_decl),
335 true, GSI_SAME_STMT);
336 tree_uid = build_int_cst (gcov_type_node, c_node->pid);
337 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 4,
338 ic_gcov_type_ptr_var,
342 gsi_insert_after (&gsi, stmt1, GSI_NEW_STMT);
344 gcc_assert (EDGE_COUNT (bb->succs) == 1);
345 bb = split_edge (EDGE_I (bb->succs, 0));
346 gsi = gsi_start_bb (bb);
347 /* Set __gcov_indirect_call_callee to 0,
348 so that calls from other modules won't get misattributed
349 to the last caller of the current callee. */
350 void0 = build_int_cst (build_pointer_type (void_type_node), 0);
351 stmt2 = gimple_build_assign (ic_void_ptr_var, void0);
352 gsi_insert_after (&gsi, stmt2, GSI_NEW_STMT);
356 /* Output instructions as GIMPLE trees for code to find the most common value
357 of a difference between two evaluations of an expression.
358 VALUE is the expression whose value is profiled. TAG is the tag of the
359 section for counters, BASE is offset of the counter position. */
362 tree_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
363 unsigned tag ATTRIBUTE_UNUSED,
364 unsigned base ATTRIBUTE_UNUSED)
366 /* FIXME implement this. */
367 #ifdef ENABLE_CHECKING
368 internal_error ("unimplemented functionality");
373 /* Output instructions as GIMPLE trees to increment the average histogram
374 counter. VALUE is the expression whose value is profiled. TAG is the
375 tag of the section for counters, BASE is offset of the counter position. */
378 tree_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
380 gimple stmt = value->hvalue.stmt;
381 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
382 tree ref_ptr = tree_coverage_counter_addr (tag, base);
386 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
388 true, GSI_SAME_STMT);
389 val = prepare_instrumented_value (&gsi, value);
390 call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
391 gsi_insert_before (&gsi, call, GSI_SAME_STMT);
394 /* Output instructions as GIMPLE trees to increment the ior histogram
395 counter. VALUE is the expression whose value is profiled. TAG is the
396 tag of the section for counters, BASE is offset of the counter position. */
399 tree_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
401 gimple stmt = value->hvalue.stmt;
402 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
403 tree ref_ptr = tree_coverage_counter_addr (tag, base);
407 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
408 true, NULL_TREE, true, GSI_SAME_STMT);
409 val = prepare_instrumented_value (&gsi, value);
410 call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
411 gsi_insert_before (&gsi, call, GSI_SAME_STMT);
414 /* Return 1 if tree-based profiling is in effect, else 0.
415 If it is, set up hooks for tree-based profiling.
416 Gate for pass_tree_profile. */
419 do_tree_profiling (void)
421 if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
423 tree_register_profile_hooks ();
424 gimple_register_value_prof_hooks ();
431 tree_profiling (void)
433 /* Don't profile functions produced at destruction time, particularly
434 the gcov datastructure initializer. Don't profile if it has been
435 already instrumented either (when OpenMP expansion creates
436 child function from already instrumented body). */
437 if (cgraph_state == CGRAPH_STATE_FINISHED
438 || cfun->after_tree_profile)
441 /* Re-set global shared temporary variable for edge-counters. */
442 gcov_type_tmp_var = NULL_TREE;
446 if (! flag_branch_probabilities
447 && flag_profile_values)
448 tree_gen_ic_func_profiler ();
450 if (flag_branch_probabilities
451 && flag_profile_values
452 && flag_value_profile_transformations)
453 value_profile_transformations ();
454 /* The above could hose dominator info. Currently there is
455 none coming in, this is a safety valve. It should be
456 easy to adjust it, if and when there is some. */
457 free_dominance_info (CDI_DOMINATORS);
458 free_dominance_info (CDI_POST_DOMINATORS);
459 cfun->after_tree_profile = 1;
463 struct gimple_opt_pass pass_tree_profile =
467 "tree_profile", /* name */
468 do_tree_profiling, /* gate */
469 tree_profiling, /* execute */
472 0, /* static_pass_number */
473 TV_BRANCH_PROB, /* tv_id */
474 PROP_gimple_leh | PROP_cfg, /* properties_required */
475 PROP_gimple_leh | PROP_cfg, /* properties_provided */
476 0, /* properties_destroyed */
477 0, /* todo_flags_start */
478 TODO_verify_stmts | TODO_dump_func /* todo_flags_finish */
482 struct profile_hooks tree_profile_hooks =
484 tree_init_edge_profiler, /* init_edge_profiler */
485 tree_gen_edge_profiler, /* gen_edge_profiler */
486 tree_gen_interval_profiler, /* gen_interval_profiler */
487 tree_gen_pow2_profiler, /* gen_pow2_profiler */
488 tree_gen_one_value_profiler, /* gen_one_value_profiler */
489 tree_gen_const_delta_profiler, /* gen_const_delta_profiler */
490 tree_gen_ic_profiler, /* gen_ic_profiler */
491 tree_gen_average_profiler, /* gen_average_profiler */
492 tree_gen_ior_profiler /* gen_ior_profiler */
495 #include "gt-tree-profile.h"