OSDN Git Service

* tree-scalar-evolution.c (scev_const_prop): Add arguments to
[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
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 2, 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 COPYING.  If not, write to the Free
24 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
25 02110-1301, USA.  */
26
27 /* Generate basic block profile instrumentation and auxiliary files.
28    Tree-based version.  See profile.c for overview.  */
29
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"
50
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;
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 addres
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 /* 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.  */
168
169 static void
170 tree_gen_edge_profiler (int edgeno, edge e)
171 {
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);
184 }
185
186 /* Emits code to get VALUE to instrument at BSI, and returns the
187    variable containing the value.  */
188
189 static tree
190 prepare_instrumented_value (block_stmt_iterator *bsi,
191                             histogram_value value)
192 {
193   tree val = value->hvalue.value;
194   return force_gimple_operand_bsi (bsi, fold_convert (gcov_type_node, val),
195                                    true, NULL_TREE, true, BSI_SAME_STMT);
196 }
197
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.  */
201
202 static void
203 tree_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
204 {
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);
211   
212   ref_ptr = force_gimple_operand_bsi (&bsi,
213                                       build_addr (ref, current_function_decl),
214                                       true, NULL_TREE, true, BSI_SAME_STMT);
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);
219 }
220
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.  */
224
225 static void
226 tree_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
227 {
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;
232   
233   ref_ptr = force_gimple_operand_bsi (&bsi,
234                                       build_addr (ref, current_function_decl),
235                                       true, NULL_TREE, true, BSI_SAME_STMT);
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);
239 }
240
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.  */
244
245 static void
246 tree_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
247 {
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;
252   
253   ref_ptr = force_gimple_operand_bsi (&bsi,
254                                       build_addr (ref, current_function_decl),
255                                       true, NULL_TREE, true, BSI_SAME_STMT);
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);
259 }
260
261
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.  */
267
268 static void
269 tree_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
270 {
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;
275
276   ref_ptr = force_gimple_operand_bsi (&bsi,
277                                       build_addr (ref, current_function_decl),
278                                       true, NULL_TREE, true, BSI_SAME_STMT);
279
280   /* Insert code:
281     
282     __gcov_indirect_call_counters = get_relevant_counter_ptr (); 
283     __gcov_indirect_call_callee = (void *) indirect call argument;
284    */
285
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);
290
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);
294 }
295
296
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.
300   */
301
302 static void
303 tree_gen_ic_func_profiler (void)
304 {
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;
312
313   if (flag_unit_at_a_time)
314     {
315       if (!c_node->needed)
316         return;
317     }
318   
319   tree_init_edge_profiler ();
320   
321   FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
322     {
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                                            true, BSI_SAME_STMT);
330       tree_uid = build_int_cst (gcov_type_node, c_node->pid);
331       stmt1 = build_call_expr (tree_indirect_call_profiler_fn, 4,
332                                ic_gcov_type_ptr_var,
333                                tree_uid,
334                                cur_func,
335                                ic_void_ptr_var);
336       bsi_insert_after (&bsi, stmt1, BSI_NEW_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 /* Output instructions as GIMPLE trees to increment the average histogram 
358    counter.  VALUE is the expression whose value is profiled.  TAG is the 
359    tag of the section for counters, BASE is offset of the counter position.  */
360
361 static void
362 tree_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
363 {
364   tree stmt = value->hvalue.stmt;
365   block_stmt_iterator bsi = bsi_for_stmt (stmt);
366   tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
367   tree call, val;
368   
369   ref_ptr = force_gimple_operand_bsi (&bsi,
370                                       build_addr (ref, current_function_decl),
371                                       true, NULL_TREE,
372                                       true, BSI_SAME_STMT);
373   val = prepare_instrumented_value (&bsi, value);
374   call = build_call_expr (tree_average_profiler_fn, 2, ref_ptr, val);
375   bsi_insert_before (&bsi, call, BSI_SAME_STMT);
376 }
377
378 /* Output instructions as GIMPLE trees to increment the ior histogram 
379    counter.  VALUE is the expression whose value is profiled.  TAG is the 
380    tag of the section for counters, BASE is offset of the counter position.  */
381
382 static void
383 tree_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
384 {
385   tree stmt = value->hvalue.stmt;
386   block_stmt_iterator bsi = bsi_for_stmt (stmt);
387   tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
388   tree call, val;
389   
390   ref_ptr = force_gimple_operand_bsi (&bsi,
391                                       build_addr (ref, current_function_decl),
392                                       true, NULL_TREE, true, BSI_SAME_STMT);
393   val = prepare_instrumented_value (&bsi, value);
394   call = build_call_expr (tree_ior_profiler_fn, 2, ref_ptr, val);
395   bsi_insert_before (&bsi, call, BSI_SAME_STMT);
396 }
397
398 /* Return 1 if tree-based profiling is in effect, else 0.
399    If it is, set up hooks for tree-based profiling.
400    Gate for pass_tree_profile.  */
401
402 static bool
403 do_tree_profiling (void)
404 {
405   if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
406     {
407       tree_register_profile_hooks ();
408       tree_register_value_prof_hooks ();
409       return true;
410     }
411   return false;
412 }
413
414 static unsigned int
415 tree_profiling (void)
416 {
417   /* Don't profile functions produced at destruction time, particularly
418      the gcov datastructure initializer.  */
419   if (cgraph_state == CGRAPH_STATE_FINISHED)
420     return 0;
421   branch_prob ();
422
423   if (! flag_branch_probabilities 
424       && flag_profile_values)
425     tree_gen_ic_func_profiler ();
426
427   if (flag_branch_probabilities
428       && flag_profile_values
429       && flag_value_profile_transformations)
430     value_profile_transformations ();
431   /* The above could hose dominator info.  Currently there is
432      none coming in, this is a safety valve.  It should be
433      easy to adjust it, if and when there is some.  */
434   free_dominance_info (CDI_DOMINATORS);
435   free_dominance_info (CDI_POST_DOMINATORS);
436   return 0;
437 }
438
439 struct tree_opt_pass pass_tree_profile = 
440 {
441   "tree_profile",                       /* name */
442   do_tree_profiling,                    /* gate */
443   tree_profiling,                       /* execute */
444   NULL,                                 /* sub */
445   NULL,                                 /* next */
446   0,                                    /* static_pass_number */
447   TV_BRANCH_PROB,                       /* tv_id */
448   PROP_gimple_leh | PROP_cfg,           /* properties_required */
449   PROP_gimple_leh | PROP_cfg,           /* properties_provided */
450   0,                                    /* properties_destroyed */
451   0,                                    /* todo_flags_start */
452   TODO_verify_stmts | TODO_dump_func,   /* todo_flags_finish */
453   0                                     /* letter */
454 };
455
456 struct profile_hooks tree_profile_hooks =
457 {
458   tree_init_edge_profiler,       /* init_edge_profiler */
459   tree_gen_edge_profiler,        /* gen_edge_profiler */
460   tree_gen_interval_profiler,    /* gen_interval_profiler */
461   tree_gen_pow2_profiler,        /* gen_pow2_profiler */
462   tree_gen_one_value_profiler,   /* gen_one_value_profiler */
463   tree_gen_const_delta_profiler, /* gen_const_delta_profiler */
464   tree_gen_ic_profiler,          /* gen_ic_profiler */
465   tree_gen_average_profiler,     /* gen_average_profiler */
466   tree_gen_ior_profiler          /* gen_ior_profiler */
467 };
468
469 #include "gt-tree-profile.h"