]> gcc.gnu.org Git - gcc.git/blame - gcc/tree-profile.c
cgraph.c (cgraph_insert_node_to_hashtable): New function.
[gcc.git] / gcc / tree-profile.c
CommitLineData
6de9cd9a
DN
1/* Calculate branch probabilities, and basic block execution counts.
2 Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999,
5f996627 3 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
6de9cd9a
DN
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
9This file is part of GCC.
10
11GCC is free software; you can redistribute it and/or modify it under
12the terms of the GNU General Public License as published by the Free
13Software Foundation; either version 2, or (at your option) any later
14version.
15
16GCC is distributed in the hope that it will be useful, but WITHOUT ANY
17WARRANTY; without even the implied warranty of MERCHANTABILITY or
18FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19for more details.
20
21You should have received a copy of the GNU General Public License
22along with GCC; see the file COPYING. If not, write to the Free
366ccddb
KC
23Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2402110-1301, USA. */
6de9cd9a
DN
25
26/* Generate basic block profile instrumentation and auxiliary files.
1f1e8527 27 Tree-based version. See profile.c for overview. */
6de9cd9a
DN
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"
9885da8e 47#include "ggc.h"
6de9cd9a 48
9885da8e
ZD
49static GTY(()) tree gcov_type_node;
50static GTY(()) tree tree_interval_profiler_fn;
51static GTY(()) tree tree_pow2_profiler_fn;
52static GTY(()) tree tree_one_value_profiler_fn;
6de9cd9a 53\f
f3df9541
AK
54
55/* Do initialization work for the edge profiler. */
56
57static void
58tree_init_edge_profiler (void)
59{
9885da8e
ZD
60 tree interval_profiler_fn_type;
61 tree pow2_profiler_fn_type;
62 tree one_value_profiler_fn_type;
63 tree gcov_type_ptr;
64
65 if (!gcov_type_node)
66 {
67 gcov_type_node = get_gcov_type ();
68 gcov_type_ptr = build_pointer_type (gcov_type_node);
69
70 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
71 interval_profiler_fn_type
72 = build_function_type_list (void_type_node,
73 gcov_type_ptr, gcov_type_node,
74 integer_type_node,
75 unsigned_type_node, NULL_TREE);
76 tree_interval_profiler_fn
77 = build_fn_decl ("__gcov_interval_profiler",
78 interval_profiler_fn_type);
79
80 /* void (*) (gcov_type *, gcov_type) */
81 pow2_profiler_fn_type
82 = build_function_type_list (void_type_node,
83 gcov_type_ptr, gcov_type_node,
84 NULL_TREE);
85 tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler",
86 pow2_profiler_fn_type);
87
88 /* void (*) (gcov_type *, gcov_type) */
89 one_value_profiler_fn_type
90 = build_function_type_list (void_type_node,
91 gcov_type_ptr, gcov_type_node,
92 NULL_TREE);
93 tree_one_value_profiler_fn
94 = build_fn_decl ("__gcov_one_value_profiler",
95 one_value_profiler_fn_type);
96 }
f3df9541
AK
97}
98
6de9cd9a
DN
99/* Output instructions as GIMPLE trees to increment the edge
100 execution count, and insert them on E. We rely on
101 bsi_insert_on_edge to preserve the order. */
102
103static void
104tree_gen_edge_profiler (int edgeno, edge e)
105{
070e3969
RS
106 tree tmp1 = create_tmp_var (gcov_type_node, "PROF");
107 tree tmp2 = create_tmp_var (gcov_type_node, "PROF");
6de9cd9a 108 tree ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
b4257cfc
RG
109 tree stmt1 = build2 (MODIFY_EXPR, gcov_type_node, tmp1, ref);
110 tree stmt2 = build2 (MODIFY_EXPR, gcov_type_node, tmp2,
111 build2 (PLUS_EXPR, gcov_type_node,
112 tmp1, integer_one_node));
113 tree stmt3 = build2 (MODIFY_EXPR, gcov_type_node, ref, tmp2);
6de9cd9a
DN
114 bsi_insert_on_edge (e, stmt1);
115 bsi_insert_on_edge (e, stmt2);
116 bsi_insert_on_edge (e, stmt3);
117}
118
9885da8e
ZD
119/* Emits code to get VALUE to instrument at BSI, and returns the
120 variable containing the value. */
121
122static tree
123prepare_instrumented_value (block_stmt_iterator *bsi,
124 histogram_value value)
125{
8a76829c 126 tree val = value->hvalue.value;
9885da8e
ZD
127 return force_gimple_operand_bsi (bsi, fold_convert (gcov_type_node, val),
128 true, NULL_TREE);
129}
130
6de9cd9a
DN
131/* Output instructions as GIMPLE trees to increment the interval histogram
132 counter. VALUE is the expression whose value is profiled. TAG is the
133 tag of the section for counters, BASE is offset of the counter position. */
134
135static void
1f1e8527 136tree_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
6de9cd9a 137{
8a76829c 138 tree stmt = value->hvalue.stmt;
1f1e8527 139 block_stmt_iterator bsi = bsi_for_stmt (stmt);
9885da8e
ZD
140 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
141 tree args, call, val;
142 tree start = build_int_cst_type (integer_type_node, value->hdata.intvl.int_start);
143 tree steps = build_int_cst_type (unsigned_type_node, value->hdata.intvl.steps);
144
145 ref_ptr = force_gimple_operand_bsi (&bsi,
bde6c65d 146 build_addr (ref, current_function_decl),
9885da8e
ZD
147 true, NULL_TREE);
148 val = prepare_instrumented_value (&bsi, value);
149 args = tree_cons (NULL_TREE, ref_ptr,
150 tree_cons (NULL_TREE, val,
151 tree_cons (NULL_TREE, start,
152 tree_cons (NULL_TREE, steps,
153 NULL_TREE))));
154 call = build_function_call_expr (tree_interval_profiler_fn, args);
155 bsi_insert_before (&bsi, call, BSI_SAME_STMT);
6de9cd9a
DN
156}
157
158/* Output instructions as GIMPLE trees to increment the power of two histogram
159 counter. VALUE is the expression whose value is profiled. TAG is the tag
160 of the section for counters, BASE is offset of the counter position. */
161
162static void
1f1e8527 163tree_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
6de9cd9a 164{
8a76829c 165 tree stmt = value->hvalue.stmt;
1f1e8527 166 block_stmt_iterator bsi = bsi_for_stmt (stmt);
9885da8e
ZD
167 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
168 tree args, call, val;
169
170 ref_ptr = force_gimple_operand_bsi (&bsi,
bde6c65d 171 build_addr (ref, current_function_decl),
9885da8e
ZD
172 true, NULL_TREE);
173 val = prepare_instrumented_value (&bsi, value);
174 args = tree_cons (NULL_TREE, ref_ptr,
175 tree_cons (NULL_TREE, val,
176 NULL_TREE));
177 call = build_function_call_expr (tree_pow2_profiler_fn, args);
178 bsi_insert_before (&bsi, call, BSI_SAME_STMT);
6de9cd9a
DN
179}
180
181/* Output instructions as GIMPLE trees for code to find the most common value.
182 VALUE is the expression whose value is profiled. TAG is the tag of the
183 section for counters, BASE is offset of the counter position. */
184
185static void
1f1e8527 186tree_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
6de9cd9a 187{
8a76829c 188 tree stmt = value->hvalue.stmt;
1f1e8527 189 block_stmt_iterator bsi = bsi_for_stmt (stmt);
9885da8e
ZD
190 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
191 tree args, call, val;
192
193 ref_ptr = force_gimple_operand_bsi (&bsi,
bde6c65d 194 build_addr (ref, current_function_decl),
9885da8e
ZD
195 true, NULL_TREE);
196 val = prepare_instrumented_value (&bsi, value);
197 args = tree_cons (NULL_TREE, ref_ptr,
198 tree_cons (NULL_TREE, val,
199 NULL_TREE));
200 call = build_function_call_expr (tree_one_value_profiler_fn, args);
201 bsi_insert_before (&bsi, call, BSI_SAME_STMT);
6de9cd9a
DN
202}
203
204/* Output instructions as GIMPLE trees for code to find the most common value
205 of a difference between two evaluations of an expression.
206 VALUE is the expression whose value is profiled. TAG is the tag of the
207 section for counters, BASE is offset of the counter position. */
208
209static void
6d9901e7 210tree_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
6de9cd9a
DN
211 unsigned tag ATTRIBUTE_UNUSED,
212 unsigned base ATTRIBUTE_UNUSED)
213{
214 /* FIXME implement this. */
1e128c5f
GB
215#ifdef ENABLE_CHECKING
216 internal_error ("unimplemented functionality");
217#endif
218 gcc_unreachable ();
6de9cd9a
DN
219}
220
221/* Return 1 if tree-based profiling is in effect, else 0.
222 If it is, set up hooks for tree-based profiling.
223 Gate for pass_tree_profile. */
224
1f1e8527
DJ
225static bool
226do_tree_profiling (void)
878f99d2 227{
8a76829c 228 if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
6de9cd9a
DN
229 {
230 tree_register_profile_hooks ();
231 tree_register_value_prof_hooks ();
bbd236a1 232 return true;
6de9cd9a 233 }
bbd236a1 234 return false;
6de9cd9a
DN
235}
236
237/* Return the file on which profile dump output goes, if any. */
238
239static FILE *tree_profile_dump_file (void) {
240 return dump_file;
241}
242
1f1e8527
DJ
243static void
244tree_profiling (void)
245{
246 branch_prob ();
247 if (flag_branch_probabilities
248 && flag_profile_values
249 && flag_value_profile_transformations)
250 value_profile_transformations ();
251 /* The above could hose dominator info. Currently there is
252 none coming in, this is a safety valve. It should be
253 easy to adjust it, if and when there is some. */
254 free_dominance_info (CDI_DOMINATORS);
255 free_dominance_info (CDI_POST_DOMINATORS);
256}
257
6de9cd9a
DN
258struct tree_opt_pass pass_tree_profile =
259{
260 "tree_profile", /* name */
261 do_tree_profiling, /* gate */
1f1e8527 262 tree_profiling, /* execute */
6de9cd9a
DN
263 NULL, /* sub */
264 NULL, /* next */
265 0, /* static_pass_number */
266 TV_BRANCH_PROB, /* tv_id */
267 PROP_gimple_leh | PROP_cfg, /* properties_required */
268 PROP_gimple_leh | PROP_cfg, /* properties_provided */
269 0, /* properties_destroyed */
270 0, /* todo_flags_start */
9f8628ba
PB
271 TODO_verify_stmts, /* todo_flags_finish */
272 0 /* letter */
6de9cd9a
DN
273};
274
d63db217
JH
275/* Return 1 if tree-based profiling is in effect, else 0.
276 If it is, set up hooks for tree-based profiling.
277 Gate for pass_tree_profile. */
278
279static bool
280do_early_tree_profiling (void)
281{
282 return (do_tree_profiling () && (!flag_unit_at_a_time || !optimize));
283}
284
285struct tree_opt_pass pass_early_tree_profile =
286{
287 "early_tree_profile", /* name */
288 do_early_tree_profiling, /* gate */
289 tree_profiling, /* execute */
290 NULL, /* sub */
291 NULL, /* next */
292 0, /* static_pass_number */
293 TV_BRANCH_PROB, /* tv_id */
294 PROP_gimple_leh | PROP_cfg, /* properties_required */
295 PROP_gimple_leh | PROP_cfg, /* properties_provided */
296 0, /* properties_destroyed */
297 0, /* todo_flags_start */
298 TODO_verify_stmts, /* todo_flags_finish */
299 0 /* letter */
300};
301
6de9cd9a
DN
302struct profile_hooks tree_profile_hooks =
303{
f3df9541 304 tree_init_edge_profiler, /* init_edge_profiler */
6de9cd9a
DN
305 tree_gen_edge_profiler, /* gen_edge_profiler */
306 tree_gen_interval_profiler, /* gen_interval_profiler */
307 tree_gen_pow2_profiler, /* gen_pow2_profiler */
308 tree_gen_one_value_profiler, /* gen_one_value_profiler */
309 tree_gen_const_delta_profiler,/* gen_const_delta_profiler */
310 tree_profile_dump_file /* profile_dump_file */
311};
9885da8e
ZD
312
313#include "gt-tree-profile.h"
This page took 1.003553 seconds and 5 git commands to generate.