target.h (globalize_decl_name): New.
[gcc.git] / gcc / tree-profile.c
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.
8
9 This file is part of GCC.
10
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.
15
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.
20
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. */
25
26 /* Generate basic block profile instrumentation and auxiliary files.
27 Tree-based version. See profile.c for overview. */
28
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"
49
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;
55 \f
56
57 static GTY(()) tree ic_void_ptr_var;
58 static GTY(()) tree ic_gcov_type_ptr_var;
59 static GTY(()) tree ptr_void;
60
61 /* Do initialization work for the edge profiler. */
62
63 /* Add code:
64 static gcov* __gcov_indirect_call_counters; // pointer to actual counter
65 static void* __gcov_indirect_call_callee; // actual callie addres
66 */
67 static void
68 tree_init_ic_make_global_vars (void)
69 {
70 tree gcov_type_ptr;
71
72 ptr_void = build_pointer_type (void_type_node);
73
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);
83
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);
94 }
95
96 static void
97 tree_init_edge_profiler (void)
98 {
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;
104
105 if (!gcov_type_node)
106 {
107 gcov_type_node = get_gcov_type ();
108 gcov_type_ptr = build_pointer_type (gcov_type_node);
109
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);
119
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);
127
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);
136
137 tree_init_ic_make_global_vars ();
138
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);
148 }
149 }
150
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. */
154
155 static void
156 tree_gen_edge_profiler (int edgeno, edge e)
157 {
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);
169 }
170
171 /* Emits code to get VALUE to instrument at BSI, and returns the
172 variable containing the value. */
173
174 static tree
175 prepare_instrumented_value (block_stmt_iterator *bsi,
176 histogram_value value)
177 {
178 tree val = value->hvalue.value;
179 return force_gimple_operand_bsi (bsi, fold_convert (gcov_type_node, val),
180 true, NULL_TREE);
181 }
182
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. */
186
187 static void
188 tree_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
189 {
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);
196
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);
208 }
209
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. */
213
214 static void
215 tree_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
216 {
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;
221
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);
231 }
232
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. */
236
237 static void
238 tree_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
239 {
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;
244
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);
254 }
255
256
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. */
262
263 static void
264 tree_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
265 {
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;
270
271 ref_ptr = force_gimple_operand_bsi (&bsi,
272 build_addr (ref, current_function_decl),
273 true, NULL_TREE);
274
275 /* Insert code:
276
277 __gcov_indirect_call_counters = get_relevant_counter_ptr ();
278 __gcov_indirect_call_callee = (void *) indirect call argument;
279 */
280
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);
289
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);
293 }
294
295
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.
299 */
300
301 static void
302 tree_gen_ic_func_profiler (void)
303 {
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;
311
312 if (flag_unit_at_a_time)
313 {
314 if (!c_node->needed)
315 return;
316 }
317
318 tree_init_edge_profiler ();
319
320 FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
321 {
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);
337 }
338 }
339
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. */
344
345 static void
346 tree_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
347 unsigned tag ATTRIBUTE_UNUSED,
348 unsigned base ATTRIBUTE_UNUSED)
349 {
350 /* FIXME implement this. */
351 #ifdef ENABLE_CHECKING
352 internal_error ("unimplemented functionality");
353 #endif
354 gcc_unreachable ();
355 }
356
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. */
360
361 static bool
362 do_tree_profiling (void)
363 {
364 if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
365 {
366 tree_register_profile_hooks ();
367 tree_register_value_prof_hooks ();
368 return true;
369 }
370 return false;
371 }
372
373 static unsigned int
374 tree_profiling (void)
375 {
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 ();
381
382 if (! flag_branch_probabilities
383 && flag_profile_values)
384 tree_gen_ic_func_profiler ();
385
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;
396 }
397
398 struct tree_opt_pass pass_tree_profile =
399 {
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 */
413 };
414
415 struct profile_hooks tree_profile_hooks =
416 {
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 */
424 };
425
426 #include "gt-tree-profile.h"