* tree-ssa-address.c (create_mem_ref): Remove ", bsi" from
[official-gcc.git] / gcc / tree-profile.c
blob2a4ec2ae9eb7e2bbdfce293834b0693229502dbb
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 Free Software Foundation, Inc.
4 Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
5 based on some ideas from Dain Samples of UC Berkeley.
6 Further mangling by Bob Manson, Cygnus Support.
7 Converted to use trees by Dale Johannesen, Apple Computer.
9 This file is part of GCC.
11 GCC is free software; you can redistribute it and/or modify it under
12 the terms of the GNU General Public License as published by the Free
13 Software Foundation; either version 2, or (at your option) any later
14 version.
16 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
17 WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 for more details.
21 You should have received a copy of the GNU General Public License
22 along with GCC; see the file COPYING. If not, write to the Free
23 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
24 02110-1301, USA. */
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 "rtl.h"
34 #include "flags.h"
35 #include "output.h"
36 #include "regs.h"
37 #include "expr.h"
38 #include "function.h"
39 #include "toplev.h"
40 #include "coverage.h"
41 #include "tree.h"
42 #include "tree-flow.h"
43 #include "tree-dump.h"
44 #include "tree-pass.h"
45 #include "timevar.h"
46 #include "value-prof.h"
47 #include "ggc.h"
48 #include "cgraph.h"
50 static GTY(()) tree gcov_type_node;
51 static GTY(()) tree tree_interval_profiler_fn;
52 static GTY(()) tree tree_pow2_profiler_fn;
53 static GTY(()) tree tree_one_value_profiler_fn;
54 static GTY(()) tree tree_indirect_call_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 callie addres
67 static void
68 tree_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 (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 assemble_variable (ic_void_ptr_var, 0, 0, 0);
84 gcov_type_ptr = build_pointer_type (get_gcov_type ());
85 ic_gcov_type_ptr_var
86 = build_decl (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 assemble_variable (ic_gcov_type_ptr_var, 0, 0, 0);
96 static void
97 tree_init_edge_profiler (void)
99 tree interval_profiler_fn_type;
100 tree pow2_profiler_fn_type;
101 tree one_value_profiler_fn_type;
102 tree gcov_type_ptr;
103 tree ic_profiler_fn_type;
105 if (!gcov_type_node)
107 gcov_type_node = get_gcov_type ();
108 gcov_type_ptr = build_pointer_type (gcov_type_node);
110 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
111 interval_profiler_fn_type
112 = build_function_type_list (void_type_node,
113 gcov_type_ptr, gcov_type_node,
114 integer_type_node,
115 unsigned_type_node, NULL_TREE);
116 tree_interval_profiler_fn
117 = build_fn_decl ("__gcov_interval_profiler",
118 interval_profiler_fn_type);
120 /* void (*) (gcov_type *, gcov_type) */
121 pow2_profiler_fn_type
122 = build_function_type_list (void_type_node,
123 gcov_type_ptr, gcov_type_node,
124 NULL_TREE);
125 tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler",
126 pow2_profiler_fn_type);
128 /* void (*) (gcov_type *, gcov_type) */
129 one_value_profiler_fn_type
130 = build_function_type_list (void_type_node,
131 gcov_type_ptr, gcov_type_node,
132 NULL_TREE);
133 tree_one_value_profiler_fn
134 = build_fn_decl ("__gcov_one_value_profiler",
135 one_value_profiler_fn_type);
137 tree_init_ic_make_global_vars ();
139 /* void (*) (gcov_type *, gcov_type, void *, void *) */
140 ic_profiler_fn_type
141 = build_function_type_list (void_type_node,
142 gcov_type_ptr, gcov_type_node,
143 ptr_void,
144 ptr_void, NULL_TREE);
145 tree_indirect_call_profiler_fn
146 = build_fn_decl ("__gcov_indirect_call_profiler",
147 ic_profiler_fn_type);
151 /* Output instructions as GIMPLE trees to increment the edge
152 execution count, and insert them on E. We rely on
153 bsi_insert_on_edge to preserve the order. */
155 static void
156 tree_gen_edge_profiler (int edgeno, edge e)
158 tree tmp1 = create_tmp_var (gcov_type_node, "PROF");
159 tree tmp2 = create_tmp_var (gcov_type_node, "PROF");
160 tree ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
161 tree stmt1 = build2 (GIMPLE_MODIFY_STMT, gcov_type_node, tmp1, ref);
162 tree stmt2 = build2 (GIMPLE_MODIFY_STMT, gcov_type_node, tmp2,
163 build2 (PLUS_EXPR, gcov_type_node,
164 tmp1, integer_one_node));
165 tree stmt3 = build2 (GIMPLE_MODIFY_STMT, gcov_type_node, ref, tmp2);
166 bsi_insert_on_edge (e, stmt1);
167 bsi_insert_on_edge (e, stmt2);
168 bsi_insert_on_edge (e, stmt3);
171 /* Emits code to get VALUE to instrument at BSI, and returns the
172 variable containing the value. */
174 static tree
175 prepare_instrumented_value (block_stmt_iterator *bsi,
176 histogram_value value)
178 tree val = value->hvalue.value;
179 return force_gimple_operand_bsi (bsi, fold_convert (gcov_type_node, val),
180 true, NULL_TREE);
183 /* Output instructions as GIMPLE trees to increment the interval histogram
184 counter. VALUE is the expression whose value is profiled. TAG is the
185 tag of the section for counters, BASE is offset of the counter position. */
187 static void
188 tree_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
190 tree stmt = value->hvalue.stmt;
191 block_stmt_iterator bsi = bsi_for_stmt (stmt);
192 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
193 tree args, call, val;
194 tree start = build_int_cst_type (integer_type_node, value->hdata.intvl.int_start);
195 tree steps = build_int_cst_type (unsigned_type_node, value->hdata.intvl.steps);
197 ref_ptr = force_gimple_operand_bsi (&bsi,
198 build_addr (ref, current_function_decl),
199 true, NULL_TREE);
200 val = prepare_instrumented_value (&bsi, value);
201 args = tree_cons (NULL_TREE, ref_ptr,
202 tree_cons (NULL_TREE, val,
203 tree_cons (NULL_TREE, start,
204 tree_cons (NULL_TREE, steps,
205 NULL_TREE))));
206 call = build_function_call_expr (tree_interval_profiler_fn, args);
207 bsi_insert_before (&bsi, call, BSI_SAME_STMT);
210 /* Output instructions as GIMPLE trees to increment the power of two histogram
211 counter. VALUE is the expression whose value is profiled. TAG is the tag
212 of the section for counters, BASE is offset of the counter position. */
214 static void
215 tree_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
217 tree stmt = value->hvalue.stmt;
218 block_stmt_iterator bsi = bsi_for_stmt (stmt);
219 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
220 tree args, call, val;
222 ref_ptr = force_gimple_operand_bsi (&bsi,
223 build_addr (ref, current_function_decl),
224 true, NULL_TREE);
225 val = prepare_instrumented_value (&bsi, value);
226 args = tree_cons (NULL_TREE, ref_ptr,
227 tree_cons (NULL_TREE, val,
228 NULL_TREE));
229 call = build_function_call_expr (tree_pow2_profiler_fn, args);
230 bsi_insert_before (&bsi, call, BSI_SAME_STMT);
233 /* Output instructions as GIMPLE trees for code to find the most common value.
234 VALUE is the expression whose value is profiled. TAG is the tag of the
235 section for counters, BASE is offset of the counter position. */
237 static void
238 tree_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
240 tree stmt = value->hvalue.stmt;
241 block_stmt_iterator bsi = bsi_for_stmt (stmt);
242 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
243 tree args, call, val;
245 ref_ptr = force_gimple_operand_bsi (&bsi,
246 build_addr (ref, current_function_decl),
247 true, NULL_TREE);
248 val = prepare_instrumented_value (&bsi, value);
249 args = tree_cons (NULL_TREE, ref_ptr,
250 tree_cons (NULL_TREE, val,
251 NULL_TREE));
252 call = build_function_call_expr (tree_one_value_profiler_fn, args);
253 bsi_insert_before (&bsi, call, BSI_SAME_STMT);
257 /* Output instructions as GIMPLE trees for code to find the most
258 common called function in indirect call.
259 VALUE is the call expression whose indirect callie is profiled.
260 TAG is the tag of the section for counters, BASE is offset of the
261 counter position. */
263 static void
264 tree_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
266 tree tmp1, stmt1, stmt2, stmt3;
267 tree stmt = value->hvalue.stmt;
268 block_stmt_iterator bsi = bsi_for_stmt (stmt);
269 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
271 ref_ptr = force_gimple_operand_bsi (&bsi,
272 build_addr (ref, current_function_decl),
273 true, NULL_TREE);
275 /* Insert code:
277 __gcov_indirect_call_counters = get_relevant_counter_ptr ();
278 __gcov_indirect_call_callee = (void *) indirect call argument;
281 tmp1 = create_tmp_var (ptr_void, "PROF");
282 stmt1 = build2 (GIMPLE_MODIFY_STMT,
283 build_pointer_type (get_gcov_type ()),
284 ic_gcov_type_ptr_var, ref_ptr);
285 stmt2 = build2 (GIMPLE_MODIFY_STMT, ptr_void, tmp1,
286 unshare_expr (value->hvalue.value));
287 stmt3 = build2 (GIMPLE_MODIFY_STMT, ptr_void,
288 ic_void_ptr_var, tmp1);
290 bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
291 bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
292 bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT);
296 /* Output instructions as GIMPLE trees for code to find the most
297 common called function in indirect call. Insert instructions at the
298 begining of every possible called function.
301 static void
302 tree_gen_ic_func_profiler (void)
304 struct cgraph_node * c_node = cgraph_node (current_function_decl);
305 block_stmt_iterator bsi;
306 edge e;
307 basic_block bb;
308 edge_iterator ei;
309 tree stmt1;
310 tree args, tree_uid, cur_func;
312 if (flag_unit_at_a_time)
314 if (!c_node->needed)
315 return;
318 tree_init_edge_profiler ();
320 FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
322 bb = split_edge (e);
323 bsi = bsi_start (bb);
324 cur_func = force_gimple_operand_bsi (&bsi,
325 build_addr (current_function_decl,
326 current_function_decl),
327 true, NULL_TREE);
328 tree_uid = build_int_cst (gcov_type_node, c_node->pid);
329 args = tree_cons (NULL_TREE, ic_gcov_type_ptr_var,
330 tree_cons (NULL_TREE, tree_uid,
331 tree_cons (NULL_TREE, cur_func,
332 tree_cons (NULL_TREE,
333 ic_void_ptr_var,
334 NULL_TREE))));
335 stmt1 = build_function_call_expr (tree_indirect_call_profiler_fn, args);
336 bsi_insert_after (&bsi, stmt1, BSI_SAME_STMT);
340 /* Output instructions as GIMPLE trees for code to find the most common value
341 of a difference between two evaluations of an expression.
342 VALUE is the expression whose value is profiled. TAG is the tag of the
343 section for counters, BASE is offset of the counter position. */
345 static void
346 tree_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
347 unsigned tag ATTRIBUTE_UNUSED,
348 unsigned base ATTRIBUTE_UNUSED)
350 /* FIXME implement this. */
351 #ifdef ENABLE_CHECKING
352 internal_error ("unimplemented functionality");
353 #endif
354 gcc_unreachable ();
357 /* Return 1 if tree-based profiling is in effect, else 0.
358 If it is, set up hooks for tree-based profiling.
359 Gate for pass_tree_profile. */
361 static bool
362 do_tree_profiling (void)
364 if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
366 tree_register_profile_hooks ();
367 tree_register_value_prof_hooks ();
368 return true;
370 return false;
373 static unsigned int
374 tree_profiling (void)
376 /* Don't profile functions produced at destruction time, particularly
377 the gcov datastructure initializer. */
378 if (cgraph_state == CGRAPH_STATE_FINISHED)
379 return 0;
380 branch_prob ();
382 if (! flag_branch_probabilities
383 && flag_profile_values)
384 tree_gen_ic_func_profiler ();
386 if (flag_branch_probabilities
387 && flag_profile_values
388 && flag_value_profile_transformations)
389 value_profile_transformations ();
390 /* The above could hose dominator info. Currently there is
391 none coming in, this is a safety valve. It should be
392 easy to adjust it, if and when there is some. */
393 free_dominance_info (CDI_DOMINATORS);
394 free_dominance_info (CDI_POST_DOMINATORS);
395 return 0;
398 struct tree_opt_pass pass_tree_profile =
400 "tree_profile", /* name */
401 do_tree_profiling, /* gate */
402 tree_profiling, /* execute */
403 NULL, /* sub */
404 NULL, /* next */
405 0, /* static_pass_number */
406 TV_BRANCH_PROB, /* tv_id */
407 PROP_gimple_leh | PROP_cfg, /* properties_required */
408 PROP_gimple_leh | PROP_cfg, /* properties_provided */
409 0, /* properties_destroyed */
410 0, /* todo_flags_start */
411 TODO_verify_stmts, /* todo_flags_finish */
412 0 /* letter */
415 struct profile_hooks tree_profile_hooks =
417 tree_init_edge_profiler, /* init_edge_profiler */
418 tree_gen_edge_profiler, /* gen_edge_profiler */
419 tree_gen_interval_profiler, /* gen_interval_profiler */
420 tree_gen_pow2_profiler, /* gen_pow2_profiler */
421 tree_gen_one_value_profiler, /* gen_one_value_profiler */
422 tree_gen_const_delta_profiler,/* gen_const_delta_profiler */
423 tree_gen_ic_profiler, /* gen_ic_profiler */
426 #include "gt-tree-profile.h"