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