Creating Intel BID library branch
[official-gcc.git] / gcc / tree-profile.c
blob2dace9c6a8f6d9a7931d4e5db365c4081a927610
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
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 2, 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 COPYING. If not, write to the Free
24 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
25 02110-1301, USA. */
27 /* Generate basic block profile instrumentation and auxiliary files.
28 Tree-based version. See profile.c for overview. */
30 #include "config.h"
31 #include "system.h"
32 #include "coretypes.h"
33 #include "tm.h"
34 #include "rtl.h"
35 #include "flags.h"
36 #include "output.h"
37 #include "regs.h"
38 #include "expr.h"
39 #include "function.h"
40 #include "toplev.h"
41 #include "coverage.h"
42 #include "tree.h"
43 #include "tree-flow.h"
44 #include "tree-dump.h"
45 #include "tree-pass.h"
46 #include "timevar.h"
47 #include "value-prof.h"
48 #include "ggc.h"
49 #include "cgraph.h"
51 static GTY(()) tree gcov_type_node;
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. */
66 /* Add code:
67 static gcov* __gcov_indirect_call_counters; // pointer to actual counter
68 static void* __gcov_indirect_call_callee; // actual callee addres
70 static void
71 tree_init_ic_make_global_vars (void)
73 tree gcov_type_ptr;
75 ptr_void = build_pointer_type (void_type_node);
77 ic_void_ptr_var
78 = build_decl (VAR_DECL,
79 get_identifier ("__gcov_indirect_call_callee"),
80 ptr_void);
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 ());
88 ic_gcov_type_ptr_var
89 = build_decl (VAR_DECL,
90 get_identifier ("__gcov_indirect_call_counters"),
91 gcov_type_ptr);
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);
99 static void
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;
105 tree gcov_type_ptr;
106 tree ic_profiler_fn_type;
107 tree average_profiler_fn_type;
109 if (!gcov_type_node)
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,
118 integer_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,
128 NULL_TREE);
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,
136 NULL_TREE);
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 *) */
144 ic_profiler_fn_type
145 = build_function_type_list (void_type_node,
146 gcov_type_ptr, gcov_type_node,
147 ptr_void,
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);
159 tree_ior_profiler_fn
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 bsi_insert_on_edge to preserve the order. */
169 static void
170 tree_gen_edge_profiler (int edgeno, edge e)
172 tree tmp1 = create_tmp_var (gcov_type_node, "PROF");
173 tree tmp2 = create_tmp_var (gcov_type_node, "PROF");
174 tree ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
175 tree one = build_int_cst (gcov_type_node, 1);
176 tree stmt1 = build_gimple_modify_stmt (tmp1, ref);
177 tree stmt2 = build_gimple_modify_stmt (tmp2,
178 build2 (PLUS_EXPR, gcov_type_node,
179 tmp1, one));
180 tree stmt3 = build_gimple_modify_stmt (ref, tmp2);
181 bsi_insert_on_edge (e, stmt1);
182 bsi_insert_on_edge (e, stmt2);
183 bsi_insert_on_edge (e, stmt3);
186 /* Emits code to get VALUE to instrument at BSI, and returns the
187 variable containing the value. */
189 static tree
190 prepare_instrumented_value (block_stmt_iterator *bsi,
191 histogram_value value)
193 tree val = value->hvalue.value;
194 return force_gimple_operand_bsi (bsi, fold_convert (gcov_type_node, val),
195 true, NULL_TREE);
198 /* Output instructions as GIMPLE trees to increment the interval histogram
199 counter. VALUE is the expression whose value is profiled. TAG is the
200 tag of the section for counters, BASE is offset of the counter position. */
202 static void
203 tree_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
205 tree stmt = value->hvalue.stmt;
206 block_stmt_iterator bsi = bsi_for_stmt (stmt);
207 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
208 tree call, val;
209 tree start = build_int_cst_type (integer_type_node, value->hdata.intvl.int_start);
210 tree steps = build_int_cst_type (unsigned_type_node, value->hdata.intvl.steps);
212 ref_ptr = force_gimple_operand_bsi (&bsi,
213 build_addr (ref, current_function_decl),
214 true, NULL_TREE);
215 val = prepare_instrumented_value (&bsi, value);
216 call = build_call_expr (tree_interval_profiler_fn, 4,
217 ref_ptr, val, start, steps);
218 bsi_insert_before (&bsi, call, BSI_SAME_STMT);
221 /* Output instructions as GIMPLE trees to increment the power of two histogram
222 counter. VALUE is the expression whose value is profiled. TAG is the tag
223 of the section for counters, BASE is offset of the counter position. */
225 static void
226 tree_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
228 tree stmt = value->hvalue.stmt;
229 block_stmt_iterator bsi = bsi_for_stmt (stmt);
230 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
231 tree call, val;
233 ref_ptr = force_gimple_operand_bsi (&bsi,
234 build_addr (ref, current_function_decl),
235 true, NULL_TREE);
236 val = prepare_instrumented_value (&bsi, value);
237 call = build_call_expr (tree_pow2_profiler_fn, 2, ref_ptr, val);
238 bsi_insert_before (&bsi, call, BSI_SAME_STMT);
241 /* Output instructions as GIMPLE trees for code to find the most common value.
242 VALUE is the expression whose value is profiled. TAG is the tag of the
243 section for counters, BASE is offset of the counter position. */
245 static void
246 tree_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
248 tree stmt = value->hvalue.stmt;
249 block_stmt_iterator bsi = bsi_for_stmt (stmt);
250 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
251 tree call, val;
253 ref_ptr = force_gimple_operand_bsi (&bsi,
254 build_addr (ref, current_function_decl),
255 true, NULL_TREE);
256 val = prepare_instrumented_value (&bsi, value);
257 call = build_call_expr (tree_one_value_profiler_fn, 2, ref_ptr, val);
258 bsi_insert_before (&bsi, call, BSI_SAME_STMT);
262 /* Output instructions as GIMPLE trees for code to find the most
263 common called function in indirect call.
264 VALUE is the call expression whose indirect callee is profiled.
265 TAG is the tag of the section for counters, BASE is offset of the
266 counter position. */
268 static void
269 tree_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
271 tree tmp1, stmt1, stmt2, stmt3;
272 tree stmt = value->hvalue.stmt;
273 block_stmt_iterator bsi = bsi_for_stmt (stmt);
274 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
276 ref_ptr = force_gimple_operand_bsi (&bsi,
277 build_addr (ref, current_function_decl),
278 true, NULL_TREE);
280 /* Insert code:
282 __gcov_indirect_call_counters = get_relevant_counter_ptr ();
283 __gcov_indirect_call_callee = (void *) indirect call argument;
286 tmp1 = create_tmp_var (ptr_void, "PROF");
287 stmt1 = build_gimple_modify_stmt (ic_gcov_type_ptr_var, ref_ptr);
288 stmt2 = build_gimple_modify_stmt (tmp1, unshare_expr (value->hvalue.value));
289 stmt3 = build_gimple_modify_stmt (ic_void_ptr_var, tmp1);
291 bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
292 bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
293 bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT);
297 /* Output instructions as GIMPLE trees for code to find the most
298 common called function in indirect call. Insert instructions at the
299 beginning of every possible called function.
302 static void
303 tree_gen_ic_func_profiler (void)
305 struct cgraph_node * c_node = cgraph_node (current_function_decl);
306 block_stmt_iterator bsi;
307 edge e;
308 basic_block bb;
309 edge_iterator ei;
310 tree stmt1;
311 tree tree_uid, cur_func;
313 if (flag_unit_at_a_time)
315 if (!c_node->needed)
316 return;
319 tree_init_edge_profiler ();
321 FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
323 bb = split_edge (e);
324 bsi = bsi_start (bb);
325 cur_func = force_gimple_operand_bsi (&bsi,
326 build_addr (current_function_decl,
327 current_function_decl),
328 true, NULL_TREE);
329 tree_uid = build_int_cst (gcov_type_node, c_node->pid);
330 stmt1 = build_call_expr (tree_indirect_call_profiler_fn, 4,
331 ic_gcov_type_ptr_var,
332 tree_uid,
333 cur_func,
334 ic_void_ptr_var);
335 bsi_insert_after (&bsi, stmt1, BSI_NEW_STMT);
339 /* Output instructions as GIMPLE trees for code to find the most common value
340 of a difference between two evaluations of an expression.
341 VALUE is the expression whose value is profiled. TAG is the tag of the
342 section for counters, BASE is offset of the counter position. */
344 static void
345 tree_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
346 unsigned tag ATTRIBUTE_UNUSED,
347 unsigned base ATTRIBUTE_UNUSED)
349 /* FIXME implement this. */
350 #ifdef ENABLE_CHECKING
351 internal_error ("unimplemented functionality");
352 #endif
353 gcc_unreachable ();
356 /* Output instructions as GIMPLE trees to increment the average histogram
357 counter. VALUE is the expression whose value is profiled. TAG is the
358 tag of the section for counters, BASE is offset of the counter position. */
360 static void
361 tree_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
363 tree stmt = value->hvalue.stmt;
364 block_stmt_iterator bsi = bsi_for_stmt (stmt);
365 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
366 tree call, val;
368 ref_ptr = force_gimple_operand_bsi (&bsi,
369 build_addr (ref, current_function_decl),
370 true, NULL_TREE);
371 val = prepare_instrumented_value (&bsi, value);
372 call = build_call_expr (tree_average_profiler_fn, 2, ref_ptr, val);
373 bsi_insert_before (&bsi, call, BSI_SAME_STMT);
376 /* Output instructions as GIMPLE trees to increment the ior histogram
377 counter. VALUE is the expression whose value is profiled. TAG is the
378 tag of the section for counters, BASE is offset of the counter position. */
380 static void
381 tree_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
383 tree stmt = value->hvalue.stmt;
384 block_stmt_iterator bsi = bsi_for_stmt (stmt);
385 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
386 tree call, val;
388 ref_ptr = force_gimple_operand_bsi (&bsi,
389 build_addr (ref, current_function_decl),
390 true, NULL_TREE);
391 val = prepare_instrumented_value (&bsi, value);
392 call = build_call_expr (tree_ior_profiler_fn, 2, ref_ptr, val);
393 bsi_insert_before (&bsi, call, BSI_SAME_STMT);
396 /* Return 1 if tree-based profiling is in effect, else 0.
397 If it is, set up hooks for tree-based profiling.
398 Gate for pass_tree_profile. */
400 static bool
401 do_tree_profiling (void)
403 if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
405 tree_register_profile_hooks ();
406 tree_register_value_prof_hooks ();
407 return true;
409 return false;
412 static unsigned int
413 tree_profiling (void)
415 /* Don't profile functions produced at destruction time, particularly
416 the gcov datastructure initializer. */
417 if (cgraph_state == CGRAPH_STATE_FINISHED)
418 return 0;
419 branch_prob ();
421 if (! flag_branch_probabilities
422 && flag_profile_values)
423 tree_gen_ic_func_profiler ();
425 if (flag_branch_probabilities
426 && flag_profile_values
427 && flag_value_profile_transformations)
428 value_profile_transformations ();
429 /* The above could hose dominator info. Currently there is
430 none coming in, this is a safety valve. It should be
431 easy to adjust it, if and when there is some. */
432 free_dominance_info (CDI_DOMINATORS);
433 free_dominance_info (CDI_POST_DOMINATORS);
434 return 0;
437 struct tree_opt_pass pass_tree_profile =
439 "tree_profile", /* name */
440 do_tree_profiling, /* gate */
441 tree_profiling, /* execute */
442 NULL, /* sub */
443 NULL, /* next */
444 0, /* static_pass_number */
445 TV_BRANCH_PROB, /* tv_id */
446 PROP_gimple_leh | PROP_cfg, /* properties_required */
447 PROP_gimple_leh | PROP_cfg, /* properties_provided */
448 0, /* properties_destroyed */
449 0, /* todo_flags_start */
450 TODO_verify_stmts | TODO_dump_func, /* todo_flags_finish */
451 0 /* letter */
454 struct profile_hooks tree_profile_hooks =
456 tree_init_edge_profiler, /* init_edge_profiler */
457 tree_gen_edge_profiler, /* gen_edge_profiler */
458 tree_gen_interval_profiler, /* gen_interval_profiler */
459 tree_gen_pow2_profiler, /* gen_pow2_profiler */
460 tree_gen_one_value_profiler, /* gen_one_value_profiler */
461 tree_gen_const_delta_profiler, /* gen_const_delta_profiler */
462 tree_gen_ic_profiler, /* gen_ic_profiler */
463 tree_gen_average_profiler, /* gen_average_profiler */
464 tree_gen_ior_profiler /* gen_ior_profiler */
467 #include "gt-tree-profile.h"