-dA enhancement
[official-gcc.git] / gcc / tree-profile.c
blobc1c0577c2efd05ca31b0024cfba009f50f39a0f0
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
15 version.
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
20 for more details.
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. */
29 #include "config.h"
30 #include "system.h"
31 #include "coretypes.h"
32 #include "tm.h"
33 #include "flags.h"
34 #include "regs.h"
35 #include "function.h"
36 #include "basic-block.h"
37 #include "diagnostic-core.h"
38 #include "coverage.h"
39 #include "tree.h"
40 #include "tree-flow.h"
41 #include "tree-dump.h"
42 #include "tree-pass.h"
43 #include "timevar.h"
44 #include "value-prof.h"
45 #include "cgraph.h"
47 static GTY(()) tree gcov_type_node;
48 static GTY(()) tree gcov_type_tmp_var;
49 static GTY(()) tree tree_interval_profiler_fn;
50 static GTY(()) tree tree_pow2_profiler_fn;
51 static GTY(()) tree tree_one_value_profiler_fn;
52 static GTY(()) tree tree_indirect_call_profiler_fn;
53 static GTY(()) tree tree_average_profiler_fn;
54 static GTY(()) tree tree_ior_profiler_fn;
57 static GTY(()) tree ic_void_ptr_var;
58 static GTY(()) tree ic_gcov_type_ptr_var;
59 static GTY(()) tree ptr_void;
61 /* Do initialization work for the edge profiler. */
63 /* Add code:
64 static gcov* __gcov_indirect_call_counters; // pointer to actual counter
65 static void* __gcov_indirect_call_callee; // actual callee address
67 static void
68 init_ic_make_global_vars (void)
70 tree gcov_type_ptr;
72 ptr_void = build_pointer_type (void_type_node);
74 ic_void_ptr_var
75 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
76 get_identifier ("__gcov_indirect_call_callee"),
77 ptr_void);
78 TREE_STATIC (ic_void_ptr_var) = 1;
79 TREE_PUBLIC (ic_void_ptr_var) = 0;
80 DECL_ARTIFICIAL (ic_void_ptr_var) = 1;
81 DECL_INITIAL (ic_void_ptr_var) = NULL;
82 varpool_finalize_decl (ic_void_ptr_var);
83 varpool_mark_needed_node (varpool_node (ic_void_ptr_var));
85 gcov_type_ptr = build_pointer_type (get_gcov_type ());
86 ic_gcov_type_ptr_var
87 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
88 get_identifier ("__gcov_indirect_call_counters"),
89 gcov_type_ptr);
90 TREE_STATIC (ic_gcov_type_ptr_var) = 1;
91 TREE_PUBLIC (ic_gcov_type_ptr_var) = 0;
92 DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1;
93 DECL_INITIAL (ic_gcov_type_ptr_var) = NULL;
94 varpool_finalize_decl (ic_gcov_type_ptr_var);
95 varpool_mark_needed_node (varpool_node (ic_gcov_type_ptr_var));
98 void
99 gimple_init_edge_profiler (void)
101 tree interval_profiler_fn_type;
102 tree pow2_profiler_fn_type;
103 tree one_value_profiler_fn_type;
104 tree gcov_type_ptr;
105 tree ic_profiler_fn_type;
106 tree average_profiler_fn_type;
108 if (!gcov_type_node)
110 gcov_type_node = get_gcov_type ();
111 gcov_type_ptr = build_pointer_type (gcov_type_node);
113 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
114 interval_profiler_fn_type
115 = build_function_type_list (void_type_node,
116 gcov_type_ptr, gcov_type_node,
117 integer_type_node,
118 unsigned_type_node, NULL_TREE);
119 tree_interval_profiler_fn
120 = build_fn_decl ("__gcov_interval_profiler",
121 interval_profiler_fn_type);
122 TREE_NOTHROW (tree_interval_profiler_fn) = 1;
123 DECL_ATTRIBUTES (tree_interval_profiler_fn)
124 = tree_cons (get_identifier ("leaf"), NULL,
125 DECL_ATTRIBUTES (tree_interval_profiler_fn));
127 /* void (*) (gcov_type *, gcov_type) */
128 pow2_profiler_fn_type
129 = build_function_type_list (void_type_node,
130 gcov_type_ptr, gcov_type_node,
131 NULL_TREE);
132 tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler",
133 pow2_profiler_fn_type);
134 TREE_NOTHROW (tree_pow2_profiler_fn) = 1;
135 DECL_ATTRIBUTES (tree_pow2_profiler_fn)
136 = tree_cons (get_identifier ("leaf"), NULL,
137 DECL_ATTRIBUTES (tree_pow2_profiler_fn));
139 /* void (*) (gcov_type *, gcov_type) */
140 one_value_profiler_fn_type
141 = build_function_type_list (void_type_node,
142 gcov_type_ptr, gcov_type_node,
143 NULL_TREE);
144 tree_one_value_profiler_fn
145 = build_fn_decl ("__gcov_one_value_profiler",
146 one_value_profiler_fn_type);
147 TREE_NOTHROW (tree_one_value_profiler_fn) = 1;
148 DECL_ATTRIBUTES (tree_one_value_profiler_fn)
149 = tree_cons (get_identifier ("leaf"), NULL,
150 DECL_ATTRIBUTES (tree_one_value_profiler_fn));
152 init_ic_make_global_vars ();
154 /* void (*) (gcov_type *, gcov_type, void *, void *) */
155 ic_profiler_fn_type
156 = build_function_type_list (void_type_node,
157 gcov_type_ptr, gcov_type_node,
158 ptr_void,
159 ptr_void, NULL_TREE);
160 tree_indirect_call_profiler_fn
161 = build_fn_decl ("__gcov_indirect_call_profiler",
162 ic_profiler_fn_type);
163 TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
164 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
165 = tree_cons (get_identifier ("leaf"), NULL,
166 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn));
168 /* void (*) (gcov_type *, gcov_type) */
169 average_profiler_fn_type
170 = build_function_type_list (void_type_node,
171 gcov_type_ptr, gcov_type_node, NULL_TREE);
172 tree_average_profiler_fn
173 = build_fn_decl ("__gcov_average_profiler",
174 average_profiler_fn_type);
175 TREE_NOTHROW (tree_average_profiler_fn) = 1;
176 DECL_ATTRIBUTES (tree_average_profiler_fn)
177 = tree_cons (get_identifier ("leaf"), NULL,
178 DECL_ATTRIBUTES (tree_average_profiler_fn));
179 tree_ior_profiler_fn
180 = build_fn_decl ("__gcov_ior_profiler",
181 average_profiler_fn_type);
182 TREE_NOTHROW (tree_ior_profiler_fn) = 1;
183 DECL_ATTRIBUTES (tree_ior_profiler_fn)
184 = tree_cons (get_identifier ("leaf"), NULL,
185 DECL_ATTRIBUTES (tree_ior_profiler_fn));
187 /* LTO streamer needs assembler names. Because we create these decls
188 late, we need to initialize them by hand. */
189 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn);
190 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn);
191 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn);
192 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn);
193 DECL_ASSEMBLER_NAME (tree_average_profiler_fn);
194 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
198 /* Output instructions as GIMPLE trees to increment the edge
199 execution count, and insert them on E. We rely on
200 gsi_insert_on_edge to preserve the order. */
202 void
203 gimple_gen_edge_profiler (int edgeno, edge e)
205 tree ref, one;
206 gimple stmt1, stmt2, stmt3;
208 /* We share one temporary variable declaration per function. This
209 gets re-set in tree_profiling. */
210 if (gcov_type_tmp_var == NULL_TREE)
211 gcov_type_tmp_var = create_tmp_reg (gcov_type_node, "PROF_edge_counter");
212 ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
213 one = build_int_cst (gcov_type_node, 1);
214 stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
215 gimple_assign_set_lhs (stmt1, make_ssa_name (gcov_type_tmp_var, stmt1));
216 stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, gcov_type_tmp_var,
217 gimple_assign_lhs (stmt1), one);
218 gimple_assign_set_lhs (stmt2, make_ssa_name (gcov_type_tmp_var, stmt2));
219 stmt3 = gimple_build_assign (unshare_expr (ref), gimple_assign_lhs (stmt2));
220 gsi_insert_on_edge (e, stmt1);
221 gsi_insert_on_edge (e, stmt2);
222 gsi_insert_on_edge (e, stmt3);
225 /* Emits code to get VALUE to instrument at GSI, and returns the
226 variable containing the value. */
228 static tree
229 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
231 tree val = value->hvalue.value;
232 if (POINTER_TYPE_P (TREE_TYPE (val)))
233 val = fold_convert (sizetype, val);
234 return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
235 true, NULL_TREE, true, GSI_SAME_STMT);
238 /* Output instructions as GIMPLE trees to increment the interval histogram
239 counter. VALUE is the expression whose value is profiled. TAG is the
240 tag of the section for counters, BASE is offset of the counter position. */
242 void
243 gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
245 gimple stmt = value->hvalue.stmt;
246 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
247 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
248 gimple call;
249 tree val;
250 tree start = build_int_cst_type (integer_type_node,
251 value->hdata.intvl.int_start);
252 tree steps = build_int_cst_type (unsigned_type_node,
253 value->hdata.intvl.steps);
255 ref_ptr = force_gimple_operand_gsi (&gsi,
256 build_addr (ref, current_function_decl),
257 true, NULL_TREE, true, GSI_SAME_STMT);
258 val = prepare_instrumented_value (&gsi, value);
259 call = gimple_build_call (tree_interval_profiler_fn, 4,
260 ref_ptr, val, start, steps);
261 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
264 /* Output instructions as GIMPLE trees to increment the power of two histogram
265 counter. VALUE is the expression whose value is profiled. TAG is the tag
266 of the section for counters, BASE is offset of the counter position. */
268 void
269 gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
271 gimple stmt = value->hvalue.stmt;
272 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
273 tree ref_ptr = tree_coverage_counter_addr (tag, base);
274 gimple call;
275 tree val;
277 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
278 true, NULL_TREE, true, GSI_SAME_STMT);
279 val = prepare_instrumented_value (&gsi, value);
280 call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val);
281 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
284 /* Output instructions as GIMPLE trees for code to find the most common value.
285 VALUE is the expression whose value is profiled. TAG is the tag of the
286 section for counters, BASE is offset of the counter position. */
288 void
289 gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
291 gimple stmt = value->hvalue.stmt;
292 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
293 tree ref_ptr = tree_coverage_counter_addr (tag, base);
294 gimple call;
295 tree val;
297 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
298 true, NULL_TREE, true, GSI_SAME_STMT);
299 val = prepare_instrumented_value (&gsi, value);
300 call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val);
301 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
305 /* Output instructions as GIMPLE trees for code to find the most
306 common called function in indirect call.
307 VALUE is the call expression whose indirect callee is profiled.
308 TAG is the tag of the section for counters, BASE is offset of the
309 counter position. */
311 void
312 gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
314 tree tmp1;
315 gimple stmt1, stmt2, stmt3;
316 gimple stmt = value->hvalue.stmt;
317 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
318 tree ref_ptr = tree_coverage_counter_addr (tag, base);
320 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
321 true, NULL_TREE, true, GSI_SAME_STMT);
323 /* Insert code:
325 __gcov_indirect_call_counters = get_relevant_counter_ptr ();
326 __gcov_indirect_call_callee = (void *) indirect call argument;
329 tmp1 = create_tmp_reg (ptr_void, "PROF");
330 stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr);
331 stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
332 gimple_assign_set_lhs (stmt2, make_ssa_name (tmp1, stmt2));
333 stmt3 = gimple_build_assign (ic_void_ptr_var, gimple_assign_lhs (stmt2));
335 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
336 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
337 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
341 /* Output instructions as GIMPLE trees for code to find the most
342 common called function in indirect call. Insert instructions at the
343 beginning of every possible called function.
346 void
347 gimple_gen_ic_func_profiler (void)
349 struct cgraph_node * c_node = cgraph_node (current_function_decl);
350 gimple_stmt_iterator gsi;
351 gimple stmt1, stmt2;
352 tree tree_uid, cur_func, counter_ptr, ptr_var, void0;
354 if (cgraph_only_called_directly_p (c_node))
355 return;
357 gimple_init_edge_profiler ();
359 gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR));
361 cur_func = force_gimple_operand_gsi (&gsi,
362 build_addr (current_function_decl,
363 current_function_decl),
364 true, NULL_TREE,
365 true, GSI_SAME_STMT);
366 counter_ptr = force_gimple_operand_gsi (&gsi, ic_gcov_type_ptr_var,
367 true, NULL_TREE, true,
368 GSI_SAME_STMT);
369 ptr_var = force_gimple_operand_gsi (&gsi, ic_void_ptr_var,
370 true, NULL_TREE, true,
371 GSI_SAME_STMT);
372 tree_uid = build_int_cst (gcov_type_node, c_node->pid);
373 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 4,
374 counter_ptr, tree_uid, cur_func, ptr_var);
375 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
377 /* Set __gcov_indirect_call_callee to 0,
378 so that calls from other modules won't get misattributed
379 to the last caller of the current callee. */
380 void0 = build_int_cst (build_pointer_type (void_type_node), 0);
381 stmt2 = gimple_build_assign (ic_void_ptr_var, void0);
382 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
385 /* Output instructions as GIMPLE trees for code to find the most common value
386 of a difference between two evaluations of an expression.
387 VALUE is the expression whose value is profiled. TAG is the tag of the
388 section for counters, BASE is offset of the counter position. */
390 void
391 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
392 unsigned tag ATTRIBUTE_UNUSED,
393 unsigned base ATTRIBUTE_UNUSED)
395 /* FIXME implement this. */
396 #ifdef ENABLE_CHECKING
397 internal_error ("unimplemented functionality");
398 #endif
399 gcc_unreachable ();
402 /* Output instructions as GIMPLE trees to increment the average histogram
403 counter. VALUE is the expression whose value is profiled. TAG is the
404 tag of the section for counters, BASE is offset of the counter position. */
406 void
407 gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
409 gimple stmt = value->hvalue.stmt;
410 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
411 tree ref_ptr = tree_coverage_counter_addr (tag, base);
412 gimple call;
413 tree val;
415 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
416 true, NULL_TREE,
417 true, GSI_SAME_STMT);
418 val = prepare_instrumented_value (&gsi, value);
419 call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
420 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
423 /* Output instructions as GIMPLE trees to increment the ior 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. */
427 void
428 gimple_gen_ior_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);
433 gimple call;
434 tree val;
436 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
437 true, NULL_TREE, true, GSI_SAME_STMT);
438 val = prepare_instrumented_value (&gsi, value);
439 call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
440 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
443 /* Profile all functions in the callgraph. */
445 static unsigned int
446 tree_profiling (void)
448 struct cgraph_node *node;
450 /* Don't profile functions produced at destruction time, particularly
451 the gcov datastructure initializer. Don't profile if it has been
452 already instrumented either (when OpenMP expansion creates
453 child function from already instrumented body). */
454 if (cgraph_state == CGRAPH_STATE_FINISHED)
455 return 0;
457 for (node = cgraph_nodes; node; node = node->next)
459 if (!node->analyzed
460 || !gimple_has_body_p (node->decl)
461 || !(!node->clone_of || node->decl != node->clone_of->decl))
462 continue;
464 /* Don't profile functions produced for builtin stuff. */
465 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION
466 || DECL_STRUCT_FUNCTION (node->decl)->after_tree_profile)
467 continue;
469 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
470 current_function_decl = node->decl;
472 /* Re-set global shared temporary variable for edge-counters. */
473 gcov_type_tmp_var = NULL_TREE;
475 branch_prob ();
477 if (! flag_branch_probabilities
478 && flag_profile_values)
479 gimple_gen_ic_func_profiler ();
481 if (flag_branch_probabilities
482 && flag_profile_values
483 && flag_value_profile_transformations)
484 gimple_value_profile_transformations ();
486 /* The above could hose dominator info. Currently there is
487 none coming in, this is a safety valve. It should be
488 easy to adjust it, if and when there is some. */
489 free_dominance_info (CDI_DOMINATORS);
490 free_dominance_info (CDI_POST_DOMINATORS);
492 current_function_decl = NULL;
493 pop_cfun ();
496 /* Drop pure/const flags from instrumented functions. */
497 for (node = cgraph_nodes; node; node = node->next)
499 if (!node->analyzed
500 || !gimple_has_body_p (node->decl)
501 || !(!node->clone_of || node->decl != node->clone_of->decl))
502 continue;
504 /* Don't profile functions produced for builtin stuff. */
505 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION
506 || DECL_STRUCT_FUNCTION (node->decl)->after_tree_profile)
507 continue;
509 cgraph_set_const_flag (node, false, false);
510 cgraph_set_pure_flag (node, false, false);
513 /* Update call statements and rebuild the cgraph. */
514 for (node = cgraph_nodes; node; node = node->next)
516 basic_block bb;
518 if (!node->analyzed
519 || !gimple_has_body_p (node->decl)
520 || !(!node->clone_of || node->decl != node->clone_of->decl))
521 continue;
523 /* Don't profile functions produced for builtin stuff. */
524 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION
525 || DECL_STRUCT_FUNCTION (node->decl)->after_tree_profile)
526 continue;
528 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
529 current_function_decl = node->decl;
531 FOR_EACH_BB (bb)
533 gimple_stmt_iterator gsi;
534 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
536 gimple stmt = gsi_stmt (gsi);
537 if (is_gimple_call (stmt))
538 update_stmt (stmt);
542 cfun->after_tree_profile = 1;
543 update_ssa (TODO_update_ssa);
545 rebuild_cgraph_edges ();
547 current_function_decl = NULL;
548 pop_cfun ();
551 return 0;
554 /* When profile instrumentation, use or test coverage shall be performed. */
556 static bool
557 gate_tree_profile_ipa (void)
559 return (!in_lto_p
560 && (flag_branch_probabilities || flag_test_coverage
561 || profile_arc_flag));
564 struct simple_ipa_opt_pass pass_ipa_tree_profile =
567 SIMPLE_IPA_PASS,
568 "tree_profile_ipa", /* name */
569 gate_tree_profile_ipa, /* gate */
570 tree_profiling, /* execute */
571 NULL, /* sub */
572 NULL, /* next */
573 0, /* static_pass_number */
574 TV_IPA_PROFILE, /* tv_id */
575 0, /* properties_required */
576 0, /* properties_provided */
577 0, /* properties_destroyed */
578 0, /* todo_flags_start */
579 TODO_dump_func /* todo_flags_finish */
583 #include "gt-tree-profile.h"