tree-ssa.h: Remove all #include's
[platform/upstream/gcc.git] / gcc / tree-profile.c
1 /* Calculate branch probabilities, and basic block execution counts.
2    Copyright (C) 1990-2013 Free Software Foundation, Inc.
3    Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
4    based on some ideas from Dain Samples of UC Berkeley.
5    Further mangling by Bob Manson, Cygnus Support.
6    Converted to use trees by Dale Johannesen, Apple Computer.
7
8 This file is part of GCC.
9
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
13 version.
14
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3.  If not see
22 <http://www.gnu.org/licenses/>.  */
23
24 /* Generate basic block profile instrumentation and auxiliary files.
25    Tree-based version.  See profile.c for overview.  */
26
27 #include "config.h"
28 #include "system.h"
29 #include "coretypes.h"
30 #include "tm.h"
31 #include "flags.h"
32 #include "function.h"
33 #include "basic-block.h"
34 #include "diagnostic-core.h"
35 #include "coverage.h"
36 #include "tree.h"
37 #include "gimple.h"
38 #include "gimple-ssa.h"
39 #include "cgraph.h"
40 #include "tree-cfg.h"
41 #include "tree-ssanames.h"
42 #include "tree-into-ssa.h"
43 #include "tree-pass.h"
44 #include "value-prof.h"
45 #include "profile.h"
46 #include "target.h"
47 #include "tree-cfgcleanup.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 static GTY(()) tree tree_indirect_call_profiler_fn;
54 static GTY(()) tree tree_average_profiler_fn;
55 static GTY(()) tree tree_ior_profiler_fn;
56 \f
57
58 static GTY(()) tree ic_void_ptr_var;
59 static GTY(()) tree ic_gcov_type_ptr_var;
60 static GTY(()) tree ptr_void;
61
62 /* Do initialization work for the edge profiler.  */
63
64 /* Add code:
65    __thread gcov*       __gcov_indirect_call_counters; // pointer to actual counter
66    __thread  void*      __gcov_indirect_call_callee; // actual callee address
67 */
68 static void
69 init_ic_make_global_vars (void)
70 {
71   tree  gcov_type_ptr;
72
73   ptr_void = build_pointer_type (void_type_node);
74
75   /* Workaround for binutils bug 14342.  Once it is fixed, remove lto path.  */
76   if (flag_lto)
77     {
78       ic_void_ptr_var
79         = build_decl (UNKNOWN_LOCATION, VAR_DECL,
80                       get_identifier ("__gcov_indirect_call_callee_ltopriv"),
81                       ptr_void);
82       TREE_PUBLIC (ic_void_ptr_var) = 1;
83       DECL_COMMON (ic_void_ptr_var) = 1;
84       DECL_VISIBILITY (ic_void_ptr_var) = VISIBILITY_HIDDEN;
85       DECL_VISIBILITY_SPECIFIED (ic_void_ptr_var) = true;
86     }
87   else
88     {
89       ic_void_ptr_var
90         = build_decl (UNKNOWN_LOCATION, VAR_DECL,
91                       get_identifier ("__gcov_indirect_call_callee"),
92                       ptr_void);
93       TREE_PUBLIC (ic_void_ptr_var) = 1;
94       DECL_EXTERNAL (ic_void_ptr_var) = 1;
95     }
96   TREE_STATIC (ic_void_ptr_var) = 1;
97   DECL_ARTIFICIAL (ic_void_ptr_var) = 1;
98   DECL_INITIAL (ic_void_ptr_var) = NULL;
99   if (targetm.have_tls)
100     DECL_TLS_MODEL (ic_void_ptr_var) =
101       decl_default_tls_model (ic_void_ptr_var);
102
103   varpool_finalize_decl (ic_void_ptr_var);
104
105   gcov_type_ptr = build_pointer_type (get_gcov_type ());
106   /* Workaround for binutils bug 14342.  Once it is fixed, remove lto path.  */
107   if (flag_lto)
108     {
109       ic_gcov_type_ptr_var
110         = build_decl (UNKNOWN_LOCATION, VAR_DECL,
111                       get_identifier ("__gcov_indirect_call_counters_ltopriv"),
112                       gcov_type_ptr);
113       TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
114       DECL_COMMON (ic_gcov_type_ptr_var) = 1;
115       DECL_VISIBILITY (ic_gcov_type_ptr_var) = VISIBILITY_HIDDEN;
116       DECL_VISIBILITY_SPECIFIED (ic_gcov_type_ptr_var) = true;
117     }
118   else
119     {
120       ic_gcov_type_ptr_var
121         = build_decl (UNKNOWN_LOCATION, VAR_DECL,
122                       get_identifier ("__gcov_indirect_call_counters"),
123                       gcov_type_ptr);
124       TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
125       DECL_EXTERNAL (ic_gcov_type_ptr_var) = 1;
126     }
127   TREE_STATIC (ic_gcov_type_ptr_var) = 1;
128   DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1;
129   DECL_INITIAL (ic_gcov_type_ptr_var) = NULL;
130   if (targetm.have_tls)
131     DECL_TLS_MODEL (ic_gcov_type_ptr_var) =
132       decl_default_tls_model (ic_gcov_type_ptr_var);
133
134   varpool_finalize_decl (ic_gcov_type_ptr_var);
135 }
136
137 /* Create the type and function decls for the interface with gcov.  */
138
139 void
140 gimple_init_edge_profiler (void)
141 {
142   tree interval_profiler_fn_type;
143   tree pow2_profiler_fn_type;
144   tree one_value_profiler_fn_type;
145   tree gcov_type_ptr;
146   tree ic_profiler_fn_type;
147   tree average_profiler_fn_type;
148
149   if (!gcov_type_node)
150     {
151       gcov_type_node = get_gcov_type ();
152       gcov_type_ptr = build_pointer_type (gcov_type_node);
153
154       /* void (*) (gcov_type *, gcov_type, int, unsigned)  */
155       interval_profiler_fn_type
156               = build_function_type_list (void_type_node,
157                                           gcov_type_ptr, gcov_type_node,
158                                           integer_type_node,
159                                           unsigned_type_node, NULL_TREE);
160       tree_interval_profiler_fn
161               = build_fn_decl ("__gcov_interval_profiler",
162                                      interval_profiler_fn_type);
163       TREE_NOTHROW (tree_interval_profiler_fn) = 1;
164       DECL_ATTRIBUTES (tree_interval_profiler_fn)
165         = tree_cons (get_identifier ("leaf"), NULL,
166                      DECL_ATTRIBUTES (tree_interval_profiler_fn));
167
168       /* void (*) (gcov_type *, gcov_type)  */
169       pow2_profiler_fn_type
170               = build_function_type_list (void_type_node,
171                                           gcov_type_ptr, gcov_type_node,
172                                           NULL_TREE);
173       tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler",
174                                                    pow2_profiler_fn_type);
175       TREE_NOTHROW (tree_pow2_profiler_fn) = 1;
176       DECL_ATTRIBUTES (tree_pow2_profiler_fn)
177         = tree_cons (get_identifier ("leaf"), NULL,
178                      DECL_ATTRIBUTES (tree_pow2_profiler_fn));
179
180       /* void (*) (gcov_type *, gcov_type)  */
181       one_value_profiler_fn_type
182               = build_function_type_list (void_type_node,
183                                           gcov_type_ptr, gcov_type_node,
184                                           NULL_TREE);
185       tree_one_value_profiler_fn
186               = build_fn_decl ("__gcov_one_value_profiler",
187                                      one_value_profiler_fn_type);
188       TREE_NOTHROW (tree_one_value_profiler_fn) = 1;
189       DECL_ATTRIBUTES (tree_one_value_profiler_fn)
190         = tree_cons (get_identifier ("leaf"), NULL,
191                      DECL_ATTRIBUTES (tree_one_value_profiler_fn));
192
193       init_ic_make_global_vars ();
194
195       /* Workaround for binutils bug 14342.  Once it is fixed, remove lto path.  */
196       if (flag_lto)
197         {
198           /* void (*) (gcov_type, void *)  */
199           ic_profiler_fn_type
200                    = build_function_type_list (void_type_node,
201                                               gcov_type_ptr, gcov_type_node,
202                                               ptr_void, ptr_void,
203                                               NULL_TREE);
204           tree_indirect_call_profiler_fn
205                   = build_fn_decl ("__gcov_indirect_call_profiler",
206                                          ic_profiler_fn_type);
207         }
208       else
209         {
210           /* void (*) (gcov_type, void *)  */
211           ic_profiler_fn_type
212                    = build_function_type_list (void_type_node,
213                                               gcov_type_node,
214                                               ptr_void,
215                                               NULL_TREE);
216           tree_indirect_call_profiler_fn
217                   = build_fn_decl ("__gcov_indirect_call_profiler_v2",
218                                          ic_profiler_fn_type);
219         }
220       TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
221       DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
222         = tree_cons (get_identifier ("leaf"), NULL,
223                      DECL_ATTRIBUTES (tree_indirect_call_profiler_fn));
224
225       /* void (*) (gcov_type *, gcov_type)  */
226       average_profiler_fn_type
227               = build_function_type_list (void_type_node,
228                                           gcov_type_ptr, gcov_type_node, NULL_TREE);
229       tree_average_profiler_fn
230               = build_fn_decl ("__gcov_average_profiler",
231                                      average_profiler_fn_type);
232       TREE_NOTHROW (tree_average_profiler_fn) = 1;
233       DECL_ATTRIBUTES (tree_average_profiler_fn)
234         = tree_cons (get_identifier ("leaf"), NULL,
235                      DECL_ATTRIBUTES (tree_average_profiler_fn));
236       tree_ior_profiler_fn
237               = build_fn_decl ("__gcov_ior_profiler",
238                                      average_profiler_fn_type);
239       TREE_NOTHROW (tree_ior_profiler_fn) = 1;
240       DECL_ATTRIBUTES (tree_ior_profiler_fn)
241         = tree_cons (get_identifier ("leaf"), NULL,
242                      DECL_ATTRIBUTES (tree_ior_profiler_fn));
243
244       /* LTO streamer needs assembler names.  Because we create these decls
245          late, we need to initialize them by hand.  */
246       DECL_ASSEMBLER_NAME (tree_interval_profiler_fn);
247       DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn);
248       DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn);
249       DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn);
250       DECL_ASSEMBLER_NAME (tree_average_profiler_fn);
251       DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
252     }
253 }
254
255 /* Output instructions as GIMPLE trees to increment the edge
256    execution count, and insert them on E.  We rely on
257    gsi_insert_on_edge to preserve the order.  */
258
259 void
260 gimple_gen_edge_profiler (int edgeno, edge e)
261 {
262   tree ref, one, gcov_type_tmp_var;
263   gimple stmt1, stmt2, stmt3;
264
265   ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
266   one = build_int_cst (gcov_type_node, 1);
267   gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
268                                           NULL, "PROF_edge_counter");
269   stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
270   gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
271                                           NULL, "PROF_edge_counter");
272   stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, gcov_type_tmp_var,
273                                         gimple_assign_lhs (stmt1), one);
274   stmt3 = gimple_build_assign (unshare_expr (ref), gimple_assign_lhs (stmt2));
275   gsi_insert_on_edge (e, stmt1);
276   gsi_insert_on_edge (e, stmt2);
277   gsi_insert_on_edge (e, stmt3);
278 }
279
280 /* Emits code to get VALUE to instrument at GSI, and returns the
281    variable containing the value.  */
282
283 static tree
284 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
285 {
286   tree val = value->hvalue.value;
287   if (POINTER_TYPE_P (TREE_TYPE (val)))
288     val = fold_convert (build_nonstandard_integer_type
289                           (TYPE_PRECISION (TREE_TYPE (val)), 1), val);
290   return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
291                                    true, NULL_TREE, true, GSI_SAME_STMT);
292 }
293
294 /* Output instructions as GIMPLE trees to increment the interval histogram
295    counter.  VALUE is the expression whose value is profiled.  TAG is the
296    tag of the section for counters, BASE is offset of the counter position.  */
297
298 void
299 gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
300 {
301   gimple stmt = value->hvalue.stmt;
302   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
303   tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
304   gimple call;
305   tree val;
306   tree start = build_int_cst_type (integer_type_node,
307                                    value->hdata.intvl.int_start);
308   tree steps = build_int_cst_type (unsigned_type_node,
309                                    value->hdata.intvl.steps);
310
311   ref_ptr = force_gimple_operand_gsi (&gsi,
312                                       build_addr (ref, current_function_decl),
313                                       true, NULL_TREE, true, GSI_SAME_STMT);
314   val = prepare_instrumented_value (&gsi, value);
315   call = gimple_build_call (tree_interval_profiler_fn, 4,
316                             ref_ptr, val, start, steps);
317   gsi_insert_before (&gsi, call, GSI_NEW_STMT);
318 }
319
320 /* Output instructions as GIMPLE trees to increment the power of two histogram
321    counter.  VALUE is the expression whose value is profiled.  TAG is the tag
322    of the section for counters, BASE is offset of the counter position.  */
323
324 void
325 gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
326 {
327   gimple stmt = value->hvalue.stmt;
328   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
329   tree ref_ptr = tree_coverage_counter_addr (tag, base);
330   gimple call;
331   tree val;
332
333   ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
334                                       true, NULL_TREE, true, GSI_SAME_STMT);
335   val = prepare_instrumented_value (&gsi, value);
336   call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val);
337   gsi_insert_before (&gsi, call, GSI_NEW_STMT);
338 }
339
340 /* Output instructions as GIMPLE trees for code to find the most common value.
341    VALUE is the expression whose value is profiled.  TAG is the tag of the
342    section for counters, BASE is offset of the counter position.  */
343
344 void
345 gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
346 {
347   gimple stmt = value->hvalue.stmt;
348   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
349   tree ref_ptr = tree_coverage_counter_addr (tag, base);
350   gimple call;
351   tree val;
352
353   ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
354                                       true, NULL_TREE, true, GSI_SAME_STMT);
355   val = prepare_instrumented_value (&gsi, value);
356   call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val);
357   gsi_insert_before (&gsi, call, GSI_NEW_STMT);
358 }
359
360
361 /* Output instructions as GIMPLE trees for code to find the most
362    common called function in indirect call.
363    VALUE is the call expression whose indirect callee is profiled.
364    TAG is the tag of the section for counters, BASE is offset of the
365    counter position.  */
366
367 void
368 gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
369 {
370   tree tmp1;
371   gimple stmt1, stmt2, stmt3;
372   gimple stmt = value->hvalue.stmt;
373   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
374   tree ref_ptr = tree_coverage_counter_addr (tag, base);
375
376   ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
377                                       true, NULL_TREE, true, GSI_SAME_STMT);
378
379   /* Insert code:
380
381     stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
382     stmt2: tmp1 = (void *) (indirect call argument value)
383     stmt3: __gcov_indirect_call_callee = tmp1;
384    */
385
386   stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr);
387   tmp1 = make_temp_ssa_name (ptr_void, NULL, "PROF");
388   stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
389   stmt3 = gimple_build_assign (ic_void_ptr_var, gimple_assign_lhs (stmt2));
390
391   gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
392   gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
393   gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
394 }
395
396
397 /* Output instructions as GIMPLE trees for code to find the most
398    common called function in indirect call. Insert instructions at the
399    beginning of every possible called function.
400   */
401
402 void
403 gimple_gen_ic_func_profiler (void)
404 {
405   struct cgraph_node * c_node = cgraph_get_node (current_function_decl);
406   gimple_stmt_iterator gsi;
407   gimple stmt1, stmt2;
408   tree tree_uid, cur_func, void0;
409
410   if (cgraph_only_called_directly_p (c_node))
411     return;
412
413   gimple_init_edge_profiler ();
414
415   /* Insert code:
416
417     stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
418                                              &current_function_decl)
419    */
420   gsi = gsi_after_labels (split_edge (single_succ_edge (ENTRY_BLOCK_PTR)));
421
422   cur_func = force_gimple_operand_gsi (&gsi,
423                                        build_addr (current_function_decl,
424                                                    current_function_decl),
425                                        true, NULL_TREE,
426                                        true, GSI_SAME_STMT);
427   tree_uid = build_int_cst
428               (gcov_type_node, cgraph_get_node (current_function_decl)->profile_id);
429   /* Workaround for binutils bug 14342.  Once it is fixed, remove lto path.  */
430   if (flag_lto)
431     {
432       tree counter_ptr, ptr_var;
433       counter_ptr = force_gimple_operand_gsi (&gsi, ic_gcov_type_ptr_var,
434                                               true, NULL_TREE, true,
435                                               GSI_SAME_STMT);
436       ptr_var = force_gimple_operand_gsi (&gsi, ic_void_ptr_var,
437                                           true, NULL_TREE, true,
438                                           GSI_SAME_STMT);
439
440       stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 4,
441                                  counter_ptr, tree_uid, cur_func, ptr_var);
442     }
443   else
444     {
445       stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2,
446                                  tree_uid, cur_func);
447     }
448   gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
449
450   /* Set __gcov_indirect_call_callee to 0,
451      so that calls from other modules won't get misattributed
452      to the last caller of the current callee. */
453   void0 = build_int_cst (build_pointer_type (void_type_node), 0);
454   stmt2 = gimple_build_assign (ic_void_ptr_var, void0);
455   gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
456 }
457
458 /* Output instructions as GIMPLE trees for code to find the most common value
459    of a difference between two evaluations of an expression.
460    VALUE is the expression whose value is profiled.  TAG is the tag of the
461    section for counters, BASE is offset of the counter position.  */
462
463 void
464 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
465                                unsigned tag ATTRIBUTE_UNUSED,
466                                unsigned base ATTRIBUTE_UNUSED)
467 {
468   /* FIXME implement this.  */
469 #ifdef ENABLE_CHECKING
470   internal_error ("unimplemented functionality");
471 #endif
472   gcc_unreachable ();
473 }
474
475 /* Output instructions as GIMPLE trees to increment the average histogram
476    counter.  VALUE is the expression whose value is profiled.  TAG is the
477    tag of the section for counters, BASE is offset of the counter position.  */
478
479 void
480 gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
481 {
482   gimple stmt = value->hvalue.stmt;
483   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
484   tree ref_ptr = tree_coverage_counter_addr (tag, base);
485   gimple call;
486   tree val;
487
488   ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
489                                       true, NULL_TREE,
490                                       true, GSI_SAME_STMT);
491   val = prepare_instrumented_value (&gsi, value);
492   call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
493   gsi_insert_before (&gsi, call, GSI_NEW_STMT);
494 }
495
496 /* Output instructions as GIMPLE trees to increment the ior histogram
497    counter.  VALUE is the expression whose value is profiled.  TAG is the
498    tag of the section for counters, BASE is offset of the counter position.  */
499
500 void
501 gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
502 {
503   gimple stmt = value->hvalue.stmt;
504   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
505   tree ref_ptr = tree_coverage_counter_addr (tag, base);
506   gimple call;
507   tree val;
508
509   ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
510                                       true, NULL_TREE, true, GSI_SAME_STMT);
511   val = prepare_instrumented_value (&gsi, value);
512   call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
513   gsi_insert_before (&gsi, call, GSI_NEW_STMT);
514 }
515
516 /* Profile all functions in the callgraph.  */
517
518 static unsigned int
519 tree_profiling (void)
520 {
521   struct cgraph_node *node;
522
523   /* This is a small-ipa pass that gets called only once, from
524      cgraphunit.c:ipa_passes().  */
525   gcc_assert (cgraph_state == CGRAPH_STATE_IPA_SSA);
526
527   init_node_map (true);
528
529   FOR_EACH_DEFINED_FUNCTION (node)
530     {
531       if (!gimple_has_body_p (node->symbol.decl))
532         continue;
533
534       /* Don't profile functions produced for builtin stuff.  */
535       if (DECL_SOURCE_LOCATION (node->symbol.decl) == BUILTINS_LOCATION)
536         continue;
537
538       push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl));
539
540       /* Local pure-const may imply need to fixup the cfg.  */
541       if (execute_fixup_cfg () & TODO_cleanup_cfg)
542         cleanup_tree_cfg ();
543
544       branch_prob ();
545
546       if (! flag_branch_probabilities
547           && flag_profile_values)
548         gimple_gen_ic_func_profiler ();
549
550       if (flag_branch_probabilities
551           && flag_profile_values
552           && flag_value_profile_transformations)
553         gimple_value_profile_transformations ();
554
555       /* The above could hose dominator info.  Currently there is
556          none coming in, this is a safety valve.  It should be
557          easy to adjust it, if and when there is some.  */
558       free_dominance_info (CDI_DOMINATORS);
559       free_dominance_info (CDI_POST_DOMINATORS);
560       pop_cfun ();
561     }
562
563   /* Drop pure/const flags from instrumented functions.  */
564   FOR_EACH_DEFINED_FUNCTION (node)
565     {
566       if (!gimple_has_body_p (node->symbol.decl)
567           || !(!node->clone_of
568           || node->symbol.decl != node->clone_of->symbol.decl))
569         continue;
570
571       /* Don't profile functions produced for builtin stuff.  */
572       if (DECL_SOURCE_LOCATION (node->symbol.decl) == BUILTINS_LOCATION)
573         continue;
574
575       cgraph_set_const_flag (node, false, false);
576       cgraph_set_pure_flag (node, false, false);
577     }
578
579   /* Update call statements and rebuild the cgraph.  */
580   FOR_EACH_DEFINED_FUNCTION (node)
581     {
582       basic_block bb;
583
584       if (!gimple_has_body_p (node->symbol.decl)
585           || !(!node->clone_of
586           || node->symbol.decl != node->clone_of->symbol.decl))
587         continue;
588
589       /* Don't profile functions produced for builtin stuff.  */
590       if (DECL_SOURCE_LOCATION (node->symbol.decl) == BUILTINS_LOCATION)
591         continue;
592
593       push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl));
594
595       FOR_EACH_BB (bb)
596         {
597           gimple_stmt_iterator gsi;
598           for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
599             {
600               gimple stmt = gsi_stmt (gsi);
601               if (is_gimple_call (stmt))
602                 update_stmt (stmt);
603             }
604         }
605
606       /* re-merge split blocks.  */
607       cleanup_tree_cfg ();
608       update_ssa (TODO_update_ssa);
609
610       rebuild_cgraph_edges ();
611
612       pop_cfun ();
613     }
614
615   del_node_map ();
616   return 0;
617 }
618
619 /* When profile instrumentation, use or test coverage shall be performed.  */
620
621 static bool
622 gate_tree_profile_ipa (void)
623 {
624   return (!in_lto_p
625           && (flag_branch_probabilities || flag_test_coverage
626               || profile_arc_flag));
627 }
628
629 namespace {
630
631 const pass_data pass_data_ipa_tree_profile =
632 {
633   SIMPLE_IPA_PASS, /* type */
634   "profile", /* name */
635   OPTGROUP_NONE, /* optinfo_flags */
636   true, /* has_gate */
637   true, /* has_execute */
638   TV_IPA_PROFILE, /* tv_id */
639   0, /* properties_required */
640   0, /* properties_provided */
641   0, /* properties_destroyed */
642   0, /* todo_flags_start */
643   0, /* todo_flags_finish */
644 };
645
646 class pass_ipa_tree_profile : public simple_ipa_opt_pass
647 {
648 public:
649   pass_ipa_tree_profile (gcc::context *ctxt)
650     : simple_ipa_opt_pass (pass_data_ipa_tree_profile, ctxt)
651   {}
652
653   /* opt_pass methods: */
654   bool gate () { return gate_tree_profile_ipa (); }
655   unsigned int execute () { return tree_profiling (); }
656
657 }; // class pass_ipa_tree_profile
658
659 } // anon namespace
660
661 simple_ipa_opt_pass *
662 make_pass_ipa_tree_profile (gcc::context *ctxt)
663 {
664   return new pass_ipa_tree_profile (ctxt);
665 }
666
667 #include "gt-tree-profile.h"