OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [tree-profile.c] - Blame information for rev 20

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 jlechner
/* 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
 
49
static GTY(()) tree gcov_type_node;
50
static GTY(()) tree tree_interval_profiler_fn;
51
static GTY(()) tree tree_pow2_profiler_fn;
52
static GTY(()) tree tree_one_value_profiler_fn;
53
 
54
 
55
/* Do initialization work for the edge profiler.  */
56
 
57
static void
58
tree_init_edge_profiler (void)
59
{
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
    }
97
}
98
 
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
 
103
static void
104
tree_gen_edge_profiler (int edgeno, edge e)
105
{
106
  tree tmp1 = create_tmp_var (gcov_type_node, "PROF");
107
  tree tmp2 = create_tmp_var (gcov_type_node, "PROF");
108
  tree ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
109
  tree stmt1 = build (MODIFY_EXPR, gcov_type_node, tmp1, ref);
110
  tree stmt2 = build (MODIFY_EXPR, gcov_type_node, tmp2,
111
                      build (PLUS_EXPR, gcov_type_node,
112
                             tmp1, integer_one_node));
113
  tree stmt3 = build (MODIFY_EXPR, gcov_type_node, ref, tmp2);
114
  bsi_insert_on_edge (e, stmt1);
115
  bsi_insert_on_edge (e, stmt2);
116
  bsi_insert_on_edge (e, stmt3);
117
}
118
 
119
/* Emits code to get VALUE to instrument at BSI, and returns the
120
   variable containing the value.  */
121
 
122
static tree
123
prepare_instrumented_value (block_stmt_iterator *bsi,
124
                            histogram_value value)
125
{
126
  tree val = value->hvalue.value;
127
  return force_gimple_operand_bsi (bsi, fold_convert (gcov_type_node, val),
128
                                   true, NULL_TREE);
129
}
130
 
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
 
135
static void
136
tree_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
137
{
138
  tree stmt = value->hvalue.stmt;
139
  block_stmt_iterator bsi = bsi_for_stmt (stmt);
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,
146
                                      build_addr (ref, current_function_decl),
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);
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
 
162
static void
163
tree_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
164
{
165
  tree stmt = value->hvalue.stmt;
166
  block_stmt_iterator bsi = bsi_for_stmt (stmt);
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,
171
                                      build_addr (ref, current_function_decl),
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);
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
 
185
static void
186
tree_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
187
{
188
  tree stmt = value->hvalue.stmt;
189
  block_stmt_iterator bsi = bsi_for_stmt (stmt);
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,
194
                                      build_addr (ref, current_function_decl),
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);
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
 
209
static void
210
tree_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
211
                                unsigned tag ATTRIBUTE_UNUSED,
212
                                unsigned base ATTRIBUTE_UNUSED)
213
{
214
  /* FIXME implement this.  */
215
#ifdef ENABLE_CHECKING
216
  internal_error ("unimplemented functionality");
217
#endif
218
  gcc_unreachable ();
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
 
225
static bool
226
do_tree_profiling (void)
227
{
228
  if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
229
    {
230
      tree_register_profile_hooks ();
231
      tree_register_value_prof_hooks ();
232
      return true;
233
    }
234
  return false;
235
}
236
 
237
/* Return the file on which profile dump output goes, if any.  */
238
 
239
static FILE *tree_profile_dump_file (void) {
240
  return dump_file;
241
}
242
 
243
static void
244
tree_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
 
258
struct tree_opt_pass pass_tree_profile =
259
{
260
  "tree_profile",                       /* name */
261
  do_tree_profiling,                    /* gate */
262
  tree_profiling,                       /* execute */
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 */
271
  TODO_verify_stmts,                    /* todo_flags_finish */
272
 
273
};
274
 
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
 
279
static bool
280
do_early_tree_profiling (void)
281
{
282
  return (do_tree_profiling () && (!flag_unit_at_a_time || !optimize));
283
}
284
 
285
struct 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
 
300
};
301
 
302
struct profile_hooks tree_profile_hooks =
303
{
304
  tree_init_edge_profiler,      /* init_edge_profiler */
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
};
312
 
313
#include "gt-tree-profile.h"

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.