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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [tree-profile.c] - Blame information for rev 749

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

Line No. Rev Author Line
1 684 jeremybenn
/* 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, 2010
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 "flags.h"
34
#include "regs.h"
35
#include "function.h"
36
#include "basic-block.h"
37
#include "diagnostic-core.h"
38
#include "coverage.h"
39
#include "tree.h"
40
#include "tree-flow.h"
41
#include "tree-dump.h"
42
#include "tree-pass.h"
43
#include "timevar.h"
44
#include "value-prof.h"
45
#include "cgraph.h"
46
#include "profile.h"
47
#include "target.h"
48
#include "output.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
 
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
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 (UNKNOWN_LOCATION, 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
  if (targetm.have_tls)
86
    DECL_TLS_MODEL (ic_void_ptr_var) =
87
      decl_default_tls_model (ic_void_ptr_var);
88
 
89
  varpool_finalize_decl (ic_void_ptr_var);
90
  varpool_mark_needed_node (varpool_node (ic_void_ptr_var));
91
 
92
  gcov_type_ptr = build_pointer_type (get_gcov_type ());
93
  ic_gcov_type_ptr_var
94
    = build_decl (UNKNOWN_LOCATION, VAR_DECL,
95
                  get_identifier ("__gcov_indirect_call_counters"),
96
                  gcov_type_ptr);
97
  TREE_STATIC (ic_gcov_type_ptr_var) = 1;
98
  TREE_PUBLIC (ic_gcov_type_ptr_var) = 0;
99
  DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1;
100
  DECL_INITIAL (ic_gcov_type_ptr_var) = NULL;
101
  if (targetm.have_tls)
102
    DECL_TLS_MODEL (ic_gcov_type_ptr_var) =
103
      decl_default_tls_model (ic_gcov_type_ptr_var);
104
 
105
  varpool_finalize_decl (ic_gcov_type_ptr_var);
106
  varpool_mark_needed_node (varpool_node (ic_gcov_type_ptr_var));
107
}
108
 
109
void
110
gimple_init_edge_profiler (void)
111
{
112
  tree interval_profiler_fn_type;
113
  tree pow2_profiler_fn_type;
114
  tree one_value_profiler_fn_type;
115
  tree gcov_type_ptr;
116
  tree ic_profiler_fn_type;
117
  tree average_profiler_fn_type;
118
 
119
  if (!gcov_type_node)
120
    {
121
      gcov_type_node = get_gcov_type ();
122
      gcov_type_ptr = build_pointer_type (gcov_type_node);
123
 
124
      /* void (*) (gcov_type *, gcov_type, int, unsigned)  */
125
      interval_profiler_fn_type
126
              = build_function_type_list (void_type_node,
127
                                          gcov_type_ptr, gcov_type_node,
128
                                          integer_type_node,
129
                                          unsigned_type_node, NULL_TREE);
130
      tree_interval_profiler_fn
131
              = build_fn_decl ("__gcov_interval_profiler",
132
                                     interval_profiler_fn_type);
133
      TREE_NOTHROW (tree_interval_profiler_fn) = 1;
134
      DECL_ATTRIBUTES (tree_interval_profiler_fn)
135
        = tree_cons (get_identifier ("leaf"), NULL,
136
                     DECL_ATTRIBUTES (tree_interval_profiler_fn));
137
 
138
      /* void (*) (gcov_type *, gcov_type)  */
139
      pow2_profiler_fn_type
140
              = build_function_type_list (void_type_node,
141
                                          gcov_type_ptr, gcov_type_node,
142
                                          NULL_TREE);
143
      tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler",
144
                                                   pow2_profiler_fn_type);
145
      TREE_NOTHROW (tree_pow2_profiler_fn) = 1;
146
      DECL_ATTRIBUTES (tree_pow2_profiler_fn)
147
        = tree_cons (get_identifier ("leaf"), NULL,
148
                     DECL_ATTRIBUTES (tree_pow2_profiler_fn));
149
 
150
      /* void (*) (gcov_type *, gcov_type)  */
151
      one_value_profiler_fn_type
152
              = build_function_type_list (void_type_node,
153
                                          gcov_type_ptr, gcov_type_node,
154
                                          NULL_TREE);
155
      tree_one_value_profiler_fn
156
              = build_fn_decl ("__gcov_one_value_profiler",
157
                                     one_value_profiler_fn_type);
158
      TREE_NOTHROW (tree_one_value_profiler_fn) = 1;
