OSDN Git Service

PR target/5362
[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, 2006, 2007, 2008
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.
9
10 This file is part of GCC.
11
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 3, or (at your option) any later
15 version.
16
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.
21
22 You should have received a copy of the GNU General Public License
23 along with GCC; see the file COPYING3.  If not see
24 <http://www.gnu.org/licenses/>.  */
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 gcov_type_tmp_var;
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;
58 \f
59
60 static GTY(()) tree ic_void_ptr_var;
61 static GTY(()) tree ic_gcov_type_ptr_var;
62 static GTY(()) tree ptr_void;
63
64 /* Do initialization work for the edge profiler.  */
65
66 /* Add code:
67    static gcov* __gcov_indirect_call_counters; // pointer to actual counter
68    static void* __gcov_indirect_call_callee; // actual callee address
69 */
70 static void
71 tree_init_ic_make_global_vars (void)
72 {
73   tree  gcov_type_ptr;
74
75   ptr_void = build_pointer_type (void_type_node);
76   
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);
86
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);
97 }
98
99 static void
100 tree_init_edge_profiler (void)
101 {
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;
108
109   if (!gcov_type_node)
110     {
111       gcov_type_node = get_gcov_type ();
112       gcov_type_ptr = build_pointer_type (gcov_type_node);
113
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);
123
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);
131
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);
140
141       tree_init_ic_make_global_vars ();
142       
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);
162     }
163 }
164
165 /* New call was added, make goto call edges if neccesary.  */
166
167 static void
168 add_abnormal_goto_call_edges (gimple_stmt_iterator gsi)
169 {
170   gimple stmt = gsi_stmt (gsi);
171
172   if (!stmt_can_make_abnormal_goto (stmt))
173     return;
174   if (!gsi_end_p (gsi))
175     split_block (gimple_bb (stmt), stmt);
176   make_abnormal_goto_edges (gimple_bb (stmt), true);
177 }
178
179 /* Output instructions as GIMPLE trees to increment the edge 
180    execution count, and insert them on E.  We rely on 
181    gsi_insert_on_edge to preserve the order.  */
182
183 static void
184 tree_gen_edge_profiler (int edgeno, edge e)
185 {
186   tree ref, one;
187   gimple stmt1, stmt2, stmt3;
188
189   /* We share one temporary variable declaration per function.  This
190      gets re-set in tree_profiling.  */
191   if (gcov_type_tmp_var == NULL_TREE)
192     gcov_type_tmp_var = create_tmp_var (gcov_type_node, "PROF_edge_counter");
193   ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
194   one = build_int_cst (gcov_type_node, 1);
195   stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
196   stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, gcov_type_tmp_var,
197                                         gcov_type_tmp_var, one);
198   stmt3 = gimple_build_assign (unshare_expr (ref), gcov_type_tmp_var);
199   gsi_insert_on_edge (e, stmt1);
200   gsi_insert_on_edge (e, stmt2);
201   gsi_insert_on_edge (e, stmt3);
202 }
203
204 /* Emits code to get VALUE to instrument at GSI, and returns the
205    variable containing the value.  */
206
207 static tree
208 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
209 {
210   tree val = value->hvalue.value;
211   return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
212                                    true, NULL_TREE, true, GSI_SAME_STMT);
213 }
214
215 /* Output instructions as GIMPLE trees to increment the interval histogram 
216    counter.  VALUE is the expression whose value is profiled.  TAG is the 
217    tag of the section for counters, BASE is offset of the counter position.  */
218
219 static void
220 tree_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
221 {
222   gimple stmt = value->hvalue.stmt;
223   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
224   tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
225   gimple call;
226   tree val;
227   tree start = build_int_cst_type (integer_type_node,
228                                    value->hdata.intvl.int_start);
229   tree steps = build_int_cst_type (unsigned_type_node,
230                                    value->hdata.intvl.steps);
231   
232   ref_ptr = force_gimple_operand_gsi (&gsi,
233                                       build_addr (ref, current_function_decl),
234                                       true, NULL_TREE, true, GSI_SAME_STMT);
235   val = prepare_instrumented_value (&gsi, value);
236   call = gimple_build_call (tree_interval_profiler_fn, 4,
237                             ref_ptr, val, start, steps);
238   gsi_insert_before (&gsi, call, GSI_NEW_STMT);
239   add_abnormal_goto_call_edges (gsi);
240 }
241
242 /* Output instructions as GIMPLE trees to increment the power of two histogram 
243    counter.  VALUE is the expression whose value is profiled.  TAG is the tag 
244    of the section for counters, BASE is offset of the counter position.  */
245
246 static void
247 tree_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
248 {
249   gimple stmt = value->hvalue.stmt;
250   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
251   tree ref_ptr = tree_coverage_counter_addr (tag, base);
252   gimple call;
253   tree val;
254   
255   ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
256                                       true, NULL_TREE, true, GSI_SAME_STMT);
257   val = prepare_instrumented_value (&gsi, value);
258   call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val);
259   gsi_insert_before (&gsi, call, GSI_NEW_STMT);
260   add_abnormal_goto_call_edges (gsi);
261 }
262
263 /* Output instructions as GIMPLE trees for code to find the most common value.
264    VALUE is the expression whose value is profiled.  TAG is the tag of the
265    section for counters, BASE is offset of the counter position.  */
266
267 static void
268 tree_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
269 {
270   gimple stmt = value->hvalue.stmt;
271   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
272   tree ref_ptr = tree_coverage_counter_addr (tag, base);
273   gimple call;
274   tree val;
275   
276   ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
277                                       true, NULL_TREE, true, GSI_SAME_STMT);
278   val = prepare_instrumented_value (&gsi, value);
279   call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val);
280   gsi_insert_before (&gsi, call, GSI_NEW_STMT);
281   add_abnormal_goto_call_edges (gsi);
282 }
283
284
285 /* Output instructions as GIMPLE trees for code to find the most
286    common called function in indirect call.  
287    VALUE is the call expression whose indirect callee is profiled.
288    TAG is the tag of the section for counters, BASE is offset of the
289    counter position.  */
290
291 static void
292 tree_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
293 {
294   tree tmp1;
295   gimple stmt1, stmt2, stmt3;
296   gimple stmt = value->hvalue.stmt;
297   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
298   tree ref_ptr = tree_coverage_counter_addr (tag, base);
299
300   ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
301                                       true, NULL_TREE, true, GSI_SAME_STMT);
302
303   /* Insert code:
304     
305     __gcov_indirect_call_counters = get_relevant_counter_ptr (); 
306     __gcov_indirect_call_callee = (void *) indirect call argument;
307    */
308
309   tmp1 = create_tmp_var (ptr_void, "PROF");
310   stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr);
311   stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
312   stmt3 = gimple_build_assign (ic_void_ptr_var, tmp1);
313
314   gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
315   gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
316   gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
317 }
318
319
320 /* Output instructions as GIMPLE trees for code to find the most
321    common called function in indirect call. Insert instructions at the
322    beginning of every possible called function.
323   */
324
325 static void
326 tree_gen_ic_func_profiler (void)
327 {
328   struct cgraph_node * c_node = cgraph_node (current_function_decl);
329   gimple_stmt_iterator gsi;
330   edge e;
331   basic_block bb;
332   edge_iterator ei;
333   gimple stmt1, stmt2;
334   tree tree_uid, cur_func;
335
336   if (!c_node->needed)
337     return;
338   
339   tree_init_edge_profiler ();
340   
341   FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
342     {
343       tree void0;
344
345       bb = split_edge (e);
346       gsi = gsi_start_bb (bb);
347
348       cur_func = force_gimple_operand_gsi (&gsi,
349                                            build_addr (current_function_decl, 
350                                                        current_function_decl),
351                                            true, NULL_TREE,
352                                            true, GSI_SAME_STMT);
353       tree_uid = build_int_cst (gcov_type_node, c_node->pid);
354       stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 4,
355                                  ic_gcov_type_ptr_var,
356                                  tree_uid,
357                                  cur_func,
358                                  ic_void_ptr_var);
359       gsi_insert_after (&gsi, stmt1, GSI_NEW_STMT);
360       gcc_assert (EDGE_COUNT (bb->succs) == 1);
361       bb = split_edge (EDGE_I (bb->succs, 0));
362       add_abnormal_goto_call_edges (gsi);
363
364       gsi = gsi_start_bb (bb);
365       /* Set __gcov_indirect_call_callee to 0,
366          so that calls from other modules won't get misattributed
367          to the last caller of the current callee. */
368       void0 = build_int_cst (build_pointer_type (void_type_node), 0);
369       stmt2 = gimple_build_assign (ic_void_ptr_var, void0);
370       gsi_insert_after (&gsi, stmt2, GSI_NEW_STMT);
371     }
372 }
373
374 /* Output instructions as GIMPLE trees for code to find the most common value 
375    of a difference between two evaluations of an expression.
376    VALUE is the expression whose value is profiled.  TAG is the tag of the
377    section for counters, BASE is offset of the counter position.  */
378
379 static void
380 tree_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
381                                unsigned tag ATTRIBUTE_UNUSED,
382                                unsigned base ATTRIBUTE_UNUSED)
383 {
384   /* FIXME implement this.  */
385 #ifdef ENABLE_CHECKING
386   internal_error ("unimplemented functionality");
387 #endif
388   gcc_unreachable ();
389 }
390
391 /* Output instructions as GIMPLE trees to increment the average 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_average_profiler (histogram_value value, unsigned tag, unsigned base)
397 {
398   gimple stmt = value->hvalue.stmt;
399   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
400   tree ref_ptr = tree_coverage_counter_addr (tag, base);
401   gimple call;
402   tree val;
403   
404   ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
405                                       true, NULL_TREE,
406                                       true, GSI_SAME_STMT);
407   val = prepare_instrumented_value (&gsi, value);
408   call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
409   gsi_insert_before (&gsi, call, GSI_NEW_STMT);
410   add_abnormal_goto_call_edges (gsi);
411 }
412
413 /* Output instructions as GIMPLE trees to increment the ior histogram 
414    counter.  VALUE is the expression whose value is profiled.  TAG is the 
415    tag of the section for counters, BASE is offset of the counter position.  */
416
417 static void
418 tree_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
419 {
420   gimple stmt = value->hvalue.stmt;
421   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
422   tree ref_ptr = tree_coverage_counter_addr (tag, base);
423   gimple call;
424   tree val;
425   
426   ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
427                                       true, NULL_TREE, true, GSI_SAME_STMT);
428   val = prepare_instrumented_value (&gsi, value);
429   call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
430   gsi_insert_before (&gsi, call, GSI_NEW_STMT);
431   add_abnormal_goto_call_edges (gsi);
432 }
433
434 /* Return 1 if tree-based profiling is in effect, else 0.
435    If it is, set up hooks for tree-based profiling.
436    Gate for pass_tree_profile.  */
437
438 static bool
439 do_tree_profiling (void)
440 {
441   if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
442     {
443       tree_register_profile_hooks ();
444       gimple_register_value_prof_hooks ();
445       return true;
446     }
447   return false;
448 }
449
450 static unsigned int
451 tree_profiling (void)
452 {
453   /* Don't profile functions produced at destruction time, particularly
454      the gcov datastructure initializer.  Don't profile if it has been
455      already instrumented either (when OpenMP expansion creates
456      child function from already instrumented body).  */
457   if (cgraph_state == CGRAPH_STATE_FINISHED
458       || cfun->after_tree_profile)
459     return 0;
460
461   /* Re-set global shared temporary variable for edge-counters.  */
462   gcov_type_tmp_var = NULL_TREE;
463
464   branch_prob ();
465
466   if (! flag_branch_probabilities 
467       && flag_profile_values)
468     tree_gen_ic_func_profiler ();
469
470   if (flag_branch_probabilities
471       && flag_profile_values
472       && flag_value_profile_transformations)
473     value_profile_transformations ();
474   /* The above could hose dominator info.  Currently there is
475      none coming in, this is a safety valve.  It should be
476      easy to adjust it, if and when there is some.  */
477   free_dominance_info (CDI_DOMINATORS);
478   free_dominance_info (CDI_POST_DOMINATORS);
479   cfun->after_tree_profile = 1;
480   return 0;
481 }
482
483 struct gimple_opt_pass pass_tree_profile = 
484 {
485  {
486   GIMPLE_PASS,
487   "tree_profile",                       /* name */
488   do_tree_profiling,                    /* gate */
489   tree_profiling,                       /* execute */
490   NULL,                                 /* sub */
491   NULL,                                 /* next */
492   0,                                    /* static_pass_number */
493   TV_BRANCH_PROB,                       /* tv_id */
494   PROP_gimple_leh | PROP_cfg,           /* properties_required */
495   PROP_gimple_leh | PROP_cfg,           /* properties_provided */
496   0,                                    /* properties_destroyed */
497   0,                                    /* todo_flags_start */
498   TODO_verify_stmts | TODO_dump_func    /* todo_flags_finish */
499  }
500 };
501
502 struct profile_hooks tree_profile_hooks =
503 {
504   tree_init_edge_profiler,       /* init_edge_profiler */
505   tree_gen_edge_profiler,        /* gen_edge_profiler */
506   tree_gen_interval_profiler,    /* gen_interval_profiler */
507   tree_gen_pow2_profiler,        /* gen_pow2_profiler */
508   tree_gen_one_value_profiler,   /* gen_one_value_profiler */
509   tree_gen_const_delta_profiler, /* gen_const_delta_profiler */
510   tree_gen_ic_profiler,          /* gen_ic_profiler */
511   tree_gen_average_profiler,     /* gen_average_profiler */
512   tree_gen_ior_profiler          /* gen_ior_profiler */
513 };
514
515 #include "gt-tree-profile.h"