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