159
      DECL_ATTRIBUTES (tree_one_value_profiler_fn)
160
        = tree_cons (get_identifier ("leaf"), NULL,
161
                     DECL_ATTRIBUTES (tree_one_value_profiler_fn));
162
 
163
      init_ic_make_global_vars ();
164
 
165
      /* void (*) (gcov_type *, gcov_type, void *, void *)  */
166
      ic_profiler_fn_type
167
               = build_function_type_list (void_type_node,
168
                                          gcov_type_ptr, gcov_type_node,
169
                                          ptr_void,
170
                                          ptr_void, NULL_TREE);
171
      tree_indirect_call_profiler_fn
172
              = build_fn_decl ("__gcov_indirect_call_profiler",
173
                                     ic_profiler_fn_type);
174
      TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
175
      DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
176
        = tree_cons (get_identifier ("leaf"), NULL,
177
                     DECL_ATTRIBUTES (tree_indirect_call_profiler_fn));
178
 
179
      /* void (*) (gcov_type *, gcov_type)  */
180
      average_profiler_fn_type
181
              = build_function_type_list (void_type_node,
182
                                          gcov_type_ptr, gcov_type_node, NULL_TREE);
183
      tree_average_profiler_fn
184
              = build_fn_decl ("__gcov_average_profiler",
185
                                     average_profiler_fn_type);
186
      TREE_NOTHROW (tree_average_profiler_fn) = 1;
187
      DECL_ATTRIBUTES (tree_average_profiler_fn)
188
        = tree_cons (get_identifier ("leaf"), NULL,
189
                     DECL_ATTRIBUTES (tree_average_profiler_fn));
190
      tree_ior_profiler_fn
191
              = build_fn_decl ("__gcov_ior_profiler",
192
                                     average_profiler_fn_type);
193
      TREE_NOTHROW (tree_ior_profiler_fn) = 1;
194
      DECL_ATTRIBUTES (tree_ior_profiler_fn)
195
        = tree_cons (get_identifier ("leaf"), NULL,
196
                     DECL_ATTRIBUTES (tree_ior_profiler_fn));
197
 
198
      /* LTO streamer needs assembler names.  Because we create these decls
199
         late, we need to initialize them by hand.  */
200
      DECL_ASSEMBLER_NAME (tree_interval_profiler_fn);
201
      DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn);
202
      DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn);
203
      DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn);
204
      DECL_ASSEMBLER_NAME (tree_average_profiler_fn);
205
      DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
206
    }
207
}
208
 
209
/* Output instructions as GIMPLE trees to increment the edge
210
   execution count, and insert them on E.  We rely on
211
   gsi_insert_on_edge to preserve the order.  */
212
 
213
void
214
gimple_gen_edge_profiler (int edgeno, edge e)
215
{
216
  tree ref, one;
217
  gimple stmt1, stmt2, stmt3;
218
 
219
  /* We share one temporary variable declaration per function.  This
220
     gets re-set in tree_profiling.  */
221
  if (gcov_type_tmp_var == NULL_TREE)
222
    gcov_type_tmp_var = create_tmp_reg (gcov_type_node, "PROF_edge_counter");
223
  ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
224
  one = build_int_cst (gcov_type_node, 1);
225
  stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
226
  gimple_assign_set_lhs (stmt1, make_ssa_name (gcov_type_tmp_var, stmt1));
227
  find_referenced_vars_in (stmt1);
228
  stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, gcov_type_tmp_var,
229
                                        gimple_assign_lhs (stmt1), one);
230
  gimple_assign_set_lhs (stmt2, make_ssa_name (gcov_type_tmp_var, stmt2));
231
  stmt3 = gimple_build_assign (unshare_expr (ref), gimple_assign_lhs (stmt2));
232
  gsi_insert_on_edge (e, stmt1);
233
  gsi_insert_on_edge (e, stmt2);
234
  gsi_insert_on_edge (e, stmt3);
235
}
236
 
237
/* Emits code to get VALUE to instrument at GSI, and returns the
238
   variable containing the value.  */
239
 
240
static tree
241
prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
242
{
243
  tree val = value->hvalue.value;
244
  if (POINTER_TYPE_P (TREE_TYPE (val)))
245
    val = fold_convert (build_nonstandard_integer_type
246
                          (TYPE_PRECISION (TREE_TYPE (val)), 1), val);
247
  return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
248
                                   true, NULL_TREE, true, GSI_SAME_STMT);
