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