2013-05-30 Ed Smith-Rowland <3dw4rd@verizon.net>
[official-gcc.git] / gcc / tree-profile.c
blob9985b40a2a87206691f7a7687c3c56a4b543c261
1 /* Calculate branch probabilities, and basic block execution counts.
2 Copyright (C) 1990-2013 Free Software Foundation, Inc.
3 Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
4 based on some ideas from Dain Samples of UC Berkeley.
5 Further mangling by Bob Manson, Cygnus Support.
6 Converted to use trees by Dale Johannesen, Apple Computer.
8 This file is part of GCC.
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
13 version.
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 for more details.
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3. If not see
22 <http://www.gnu.org/licenses/>. */
24 /* Generate basic block profile instrumentation and auxiliary files.
25 Tree-based version. See profile.c for overview. */
27 #include "config.h"
28 #include "system.h"
29 #include "coretypes.h"
30 #include "tm.h"
31 #include "flags.h"
32 #include "function.h"
33 #include "basic-block.h"
34 #include "diagnostic-core.h"
35 #include "coverage.h"
36 #include "tree.h"
37 #include "tree-flow.h"
38 #include "tree-pass.h"
39 #include "value-prof.h"
40 #include "cgraph.h"
41 #include "profile.h"
42 #include "target.h"
44 static GTY(()) tree gcov_type_node;
45 static GTY(()) tree tree_interval_profiler_fn;
46 static GTY(()) tree tree_pow2_profiler_fn;
47 static GTY(()) tree tree_one_value_profiler_fn;
48 static GTY(()) tree tree_indirect_call_profiler_fn;
49 static GTY(()) tree tree_average_profiler_fn;
50 static GTY(()) tree tree_ior_profiler_fn;
53 static GTY(()) tree ic_void_ptr_var;
54 static GTY(()) tree ic_gcov_type_ptr_var;
55 static GTY(()) tree ptr_void;
57 /* Do initialization work for the edge profiler. */
59 /* Add code:
60 static gcov* __gcov_indirect_call_counters; // pointer to actual counter
61 static void* __gcov_indirect_call_callee; // actual callee address
63 static void
64 init_ic_make_global_vars (void)
66 tree gcov_type_ptr;
68 ptr_void = build_pointer_type (void_type_node);
70 ic_void_ptr_var
71 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
72 get_identifier ("__gcov_indirect_call_callee"),
73 ptr_void);
74 TREE_STATIC (ic_void_ptr_var) = 1;
75 TREE_PUBLIC (ic_void_ptr_var) = 0;
76 DECL_ARTIFICIAL (ic_void_ptr_var) = 1;
77 DECL_INITIAL (ic_void_ptr_var) = NULL;
78 if (targetm.have_tls)
79 DECL_TLS_MODEL (ic_void_ptr_var) =
80 decl_default_tls_model (ic_void_ptr_var);
82 varpool_finalize_decl (ic_void_ptr_var);
84 gcov_type_ptr = build_pointer_type (get_gcov_type ());
85 ic_gcov_type_ptr_var
86 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
87 get_identifier ("__gcov_indirect_call_counters"),
88 gcov_type_ptr);
89 TREE_STATIC (ic_gcov_type_ptr_var) = 1;
90 TREE_PUBLIC (ic_gcov_type_ptr_var) = 0;
91 DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1;
92 DECL_INITIAL (ic_gcov_type_ptr_var) = NULL;
93 if (targetm.have_tls)
94 DECL_TLS_MODEL (ic_gcov_type_ptr_var) =
95 decl_default_tls_model (ic_gcov_type_ptr_var);
97 varpool_finalize_decl (ic_gcov_type_ptr_var);
100 /* Create the type and function decls for the interface with gcov. */
102 void
103 gimple_init_edge_profiler (void)
105 tree interval_profiler_fn_type;
106 tree pow2_profiler_fn_type;
107 tree one_value_profiler_fn_type;
108 tree gcov_type_ptr;
109 tree ic_profiler_fn_type;
110 tree average_profiler_fn_type;
112 if (!gcov_type_node)
114 gcov_type_node = get_gcov_type ();
115 gcov_type_ptr = build_pointer_type (gcov_type_node);
117 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
118 interval_profiler_fn_type
119 = build_function_type_list (void_type_node,
120 gcov_type_ptr, gcov_type_node,
121 integer_type_node,
122 unsigned_type_node, NULL_TREE);
123 tree_interval_profiler_fn
124 = build_fn_decl ("__gcov_interval_profiler",
125 interval_profiler_fn_type);
126 TREE_NOTHROW (tree_interval_profiler_fn) = 1;
127 DECL_ATTRIBUTES (tree_interval_profiler_fn)
128 = tree_cons (get_identifier ("leaf"), NULL,
129 DECL_ATTRIBUTES (tree_interval_profiler_fn));
131 /* void (*) (gcov_type *, gcov_type) */
132 pow2_profiler_fn_type
133 = build_function_type_list (void_type_node,
134 gcov_type_ptr, gcov_type_node,
135 NULL_TREE);
136 tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler",
137 pow2_profiler_fn_type);
138 TREE_NOTHROW (tree_pow2_profiler_fn) = 1;
139 DECL_ATTRIBUTES (tree_pow2_profiler_fn)
140 = tree_cons (get_identifier ("leaf"), NULL,
141 DECL_ATTRIBUTES (tree_pow2_profiler_fn));
143 /* void (*) (gcov_type *, gcov_type) */
144 one_value_profiler_fn_type
145 = build_function_type_list (void_type_node,
146 gcov_type_ptr, gcov_type_node,
147 NULL_TREE);
148 tree_one_value_profiler_fn
149 = build_fn_decl ("__gcov_one_value_profiler",
150 one_value_profiler_fn_type);
151 TREE_NOTHROW (tree_one_value_profiler_fn) = 1;
152 DECL_ATTRIBUTES (tree_one_value_profiler_fn)
153 = tree_cons (get_identifier ("leaf"), NULL,
154 DECL_ATTRIBUTES (tree_one_value_profiler_fn));
156 init_ic_make_global_vars ();
158 /* void (*) (gcov_type *, gcov_type, void *, void *) */
159 ic_profiler_fn_type
160 = build_function_type_list (void_type_node,
161 gcov_type_ptr, gcov_type_node,
162 ptr_void,
163 ptr_void, NULL_TREE);
164 tree_indirect_call_profiler_fn
165 = build_fn_decl ("__gcov_indirect_call_profiler",
166 ic_profiler_fn_type);
167 TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
168 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
169 = tree_cons (get_identifier ("leaf"), NULL,
170 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn));
172 /* void (*) (gcov_type *, gcov_type) */
173 average_profiler_fn_type
174 = build_function_type_list (void_type_node,
175 gcov_type_ptr, gcov_type_node, NULL_TREE);
176 tree_average_profiler_fn
177 = build_fn_decl ("__gcov_average_profiler",
178 average_profiler_fn_type);
179 TREE_NOTHROW (tree_average_profiler_fn) = 1;
180 DECL_ATTRIBUTES (tree_average_profiler_fn)
181 = tree_cons (get_identifier ("leaf"), NULL,
182 DECL_ATTRIBUTES (tree_average_profiler_fn));
183 tree_ior_profiler_fn
184 = build_fn_decl ("__gcov_ior_profiler",
185 average_profiler_fn_type);
186 TREE_NOTHROW (tree_ior_profiler_fn) = 1;
187 DECL_ATTRIBUTES (tree_ior_profiler_fn)
188 = tree_cons (get_identifier ("leaf"), NULL,
189 DECL_ATTRIBUTES (tree_ior_profiler_fn));
191 /* LTO streamer needs assembler names. Because we create these decls
192 late, we need to initialize them by hand. */
193 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn);
194 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn);
195 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn);
196 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn);
197 DECL_ASSEMBLER_NAME (tree_average_profiler_fn);
198 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
202 /* Output instructions as GIMPLE trees to increment the edge
203 execution count, and insert them on E. We rely on
204 gsi_insert_on_edge to preserve the order. */
206 void
207 gimple_gen_edge_profiler (int edgeno, edge e)
209 tree ref, one, gcov_type_tmp_var;
210 gimple stmt1, stmt2, stmt3;
212 ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
213 one = build_int_cst (gcov_type_node, 1);
214 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
215 NULL, "PROF_edge_counter");
216 stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
217 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
218 NULL, "PROF_edge_counter");
219 stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, gcov_type_tmp_var,
220 gimple_assign_lhs (stmt1), one);
221 stmt3 = gimple_build_assign (unshare_expr (ref), gimple_assign_lhs (stmt2));
222 gsi_insert_on_edge (e, stmt1);
223 gsi_insert_on_edge (e, stmt2);
224 gsi_insert_on_edge (e, stmt3);
227 /* Emits code to get VALUE to instrument at GSI, and returns the
228 variable containing the value. */
230 static tree
231 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
233 tree val = value->hvalue.value;
234 if (POINTER_TYPE_P (TREE_TYPE (val)))
235 val = fold_convert (build_nonstandard_integer_type
236 (TYPE_PRECISION (TREE_TYPE (val)), 1), val);
237 return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
238 true, NULL_TREE, true, GSI_SAME_STMT);
241 /* Output instructions as GIMPLE trees to increment the interval histogram
242 counter. VALUE is the expression whose value is profiled. TAG is the
243 tag of the section for counters, BASE is offset of the counter position. */
245 void
246 gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
248 gimple stmt = value->hvalue.stmt;
249 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
250 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
251 gimple call;
252 tree val;
253 tree start = build_int_cst_type (integer_type_node,
254 value->hdata.intvl.int_start);
255 tree steps = build_int_cst_type (unsigned_type_node,
256 value->hdata.intvl.steps);
258 ref_ptr = force_gimple_operand_gsi (&gsi,
259 build_addr (ref, current_function_decl),
260 true, NULL_TREE, true, GSI_SAME_STMT);
261 val = prepare_instrumented_value (&gsi, value);
262 call = gimple_build_call (tree_interval_profiler_fn, 4,
263 ref_ptr, val, start, steps);
264 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
267 /* Output instructions as GIMPLE trees to increment the power of two histogram
268 counter. VALUE is the expression whose value is profiled. TAG is the tag
269 of the section for counters, BASE is offset of the counter position. */
271 void
272 gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
274 gimple stmt = value->hvalue.stmt;
275 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
276 tree ref_ptr = tree_coverage_counter_addr (tag, base);
277 gimple call;
278 tree val;
280 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
281 true, NULL_TREE, true, GSI_SAME_STMT);
282 val = prepare_instrumented_value (&gsi, value);
283 call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val);
284 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
287 /* Output instructions as GIMPLE trees for code to find the most common value.
288 VALUE is the expression whose value is profiled. TAG is the tag of the
289 section for counters, BASE is offset of the counter position. */
291 void
292 gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
294 gimple stmt = value->hvalue.stmt;
295 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
296 tree ref_ptr = tree_coverage_counter_addr (tag, base);
297 gimple call;
298 tree val;
300 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
301 true, NULL_TREE, true, GSI_SAME_STMT);
302 val = prepare_instrumented_value (&gsi, value);
303 call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val);
304 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
308 /* Output instructions as GIMPLE trees for code to find the most
309 common called function in indirect call.
310 VALUE is the call expression whose indirect callee is profiled.
311 TAG is the tag of the section for counters, BASE is offset of the
312 counter position. */
314 void
315 gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
317 tree tmp1;
318 gimple stmt1, stmt2, stmt3;
319 gimple stmt = value->hvalue.stmt;
320 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
321 tree ref_ptr = tree_coverage_counter_addr (tag, base);
323 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
324 true, NULL_TREE, true, GSI_SAME_STMT);
326 /* Insert code:
328 stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
329 stmt2: tmp1 = (void *) (indirect call argument value)
330 stmt3: __gcov_indirect_call_callee = tmp1;
333 stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr);
334 tmp1 = make_temp_ssa_name (ptr_void, NULL, "PROF");
335 stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
336 stmt3 = gimple_build_assign (ic_void_ptr_var, gimple_assign_lhs (stmt2));
338 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
339 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
340 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
344 /* Output instructions as GIMPLE trees for code to find the most
345 common called function in indirect call. Insert instructions at the
346 beginning of every possible called function.
349 void
350 gimple_gen_ic_func_profiler (void)
352 struct cgraph_node * c_node = cgraph_get_node (current_function_decl);
353 gimple_stmt_iterator gsi;
354 gimple stmt1, stmt2;
355 tree tree_uid, cur_func, counter_ptr, ptr_var, void0;
357 if (cgraph_only_called_directly_p (c_node))
358 return;
360 gimple_init_edge_profiler ();
362 /* Insert code:
364 stmt1: __gcov_indirect_call_profiler (__gcov_indirect_call_counters,
365 current_function_funcdef_no,
366 &current_function_decl,
367 __gcov_indirect_call_callee);
369 gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR));
371 cur_func = force_gimple_operand_gsi (&gsi,
372 build_addr (current_function_decl,
373 current_function_decl),
374 true, NULL_TREE,
375 true, GSI_SAME_STMT);
376 counter_ptr = force_gimple_operand_gsi (&gsi, ic_gcov_type_ptr_var,
377 true, NULL_TREE, true,
378 GSI_SAME_STMT);
379 ptr_var = force_gimple_operand_gsi (&gsi, ic_void_ptr_var,
380 true, NULL_TREE, true,
381 GSI_SAME_STMT);
382 tree_uid = build_int_cst (gcov_type_node, current_function_funcdef_no);
383 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 4,
384 counter_ptr, tree_uid, cur_func, ptr_var);
385 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
387 /* Set __gcov_indirect_call_callee to 0,
388 so that calls from other modules won't get misattributed
389 to the last caller of the current callee. */
390 void0 = build_int_cst (build_pointer_type (void_type_node), 0);
391 stmt2 = gimple_build_assign (ic_void_ptr_var, void0);
392 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
395 /* Output instructions as GIMPLE trees for code to find the most common value
396 of a difference between two evaluations of an expression.
397 VALUE is the expression whose value is profiled. TAG is the tag of the
398 section for counters, BASE is offset of the counter position. */
400 void
401 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
402 unsigned tag ATTRIBUTE_UNUSED,
403 unsigned base ATTRIBUTE_UNUSED)
405 /* FIXME implement this. */
406 #ifdef ENABLE_CHECKING
407 internal_error ("unimplemented functionality");
408 #endif
409 gcc_unreachable ();
412 /* Output instructions as GIMPLE trees to increment the average histogram
413 counter. VALUE is the expression whose value is profiled. TAG is the
414 tag of the section for counters, BASE is offset of the counter position. */
416 void
417 gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
419 gimple stmt = value->hvalue.stmt;
420 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
421 tree ref_ptr = tree_coverage_counter_addr (tag, base);
422 gimple call;
423 tree val;
425 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
426 true, NULL_TREE,
427 true, GSI_SAME_STMT);
428 val = prepare_instrumented_value (&gsi, value);
429 call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
430 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
433 /* Output instructions as GIMPLE trees to increment the ior histogram
434 counter. VALUE is the expression whose value is profiled. TAG is the
435 tag of the section for counters, BASE is offset of the counter position. */
437 void
438 gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
440 gimple stmt = value->hvalue.stmt;
441 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
442 tree ref_ptr = tree_coverage_counter_addr (tag, base);
443 gimple call;
444 tree val;
446 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
447 true, NULL_TREE, true, GSI_SAME_STMT);
448 val = prepare_instrumented_value (&gsi, value);
449 call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
450 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
453 /* Profile all functions in the callgraph. */
455 static unsigned int
456 tree_profiling (void)
458 struct cgraph_node *node;
460 /* This is a small-ipa pass that gets called only once, from
461 cgraphunit.c:ipa_passes(). */
462 gcc_assert (cgraph_state == CGRAPH_STATE_IPA_SSA);
464 init_node_map();
466 FOR_EACH_DEFINED_FUNCTION (node)
468 if (!gimple_has_body_p (node->symbol.decl))
469 continue;
471 /* Don't profile functions produced for builtin stuff. */
472 if (DECL_SOURCE_LOCATION (node->symbol.decl) == BUILTINS_LOCATION)
473 continue;
475 push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl));
477 /* Local pure-const may imply need to fixup the cfg. */
478 if (execute_fixup_cfg () & TODO_cleanup_cfg)
479 cleanup_tree_cfg ();
481 branch_prob ();
483 if (! flag_branch_probabilities
484 && flag_profile_values)
485 gimple_gen_ic_func_profiler ();
487 if (flag_branch_probabilities
488 && flag_profile_values
489 && flag_value_profile_transformations)
490 gimple_value_profile_transformations ();
492 /* The above could hose dominator info. Currently there is
493 none coming in, this is a safety valve. It should be
494 easy to adjust it, if and when there is some. */
495 free_dominance_info (CDI_DOMINATORS);
496 free_dominance_info (CDI_POST_DOMINATORS);
497 pop_cfun ();
500 /* Drop pure/const flags from instrumented functions. */
501 FOR_EACH_DEFINED_FUNCTION (node)
503 if (!gimple_has_body_p (node->symbol.decl)
504 || !(!node->clone_of
505 || node->symbol.decl != node->clone_of->symbol.decl))
506 continue;
508 /* Don't profile functions produced for builtin stuff. */
509 if (DECL_SOURCE_LOCATION (node->symbol.decl) == BUILTINS_LOCATION)
510 continue;
512 cgraph_set_const_flag (node, false, false);
513 cgraph_set_pure_flag (node, false, false);
516 /* Update call statements and rebuild the cgraph. */
517 FOR_EACH_DEFINED_FUNCTION (node)
519 basic_block bb;
521 if (!gimple_has_body_p (node->symbol.decl)
522 || !(!node->clone_of
523 || node->symbol.decl != node->clone_of->symbol.decl))
524 continue;
526 /* Don't profile functions produced for builtin stuff. */
527 if (DECL_SOURCE_LOCATION (node->symbol.decl) == BUILTINS_LOCATION)
528 continue;
530 push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl));
532 FOR_EACH_BB (bb)
534 gimple_stmt_iterator gsi;
535 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
537 gimple stmt = gsi_stmt (gsi);
538 if (is_gimple_call (stmt))
539 update_stmt (stmt);
543 update_ssa (TODO_update_ssa);
545 rebuild_cgraph_edges ();
547 pop_cfun ();
550 del_node_map();
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 "profile", /* name */
569 OPTGROUP_NONE, /* optinfo_flags */
570 gate_tree_profile_ipa, /* gate */
571 tree_profiling, /* execute */
572 NULL, /* sub */
573 NULL, /* next */
574 0, /* static_pass_number */
575 TV_IPA_PROFILE, /* tv_id */
576 0, /* properties_required */
577 0, /* properties_provided */
578 0, /* properties_destroyed */
579 0, /* todo_flags_start */
580 0 /* todo_flags_finish */
584 #include "gt-tree-profile.h"