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