OSDN Git Service

b819665838521b0d06ea58463858f67d7fb159a3
[pf3gnuchains/gcc-fork.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 static GTY(()) tree tree_average_profiler_fn;
56 static GTY(()) tree tree_ior_profiler_fn;
57 \f
58
59 static GTY(()) tree ic_void_ptr_var;
60 static GTY(()) tree ic_gcov_type_ptr_var;
61 static GTY(()) tree ptr_void;
62
63 /* Do initialization work for the edge profiler.  */
64
65 /* Add code:
66    static gcov* __gcov_indirect_call_counters; // pointer to actual counter
67    static void* __gcov_indirect_call_callee; // actual callee address
68 */
69 static void
70 tree_init_ic_make_global_vars (void)
71 {
72   tree  gcov_type_ptr;
73
74   ptr_void = build_pointer_type (void_type_node);
75   
76   ic_void_ptr_var 
77     = build_decl (VAR_DECL, 
78                   get_identifier ("__gcov_indirect_call_callee"), 
79                   ptr_void);
80   TREE_STATIC (ic_void_ptr_var) = 1;
81   TREE_PUBLIC (ic_void_ptr_var) = 0;
82   DECL_ARTIFICIAL (ic_void_ptr_var) = 1;
83   DECL_INITIAL (ic_void_ptr_var) = NULL;
84   assemble_variable (ic_void_ptr_var, 0, 0, 0);
85
86   gcov_type_ptr = build_pointer_type (get_gcov_type ());
87   ic_gcov_type_ptr_var 
88     = build_decl (VAR_DECL, 
89                   get_identifier ("__gcov_indirect_call_counters"), 
90                   gcov_type_ptr);
91   TREE_STATIC (ic_gcov_type_ptr_var) = 1;
92   TREE_PUBLIC (ic_gcov_type_ptr_var) = 0;
93   DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1;
94   DECL_INITIAL (ic_gcov_type_ptr_var) = NULL;
95   assemble_variable (ic_gcov_type_ptr_var, 0, 0, 0);
96 }
97
98 static void
99 tree_init_edge_profiler (void)
100 {
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;
107
108   if (!gcov_type_node)
109     {
110       gcov_type_node = get_gcov_type ();
111       gcov_type_ptr = build_pointer_type (gcov_type_node);
112
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
123       /* void (*) (gcov_type *, gcov_type)  */
124       pow2_profiler_fn_type
125               = build_function_type_list (void_type_node,
126                                           gcov_type_ptr, gcov_type_node,
127                                           NULL_TREE);
128       tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler",
129                                                    pow2_profiler_fn_type);
130
131       /* void (*) (gcov_type *, gcov_type)  */
132       one_value_profiler_fn_type
133               = build_function_type_list (void_type_node,
134                                           gcov_type_ptr, gcov_type_node,
135                                           NULL_TREE);
136       tree_one_value_profiler_fn
137               = build_fn_decl ("__gcov_one_value_profiler",
138                                      one_value_profiler_fn_type);
139
140       tree_init_ic_make_global_vars ();
141       
142       /* void (*) (gcov_type *, gcov_type, void *, void *)  */
143       ic_profiler_fn_type
144                = build_function_type_list (void_type_node,
145                                           gcov_type_ptr, gcov_type_node,
146                                           ptr_void,
147                                           ptr_void, NULL_TREE);
148       tree_indirect_call_profiler_fn
149               = build_fn_decl ("__gcov_indirect_call_profiler",
150                                      ic_profiler_fn_type);
151       /* void (*) (gcov_type *, gcov_type)  */
152       average_profiler_fn_type
153               = build_function_type_list (void_type_node,
154                                           gcov_type_ptr, gcov_type_node, NULL_TREE);
155       tree_average_profiler_fn
156               = build_fn_decl ("__gcov_average_profiler",
157                                      average_profiler_fn_type);
158       tree_ior_profiler_fn
159               = build_fn_decl ("__gcov_ior_profiler",
160                                      average_profiler_fn_type);
161     }
162 }
163
164 /* Output instructions as GIMPLE trees to increment the edge 
165    execution count, and insert them on E.  We rely on 
166    bsi_insert_on_edge to preserve the order.  */
167
168 static void
169 tree_gen_edge_profiler (int edgeno, edge e)
170 {
171   tree tmp1 = create_tmp_var (gcov_type_node, "PROF");
172   tree tmp2 = create_tmp_var (gcov_type_node, "PROF");
173   tree ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
174   tree stmt1 = build2 (GIMPLE_MODIFY_STMT, gcov_type_node, tmp1, ref);
175   tree stmt2 = build2 (GIMPLE_MODIFY_STMT, gcov_type_node, tmp2,
176                        build2 (PLUS_EXPR, gcov_type_node, 
177                               tmp1, integer_one_node));
178   tree stmt3 = build2 (GIMPLE_MODIFY_STMT, gcov_type_node, ref, tmp2);
179   bsi_insert_on_edge (e, stmt1);
180   bsi_insert_on_edge (e, stmt2);
181   bsi_insert_on_edge (e, stmt3);
182 }
183
184 /* Emits code to get VALUE to instrument at BSI, and returns the
185    variable containing the value.  */
186
187 static tree
188 prepare_instrumented_value (block_stmt_iterator *bsi,
189                             histogram_value value)
190 {
191   tree val = value->hvalue.value;
192   return force_gimple_operand_bsi (bsi, fold_convert (gcov_type_node, val),
193                                    true, NULL_TREE);
194 }
195
196 /* Output instructions as GIMPLE trees to increment the interval histogram 
197    counter.  VALUE is the expression whose value is profiled.  TAG is the 
198    tag of the section for counters, BASE is offset of the counter position.  */
199
200 static void
201 tree_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
202 {
203   tree stmt = value->hvalue.stmt;
204   block_stmt_iterator bsi = bsi_for_stmt (stmt);
205   tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
206   tree args, call, val;
207   tree start = build_int_cst_type (integer_type_node, value->hdata.intvl.int_start);
208   tree steps = build_int_cst_type (unsigned_type_node, value->hdata.intvl.steps);
209   
210   ref_ptr = force_gimple_operand_bsi (&bsi,
211                                       build_addr (ref, current_function_decl),
212                                       true, NULL_TREE);
213   val = prepare_instrumented_value (&bsi, value);
214   args = tree_cons (NULL_TREE, ref_ptr,
215                     tree_cons (NULL_TREE, val,
216                                tree_cons (NULL_TREE, start,
217                                           tree_cons (NULL_TREE, steps,
218                                                      NULL_TREE))));
219   call = build_function_call_expr (tree_interval_profiler_fn, args);
220   bsi_insert_before (&bsi, call, BSI_SAME_STMT);
221 }
222
223 /* Output instructions as GIMPLE trees to increment the power of two histogram 
224    counter.  VALUE is the expression whose value is profiled.  TAG is the tag 
225    of the section for counters, BASE is offset of the counter position.  */
226
227 static void
228 tree_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
229 {
230   tree stmt = value->hvalue.stmt;
231   block_stmt_iterator bsi = bsi_for_stmt (stmt);
232   tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
233   tree args, call, val;
234   
235   ref_ptr = force_gimple_operand_bsi (&bsi,
236                                       build_addr (ref, current_function_decl),
237                                       true, NULL_TREE);
238   val = prepare_instrumented_value (&bsi, value);
239   args = tree_cons (NULL_TREE, ref_ptr,
240                     tree_cons (NULL_TREE, val,
241                                NULL_TREE));
242   call = build_function_call_expr (tree_pow2_profiler_fn, args);
243   bsi_insert_before (&bsi, call, BSI_SAME_STMT);
244 }
245
246 /* Output instructions as GIMPLE trees for code to find the most common value.
247    VALUE is the expression whose value is profiled.  TAG is the tag of the
248    section for counters, BASE is offset of the counter position.  */
249
250 static void
251 tree_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
252 {
253   tree stmt = value->hvalue.stmt;
254   block_stmt_iterator bsi = bsi_for_stmt (stmt);
255   tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
256   tree args, call, val;
257   
258   ref_ptr = force_gimple_operand_bsi (&bsi,
259                                       build_addr (ref, current_function_decl),
260                                       true, NULL_TREE);
261   val = prepare_instrumented_value (&bsi, value);
262   args = tree_cons (NULL_TREE, ref_ptr,
263                     tree_cons (NULL_TREE, val,
264                                NULL_TREE));
265   call = build_function_call_expr (tree_one_value_profiler_fn, args);
266   bsi_insert_before (&bsi, call, BSI_SAME_STMT);
267 }
268
269
270 /* Output instructions as GIMPLE trees for code to find the most
271    common called function in indirect call.  
272    VALUE is the call expression whose indirect callee is profiled.
273    TAG is the tag of the section for counters, BASE is offset of the
274    counter position.  */
275
276 static void
277 tree_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
278 {
279   tree tmp1, stmt1, stmt2, stmt3;
280   tree stmt = value->hvalue.stmt;
281   block_stmt_iterator bsi = bsi_for_stmt (stmt);
282   tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
283
284   ref_ptr = force_gimple_operand_bsi (&bsi,
285                                       build_addr (ref, current_function_decl),
286                                       true, NULL_TREE);
287
288   /* Insert code:
289     
290     __gcov_indirect_call_counters = get_relevant_counter_ptr (); 
291     __gcov_indirect_call_callee = (void *) indirect call argument;
292    */
293
294   tmp1 = create_tmp_var (ptr_void, "PROF");
295   stmt1 = build2 (GIMPLE_MODIFY_STMT, 
296                   build_pointer_type (get_gcov_type ()), 
297                   ic_gcov_type_ptr_var, ref_ptr);
298   stmt2 = build2 (GIMPLE_MODIFY_STMT, ptr_void, tmp1, 
299                   unshare_expr (value->hvalue.value));
300   stmt3 = build2 (GIMPLE_MODIFY_STMT, ptr_void, 
301                   ic_void_ptr_var, tmp1);
302
303   bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
304   bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
305   bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT);
306 }
307
308
309 /* Output instructions as GIMPLE trees for code to find the most
310    common called function in indirect call. Insert instructions at the
311    beginning of every possible called function.
312   */
313
314 static void
315 tree_gen_ic_func_profiler (void)
316 {
317   struct cgraph_node * c_node = cgraph_node (current_function_decl);
318   block_stmt_iterator bsi;
319   edge e;
320   basic_block bb;
321   edge_iterator ei;
322   tree stmt1;
323   tree args, tree_uid, cur_func;
324
325   if (flag_unit_at_a_time)
326     {
327       if (!c_node->needed)
328         return;
329     }
330   
331   tree_init_edge_profiler ();
332   
333   FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
334     {
335       bb = split_edge (e);
336       bsi = bsi_start (bb);
337       cur_func = force_gimple_operand_bsi (&bsi,
338                                            build_addr (current_function_decl, 
339                                                        current_function_decl),
340                                            true, NULL_TREE);
341       tree_uid = build_int_cst (gcov_type_node, c_node->pid);
342       args = tree_cons (NULL_TREE, ic_gcov_type_ptr_var,
343                         tree_cons (NULL_TREE, tree_uid,
344                                    tree_cons (NULL_TREE, cur_func,
345                                               tree_cons (NULL_TREE, 
346                                                          ic_void_ptr_var,
347                                                          NULL_TREE))));
348       stmt1 = build_function_call_expr (tree_indirect_call_profiler_fn, args);
349       bsi_insert_after (&bsi, stmt1, BSI_SAME_STMT);
350     }
351 }
352
353 /* Output instructions as GIMPLE trees for code to find the most common value 
354    of a difference between two evaluations of an expression.
355    VALUE is the expression whose value is profiled.  TAG is the tag of the
356    section for counters, BASE is offset of the counter position.  */
357
358 static void
359 tree_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED, 
360                                 unsigned tag ATTRIBUTE_UNUSED,
361                                 unsigned base ATTRIBUTE_UNUSED)
362 {
363   /* FIXME implement this.  */
364 #ifdef ENABLE_CHECKING
365   internal_error ("unimplemented functionality");
366 #endif
367   gcc_unreachable ();
368 }
369
370 /* Output instructions as GIMPLE trees to increment the average histogram 
371    counter.  VALUE is the expression whose value is profiled.  TAG is the 
372    tag of the section for counters, BASE is offset of the counter position.  */
373
374 static void
375 tree_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
376 {
377   tree stmt = value->hvalue.stmt;
378   block_stmt_iterator bsi = bsi_for_stmt (stmt);
379   tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
380   tree args, call, val;
381   
382   ref_ptr = force_gimple_operand_bsi (&bsi,
383                                       build_addr (ref, current_function_decl),
384                                       true, NULL_TREE);
385   val = prepare_instrumented_value (&bsi, value);
386   args = tree_cons (NULL_TREE, ref_ptr, tree_cons (NULL_TREE, val, NULL_TREE));
387   call = build_function_call_expr (tree_average_profiler_fn, args);
388   bsi_insert_before (&bsi, call, BSI_SAME_STMT);
389 }
390
391 /* Output instructions as GIMPLE trees to increment the ior histogram 
392    counter.  VALUE is the expression whose value is profiled.  TAG is the 
393    tag of the section for counters, BASE is offset of the counter position.  */
394
395 static void
396 tree_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
397 {
398   tree stmt = value->hvalue.stmt;
399   block_stmt_iterator bsi = bsi_for_stmt (stmt);
400   tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
401   tree args, call, val;
402   
403   ref_ptr = force_gimple_operand_bsi (&bsi,
404                                       build_addr (ref, current_function_decl),
405                                       true, NULL_TREE);
406   val = prepare_instrumented_value (&bsi, value);
407   args = tree_cons (NULL_TREE, ref_ptr, tree_cons (NULL_TREE, val, NULL_TREE));
408   call = build_function_call_expr (tree_ior_profiler_fn, args);
409   bsi_insert_before (&bsi, call, BSI_SAME_STMT);
410 }
411
412 /* Return 1 if tree-based profiling is in effect, else 0.
413    If it is, set up hooks for tree-based profiling.
414    Gate for pass_tree_profile.  */
415
416 static bool
417 do_tree_profiling (void)
418 {
419   if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
420     {
421       tree_register_profile_hooks ();
422       tree_register_value_prof_hooks ();
423       return true;
424     }
425   return false;
426 }
427
428 static unsigned int
429 tree_profiling (void)
430 {
431   /* Don't profile functions produced at destruction time, particularly
432      the gcov datastructure initializer.  */
433   if (cgraph_state == CGRAPH_STATE_FINISHED)
434     return 0;
435   branch_prob ();
436
437   if (! flag_branch_probabilities 
438       && flag_profile_values)
439     tree_gen_ic_func_profiler ();
440
441   if (flag_branch_probabilities
442       && flag_profile_values
443       && flag_value_profile_transformations)
444     value_profile_transformations ();
445   /* The above could hose dominator info.  Currently there is
446      none coming in, this is a safety valve.  It should be
447      easy to adjust it, if and when there is some.  */
448   free_dominance_info (CDI_DOMINATORS);
449   free_dominance_info (CDI_POST_DOMINATORS);
450   return 0;
451 }
452
453 struct tree_opt_pass pass_tree_profile = 
454 {
455   "tree_profile",                       /* name */
456   do_tree_profiling,                    /* gate */
457   tree_profiling,                       /* execute */
458   NULL,                                 /* sub */
459   NULL,                                 /* next */
460   0,                                    /* static_pass_number */
461   TV_BRANCH_PROB,                       /* tv_id */
462   PROP_gimple_leh | PROP_cfg,           /* properties_required */
463   PROP_gimple_leh | PROP_cfg,           /* properties_provided */
464   0,                                    /* properties_destroyed */
465   0,                                    /* todo_flags_start */
466   TODO_verify_stmts | TODO_dump_func,   /* todo_flags_finish */
467   0                                     /* letter */
468 };
469
470 struct profile_hooks tree_profile_hooks =
471 {
472   tree_init_edge_profiler,       /* init_edge_profiler */
473   tree_gen_edge_profiler,        /* gen_edge_profiler */
474   tree_gen_interval_profiler,    /* gen_interval_profiler */
475   tree_gen_pow2_profiler,        /* gen_pow2_profiler */
476   tree_gen_one_value_profiler,   /* gen_one_value_profiler */
477   tree_gen_const_delta_profiler, /* gen_const_delta_profiler */
478   tree_gen_ic_profiler,          /* gen_ic_profiler */
479   tree_gen_average_profiler,     /* gen_average_profiler */
480   tree_gen_ior_profiler          /* gen_ior_profiler */
481 };
482
483 #include "gt-tree-profile.h"