249
}
250
 
251
/* Output instructions as GIMPLE trees to increment the interval histogram
252
   counter.  VALUE is the expression whose value is profiled.  TAG is the
253
   tag of the section for counters, BASE is offset of the counter position.  */
254
 
255
void
256
gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
257
{
258
  gimple stmt = value->hvalue.stmt;
259
  gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
260
  tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
261
  gimple call;
262
  tree val;
263
  tree start = build_int_cst_type (integer_type_node,
264
                                   value->hdata.intvl.int_start);
265
  tree steps = build_int_cst_type (unsigned_type_node,
266
                                   value->hdata.intvl.steps);
267
 
268
  ref_ptr = force_gimple_operand_gsi (&gsi,
269
                                      build_addr (ref, current_function_decl),
270
                                      true, NULL_TREE, true, GSI_SAME_STMT);
271
  val = prepare_instrumented_value (&gsi, value);
272
  call = gimple_build_call (tree_interval_profiler_fn, 4,
273
                            ref_ptr, val, start, steps);
274
  find_referenced_vars_in (call);
275
  gsi_insert_before (&gsi, call, GSI_NEW_STMT);
276
}
277
 
278
/* Output instructions as GIMPLE trees to increment the power of two histogram
279
   counter.  VALUE is the expression whose value is profiled.  TAG is the tag
280
   of the section for counters, BASE is offset of the counter position.  */
281
 
282
void
283
gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
284
{
285
  gimple stmt = value->hvalue.stmt;
286
  gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
287
  tree ref_ptr = tree_coverage_counter_addr (tag, base);
288
  gimple call;
289
  tree val;
290
 
291
  ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
292
                                      true, NULL_TREE, true, GSI_SAME_STMT);
293
  val = prepare_instrumented_value (&gsi, value);
294
  call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val);
295
  find_referenced_vars_in (call);
296
  gsi_insert_before (&gsi, call, GSI_NEW_STMT);
297
}
298
 
299
/* Output instructions as GIMPLE trees for code to find the most common value.
300
   VALUE is the expression whose value is profiled.  TAG is the tag of the
301
   section for counters, BASE is offset of the counter position.  */
302
 
303
void
304
gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
305
{
306
  gimple stmt = value->hvalue.stmt;
307
  gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
308
  tree ref_ptr = tree_coverage_counter_addr (tag, base);
309
  gimple call;
310
  tree val;
311
 
312
  ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
313
                                      true, NULL_TREE, true, GSI_SAME_STMT);
314
  val = prepare_instrumented_value (&gsi, value);
315
  call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val);
316
  find_referenced_vars_in (call);
317
  gsi_insert_before (&gsi, call, GSI_NEW_STMT);
318
}
319
 
320
 
321
/* Output instructions as GIMPLE trees for code to find the most
322
   common called function in indirect call.
323
   VALUE is the call expression whose indirect callee is profiled.
324
   TAG is the tag of the section for counters, BASE is offset of the
325
   counter position.  */
326
 
327
void
328
gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
329
{
330
  tree tmp1;
331
  gimple stmt1, stmt2, stmt3;
332
  gimple stmt = value->hvalue.stmt;
333
  gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
334
  tree ref_ptr = tree_coverage_counter_addr (tag, base);
335
 
336
  ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
337
                                      true, NULL_TREE, true, GSI_SAME_STMT);
338
 
339
  /* Insert code:
340
 
341
    __gcov_indirect_call_counters = get_relevant_counter_ptr ();
342
    __gcov_indirect_call_callee = (void *) indirect call argument;
343
   */
344
 
345
  tmp1 = create_tmp_reg (ptr_void, "PROF");
346
  stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr);
347
  find_referenced_vars_in (stmt1);
348
  stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
349
  gimple_assign_set_lhs (stmt2, make_ssa_name (tmp1, stmt2));
350
  find_referenced_vars_in (stmt2);
351
  stmt3 = gimple_build_assign (ic_void_ptr_var, gimple_assign_lhs (stmt2));
352
  add_referenced_var (ic_void_ptr_var);
353
 
354
  gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
355
  gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
356
  gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
357
}
358
 
359
 
360
/* Output instructions as GIMPLE trees for code to find the most
361
   common called function in indirect call. Insert instructions at the
362
   beginning of every possible called function.
363
  */
364
 
