gcov: Add gen_counter_update()
[official-gcc.git] / gcc / tree-profile.cc
blob24805ff905c70ffcedb3bb4cf7d72229502fc302
1 /* Calculate branch probabilities, and basic block execution counts.
2 Copyright (C) 1990-2023 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.
8 This file is part of GCC.
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.
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.
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/>. */
24 /* Generate basic block profile instrumentation and auxiliary files.
25 Tree-based version. See profile.cc for overview. */
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 "stringpool.h"
53 #include "attribs.h"
54 #include "tree-pretty-print.h"
55 #include "langhooks.h"
56 #include "stor-layout.h"
57 #include "xregex.h"
58 #include "alloc-pool.h"
59 #include "symbol-summary.h"
60 #include "symtab-thunks.h"
62 static GTY(()) tree gcov_type_node;
63 static GTY(()) tree tree_interval_profiler_fn;
64 static GTY(()) tree tree_pow2_profiler_fn;
65 static GTY(()) tree tree_topn_values_profiler_fn;
66 static GTY(()) tree tree_indirect_call_profiler_fn;
67 static GTY(()) tree tree_average_profiler_fn;
68 static GTY(()) tree tree_ior_profiler_fn;
69 static GTY(()) tree tree_time_profiler_counter;
72 static GTY(()) tree ic_tuple_var;
73 static GTY(()) tree ic_tuple_counters_field;
74 static GTY(()) tree ic_tuple_callee_field;
76 /* Do initialization work for the edge profiler. */
78 /* Add code:
79 __thread gcov* __gcov_indirect_call.counters; // pointer to actual counter
80 __thread void* __gcov_indirect_call.callee; // actual callee address
81 __thread int __gcov_function_counter; // time profiler function counter
83 static void
84 init_ic_make_global_vars (void)
86 tree gcov_type_ptr;
88 gcov_type_ptr = build_pointer_type (get_gcov_type ());
90 tree tuple_type = lang_hooks.types.make_type (RECORD_TYPE);
92 /* callee */
93 ic_tuple_callee_field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
94 ptr_type_node);
96 /* counters */
97 ic_tuple_counters_field = build_decl (BUILTINS_LOCATION, FIELD_DECL,
98 NULL_TREE, gcov_type_ptr);
99 DECL_CHAIN (ic_tuple_counters_field) = ic_tuple_callee_field;
101 finish_builtin_struct (tuple_type, "indirect_call_tuple",
102 ic_tuple_counters_field, NULL_TREE);
104 ic_tuple_var
105 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
106 get_identifier ("__gcov_indirect_call"), tuple_type);
107 TREE_PUBLIC (ic_tuple_var) = 1;
108 DECL_ARTIFICIAL (ic_tuple_var) = 1;
109 DECL_INITIAL (ic_tuple_var) = NULL;
110 DECL_EXTERNAL (ic_tuple_var) = 1;
111 if (targetm.have_tls)
112 set_decl_tls_model (ic_tuple_var, decl_default_tls_model (ic_tuple_var));
115 /* Create the type and function decls for the interface with gcov. */
117 void
118 gimple_init_gcov_profiler (void)
120 tree interval_profiler_fn_type;
121 tree pow2_profiler_fn_type;
122 tree topn_values_profiler_fn_type;
123 tree gcov_type_ptr;
124 tree ic_profiler_fn_type;
125 tree average_profiler_fn_type;
126 const char *fn_name;
128 if (!gcov_type_node)
130 const char *fn_suffix
131 = flag_profile_update == PROFILE_UPDATE_ATOMIC ? "_atomic" : "";
133 gcov_type_node = get_gcov_type ();
134 gcov_type_ptr = build_pointer_type (gcov_type_node);
136 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
137 interval_profiler_fn_type
138 = build_function_type_list (void_type_node,
139 gcov_type_ptr, gcov_type_node,
140 integer_type_node,
141 unsigned_type_node, NULL_TREE);
142 fn_name = concat ("__gcov_interval_profiler", fn_suffix, NULL);
143 tree_interval_profiler_fn = build_fn_decl (fn_name,
144 interval_profiler_fn_type);
145 free (CONST_CAST (char *, fn_name));
146 TREE_NOTHROW (tree_interval_profiler_fn) = 1;
147 DECL_ATTRIBUTES (tree_interval_profiler_fn)
148 = tree_cons (get_identifier ("leaf"), NULL,
149 DECL_ATTRIBUTES (tree_interval_profiler_fn));
151 /* void (*) (gcov_type *, gcov_type) */
152 pow2_profiler_fn_type
153 = build_function_type_list (void_type_node,
154 gcov_type_ptr, gcov_type_node,
155 NULL_TREE);
156 fn_name = concat ("__gcov_pow2_profiler", fn_suffix, NULL);
157 tree_pow2_profiler_fn = build_fn_decl (fn_name, pow2_profiler_fn_type);
158 free (CONST_CAST (char *, fn_name));
159 TREE_NOTHROW (tree_pow2_profiler_fn) = 1;
160 DECL_ATTRIBUTES (tree_pow2_profiler_fn)
161 = tree_cons (get_identifier ("leaf"), NULL,
162 DECL_ATTRIBUTES (tree_pow2_profiler_fn));
164 /* void (*) (gcov_type *, gcov_type) */
165 topn_values_profiler_fn_type
166 = build_function_type_list (void_type_node,
167 gcov_type_ptr, gcov_type_node,
168 NULL_TREE);
169 fn_name = concat ("__gcov_topn_values_profiler", fn_suffix, NULL);
170 tree_topn_values_profiler_fn
171 = build_fn_decl (fn_name, topn_values_profiler_fn_type);
172 free (CONST_CAST (char *, fn_name));
174 TREE_NOTHROW (tree_topn_values_profiler_fn) = 1;
175 DECL_ATTRIBUTES (tree_topn_values_profiler_fn)
176 = tree_cons (get_identifier ("leaf"), NULL,
177 DECL_ATTRIBUTES (tree_topn_values_profiler_fn));
179 init_ic_make_global_vars ();
181 /* void (*) (gcov_type, void *) */
182 ic_profiler_fn_type
183 = build_function_type_list (void_type_node,
184 gcov_type_node,
185 ptr_type_node,
186 NULL_TREE);
187 fn_name = concat ("__gcov_indirect_call_profiler_v4", fn_suffix, NULL);
188 tree_indirect_call_profiler_fn
189 = build_fn_decl (fn_name, ic_profiler_fn_type);
190 free (CONST_CAST (char *, fn_name));
192 TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
193 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
194 = tree_cons (get_identifier ("leaf"), NULL,
195 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn));
197 tree_time_profiler_counter
198 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
199 get_identifier ("__gcov_time_profiler_counter"),
200 get_gcov_type ());
201 TREE_PUBLIC (tree_time_profiler_counter) = 1;
202 DECL_EXTERNAL (tree_time_profiler_counter) = 1;
203 TREE_STATIC (tree_time_profiler_counter) = 1;
204 DECL_ARTIFICIAL (tree_time_profiler_counter) = 1;
205 DECL_INITIAL (tree_time_profiler_counter) = NULL;
207 /* void (*) (gcov_type *, gcov_type) */
208 average_profiler_fn_type
209 = build_function_type_list (void_type_node,
210 gcov_type_ptr, gcov_type_node, NULL_TREE);
211 fn_name = concat ("__gcov_average_profiler", fn_suffix, NULL);
212 tree_average_profiler_fn = build_fn_decl (fn_name,
213 average_profiler_fn_type);
214 free (CONST_CAST (char *, fn_name));
215 TREE_NOTHROW (tree_average_profiler_fn) = 1;
216 DECL_ATTRIBUTES (tree_average_profiler_fn)
217 = tree_cons (get_identifier ("leaf"), NULL,
218 DECL_ATTRIBUTES (tree_average_profiler_fn));
219 fn_name = concat ("__gcov_ior_profiler", fn_suffix, NULL);
220 tree_ior_profiler_fn = build_fn_decl (fn_name, average_profiler_fn_type);
221 free (CONST_CAST (char *, fn_name));
222 TREE_NOTHROW (tree_ior_profiler_fn) = 1;
223 DECL_ATTRIBUTES (tree_ior_profiler_fn)
224 = tree_cons (get_identifier ("leaf"), NULL,
225 DECL_ATTRIBUTES (tree_ior_profiler_fn));
227 /* LTO streamer needs assembler names. Because we create these decls
228 late, we need to initialize them by hand. */
229 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn);
230 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn);
231 DECL_ASSEMBLER_NAME (tree_topn_values_profiler_fn);
232 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn);
233 DECL_ASSEMBLER_NAME (tree_average_profiler_fn);
234 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
238 /* If RESULT is not null, then output instructions as GIMPLE trees to assign
239 the updated counter from CALL of FUNC to RESULT. Insert the CALL and the
240 optional assignment instructions to GSI. Use NAME for temporary values. */
242 static inline void
243 gen_assign_counter_update (gimple_stmt_iterator *gsi, gcall *call, tree func,
244 tree result, const char *name)
246 if (result)
248 tree result_type = TREE_TYPE (TREE_TYPE (func));
249 tree tmp = make_temp_ssa_name (result_type, NULL, name);
250 gimple_set_lhs (call, tmp);
251 gsi_insert_after (gsi, call, GSI_NEW_STMT);
252 gassign *assign = gimple_build_assign (result, tmp);
253 gsi_insert_after (gsi, assign, GSI_NEW_STMT);
255 else
256 gsi_insert_after (gsi, call, GSI_NEW_STMT);
259 /* Output instructions as GIMPLE trees to increment the COUNTER. If RESULT is
260 not null, then assign the updated counter value to RESULT. Insert the
261 instructions to GSI. Use NAME for temporary values. */
263 static inline void
264 gen_counter_update (gimple_stmt_iterator *gsi, tree counter, tree result,
265 const char *name)
267 tree type = gcov_type_node;
268 tree addr = build_fold_addr_expr (counter);
269 tree one = build_int_cst (type, 1);
270 tree relaxed = build_int_cst (integer_type_node, MEMMODEL_RELAXED);
272 if (flag_profile_update == PROFILE_UPDATE_ATOMIC)
274 /* __atomic_fetch_add (&counter, 1, MEMMODEL_RELAXED); */
275 tree f = builtin_decl_explicit (TYPE_PRECISION (type) > 32
276 ? BUILT_IN_ATOMIC_ADD_FETCH_8:
277 BUILT_IN_ATOMIC_ADD_FETCH_4);
278 gcall *call = gimple_build_call (f, 3, addr, one, relaxed);
279 gen_assign_counter_update (gsi, call, f, result, name);
281 else
283 tree tmp1 = make_temp_ssa_name (type, NULL, name);
284 gassign *assign1 = gimple_build_assign (tmp1, counter);
285 gsi_insert_after (gsi, assign1, GSI_NEW_STMT);
286 tree tmp2 = make_temp_ssa_name (type, NULL, name);
287 gassign *assign2 = gimple_build_assign (tmp2, PLUS_EXPR, tmp1, one);
288 gsi_insert_after (gsi, assign2, GSI_NEW_STMT);
289 gassign *assign3 = gimple_build_assign (counter, tmp2);
290 gsi_insert_after (gsi, assign3, GSI_NEW_STMT);
291 if (result)
293 gassign *assign4 = gimple_build_assign (result, tmp2);
294 gsi_insert_after (gsi, assign4, GSI_NEW_STMT);
299 /* Output instructions as GIMPLE trees to increment the edge
300 execution count, and insert them on E. */
302 void
303 gimple_gen_edge_profiler (int edgeno, edge e)
305 gimple_stmt_iterator gsi = gsi_last (PENDING_STMT (e));
306 tree counter = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
307 gen_counter_update (&gsi, counter, NULL_TREE, "PROF_edge_counter");
310 /* Emits code to get VALUE to instrument at GSI, and returns the
311 variable containing the value. */
313 static tree
314 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
316 tree val = value->hvalue.value;
317 if (POINTER_TYPE_P (TREE_TYPE (val)))
318 val = fold_convert (build_nonstandard_integer_type
319 (TYPE_PRECISION (TREE_TYPE (val)), 1), val);
320 return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
321 true, NULL_TREE, true, GSI_SAME_STMT);
324 /* Output instructions as GIMPLE trees to increment the interval histogram
325 counter. VALUE is the expression whose value is profiled. TAG is the
326 tag of the section for counters, BASE is offset of the counter position. */
328 void
329 gimple_gen_interval_profiler (histogram_value value, unsigned tag)
331 gimple *stmt = value->hvalue.stmt;
332 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
333 tree ref = tree_coverage_counter_ref (tag, 0), ref_ptr;
334 gcall *call;
335 tree val;
336 tree start = build_int_cst_type (integer_type_node,
337 value->hdata.intvl.int_start);
338 tree steps = build_int_cst_type (unsigned_type_node,
339 value->hdata.intvl.steps);
341 ref_ptr = force_gimple_operand_gsi (&gsi,
342 build_addr (ref),
343 true, NULL_TREE, true, GSI_SAME_STMT);
344 val = prepare_instrumented_value (&gsi, value);
345 call = gimple_build_call (tree_interval_profiler_fn, 4,
346 ref_ptr, val, start, steps);
347 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
350 /* Output instructions as GIMPLE trees to increment the power of two histogram
351 counter. VALUE is the expression whose value is profiled. TAG is the tag
352 of the section for counters. */
354 void
355 gimple_gen_pow2_profiler (histogram_value value, unsigned tag)
357 gimple *stmt = value->hvalue.stmt;
358 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
359 tree ref_ptr = tree_coverage_counter_addr (tag, 0);
360 gcall *call;
361 tree val;
363 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
364 true, NULL_TREE, true, GSI_SAME_STMT);
365 val = prepare_instrumented_value (&gsi, value);
366 call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val);
367 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
370 /* Output instructions as GIMPLE trees for code to find the most N common
371 values. VALUE is the expression whose value is profiled. TAG is the tag
372 of the section for counters. */
374 void
375 gimple_gen_topn_values_profiler (histogram_value value, unsigned tag)
377 gimple *stmt = value->hvalue.stmt;
378 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
379 tree ref_ptr = tree_coverage_counter_addr (tag, 0);
380 gcall *call;
381 tree val;
383 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
384 true, NULL_TREE, true, GSI_SAME_STMT);
385 val = prepare_instrumented_value (&gsi, value);
386 call = gimple_build_call (tree_topn_values_profiler_fn, 2, ref_ptr, val);
387 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
391 /* Output instructions as GIMPLE trees for code to find the most
392 common called function in indirect call.
393 VALUE is the call expression whose indirect callee is profiled.
394 TAG is the tag of the section for counters. */
396 void
397 gimple_gen_ic_profiler (histogram_value value, unsigned tag)
399 tree tmp1;
400 gassign *stmt1, *stmt2, *stmt3;
401 gimple *stmt = value->hvalue.stmt;
402 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
403 tree ref_ptr = tree_coverage_counter_addr (tag, 0);
405 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
406 true, NULL_TREE, true, GSI_SAME_STMT);
408 /* Insert code:
410 stmt1: __gcov_indirect_call.counters = get_relevant_counter_ptr ();
411 stmt2: tmp1 = (void *) (indirect call argument value)
412 stmt3: __gcov_indirect_call.callee = tmp1;
414 Example:
415 f_1 = foo;
416 __gcov_indirect_call.counters = &__gcov4.main[0];
417 PROF_fn_9 = f_1;
418 __gcov_indirect_call.callee = PROF_fn_9;
419 _4 = f_1 ();
422 tree gcov_type_ptr = build_pointer_type (get_gcov_type ());
424 tree counter_ref = build3 (COMPONENT_REF, gcov_type_ptr,
425 ic_tuple_var, ic_tuple_counters_field, NULL_TREE);
427 stmt1 = gimple_build_assign (counter_ref, ref_ptr);
428 tmp1 = make_temp_ssa_name (ptr_type_node, NULL, "PROF_fn");
429 stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
430 tree callee_ref = build3 (COMPONENT_REF, ptr_type_node,
431 ic_tuple_var, ic_tuple_callee_field, NULL_TREE);
432 stmt3 = gimple_build_assign (callee_ref, tmp1);
434 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
435 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
436 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
440 /* Output instructions as GIMPLE trees for code to find the most
441 common called function in indirect call. Insert instructions at the
442 beginning of every possible called function.
445 void
446 gimple_gen_ic_func_profiler (void)
448 struct cgraph_node * c_node = cgraph_node::get (current_function_decl);
449 gcall *stmt1;
450 tree tree_uid, cur_func, void0;
452 if (c_node->only_called_directly_p ())
453 return;
455 gimple_init_gcov_profiler ();
457 basic_block entry = ENTRY_BLOCK_PTR_FOR_FN (cfun);
458 basic_block cond_bb = split_edge (single_succ_edge (entry));
459 basic_block update_bb = split_edge (single_succ_edge (cond_bb));
461 /* We need to do an extra split in order to not create an input
462 for a possible PHI node. */
463 split_edge (single_succ_edge (update_bb));
465 edge true_edge = single_succ_edge (cond_bb);
466 true_edge->flags = EDGE_TRUE_VALUE;
468 profile_probability probability;
469 if (DECL_VIRTUAL_P (current_function_decl))
470 probability = profile_probability::very_likely ();
471 else
472 probability = profile_probability::unlikely ();
474 true_edge->probability = probability;
475 edge e = make_edge (cond_bb, single_succ_edge (update_bb)->dest,
476 EDGE_FALSE_VALUE);
477 e->probability = true_edge->probability.invert ();
479 /* Insert code:
481 if (__gcov_indirect_call.callee != NULL)
482 __gcov_indirect_call_profiler_v3 (profile_id, &current_function_decl);
484 The function __gcov_indirect_call_profiler_v3 is responsible for
485 resetting __gcov_indirect_call.callee to NULL. */
487 gimple_stmt_iterator gsi = gsi_start_bb (cond_bb);
488 void0 = build_int_cst (ptr_type_node, 0);
490 tree callee_ref = build3 (COMPONENT_REF, ptr_type_node,
491 ic_tuple_var, ic_tuple_callee_field, NULL_TREE);
493 tree ref = force_gimple_operand_gsi (&gsi, callee_ref, true, NULL_TREE,
494 true, GSI_SAME_STMT);
496 gcond *cond = gimple_build_cond (NE_EXPR, ref,
497 void0, NULL, NULL);
498 gsi_insert_before (&gsi, cond, GSI_NEW_STMT);
500 gsi = gsi_after_labels (update_bb);
502 cur_func = force_gimple_operand_gsi (&gsi,
503 build_addr (current_function_decl),
504 true, NULL_TREE,
505 true, GSI_SAME_STMT);
506 tree_uid = build_int_cst
507 (gcov_type_node,
508 cgraph_node::get (current_function_decl)->profile_id);
509 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2,
510 tree_uid, cur_func);
511 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
514 /* Output instructions as GIMPLE tree at the beginning for each function.
515 TAG is the tag of the section for counters, BASE is offset of the
516 counter position and GSI is the iterator we place the counter. */
518 void
519 gimple_gen_time_profiler (unsigned tag)
521 tree type = get_gcov_type ();
522 basic_block entry = ENTRY_BLOCK_PTR_FOR_FN (cfun);
523 basic_block cond_bb = split_edge (single_succ_edge (entry));
524 basic_block update_bb = split_edge (single_succ_edge (cond_bb));
526 /* We need to do an extra split in order to not create an input
527 for a possible PHI node. */
528 split_edge (single_succ_edge (update_bb));
530 edge true_edge = single_succ_edge (cond_bb);
531 true_edge->flags = EDGE_TRUE_VALUE;
532 true_edge->probability = profile_probability::unlikely ();
533 edge e
534 = make_edge (cond_bb, single_succ_edge (update_bb)->dest, EDGE_FALSE_VALUE);
535 e->probability = true_edge->probability.invert ();
537 gimple_stmt_iterator gsi = gsi_start_bb (cond_bb);
538 tree original_ref = tree_coverage_counter_ref (tag, 0);
539 tree ref = force_gimple_operand_gsi (&gsi, original_ref, true, NULL_TREE,
540 true, GSI_SAME_STMT);
542 /* Emit: if (counters[0] != 0). */
543 gcond *cond = gimple_build_cond (EQ_EXPR, ref, build_int_cst (type, 0),
544 NULL, NULL);
545 gsi_insert_before (&gsi, cond, GSI_NEW_STMT);
547 /* Emit: counters[0] = ++__gcov_time_profiler_counter. */
548 gsi = gsi_start_bb (update_bb);
549 gen_counter_update (&gsi, tree_time_profiler_counter, original_ref,
550 "PROF_time_profile");
553 /* Output instructions as GIMPLE trees to increment the average histogram
554 counter. VALUE is the expression whose value is profiled. TAG is the
555 tag of the section for counters, BASE is offset of the counter position. */
557 void
558 gimple_gen_average_profiler (histogram_value value, unsigned tag)
560 gimple *stmt = value->hvalue.stmt;
561 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
562 tree ref_ptr = tree_coverage_counter_addr (tag, 0);
563 gcall *call;
564 tree val;
566 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
567 true, NULL_TREE,
568 true, GSI_SAME_STMT);
569 val = prepare_instrumented_value (&gsi, value);
570 call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
571 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
574 /* Output instructions as GIMPLE trees to increment the ior histogram
575 counter. VALUE is the expression whose value is profiled. TAG is the
576 tag of the section for counters, BASE is offset of the counter position. */
578 void
579 gimple_gen_ior_profiler (histogram_value value, unsigned tag)
581 gimple *stmt = value->hvalue.stmt;
582 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
583 tree ref_ptr = tree_coverage_counter_addr (tag, 0);
584 gcall *call;
585 tree val;
587 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
588 true, NULL_TREE, true, GSI_SAME_STMT);
589 val = prepare_instrumented_value (&gsi, value);
590 call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
591 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
594 static vec<regex_t> profile_filter_files;
595 static vec<regex_t> profile_exclude_files;
597 /* Parse list of provided REGEX (separated with semi-collon) and
598 create expressions (of type regex_t) and save them into V vector.
599 If there is a regular expression parsing error, error message is
600 printed for FLAG_NAME. */
602 static void
603 parse_profile_filter (const char *regex, vec<regex_t> *v,
604 const char *flag_name)
606 v->create (4);
607 if (regex != NULL)
609 char *str = xstrdup (regex);
610 for (char *p = strtok (str, ";"); p != NULL; p = strtok (NULL, ";"))
612 regex_t r;
613 if (regcomp (&r, p, REG_EXTENDED | REG_NOSUB) != 0)
615 error ("invalid regular expression %qs in %qs",
616 p, flag_name);
617 return;
620 v->safe_push (r);
625 /* Parse values of -fprofile-filter-files and -fprofile-exclude-files
626 options. */
628 static void
629 parse_profile_file_filtering ()
631 parse_profile_filter (flag_profile_filter_files, &profile_filter_files,
632 "-fprofile-filter-files");
633 parse_profile_filter (flag_profile_exclude_files, &profile_exclude_files,
634 "-fprofile-exclude-files");
637 /* Parse vectors of regular expressions. */
639 static void
640 release_profile_file_filtering ()
642 profile_filter_files.release ();
643 profile_exclude_files.release ();
646 /* Return true when FILENAME should be instrumented based on
647 -fprofile-filter-files and -fprofile-exclude-files options. */
649 static bool
650 include_source_file_for_profile (const char *filename)
652 /* First check whether file is included in flag_profile_exclude_files. */
653 for (unsigned i = 0; i < profile_exclude_files.length (); i++)
654 if (regexec (&profile_exclude_files[i],
655 filename, 0, NULL, 0) == REG_NOERROR)
656 return false;
658 /* For non-empty flag_profile_filter_files include only files matching a
659 regex in the flag. */
660 if (profile_filter_files.is_empty ())
661 return true;
663 for (unsigned i = 0; i < profile_filter_files.length (); i++)
664 if (regexec (&profile_filter_files[i], filename, 0, NULL, 0) == REG_NOERROR)
665 return true;
667 return false;
670 #ifndef HAVE_sync_compare_and_swapsi
671 #define HAVE_sync_compare_and_swapsi 0
672 #endif
673 #ifndef HAVE_atomic_compare_and_swapsi
674 #define HAVE_atomic_compare_and_swapsi 0
675 #endif
677 #ifndef HAVE_sync_compare_and_swapdi
678 #define HAVE_sync_compare_and_swapdi 0
679 #endif
680 #ifndef HAVE_atomic_compare_and_swapdi
681 #define HAVE_atomic_compare_and_swapdi 0
682 #endif
684 /* Profile all functions in the callgraph. */
686 static unsigned int
687 tree_profiling (void)
689 struct cgraph_node *node;
691 /* Verify whether we can utilize atomic update operations. */
692 bool can_support_atomic = false;
693 unsigned HOST_WIDE_INT gcov_type_size
694 = tree_to_uhwi (TYPE_SIZE_UNIT (get_gcov_type ()));
695 if (gcov_type_size == 4)
696 can_support_atomic
697 = HAVE_sync_compare_and_swapsi || HAVE_atomic_compare_and_swapsi;
698 else if (gcov_type_size == 8)
699 can_support_atomic
700 = HAVE_sync_compare_and_swapdi || HAVE_atomic_compare_and_swapdi;
702 if (flag_profile_update == PROFILE_UPDATE_ATOMIC
703 && !can_support_atomic)
705 warning (0, "target does not support atomic profile update, "
706 "single mode is selected");
707 flag_profile_update = PROFILE_UPDATE_SINGLE;
709 else if (flag_profile_update == PROFILE_UPDATE_PREFER_ATOMIC)
710 flag_profile_update = can_support_atomic
711 ? PROFILE_UPDATE_ATOMIC : PROFILE_UPDATE_SINGLE;
713 /* This is a small-ipa pass that gets called only once, from
714 cgraphunit.cc:ipa_passes(). */
715 gcc_assert (symtab->state == IPA_SSA);
717 init_node_map (true);
718 parse_profile_file_filtering ();
720 FOR_EACH_DEFINED_FUNCTION (node)
722 bool thunk = false;
723 if (!gimple_has_body_p (node->decl) && !node->thunk)
724 continue;
726 /* Don't profile functions produced for builtin stuff. */
727 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
728 continue;
730 if (lookup_attribute ("no_profile_instrument_function",
731 DECL_ATTRIBUTES (node->decl)))
732 continue;
733 /* Do not instrument extern inline functions when testing coverage.
734 While this is not perfectly consistent (early inlined extern inlines
735 will get acocunted), testsuite expects that. */
736 if (DECL_EXTERNAL (node->decl)
737 && flag_test_coverage)
738 continue;
740 const char *file = LOCATION_FILE (DECL_SOURCE_LOCATION (node->decl));
741 if (!include_source_file_for_profile (file))
742 continue;
744 if (node->thunk)
746 /* We cannot expand variadic thunks to Gimple. */
747 if (stdarg_p (TREE_TYPE (node->decl)))
748 continue;
749 thunk = true;
750 /* When generate profile, expand thunk to gimple so it can be
751 instrumented same way as other functions. */
752 if (profile_arc_flag)
753 expand_thunk (node, false, true);
754 /* Read cgraph profile but keep function as thunk at profile-use
755 time. */
756 else
758 read_thunk_profile (node);
759 continue;
763 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
765 if (dump_file)
766 dump_function_header (dump_file, cfun->decl, dump_flags);
768 /* Local pure-const may imply need to fixup the cfg. */
769 if (gimple_has_body_p (node->decl)
770 && (execute_fixup_cfg () & TODO_cleanup_cfg))
771 cleanup_tree_cfg ();
773 branch_prob (thunk);
775 if (! flag_branch_probabilities
776 && flag_profile_values)
777 gimple_gen_ic_func_profiler ();
779 if (flag_branch_probabilities
780 && !thunk
781 && flag_profile_values
782 && flag_value_profile_transformations
783 && profile_status_for_fn (cfun) == PROFILE_READ)
784 gimple_value_profile_transformations ();
786 /* The above could hose dominator info. Currently there is
787 none coming in, this is a safety valve. It should be
788 easy to adjust it, if and when there is some. */
789 free_dominance_info (CDI_DOMINATORS);
790 free_dominance_info (CDI_POST_DOMINATORS);
791 pop_cfun ();
794 release_profile_file_filtering ();
796 /* Drop pure/const flags from instrumented functions. */
797 if (profile_arc_flag || flag_test_coverage)
798 FOR_EACH_DEFINED_FUNCTION (node)
800 if (!gimple_has_body_p (node->decl)
801 || !(!node->clone_of
802 || node->decl != node->clone_of->decl))
803 continue;
805 /* Don't profile functions produced for builtin stuff. */
806 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
807 continue;
809 node->set_const_flag (false, false);
810 node->set_pure_flag (false, false);
813 /* Update call statements and rebuild the cgraph. */
814 FOR_EACH_DEFINED_FUNCTION (node)
816 basic_block bb;
818 if (!gimple_has_body_p (node->decl)
819 || !(!node->clone_of
820 || node->decl != node->clone_of->decl))
821 continue;
823 /* Don't profile functions produced for builtin stuff. */
824 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
825 continue;
827 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
829 if (profile_arc_flag || flag_test_coverage)
830 FOR_EACH_BB_FN (bb, cfun)
832 gimple_stmt_iterator gsi;
833 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
835 gcall *call = dyn_cast <gcall *> (gsi_stmt (gsi));
836 if (!call || gimple_call_internal_p (call))
837 continue;
839 /* We do not clear pure/const on decls without body. */
840 tree fndecl = gimple_call_fndecl (call);
841 cgraph_node *callee;
842 if (fndecl
843 && (callee = cgraph_node::get (fndecl))
844 && callee->get_availability (node) == AVAIL_NOT_AVAILABLE)
845 continue;
847 /* Drop the const attribute from the call type (the pure
848 attribute is not available on types). */
849 tree fntype = gimple_call_fntype (call);
850 if (fntype && TYPE_READONLY (fntype))
852 int quals = TYPE_QUALS (fntype) & ~TYPE_QUAL_CONST;
853 fntype = build_qualified_type (fntype, quals);
854 gimple_call_set_fntype (call, fntype);
857 /* Update virtual operands of calls to no longer const/pure
858 functions. */
859 update_stmt (call);
863 /* re-merge split blocks. */
864 cleanup_tree_cfg ();
865 update_ssa (TODO_update_ssa);
867 cgraph_edge::rebuild_edges ();
869 pop_cfun ();
872 handle_missing_profiles ();
874 del_node_map ();
875 return 0;
878 namespace {
880 const pass_data pass_data_ipa_tree_profile =
882 SIMPLE_IPA_PASS, /* type */
883 "profile", /* name */
884 OPTGROUP_NONE, /* optinfo_flags */
885 TV_IPA_PROFILE, /* tv_id */
886 0, /* properties_required */
887 0, /* properties_provided */
888 0, /* properties_destroyed */
889 0, /* todo_flags_start */
890 TODO_dump_symtab, /* todo_flags_finish */
893 class pass_ipa_tree_profile : public simple_ipa_opt_pass
895 public:
896 pass_ipa_tree_profile (gcc::context *ctxt)
897 : simple_ipa_opt_pass (pass_data_ipa_tree_profile, ctxt)
900 /* opt_pass methods: */
901 bool gate (function *) final override;
902 unsigned int execute (function *) final override { return tree_profiling (); }
904 }; // class pass_ipa_tree_profile
906 bool
907 pass_ipa_tree_profile::gate (function *)
909 /* When profile instrumentation, use or test coverage shall be performed.
910 But for AutoFDO, this there is no instrumentation, thus this pass is
911 disabled. */
912 return (!in_lto_p && !flag_auto_profile
913 && (flag_branch_probabilities || flag_test_coverage
914 || profile_arc_flag));
917 } // anon namespace
919 simple_ipa_opt_pass *
920 make_pass_ipa_tree_profile (gcc::context *ctxt)
922 return new pass_ipa_tree_profile (ctxt);
925 #include "gt-tree-profile.h"