tree-optimization/114485 - neg induction with partial vectors
[official-gcc.git] / gcc / tree-profile.cc
blob625f7e9229ade58c35c14d209067bc835a99d0e7
1 /* Calculate branch probabilities, and basic block execution counts.
2 Copyright (C) 1990-2024 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 /* Types of counter update methods.
78 By default, the counter updates are done for a single threaded system
79 (COUNTER_UPDATE_SINGLE_THREAD).
81 If the user selected atomic profile counter updates
82 (-fprofile-update=atomic), then the counter updates will be done atomically
83 on a best-effort basis. One of three methods to do the counter updates is
84 selected according to the target capabilities.
86 Ideally, the counter updates are done through atomic operations in hardware
87 (COUNTER_UPDATE_ATOMIC_BUILTIN).
89 If the target supports only 32-bit atomic increments and gcov_type_node is a
90 64-bit integer type, then for the profile edge counters the increment is
91 performed through two separate 32-bit atomic increments
92 (COUNTER_UPDATE_ATOMIC_SPLIT or COUNTER_UPDATE_ATOMIC_PARTIAL). If the
93 target supports libatomic (targetm.have_libatomic), then other counter
94 updates are carried out by libatomic calls (COUNTER_UPDATE_ATOMIC_SPLIT).
95 If the target does not support libatomic, then the other counter updates are
96 not done atomically (COUNTER_UPDATE_ATOMIC_PARTIAL) and a warning is
97 issued.
99 If the target does not support atomic operations in hardware, however, it
100 supports libatomic, then all updates are carried out by libatomic calls
101 (COUNTER_UPDATE_ATOMIC_BUILTIN). */
102 enum counter_update_method {
103 COUNTER_UPDATE_SINGLE_THREAD,
104 COUNTER_UPDATE_ATOMIC_BUILTIN,
105 COUNTER_UPDATE_ATOMIC_SPLIT,
106 COUNTER_UPDATE_ATOMIC_PARTIAL
109 static counter_update_method counter_update = COUNTER_UPDATE_SINGLE_THREAD;
111 /* Do initialization work for the edge profiler. */
113 /* Add code:
114 __thread gcov* __gcov_indirect_call.counters; // pointer to actual counter
115 __thread void* __gcov_indirect_call.callee; // actual callee address
116 __thread int __gcov_function_counter; // time profiler function counter
118 static void
119 init_ic_make_global_vars (void)
121 tree gcov_type_ptr;
123 gcov_type_ptr = build_pointer_type (get_gcov_type ());
125 tree tuple_type = lang_hooks.types.make_type (RECORD_TYPE);
127 /* callee */
128 ic_tuple_callee_field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
129 ptr_type_node);
131 /* counters */
132 ic_tuple_counters_field = build_decl (BUILTINS_LOCATION, FIELD_DECL,
133 NULL_TREE, gcov_type_ptr);
134 DECL_CHAIN (ic_tuple_counters_field) = ic_tuple_callee_field;
136 finish_builtin_struct (tuple_type, "indirect_call_tuple",
137 ic_tuple_counters_field, NULL_TREE);
139 ic_tuple_var
140 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
141 get_identifier ("__gcov_indirect_call"), tuple_type);
142 TREE_PUBLIC (ic_tuple_var) = 1;
143 DECL_ARTIFICIAL (ic_tuple_var) = 1;
144 DECL_INITIAL (ic_tuple_var) = NULL;
145 DECL_EXTERNAL (ic_tuple_var) = 1;
146 if (targetm.have_tls)
147 set_decl_tls_model (ic_tuple_var, decl_default_tls_model (ic_tuple_var));
150 /* Create the type and function decls for the interface with gcov. */
152 void
153 gimple_init_gcov_profiler (void)
155 tree interval_profiler_fn_type;
156 tree pow2_profiler_fn_type;
157 tree topn_values_profiler_fn_type;
158 tree gcov_type_ptr;
159 tree ic_profiler_fn_type;
160 tree average_profiler_fn_type;
161 const char *fn_name;
163 if (!gcov_type_node)
165 const char *fn_suffix
166 = flag_profile_update == PROFILE_UPDATE_ATOMIC ? "_atomic" : "";
168 gcov_type_node = get_gcov_type ();
169 gcov_type_ptr = build_pointer_type (gcov_type_node);
171 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
172 interval_profiler_fn_type
173 = build_function_type_list (void_type_node,
174 gcov_type_ptr, gcov_type_node,
175 integer_type_node,
176 unsigned_type_node, NULL_TREE);
177 fn_name = concat ("__gcov_interval_profiler", fn_suffix, NULL);
178 tree_interval_profiler_fn = build_fn_decl (fn_name,
179 interval_profiler_fn_type);
180 free (CONST_CAST (char *, fn_name));
181 TREE_NOTHROW (tree_interval_profiler_fn) = 1;
182 DECL_ATTRIBUTES (tree_interval_profiler_fn)
183 = tree_cons (get_identifier ("leaf"), NULL,
184 DECL_ATTRIBUTES (tree_interval_profiler_fn));
186 /* void (*) (gcov_type *, gcov_type) */
187 pow2_profiler_fn_type
188 = build_function_type_list (void_type_node,
189 gcov_type_ptr, gcov_type_node,
190 NULL_TREE);
191 fn_name = concat ("__gcov_pow2_profiler", fn_suffix, NULL);
192 tree_pow2_profiler_fn = build_fn_decl (fn_name, pow2_profiler_fn_type);
193 free (CONST_CAST (char *, fn_name));
194 TREE_NOTHROW (tree_pow2_profiler_fn) = 1;
195 DECL_ATTRIBUTES (tree_pow2_profiler_fn)
196 = tree_cons (get_identifier ("leaf"), NULL,
197 DECL_ATTRIBUTES (tree_pow2_profiler_fn));
199 /* void (*) (gcov_type *, gcov_type) */
200 topn_values_profiler_fn_type
201 = build_function_type_list (void_type_node,
202 gcov_type_ptr, gcov_type_node,
203 NULL_TREE);
204 fn_name = concat ("__gcov_topn_values_profiler", fn_suffix, NULL);
205 tree_topn_values_profiler_fn
206 = build_fn_decl (fn_name, topn_values_profiler_fn_type);
207 free (CONST_CAST (char *, fn_name));
209 TREE_NOTHROW (tree_topn_values_profiler_fn) = 1;
210 DECL_ATTRIBUTES (tree_topn_values_profiler_fn)
211 = tree_cons (get_identifier ("leaf"), NULL,
212 DECL_ATTRIBUTES (tree_topn_values_profiler_fn));
214 init_ic_make_global_vars ();
216 /* void (*) (gcov_type, void *) */
217 ic_profiler_fn_type
218 = build_function_type_list (void_type_node,
219 gcov_type_node,
220 ptr_type_node,
221 NULL_TREE);
222 fn_name = concat ("__gcov_indirect_call_profiler_v4", fn_suffix, NULL);
223 tree_indirect_call_profiler_fn
224 = build_fn_decl (fn_name, ic_profiler_fn_type);
225 free (CONST_CAST (char *, fn_name));
227 TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
228 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
229 = tree_cons (get_identifier ("leaf"), NULL,
230 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn));
232 tree_time_profiler_counter
233 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
234 get_identifier ("__gcov_time_profiler_counter"),
235 get_gcov_type ());
236 TREE_PUBLIC (tree_time_profiler_counter) = 1;
237 DECL_EXTERNAL (tree_time_profiler_counter) = 1;
238 TREE_STATIC (tree_time_profiler_counter) = 1;
239 DECL_ARTIFICIAL (tree_time_profiler_counter) = 1;
240 DECL_INITIAL (tree_time_profiler_counter) = NULL;
242 /* void (*) (gcov_type *, gcov_type) */
243 average_profiler_fn_type
244 = build_function_type_list (void_type_node,
245 gcov_type_ptr, gcov_type_node, NULL_TREE);
246 fn_name = concat ("__gcov_average_profiler", fn_suffix, NULL);
247 tree_average_profiler_fn = build_fn_decl (fn_name,
248 average_profiler_fn_type);
249 free (CONST_CAST (char *, fn_name));
250 TREE_NOTHROW (tree_average_profiler_fn) = 1;
251 DECL_ATTRIBUTES (tree_average_profiler_fn)
252 = tree_cons (get_identifier ("leaf"), NULL,
253 DECL_ATTRIBUTES (tree_average_profiler_fn));
254 fn_name = concat ("__gcov_ior_profiler", fn_suffix, NULL);
255 tree_ior_profiler_fn = build_fn_decl (fn_name, average_profiler_fn_type);
256 free (CONST_CAST (char *, fn_name));
257 TREE_NOTHROW (tree_ior_profiler_fn) = 1;
258 DECL_ATTRIBUTES (tree_ior_profiler_fn)
259 = tree_cons (get_identifier ("leaf"), NULL,
260 DECL_ATTRIBUTES (tree_ior_profiler_fn));
262 /* LTO streamer needs assembler names. Because we create these decls
263 late, we need to initialize them by hand. */
264 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn);
265 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn);
266 DECL_ASSEMBLER_NAME (tree_topn_values_profiler_fn);
267 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn);
268 DECL_ASSEMBLER_NAME (tree_average_profiler_fn);
269 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
273 /* If RESULT is not null, then output instructions as GIMPLE trees to assign
274 the updated counter from CALL of FUNC to RESULT. Insert the CALL and the
275 optional assignment instructions to GSI. Use NAME for temporary values. */
277 static inline void
278 gen_assign_counter_update (gimple_stmt_iterator *gsi, gcall *call, tree func,
279 tree result, const char *name)
281 if (result)
283 tree result_type = TREE_TYPE (TREE_TYPE (func));
284 tree tmp1 = make_temp_ssa_name (result_type, NULL, name);
285 gimple_set_lhs (call, tmp1);
286 gsi_insert_after (gsi, call, GSI_NEW_STMT);
287 tree tmp2 = make_temp_ssa_name (TREE_TYPE (result), NULL, name);
288 gassign *assign = gimple_build_assign (tmp2, NOP_EXPR, tmp1);
289 gsi_insert_after (gsi, assign, GSI_NEW_STMT);
290 assign = gimple_build_assign (result, tmp2);
291 gsi_insert_after (gsi, assign, GSI_NEW_STMT);
293 else
294 gsi_insert_after (gsi, call, GSI_NEW_STMT);
297 /* Output instructions as GIMPLE trees to increment the COUNTER. If RESULT is
298 not null, then assign the updated counter value to RESULT. Insert the
299 instructions to GSI. Use NAME for temporary values. */
301 static inline void
302 gen_counter_update (gimple_stmt_iterator *gsi, tree counter, tree result,
303 const char *name)
305 tree type = gcov_type_node;
306 tree addr = build_fold_addr_expr (counter);
307 tree one = build_int_cst (type, 1);
308 tree relaxed = build_int_cst (integer_type_node, MEMMODEL_RELAXED);
310 if (counter_update == COUNTER_UPDATE_ATOMIC_BUILTIN
311 || (result && counter_update == COUNTER_UPDATE_ATOMIC_SPLIT))
313 /* __atomic_fetch_add (&counter, 1, MEMMODEL_RELAXED); */
314 tree f = builtin_decl_explicit (TYPE_PRECISION (type) > 32
315 ? BUILT_IN_ATOMIC_ADD_FETCH_8
316 : BUILT_IN_ATOMIC_ADD_FETCH_4);
317 gcall *call = gimple_build_call (f, 3, addr, one, relaxed);
318 gen_assign_counter_update (gsi, call, f, result, name);
320 else if (!result && (counter_update == COUNTER_UPDATE_ATOMIC_SPLIT
321 || counter_update == COUNTER_UPDATE_ATOMIC_PARTIAL))
323 /* low = __atomic_add_fetch_4 (addr, 1, MEMMODEL_RELAXED);
324 high_inc = low == 0 ? 1 : 0;
325 __atomic_add_fetch_4 (addr_high, high_inc, MEMMODEL_RELAXED); */
326 tree zero32 = build_zero_cst (uint32_type_node);
327 tree one32 = build_one_cst (uint32_type_node);
328 tree addr_high = make_temp_ssa_name (TREE_TYPE (addr), NULL, name);
329 tree four = build_int_cst (size_type_node, 4);
330 gassign *assign1 = gimple_build_assign (addr_high, POINTER_PLUS_EXPR,
331 addr, four);
332 gsi_insert_after (gsi, assign1, GSI_NEW_STMT);
333 if (WORDS_BIG_ENDIAN)
334 std::swap (addr, addr_high);
335 tree f = builtin_decl_explicit (BUILT_IN_ATOMIC_ADD_FETCH_4);
336 gcall *call1 = gimple_build_call (f, 3, addr, one, relaxed);
337 tree low = make_temp_ssa_name (uint32_type_node, NULL, name);
338 gimple_call_set_lhs (call1, low);
339 gsi_insert_after (gsi, call1, GSI_NEW_STMT);
340 tree is_zero = make_temp_ssa_name (boolean_type_node, NULL, name);
341 gassign *assign2 = gimple_build_assign (is_zero, EQ_EXPR, low,
342 zero32);
343 gsi_insert_after (gsi, assign2, GSI_NEW_STMT);
344 tree high_inc = make_temp_ssa_name (uint32_type_node, NULL, name);
345 gassign *assign3 = gimple_build_assign (high_inc, COND_EXPR,
346 is_zero, one32, zero32);
347 gsi_insert_after (gsi, assign3, GSI_NEW_STMT);
348 gcall *call2 = gimple_build_call (f, 3, addr_high, high_inc,
349 relaxed);
350 gsi_insert_after (gsi, call2, GSI_NEW_STMT);
352 else
354 tree tmp1 = make_temp_ssa_name (type, NULL, name);
355 gassign *assign1 = gimple_build_assign (tmp1, counter);
356 gsi_insert_after (gsi, assign1, GSI_NEW_STMT);
357 tree tmp2 = make_temp_ssa_name (type, NULL, name);
358 gassign *assign2 = gimple_build_assign (tmp2, PLUS_EXPR, tmp1, one);
359 gsi_insert_after (gsi, assign2, GSI_NEW_STMT);
360 gassign *assign3 = gimple_build_assign (unshare_expr (counter), tmp2);
361 gsi_insert_after (gsi, assign3, GSI_NEW_STMT);
362 if (result)
364 gassign *assign4 = gimple_build_assign (result, tmp2);
365 gsi_insert_after (gsi, assign4, GSI_NEW_STMT);
370 /* Output instructions as GIMPLE trees to increment the edge
371 execution count, and insert them on E. */
373 void
374 gimple_gen_edge_profiler (int edgeno, edge e)
376 gimple_stmt_iterator gsi = gsi_last (PENDING_STMT (e));
377 tree counter = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
378 gen_counter_update (&gsi, counter, NULL_TREE, "PROF_edge_counter");
381 /* Emits code to get VALUE to instrument at GSI, and returns the
382 variable containing the value. */
384 static tree
385 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
387 tree val = value->hvalue.value;
388 if (POINTER_TYPE_P (TREE_TYPE (val)))
389 val = fold_convert (build_nonstandard_integer_type
390 (TYPE_PRECISION (TREE_TYPE (val)), 1), val);
391 return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
392 true, NULL_TREE, true, GSI_SAME_STMT);
395 /* Output instructions as GIMPLE trees to increment the interval histogram
396 counter. VALUE is the expression whose value is profiled. TAG is the
397 tag of the section for counters, BASE is offset of the counter position. */
399 void
400 gimple_gen_interval_profiler (histogram_value value, unsigned tag)
402 gimple *stmt = value->hvalue.stmt;
403 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
404 tree ref = tree_coverage_counter_ref (tag, 0), ref_ptr;
405 gcall *call;
406 tree val;
407 tree start = build_int_cst_type (integer_type_node,
408 value->hdata.intvl.int_start);
409 tree steps = build_int_cst_type (unsigned_type_node,
410 value->hdata.intvl.steps);
412 ref_ptr = force_gimple_operand_gsi (&gsi,
413 build_addr (ref),
414 true, NULL_TREE, true, GSI_SAME_STMT);
415 val = prepare_instrumented_value (&gsi, value);
416 call = gimple_build_call (tree_interval_profiler_fn, 4,
417 ref_ptr, val, start, steps);
418 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
421 /* Output instructions as GIMPLE trees to increment the power of two histogram
422 counter. VALUE is the expression whose value is profiled. TAG is the tag
423 of the section for counters. */
425 void
426 gimple_gen_pow2_profiler (histogram_value value, unsigned tag)
428 gimple *stmt = value->hvalue.stmt;
429 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
430 tree ref_ptr = tree_coverage_counter_addr (tag, 0);
431 gcall *call;
432 tree val;
434 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
435 true, NULL_TREE, true, GSI_SAME_STMT);
436 val = prepare_instrumented_value (&gsi, value);
437 call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val);
438 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
441 /* Output instructions as GIMPLE trees for code to find the most N common
442 values. VALUE is the expression whose value is profiled. TAG is the tag
443 of the section for counters. */
445 void
446 gimple_gen_topn_values_profiler (histogram_value value, unsigned tag)
448 gimple *stmt = value->hvalue.stmt;
449 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
450 tree ref_ptr = tree_coverage_counter_addr (tag, 0);
451 gcall *call;
452 tree val;
454 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
455 true, NULL_TREE, true, GSI_SAME_STMT);
456 val = prepare_instrumented_value (&gsi, value);
457 call = gimple_build_call (tree_topn_values_profiler_fn, 2, ref_ptr, val);
458 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
462 /* Output instructions as GIMPLE trees for code to find the most
463 common called function in indirect call.
464 VALUE is the call expression whose indirect callee is profiled.
465 TAG is the tag of the section for counters. */
467 void
468 gimple_gen_ic_profiler (histogram_value value, unsigned tag)
470 tree tmp1;
471 gassign *stmt1, *stmt2, *stmt3;
472 gimple *stmt = value->hvalue.stmt;
473 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
474 tree ref_ptr = tree_coverage_counter_addr (tag, 0);
476 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
477 true, NULL_TREE, true, GSI_SAME_STMT);
479 /* Insert code:
481 stmt1: __gcov_indirect_call.counters = get_relevant_counter_ptr ();
482 stmt2: tmp1 = (void *) (indirect call argument value)
483 stmt3: __gcov_indirect_call.callee = tmp1;
485 Example:
486 f_1 = foo;
487 __gcov_indirect_call.counters = &__gcov4.main[0];
488 PROF_fn_9 = f_1;
489 __gcov_indirect_call.callee = PROF_fn_9;
490 _4 = f_1 ();
493 tree gcov_type_ptr = build_pointer_type (get_gcov_type ());
495 tree counter_ref = build3 (COMPONENT_REF, gcov_type_ptr,
496 ic_tuple_var, ic_tuple_counters_field, NULL_TREE);
498 stmt1 = gimple_build_assign (counter_ref, ref_ptr);
499 tmp1 = make_temp_ssa_name (ptr_type_node, NULL, "PROF_fn");
500 stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
501 tree callee_ref = build3 (COMPONENT_REF, ptr_type_node,
502 ic_tuple_var, ic_tuple_callee_field, NULL_TREE);
503 stmt3 = gimple_build_assign (callee_ref, tmp1);
505 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
506 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
507 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
511 /* Output instructions as GIMPLE trees for code to find the most
512 common called function in indirect call. Insert instructions at the
513 beginning of every possible called function.
516 void
517 gimple_gen_ic_func_profiler (void)
519 struct cgraph_node * c_node = cgraph_node::get (current_function_decl);
520 gcall *stmt1;
521 tree tree_uid, cur_func, void0;
523 /* Disable indirect call profiling for an IFUNC resolver and its
524 callees since it requires TLS which hasn't been set up yet when
525 the dynamic linker is resolving IFUNC symbols. See
526 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114115
528 if (c_node->only_called_directly_p ()
529 || c_node->called_by_ifunc_resolver)
530 return;
532 gimple_init_gcov_profiler ();
534 basic_block entry = ENTRY_BLOCK_PTR_FOR_FN (cfun);
535 basic_block cond_bb = split_edge (single_succ_edge (entry));
536 basic_block update_bb = split_edge (single_succ_edge (cond_bb));
538 /* We need to do an extra split in order to not create an input
539 for a possible PHI node. */
540 split_edge (single_succ_edge (update_bb));
542 edge true_edge = single_succ_edge (cond_bb);
543 true_edge->flags = EDGE_TRUE_VALUE;
545 profile_probability probability;
546 if (DECL_VIRTUAL_P (current_function_decl))
547 probability = profile_probability::very_likely ();
548 else
549 probability = profile_probability::unlikely ();
551 true_edge->probability = probability;
552 edge e = make_edge (cond_bb, single_succ_edge (update_bb)->dest,
553 EDGE_FALSE_VALUE);
554 e->probability = true_edge->probability.invert ();
556 /* Insert code:
558 if (__gcov_indirect_call.callee != NULL)
559 __gcov_indirect_call_profiler_v3 (profile_id, &current_function_decl);
561 The function __gcov_indirect_call_profiler_v3 is responsible for
562 resetting __gcov_indirect_call.callee to NULL. */
564 gimple_stmt_iterator gsi = gsi_start_bb (cond_bb);
565 void0 = build_int_cst (ptr_type_node, 0);
567 tree callee_ref = build3 (COMPONENT_REF, ptr_type_node,
568 ic_tuple_var, ic_tuple_callee_field, NULL_TREE);
570 tree ref = force_gimple_operand_gsi (&gsi, callee_ref, true, NULL_TREE,
571 true, GSI_SAME_STMT);
573 gcond *cond = gimple_build_cond (NE_EXPR, ref,
574 void0, NULL, NULL);
575 gsi_insert_before (&gsi, cond, GSI_NEW_STMT);
577 gsi = gsi_after_labels (update_bb);
579 cur_func = force_gimple_operand_gsi (&gsi,
580 build_addr (current_function_decl),
581 true, NULL_TREE,
582 true, GSI_SAME_STMT);
583 tree_uid = build_int_cst
584 (gcov_type_node,
585 cgraph_node::get (current_function_decl)->profile_id);
586 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2,
587 tree_uid, cur_func);
588 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
591 /* Output instructions as GIMPLE tree at the beginning for each function.
592 TAG is the tag of the section for counters, BASE is offset of the
593 counter position and GSI is the iterator we place the counter. */
595 void
596 gimple_gen_time_profiler (unsigned tag)
598 tree type = get_gcov_type ();
599 basic_block entry = ENTRY_BLOCK_PTR_FOR_FN (cfun);
600 basic_block cond_bb = split_edge (single_succ_edge (entry));
601 basic_block update_bb = split_edge (single_succ_edge (cond_bb));
603 /* We need to do an extra split in order to not create an input
604 for a possible PHI node. */
605 split_edge (single_succ_edge (update_bb));
607 edge true_edge = single_succ_edge (cond_bb);
608 true_edge->flags = EDGE_TRUE_VALUE;
609 true_edge->probability = profile_probability::unlikely ();
610 edge e
611 = make_edge (cond_bb, single_succ_edge (update_bb)->dest, EDGE_FALSE_VALUE);
612 e->probability = true_edge->probability.invert ();
614 gimple_stmt_iterator gsi = gsi_start_bb (cond_bb);
615 tree original_ref = tree_coverage_counter_ref (tag, 0);
616 tree ref = force_gimple_operand_gsi (&gsi, original_ref, true, NULL_TREE,
617 true, GSI_SAME_STMT);
619 /* Emit: if (counters[0] != 0). */
620 gcond *cond = gimple_build_cond (EQ_EXPR, ref, build_int_cst (type, 0),
621 NULL, NULL);
622 gsi_insert_before (&gsi, cond, GSI_NEW_STMT);
624 /* Emit: counters[0] = ++__gcov_time_profiler_counter. */
625 gsi = gsi_start_bb (update_bb);
626 gen_counter_update (&gsi, tree_time_profiler_counter, original_ref,
627 "PROF_time_profile");
630 /* Output instructions as GIMPLE trees to increment the average histogram
631 counter. VALUE is the expression whose value is profiled. TAG is the
632 tag of the section for counters, BASE is offset of the counter position. */
634 void
635 gimple_gen_average_profiler (histogram_value value, unsigned tag)
637 gimple *stmt = value->hvalue.stmt;
638 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
639 tree ref_ptr = tree_coverage_counter_addr (tag, 0);
640 gcall *call;
641 tree val;
643 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
644 true, NULL_TREE,
645 true, GSI_SAME_STMT);
646 val = prepare_instrumented_value (&gsi, value);
647 call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
648 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
651 /* Output instructions as GIMPLE trees to increment the ior histogram
652 counter. VALUE is the expression whose value is profiled. TAG is the
653 tag of the section for counters, BASE is offset of the counter position. */
655 void
656 gimple_gen_ior_profiler (histogram_value value, unsigned tag)
658 gimple *stmt = value->hvalue.stmt;
659 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
660 tree ref_ptr = tree_coverage_counter_addr (tag, 0);
661 gcall *call;
662 tree val;
664 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
665 true, NULL_TREE, true, GSI_SAME_STMT);
666 val = prepare_instrumented_value (&gsi, value);
667 call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
668 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
671 static vec<regex_t> profile_filter_files;
672 static vec<regex_t> profile_exclude_files;
674 /* Parse list of provided REGEX (separated with semi-collon) and
675 create expressions (of type regex_t) and save them into V vector.
676 If there is a regular expression parsing error, error message is
677 printed for FLAG_NAME. */
679 static void
680 parse_profile_filter (const char *regex, vec<regex_t> *v,
681 const char *flag_name)
683 v->create (4);
684 if (regex != NULL)
686 char *str = xstrdup (regex);
687 for (char *p = strtok (str, ";"); p != NULL; p = strtok (NULL, ";"))
689 regex_t r;
690 if (regcomp (&r, p, REG_EXTENDED | REG_NOSUB) != 0)
692 error ("invalid regular expression %qs in %qs",
693 p, flag_name);
694 return;
697 v->safe_push (r);
702 /* Parse values of -fprofile-filter-files and -fprofile-exclude-files
703 options. */
705 static void
706 parse_profile_file_filtering ()
708 parse_profile_filter (flag_profile_filter_files, &profile_filter_files,
709 "-fprofile-filter-files");
710 parse_profile_filter (flag_profile_exclude_files, &profile_exclude_files,
711 "-fprofile-exclude-files");
714 /* Parse vectors of regular expressions. */
716 static void
717 release_profile_file_filtering ()
719 profile_filter_files.release ();
720 profile_exclude_files.release ();
723 /* Return true when FILENAME should be instrumented based on
724 -fprofile-filter-files and -fprofile-exclude-files options. */
726 static bool
727 include_source_file_for_profile (const char *filename)
729 /* First check whether file is included in flag_profile_exclude_files. */
730 for (unsigned i = 0; i < profile_exclude_files.length (); i++)
731 if (regexec (&profile_exclude_files[i],
732 filename, 0, NULL, 0) == REG_NOERROR)
733 return false;
735 /* For non-empty flag_profile_filter_files include only files matching a
736 regex in the flag. */
737 if (profile_filter_files.is_empty ())
738 return true;
740 for (unsigned i = 0; i < profile_filter_files.length (); i++)
741 if (regexec (&profile_filter_files[i], filename, 0, NULL, 0) == REG_NOERROR)
742 return true;
744 return false;
747 #ifndef HAVE_sync_compare_and_swapsi
748 #define HAVE_sync_compare_and_swapsi 0
749 #endif
750 #ifndef HAVE_atomic_compare_and_swapsi
751 #define HAVE_atomic_compare_and_swapsi 0
752 #endif
754 #ifndef HAVE_sync_compare_and_swapdi
755 #define HAVE_sync_compare_and_swapdi 0
756 #endif
757 #ifndef HAVE_atomic_compare_and_swapdi
758 #define HAVE_atomic_compare_and_swapdi 0
759 #endif
761 /* Profile all functions in the callgraph. */
763 static unsigned int
764 tree_profiling (void)
766 struct cgraph_node *node;
768 /* Verify whether we can utilize atomic update operations. */
769 bool can_support_atomic = targetm.have_libatomic;
770 unsigned HOST_WIDE_INT gcov_type_size
771 = tree_to_uhwi (TYPE_SIZE_UNIT (get_gcov_type ()));
772 bool have_atomic_4
773 = HAVE_sync_compare_and_swapsi || HAVE_atomic_compare_and_swapsi;
774 bool have_atomic_8
775 = HAVE_sync_compare_and_swapdi || HAVE_atomic_compare_and_swapdi;
776 bool needs_split = gcov_type_size == 8 && !have_atomic_8 && have_atomic_4;
777 if (!can_support_atomic)
779 if (gcov_type_size == 4)
780 can_support_atomic = have_atomic_4;
781 else if (gcov_type_size == 8)
782 can_support_atomic = have_atomic_8;
785 if (flag_profile_update != PROFILE_UPDATE_SINGLE && needs_split)
786 counter_update = COUNTER_UPDATE_ATOMIC_PARTIAL;
788 if (flag_profile_update == PROFILE_UPDATE_ATOMIC
789 && !can_support_atomic)
791 warning (0, "target does not support atomic profile update, "
792 "single mode is selected");
793 flag_profile_update = PROFILE_UPDATE_SINGLE;
795 else if (flag_profile_update == PROFILE_UPDATE_PREFER_ATOMIC)
796 flag_profile_update
797 = can_support_atomic ? PROFILE_UPDATE_ATOMIC : PROFILE_UPDATE_SINGLE;
799 if (flag_profile_update == PROFILE_UPDATE_ATOMIC)
801 if (needs_split)
802 counter_update = COUNTER_UPDATE_ATOMIC_SPLIT;
803 else
804 counter_update = COUNTER_UPDATE_ATOMIC_BUILTIN;
807 /* This is a small-ipa pass that gets called only once, from
808 cgraphunit.cc:ipa_passes(). */
809 gcc_assert (symtab->state == IPA_SSA);
811 init_node_map (true);
812 parse_profile_file_filtering ();
814 FOR_EACH_DEFINED_FUNCTION (node)
816 bool thunk = false;
817 if (!gimple_has_body_p (node->decl) && !node->thunk)
818 continue;
820 /* Don't profile functions produced for builtin stuff. */
821 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
822 continue;
824 if (lookup_attribute ("no_profile_instrument_function",
825 DECL_ATTRIBUTES (node->decl)))
826 continue;
827 /* Do not instrument extern inline functions when testing coverage.
828 While this is not perfectly consistent (early inlined extern inlines
829 will get acocunted), testsuite expects that. */
830 if (DECL_EXTERNAL (node->decl)
831 && flag_test_coverage)
832 continue;
834 const char *file = LOCATION_FILE (DECL_SOURCE_LOCATION (node->decl));
835 if (!include_source_file_for_profile (file))
836 continue;
838 if (node->thunk)
840 /* We cannot expand variadic thunks to Gimple. */
841 if (stdarg_p (TREE_TYPE (node->decl)))
842 continue;
843 thunk = true;
844 /* When generate profile, expand thunk to gimple so it can be
845 instrumented same way as other functions. */
846 if (profile_arc_flag)
847 expand_thunk (node, false, true);
848 /* Read cgraph profile but keep function as thunk at profile-use
849 time. */
850 else
852 read_thunk_profile (node);
853 continue;
857 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
859 if (dump_file)
860 dump_function_header (dump_file, cfun->decl, dump_flags);
862 /* Local pure-const may imply need to fixup the cfg. */
863 if (gimple_has_body_p (node->decl)
864 && (execute_fixup_cfg () & TODO_cleanup_cfg))
865 cleanup_tree_cfg ();
867 branch_prob (thunk);
869 if (! flag_branch_probabilities
870 && flag_profile_values)
871 gimple_gen_ic_func_profiler ();
873 if (flag_branch_probabilities
874 && !thunk
875 && flag_profile_values
876 && flag_value_profile_transformations
877 && profile_status_for_fn (cfun) == PROFILE_READ)
878 gimple_value_profile_transformations ();
880 /* The above could hose dominator info. Currently there is
881 none coming in, this is a safety valve. It should be
882 easy to adjust it, if and when there is some. */
883 free_dominance_info (CDI_DOMINATORS);
884 free_dominance_info (CDI_POST_DOMINATORS);
885 pop_cfun ();
888 release_profile_file_filtering ();
890 /* Drop pure/const flags from instrumented functions. */
891 if (profile_arc_flag || flag_test_coverage)
892 FOR_EACH_DEFINED_FUNCTION (node)
894 if (!gimple_has_body_p (node->decl)
895 || !(!node->clone_of
896 || node->decl != node->clone_of->decl))
897 continue;
899 /* Don't profile functions produced for builtin stuff. */
900 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
901 continue;
903 node->set_const_flag (false, false);
904 node->set_pure_flag (false, false);
907 /* Update call statements and rebuild the cgraph. */
908 FOR_EACH_DEFINED_FUNCTION (node)
910 basic_block bb;
912 if (!gimple_has_body_p (node->decl)
913 || !(!node->clone_of
914 || node->decl != node->clone_of->decl))
915 continue;
917 /* Don't profile functions produced for builtin stuff. */
918 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
919 continue;
921 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
923 if (profile_arc_flag || flag_test_coverage)
924 FOR_EACH_BB_FN (bb, cfun)
926 gimple_stmt_iterator gsi;
927 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
929 gcall *call = dyn_cast <gcall *> (gsi_stmt (gsi));
930 if (!call || gimple_call_internal_p (call))
931 continue;
933 /* We do not clear pure/const on decls without body. */
934 tree fndecl = gimple_call_fndecl (call);
935 cgraph_node *callee;
936 if (fndecl
937 && (callee = cgraph_node::get (fndecl))
938 && callee->get_availability (node) == AVAIL_NOT_AVAILABLE)
939 continue;
941 /* Drop the const attribute from the call type (the pure
942 attribute is not available on types). */
943 tree fntype = gimple_call_fntype (call);
944 if (fntype && TYPE_READONLY (fntype))
946 int quals = TYPE_QUALS (fntype) & ~TYPE_QUAL_CONST;
947 fntype = build_qualified_type (fntype, quals);
948 gimple_call_set_fntype (call, fntype);
951 /* Update virtual operands of calls to no longer const/pure
952 functions. */
953 update_stmt (call);
957 /* re-merge split blocks. */
958 cleanup_tree_cfg ();
959 update_ssa (TODO_update_ssa);
961 cgraph_edge::rebuild_edges ();
963 pop_cfun ();
966 handle_missing_profiles ();
968 del_node_map ();
969 return 0;
972 namespace {
974 const pass_data pass_data_ipa_tree_profile =
976 SIMPLE_IPA_PASS, /* type */
977 "profile", /* name */
978 OPTGROUP_NONE, /* optinfo_flags */
979 TV_IPA_PROFILE, /* tv_id */
980 0, /* properties_required */
981 0, /* properties_provided */
982 0, /* properties_destroyed */
983 0, /* todo_flags_start */
984 TODO_dump_symtab, /* todo_flags_finish */
987 class pass_ipa_tree_profile : public simple_ipa_opt_pass
989 public:
990 pass_ipa_tree_profile (gcc::context *ctxt)
991 : simple_ipa_opt_pass (pass_data_ipa_tree_profile, ctxt)
994 /* opt_pass methods: */
995 bool gate (function *) final override;
996 unsigned int execute (function *) final override { return tree_profiling (); }
998 }; // class pass_ipa_tree_profile
1000 bool
1001 pass_ipa_tree_profile::gate (function *)
1003 /* When profile instrumentation, use or test coverage shall be performed.
1004 But for AutoFDO, this there is no instrumentation, thus this pass is
1005 disabled. */
1006 return (!in_lto_p && !flag_auto_profile
1007 && (flag_branch_probabilities || flag_test_coverage
1008 || profile_arc_flag));
1011 } // anon namespace
1013 simple_ipa_opt_pass *
1014 make_pass_ipa_tree_profile (gcc::context *ctxt)
1016 return new pass_ipa_tree_profile (ctxt);
1019 #include "gt-tree-profile.h"