365
void
366
gimple_gen_ic_func_profiler (void)
367
{
368
  struct cgraph_node * c_node = cgraph_get_node (current_function_decl);
369
  gimple_stmt_iterator gsi;
370
  gimple stmt1, stmt2;
371
  tree tree_uid, cur_func, counter_ptr, ptr_var, void0;
372
 
373
  if (cgraph_only_called_directly_p (c_node))
374
    return;
375
 
376
  gimple_init_edge_profiler ();
377
 
378
  gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR));
379
 
380
  cur_func = force_gimple_operand_gsi (&gsi,
381
                                       build_addr (current_function_decl,
382
                                                   current_function_decl),
383
                                       true, NULL_TREE,
384
                                       true, GSI_SAME_STMT);
385
  counter_ptr = force_gimple_operand_gsi (&gsi, ic_gcov_type_ptr_var,
386
                                          true, NULL_TREE, true,
387
                                          GSI_SAME_STMT);
388
  add_referenced_var (ic_gcov_type_ptr_var);
389
  ptr_var = force_gimple_operand_gsi (&gsi, ic_void_ptr_var,
390
                                      true, NULL_TREE, true,
391
                                      GSI_SAME_STMT);
392
  add_referenced_var (ic_void_ptr_var);
393
  tree_uid = build_int_cst (gcov_type_node, current_function_funcdef_no);
394
  stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 4,
395
                             counter_ptr, tree_uid, cur_func, ptr_var);
396
  gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
397
 
398
  /* Set __gcov_indirect_call_callee to 0,
399
     so that calls from other modules won't get misattributed
400
     to the last caller of the current callee. */
401
  void0 = build_int_cst (build_pointer_type (void_type_node), 0);
402
  stmt2 = gimple_build_assign (ic_void_ptr_var, void0);
403
  gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
404
}
405
 
406
/* Output instructions as GIMPLE trees for code to find the most common value
407
   of a difference between two evaluations of an expression.
408
   VALUE is the expression whose value is profiled.  TAG is the tag of the
409
   section for counters, BASE is offset of the counter position.  */
410
 
411
void
412
gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
413
                               unsigned tag ATTRIBUTE_UNUSED,
414
                               unsigned base ATTRIBUTE_UNUSED)
415
{
416
  /* FIXME implement this.  */
417
#ifdef ENABLE_CHECKING
418
  internal_error ("unimplemented functionality");
419
#endif
420
  gcc_unreachable ();
421
}
422
 
423
/* Output instructions as GIMPLE trees to increment the average histogram
424
   counter.  VALUE is the expression whose value is profiled.  TAG is the
425
   tag of the section for counters, BASE is offset of the counter position.  */
426
 
427
void
428
gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
429
{
430
  gimple stmt = value->hvalue.stmt;
431
  gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
432
  tree ref_ptr = tree_coverage_counter_addr (tag, base);
433
  gimple call;
434
  tree val;
435
 
436
  ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
437
                                      true, NULL_TREE,
438
                                      true, GSI_SAME_STMT);
439
  val = prepare_instrumented_value (&gsi, value);
440
  call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
441
  find_referenced_vars_in (call);
442
  gsi_insert_before (&gsi, call, GSI_NEW_STMT);
443
}
444
 
445
/* Output instructions as GIMPLE trees to increment the ior histogram
446
   counter.  VALUE is the expression whose value is profiled.  TAG is the
447
   tag of the section for counters, BASE is offset of the counter position.  */
448
 
449
void
450
gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
451
{
452
  gimple stmt = value->hvalue.stmt;
453
  gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
454
  tree ref_ptr = tree_coverage_counter_addr (tag, base);
455
  gimple call;
456
  tree val;
457
 
458
  ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
459
                                      true, NULL_TREE, true, GSI_SAME_STMT);
460
  val = prepare_instrumented_value (&gsi, value);
461
  call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
462
  find_referenced_vars_in (call);
463
  gsi_insert_before (&gsi, call, GSI_NEW_STMT);
464
}
465
 
466
/* Profile all functions in the callgraph.  */
467
 
468
static unsigned int
469
tree_profiling (void)
470
{
471
  struct cgraph_node *node;
472
 
473
  /* Don't profile functions produced at destruction time, particularly
474
     the gcov datastructure initializer.  Don't profile if it has been
475
     already instrumented either (when OpenMP expansion creates
476
     child function from already instrumented body).  */
477
  if (cgraph_state == CGRAPH_STATE_FINISHED)
478
    return 0;
479
 
480
  init_node_map();
481
 
482
  for (node = cgraph_nodes; node; node = node->next)
483
    {
484
      if (!node->analyzed
485
          || !gimple_has_body_p (node->decl))
486
        continue;
487
 
488
      /* Don't profile functions produced for builtin stuff.  */
489
      if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION
490
          || DECL_STRUCT_FUNCTION (node->decl)->after_tree_profile)
491
        continue;
492
 
493
      push_cfun (DECL_STRUCT_FUNCTION (node->decl));
494
      current_function_decl = node->decl;
495
 
496
      /* Re-set global shared temporary variable for edge-counters.  */
497
      gcov_type_tmp_var = NULL_TREE;
498
 
499
      /* Local pure-const may imply need to fixup the cfg.  */
500
      execute_fixup_cfg ();
501
      branch_prob ();
502
 
503
      if (! flag_branch_probabilities
504
          && flag_profile_values)
505
        gimple_gen_ic_func_profiler ();
506
 
507
      if (flag_branch_probabilities
508
          && flag_profile_values
509
          && flag_value_profile_transformations)
510
        gimple_value_profile_transformations ();
511
 
512
      /* The above could hose dominator info.  Currently there is
513
         none coming in, this is a safety valve.  It should be
514
         easy to adjust it, if and when there is some.  */
515
      free_dominance_info (CDI_DOMINATORS);
516
      free_dominance_info (CDI_POST_DOMINATORS);
517
 
518
      current_function_decl = NULL;
519
      pop_cfun ();
520
    }
521
 
522
  /* Drop pure/const flags from instrumented functions.  */
523
  for (node = cgraph_nodes; node; node = node->next)
524
    {
525
      if (!node->analyzed
526
          || !gimple_has_body_p (node->decl)
527
          || !(!node->clone_of || node->decl != node->clone_of->decl))
528
        continue;
529
 
530
      /* Don't profile functions produced for builtin stuff.  */
531
      if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION
532
          || DECL_STRUCT_FUNCTION (node->decl)->after_tree_profile)
533
        continue;
534
 
535
      cgraph_set_const_flag (node, false, false);
536
      cgraph_set_pure_flag (node, false, false);
537
    }
538
 
539
  /* Update call statements and rebuild the cgraph.  */
540
  for (node = cgraph_nodes; node; node = node->next)
541
    {
542
      basic_block bb;
543
 
544
      if (!node->analyzed
545
          || !gimple_has_body_p (node->decl)
546
          || !(!node->clone_of || node->decl != node->clone_of->decl))
547
        continue;
548
 
549
      /* Don't profile functions produced for builtin stuff.  */
550
      if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION
551
          || DECL_STRUCT_FUNCTION (node->decl)->after_tree_profile)
552
        continue;
553
 
554
      push_cfun (DECL_STRUCT_FUNCTION (node->decl));
555
      current_function_decl = node->decl;
556
 
557
      FOR_EACH_BB (bb)
558
        {
559
          gimple_stmt_iterator gsi;
560
          for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
561
            {
562
              gimple stmt = gsi_stmt (gsi);
563
              if (is_gimple_call (stmt))
564
                update_stmt (stmt);
565
            }
566
        }
567
 
568
      cfun->after_tree_profile = 1;
569
      update_ssa (TODO_update_ssa);
570
 
571
      rebuild_cgraph_edges ();
572
 
573
      current_function_decl = NULL;
574
      pop_cfun ();
575
    }
576
 
577
  del_node_map();
578
  return 0;
579
}
580
 
581
/* When profile instrumentation, use or test coverage shall be performed.  */
582
 
583
static bool
584
gate_tree_profile_ipa (void)
585
{
586
  return (!in_lto_p
587
          && (flag_branch_probabilities || flag_test_coverage
588
              || profile_arc_flag));
589
}
590
 
591
struct simple_ipa_opt_pass pass_ipa_tree_profile =
592
{
593
 {
594
  SIMPLE_IPA_PASS,
595
  "profile",                           /* name */
596
  gate_tree_profile_ipa,               /* gate */
597
  tree_profiling,                      /* execute */
598
  NULL,                                /* sub */
599
  NULL,                                /* next */
600
  0,                                   /* static_pass_number */
601
  TV_IPA_PROFILE,                      /* tv_id */
602
  0,                                   /* properties_required */
603
  0,                                   /* properties_provided */
604
  0,                                   /* properties_destroyed */
605
  0,                                   /* todo_flags_start */
606
 
607
 }
608
};
609
 
610
#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.