Fix previous commit
[official-gcc.git] / gcc / tree-profile.c
blob4c1ead5781fc502ef2ca2fb49e9415e548a56f4f
1 /* Calculate branch probabilities, and basic block execution counts.
2 Copyright (C) 1990-2019 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.c 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 "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 #include "xregex.h"
60 static GTY(()) tree gcov_type_node;
61 static GTY(()) tree tree_interval_profiler_fn;
62 static GTY(()) tree tree_pow2_profiler_fn;
63 static GTY(()) tree tree_topn_values_profiler_fn;
64 static GTY(()) tree tree_indirect_call_profiler_fn;
65 static GTY(()) tree tree_average_profiler_fn;
66 static GTY(()) tree tree_ior_profiler_fn;
67 static GTY(()) tree tree_time_profiler_counter;
70 static GTY(()) tree ic_tuple_var;
71 static GTY(()) tree ic_tuple_counters_field;
72 static GTY(()) tree ic_tuple_callee_field;
74 /* Do initialization work for the edge profiler. */
76 /* Add code:
77 __thread gcov* __gcov_indirect_call_counters; // pointer to actual counter
78 __thread void* __gcov_indirect_call_callee; // actual callee address
79 __thread int __gcov_function_counter; // time profiler function counter
81 static void
82 init_ic_make_global_vars (void)
84 tree gcov_type_ptr;
86 gcov_type_ptr = build_pointer_type (get_gcov_type ());
88 tree tuple_type = lang_hooks.types.make_type (RECORD_TYPE);
90 /* callee */
91 ic_tuple_callee_field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
92 ptr_type_node);
94 /* counters */
95 ic_tuple_counters_field = build_decl (BUILTINS_LOCATION, FIELD_DECL,
96 NULL_TREE, gcov_type_ptr);
97 DECL_CHAIN (ic_tuple_counters_field) = ic_tuple_callee_field;
99 finish_builtin_struct (tuple_type, "indirect_call_tuple",
100 ic_tuple_counters_field, NULL_TREE);
102 ic_tuple_var
103 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
104 get_identifier ("__gcov_indirect_call"), tuple_type);
105 TREE_PUBLIC (ic_tuple_var) = 1;
106 DECL_ARTIFICIAL (ic_tuple_var) = 1;
107 DECL_INITIAL (ic_tuple_var) = NULL;
108 DECL_EXTERNAL (ic_tuple_var) = 1;
109 if (targetm.have_tls)
110 set_decl_tls_model (ic_tuple_var, decl_default_tls_model (ic_tuple_var));
113 /* Create the type and function decls for the interface with gcov. */
115 void
116 gimple_init_gcov_profiler (void)
118 tree interval_profiler_fn_type;
119 tree pow2_profiler_fn_type;
120 tree topn_values_profiler_fn_type;
121 tree gcov_type_ptr;
122 tree ic_profiler_fn_type;
123 tree average_profiler_fn_type;
124 const char *profiler_fn_name;
125 const char *fn_name;
127 if (!gcov_type_node)
129 const char *fn_suffix
130 = flag_profile_update == PROFILE_UPDATE_ATOMIC ? "_atomic" : "";
132 gcov_type_node = get_gcov_type ();
133 gcov_type_ptr = build_pointer_type (gcov_type_node);
135 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
136 interval_profiler_fn_type
137 = build_function_type_list (void_type_node,
138 gcov_type_ptr, gcov_type_node,
139 integer_type_node,
140 unsigned_type_node, NULL_TREE);
141 fn_name = concat ("__gcov_interval_profiler", fn_suffix, NULL);
142 tree_interval_profiler_fn = build_fn_decl (fn_name,
143 interval_profiler_fn_type);
144 free (CONST_CAST (char *, fn_name));
145 TREE_NOTHROW (tree_interval_profiler_fn) = 1;
146 DECL_ATTRIBUTES (tree_interval_profiler_fn)
147 = tree_cons (get_identifier ("leaf"), NULL,
148 DECL_ATTRIBUTES (tree_interval_profiler_fn));
150 /* void (*) (gcov_type *, gcov_type) */
151 pow2_profiler_fn_type
152 = build_function_type_list (void_type_node,
153 gcov_type_ptr, gcov_type_node,
154 NULL_TREE);
155 fn_name = concat ("__gcov_pow2_profiler", fn_suffix, NULL);
156 tree_pow2_profiler_fn = build_fn_decl (fn_name, pow2_profiler_fn_type);
157 free (CONST_CAST (char *, fn_name));
158 TREE_NOTHROW (tree_pow2_profiler_fn) = 1;
159 DECL_ATTRIBUTES (tree_pow2_profiler_fn)
160 = tree_cons (get_identifier ("leaf"), NULL,
161 DECL_ATTRIBUTES (tree_pow2_profiler_fn));
163 /* void (*) (gcov_type *, gcov_type) */
164 topn_values_profiler_fn_type
165 = build_function_type_list (void_type_node,
166 gcov_type_ptr, gcov_type_node,
167 NULL_TREE);
168 fn_name = concat ("__gcov_topn_values_profiler", fn_suffix, NULL);
169 tree_topn_values_profiler_fn
170 = build_fn_decl (fn_name, topn_values_profiler_fn_type);
172 TREE_NOTHROW (tree_topn_values_profiler_fn) = 1;
173 DECL_ATTRIBUTES (tree_topn_values_profiler_fn)
174 = tree_cons (get_identifier ("leaf"), NULL,
175 DECL_ATTRIBUTES (tree_topn_values_profiler_fn));
177 init_ic_make_global_vars ();
179 /* void (*) (gcov_type, void *) */
180 ic_profiler_fn_type
181 = build_function_type_list (void_type_node,
182 gcov_type_node,
183 ptr_type_node,
184 NULL_TREE);
185 profiler_fn_name = "__gcov_indirect_call_profiler_v4";
187 tree_indirect_call_profiler_fn
188 = build_fn_decl (profiler_fn_name, ic_profiler_fn_type);
190 TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
191 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
192 = tree_cons (get_identifier ("leaf"), NULL,
193 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn));
195 tree_time_profiler_counter
196 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
197 get_identifier ("__gcov_time_profiler_counter"),
198 get_gcov_type ());
199 TREE_PUBLIC (tree_time_profiler_counter) = 1;
200 DECL_EXTERNAL (tree_time_profiler_counter) = 1;
201 TREE_STATIC (tree_time_profiler_counter) = 1;
202 DECL_ARTIFICIAL (tree_time_profiler_counter) = 1;
203 DECL_INITIAL (tree_time_profiler_counter) = NULL;
205 /* void (*) (gcov_type *, gcov_type) */
206 average_profiler_fn_type
207 = build_function_type_list (void_type_node,
208 gcov_type_ptr, gcov_type_node, NULL_TREE);
209 fn_name = concat ("__gcov_average_profiler", fn_suffix, NULL);
210 tree_average_profiler_fn = build_fn_decl (fn_name,
211 average_profiler_fn_type);
212 free (CONST_CAST (char *, fn_name));
213 TREE_NOTHROW (tree_average_profiler_fn) = 1;
214 DECL_ATTRIBUTES (tree_average_profiler_fn)
215 = tree_cons (get_identifier ("leaf"), NULL,
216 DECL_ATTRIBUTES (tree_average_profiler_fn));
217 fn_name = concat ("__gcov_ior_profiler", fn_suffix, NULL);
218 tree_ior_profiler_fn = build_fn_decl (fn_name, average_profiler_fn_type);
219 free (CONST_CAST (char *, fn_name));
220 TREE_NOTHROW (tree_ior_profiler_fn) = 1;
221 DECL_ATTRIBUTES (tree_ior_profiler_fn)
222 = tree_cons (get_identifier ("leaf"), NULL,
223 DECL_ATTRIBUTES (tree_ior_profiler_fn));
225 /* LTO streamer needs assembler names. Because we create these decls
226 late, we need to initialize them by hand. */
227 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn);
228 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn);
229 DECL_ASSEMBLER_NAME (tree_topn_values_profiler_fn);
230 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn);
231 DECL_ASSEMBLER_NAME (tree_average_profiler_fn);
232 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
236 /* Output instructions as GIMPLE trees to increment the edge
237 execution count, and insert them on E. We rely on
238 gsi_insert_on_edge to preserve the order. */
240 void
241 gimple_gen_edge_profiler (int edgeno, edge e)
243 tree one;
245 one = build_int_cst (gcov_type_node, 1);
247 if (flag_profile_update == PROFILE_UPDATE_ATOMIC)
249 /* __atomic_fetch_add (&counter, 1, MEMMODEL_RELAXED); */
250 tree addr = tree_coverage_counter_addr (GCOV_COUNTER_ARCS, edgeno);
251 tree f = builtin_decl_explicit (LONG_LONG_TYPE_SIZE > 32
252 ? BUILT_IN_ATOMIC_FETCH_ADD_8:
253 BUILT_IN_ATOMIC_FETCH_ADD_4);
254 gcall *stmt = gimple_build_call (f, 3, addr, one,
255 build_int_cst (integer_type_node,
256 MEMMODEL_RELAXED));
257 gsi_insert_on_edge (e, stmt);
259 else
261 tree ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
262 tree gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
263 NULL, "PROF_edge_counter");
264 gassign *stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
265 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
266 NULL, "PROF_edge_counter");
267 gassign *stmt2 = gimple_build_assign (gcov_type_tmp_var, PLUS_EXPR,
268 gimple_assign_lhs (stmt1), one);
269 gassign *stmt3 = gimple_build_assign (unshare_expr (ref),
270 gimple_assign_lhs (stmt2));
271 gsi_insert_on_edge (e, stmt1);
272 gsi_insert_on_edge (e, stmt2);
273 gsi_insert_on_edge (e, stmt3);
277 /* Emits code to get VALUE to instrument at GSI, and returns the
278 variable containing the value. */
280 static tree
281 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
283 tree val = value->hvalue.value;
284 if (POINTER_TYPE_P (TREE_TYPE (val)))
285 val = fold_convert (build_nonstandard_integer_type
286 (TYPE_PRECISION (TREE_TYPE (val)), 1), val);
287 return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
288 true, NULL_TREE, true, GSI_SAME_STMT);
291 /* Output instructions as GIMPLE trees to increment the interval histogram
292 counter. VALUE is the expression whose value is profiled. TAG is the
293 tag of the section for counters, BASE is offset of the counter position. */
295 void
296 gimple_gen_interval_profiler (histogram_value value, unsigned tag)
298 gimple *stmt = value->hvalue.stmt;
299 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
300 tree ref = tree_coverage_counter_ref (tag, 0), ref_ptr;
301 gcall *call;
302 tree val;
303 tree start = build_int_cst_type (integer_type_node,
304 value->hdata.intvl.int_start);
305 tree steps = build_int_cst_type (unsigned_type_node,
306 value->hdata.intvl.steps);
308 ref_ptr = force_gimple_operand_gsi (&gsi,
309 build_addr (ref),
310 true, NULL_TREE, true, GSI_SAME_STMT);
311 val = prepare_instrumented_value (&gsi, value);
312 call = gimple_build_call (tree_interval_profiler_fn, 4,
313 ref_ptr, val, start, steps);
314 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
317 /* Output instructions as GIMPLE trees to increment the power of two histogram
318 counter. VALUE is the expression whose value is profiled. TAG is the tag
319 of the section for counters. */
321 void
322 gimple_gen_pow2_profiler (histogram_value value, unsigned tag)
324 gimple *stmt = value->hvalue.stmt;
325 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
326 tree ref_ptr = tree_coverage_counter_addr (tag, 0);
327 gcall *call;
328 tree val;
330 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
331 true, NULL_TREE, true, GSI_SAME_STMT);
332 val = prepare_instrumented_value (&gsi, value);
333 call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val);
334 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
337 /* Output instructions as GIMPLE trees for code to find the most N common
338 values. VALUE is the expression whose value is profiled. TAG is the tag
339 of the section for counters. */
341 void
342 gimple_gen_topn_values_profiler (histogram_value value, unsigned tag)
344 gimple *stmt = value->hvalue.stmt;
345 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
346 tree ref_ptr = tree_coverage_counter_addr (tag, 0);
347 gcall *call;
348 tree val;
350 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
351 true, NULL_TREE, true, GSI_SAME_STMT);
352 val = prepare_instrumented_value (&gsi, value);
353 call = gimple_build_call (tree_topn_values_profiler_fn, 2, ref_ptr, val);
354 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
358 /* Output instructions as GIMPLE trees for code to find the most
359 common called function in indirect call.
360 VALUE is the call expression whose indirect callee is profiled.
361 TAG is the tag of the section for counters. */
363 void
364 gimple_gen_ic_profiler (histogram_value value, unsigned tag)
366 tree tmp1;
367 gassign *stmt1, *stmt2, *stmt3;
368 gimple *stmt = value->hvalue.stmt;
369 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
370 tree ref_ptr = tree_coverage_counter_addr (tag, 0);
372 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
373 true, NULL_TREE, true, GSI_SAME_STMT);
375 /* Insert code:
377 stmt1: __gcov_indirect_call.counters = get_relevant_counter_ptr ();
378 stmt2: tmp1 = (void *) (indirect call argument value)
379 stmt3: __gcov_indirect_call.callee = tmp1;
381 Example:
382 f_1 = foo;
383 __gcov_indirect_call.counters = &__gcov4.main[0];
384 PROF_9 = f_1;
385 __gcov_indirect_call_callee = PROF_9;
386 _4 = f_1 ();
389 tree gcov_type_ptr = build_pointer_type (get_gcov_type ());
391 tree counter_ref = build3 (COMPONENT_REF, gcov_type_ptr,
392 ic_tuple_var, ic_tuple_counters_field, NULL_TREE);
394 stmt1 = gimple_build_assign (counter_ref, ref_ptr);
395 tmp1 = make_temp_ssa_name (ptr_type_node, NULL, "PROF");
396 stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
397 tree callee_ref = build3 (COMPONENT_REF, ptr_type_node,
398 ic_tuple_var, ic_tuple_callee_field, NULL_TREE);
399 stmt3 = gimple_build_assign (callee_ref, tmp1);
401 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
402 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
403 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
407 /* Output instructions as GIMPLE trees for code to find the most
408 common called function in indirect call. Insert instructions at the
409 beginning of every possible called function.
412 void
413 gimple_gen_ic_func_profiler (void)
415 struct cgraph_node * c_node = cgraph_node::get (current_function_decl);
416 gcall *stmt1;
417 tree tree_uid, cur_func, void0;
419 if (c_node->only_called_directly_p ())
420 return;
422 gimple_init_gcov_profiler ();
424 basic_block entry = ENTRY_BLOCK_PTR_FOR_FN (cfun);
425 basic_block cond_bb = split_edge (single_succ_edge (entry));
426 basic_block update_bb = split_edge (single_succ_edge (cond_bb));
428 /* We need to do an extra split in order to not create an input
429 for a possible PHI node. */
430 split_edge (single_succ_edge (update_bb));
432 edge true_edge = single_succ_edge (cond_bb);
433 true_edge->flags = EDGE_TRUE_VALUE;
435 profile_probability probability;
436 if (DECL_VIRTUAL_P (current_function_decl))
437 probability = profile_probability::very_likely ();
438 else
439 probability = profile_probability::unlikely ();
441 true_edge->probability = probability;
442 edge e = make_edge (cond_bb, single_succ_edge (update_bb)->dest,
443 EDGE_FALSE_VALUE);
444 e->probability = true_edge->probability.invert ();
446 /* Insert code:
448 if (__gcov_indirect_call_callee != NULL)
449 __gcov_indirect_call_profiler_v3 (profile_id, &current_function_decl);
451 The function __gcov_indirect_call_profiler_v3 is responsible for
452 resetting __gcov_indirect_call_callee to NULL. */
454 gimple_stmt_iterator gsi = gsi_start_bb (cond_bb);
455 void0 = build_int_cst (ptr_type_node, 0);
457 tree callee_ref = build3 (COMPONENT_REF, ptr_type_node,
458 ic_tuple_var, ic_tuple_callee_field, NULL_TREE);
460 tree ref = force_gimple_operand_gsi (&gsi, callee_ref, true, NULL_TREE,
461 true, GSI_SAME_STMT);
463 gcond *cond = gimple_build_cond (NE_EXPR, ref,
464 void0, NULL, NULL);
465 gsi_insert_before (&gsi, cond, GSI_NEW_STMT);
467 gsi = gsi_after_labels (update_bb);
469 cur_func = force_gimple_operand_gsi (&gsi,
470 build_addr (current_function_decl),
471 true, NULL_TREE,
472 true, GSI_SAME_STMT);
473 tree_uid = build_int_cst
474 (gcov_type_node,
475 cgraph_node::get (current_function_decl)->profile_id);
476 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2,
477 tree_uid, cur_func);
478 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
481 /* Output instructions as GIMPLE tree at the beginning for each function.
482 TAG is the tag of the section for counters, BASE is offset of the
483 counter position and GSI is the iterator we place the counter. */
485 void
486 gimple_gen_time_profiler (unsigned tag)
488 tree type = get_gcov_type ();
489 basic_block entry = ENTRY_BLOCK_PTR_FOR_FN (cfun);
490 basic_block cond_bb = split_edge (single_succ_edge (entry));
491 basic_block update_bb = split_edge (single_succ_edge (cond_bb));
493 /* We need to do an extra split in order to not create an input
494 for a possible PHI node. */
495 split_edge (single_succ_edge (update_bb));
497 edge true_edge = single_succ_edge (cond_bb);
498 true_edge->flags = EDGE_TRUE_VALUE;
499 true_edge->probability = profile_probability::unlikely ();
500 edge e
501 = make_edge (cond_bb, single_succ_edge (update_bb)->dest, EDGE_FALSE_VALUE);
502 e->probability = true_edge->probability.invert ();
504 gimple_stmt_iterator gsi = gsi_start_bb (cond_bb);
505 tree original_ref = tree_coverage_counter_ref (tag, 0);
506 tree ref = force_gimple_operand_gsi (&gsi, original_ref, true, NULL_TREE,
507 true, GSI_SAME_STMT);
508 tree one = build_int_cst (type, 1);
510 /* Emit: if (counters[0] != 0). */
511 gcond *cond = gimple_build_cond (EQ_EXPR, ref, build_int_cst (type, 0),
512 NULL, NULL);
513 gsi_insert_before (&gsi, cond, GSI_NEW_STMT);
515 gsi = gsi_start_bb (update_bb);
517 /* Emit: counters[0] = ++__gcov_time_profiler_counter. */
518 if (flag_profile_update == PROFILE_UPDATE_ATOMIC)
520 tree ptr = make_temp_ssa_name (build_pointer_type (type), NULL,
521 "time_profiler_counter_ptr");
522 tree addr = build1 (ADDR_EXPR, TREE_TYPE (ptr),
523 tree_time_profiler_counter);
524 gassign *assign = gimple_build_assign (ptr, NOP_EXPR, addr);
525 gsi_insert_before (&gsi, assign, GSI_NEW_STMT);
526 tree f = builtin_decl_explicit (LONG_LONG_TYPE_SIZE > 32
527 ? BUILT_IN_ATOMIC_ADD_FETCH_8:
528 BUILT_IN_ATOMIC_ADD_FETCH_4);
529 gcall *stmt = gimple_build_call (f, 3, ptr, one,
530 build_int_cst (integer_type_node,
531 MEMMODEL_RELAXED));
532 tree result_type = TREE_TYPE (TREE_TYPE (f));
533 tree tmp = make_temp_ssa_name (result_type, NULL, "time_profile");
534 gimple_set_lhs (stmt, tmp);
535 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
536 tmp = make_temp_ssa_name (type, NULL, "time_profile");
537 assign = gimple_build_assign (tmp, NOP_EXPR,
538 gimple_call_lhs (stmt));
539 gsi_insert_after (&gsi, assign, GSI_NEW_STMT);
540 assign = gimple_build_assign (original_ref, tmp);
541 gsi_insert_after (&gsi, assign, GSI_NEW_STMT);
543 else
545 tree tmp = make_temp_ssa_name (type, NULL, "time_profile");
546 gassign *assign = gimple_build_assign (tmp, tree_time_profiler_counter);
547 gsi_insert_before (&gsi, assign, GSI_NEW_STMT);
549 tmp = make_temp_ssa_name (type, NULL, "time_profile");
550 assign = gimple_build_assign (tmp, PLUS_EXPR, gimple_assign_lhs (assign),
551 one);
552 gsi_insert_after (&gsi, assign, GSI_NEW_STMT);
553 assign = gimple_build_assign (original_ref, tmp);
554 gsi_insert_after (&gsi, assign, GSI_NEW_STMT);
555 assign = gimple_build_assign (tree_time_profiler_counter, tmp);
556 gsi_insert_after (&gsi, assign, GSI_NEW_STMT);
560 /* Output instructions as GIMPLE trees to increment the average histogram
561 counter. VALUE is the expression whose value is profiled. TAG is the
562 tag of the section for counters, BASE is offset of the counter position. */
564 void
565 gimple_gen_average_profiler (histogram_value value, unsigned tag)
567 gimple *stmt = value->hvalue.stmt;
568 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
569 tree ref_ptr = tree_coverage_counter_addr (tag, 0);
570 gcall *call;
571 tree val;
573 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
574 true, NULL_TREE,
575 true, GSI_SAME_STMT);
576 val = prepare_instrumented_value (&gsi, value);
577 call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
578 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
581 /* Output instructions as GIMPLE trees to increment the ior histogram
582 counter. VALUE is the expression whose value is profiled. TAG is the
583 tag of the section for counters, BASE is offset of the counter position. */
585 void
586 gimple_gen_ior_profiler (histogram_value value, unsigned tag)
588 gimple *stmt = value->hvalue.stmt;
589 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
590 tree ref_ptr = tree_coverage_counter_addr (tag, 0);
591 gcall *call;
592 tree val;
594 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
595 true, NULL_TREE, true, GSI_SAME_STMT);
596 val = prepare_instrumented_value (&gsi, value);
597 call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
598 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
601 static vec<regex_t> profile_filter_files;
602 static vec<regex_t> profile_exclude_files;
604 /* Parse list of provided REGEX (separated with semi-collon) and
605 create expressions (of type regex_t) and save them into V vector.
606 If there is a regular expression parsing error, error message is
607 printed for FLAG_NAME. */
609 static void
610 parse_profile_filter (const char *regex, vec<regex_t> *v,
611 const char *flag_name)
613 v->create (4);
614 if (regex != NULL)
616 char *str = xstrdup (regex);
617 for (char *p = strtok (str, ";"); p != NULL; p = strtok (NULL, ";"))
619 regex_t r;
620 if (regcomp (&r, p, REG_EXTENDED | REG_NOSUB) != 0)
622 error ("invalid regular expression %qs in %qs",
623 p, flag_name);
624 return;
627 v->safe_push (r);
632 /* Parse values of -fprofile-filter-files and -fprofile-exclude-files
633 options. */
635 static void
636 parse_profile_file_filtering ()
638 parse_profile_filter (flag_profile_filter_files, &profile_filter_files,
639 "-fprofile-filter-files");
640 parse_profile_filter (flag_profile_exclude_files, &profile_exclude_files,
641 "-fprofile-exclude-files");
644 /* Parse vectors of regular expressions. */
646 static void
647 release_profile_file_filtering ()
649 profile_filter_files.release ();
650 profile_exclude_files.release ();
653 /* Return true when FILENAME should be instrumented based on
654 -fprofile-filter-files and -fprofile-exclude-files options. */
656 static bool
657 include_source_file_for_profile (const char *filename)
659 /* First check whether file is included in flag_profile_exclude_files. */
660 for (unsigned i = 0; i < profile_exclude_files.length (); i++)
661 if (regexec (&profile_exclude_files[i],
662 filename, 0, NULL, 0) == REG_NOERROR)
663 return false;
665 /* For non-empty flag_profile_filter_files include only files matching a
666 regex in the flag. */
667 if (profile_filter_files.is_empty ())
668 return true;
670 for (unsigned i = 0; i < profile_filter_files.length (); i++)
671 if (regexec (&profile_filter_files[i], filename, 0, NULL, 0) == REG_NOERROR)
672 return true;
674 return false;
677 #ifndef HAVE_sync_compare_and_swapsi
678 #define HAVE_sync_compare_and_swapsi 0
679 #endif
680 #ifndef HAVE_atomic_compare_and_swapsi
681 #define HAVE_atomic_compare_and_swapsi 0
682 #endif
684 #ifndef HAVE_sync_compare_and_swapdi
685 #define HAVE_sync_compare_and_swapdi 0
686 #endif
687 #ifndef HAVE_atomic_compare_and_swapdi
688 #define HAVE_atomic_compare_and_swapdi 0
689 #endif
691 /* Profile all functions in the callgraph. */
693 static unsigned int
694 tree_profiling (void)
696 struct cgraph_node *node;
698 /* Verify whether we can utilize atomic update operations. */
699 bool can_support_atomic = false;
700 unsigned HOST_WIDE_INT gcov_type_size
701 = tree_to_uhwi (TYPE_SIZE_UNIT (get_gcov_type ()));
702 if (gcov_type_size == 4)
703 can_support_atomic
704 = HAVE_sync_compare_and_swapsi || HAVE_atomic_compare_and_swapsi;
705 else if (gcov_type_size == 8)
706 can_support_atomic
707 = HAVE_sync_compare_and_swapdi || HAVE_atomic_compare_and_swapdi;
709 if (flag_profile_update == PROFILE_UPDATE_ATOMIC
710 && !can_support_atomic)
712 warning (0, "target does not support atomic profile update, "
713 "single mode is selected");
714 flag_profile_update = PROFILE_UPDATE_SINGLE;
716 else if (flag_profile_update == PROFILE_UPDATE_PREFER_ATOMIC)
717 flag_profile_update = can_support_atomic
718 ? PROFILE_UPDATE_ATOMIC : PROFILE_UPDATE_SINGLE;
720 /* This is a small-ipa pass that gets called only once, from
721 cgraphunit.c:ipa_passes(). */
722 gcc_assert (symtab->state == IPA_SSA);
724 init_node_map (true);
725 parse_profile_file_filtering ();
727 FOR_EACH_DEFINED_FUNCTION (node)
729 bool thunk = false;
730 if (!gimple_has_body_p (node->decl) && !node->thunk.thunk_p)
731 continue;
733 /* Don't profile functions produced for builtin stuff. */
734 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
735 continue;
737 if (lookup_attribute ("no_profile_instrument_function",
738 DECL_ATTRIBUTES (node->decl)))
739 continue;
740 /* Do not instrument extern inline functions when testing coverage.
741 While this is not perfectly consistent (early inlined extern inlines
742 will get acocunted), testsuite expects that. */
743 if (DECL_EXTERNAL (node->decl)
744 && flag_test_coverage)
745 continue;
747 const char *file = LOCATION_FILE (DECL_SOURCE_LOCATION (node->decl));
748 if (!include_source_file_for_profile (file))
749 continue;
751 if (node->thunk.thunk_p)
753 /* We cannot expand variadic thunks to Gimple. */
754 if (stdarg_p (TREE_TYPE (node->decl)))
755 continue;
756 thunk = true;
757 /* When generate profile, expand thunk to gimple so it can be
758 instrumented same way as other functions. */
759 if (profile_arc_flag)
760 node->expand_thunk (false, true);
761 /* Read cgraph profile but keep function as thunk at profile-use
762 time. */
763 else
765 read_thunk_profile (node);
766 continue;
770 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
772 if (dump_file)
773 dump_function_header (dump_file, cfun->decl, dump_flags);
775 /* Local pure-const may imply need to fixup the cfg. */
776 if (gimple_has_body_p (node->decl)
777 && (execute_fixup_cfg () & TODO_cleanup_cfg))
778 cleanup_tree_cfg ();
780 branch_prob (thunk);
782 if (! flag_branch_probabilities
783 && flag_profile_values)
784 gimple_gen_ic_func_profiler ();
786 if (flag_branch_probabilities
787 && !thunk
788 && flag_profile_values
789 && flag_value_profile_transformations)
790 gimple_value_profile_transformations ();
792 /* The above could hose dominator info. Currently there is
793 none coming in, this is a safety valve. It should be
794 easy to adjust it, if and when there is some. */
795 free_dominance_info (CDI_DOMINATORS);
796 free_dominance_info (CDI_POST_DOMINATORS);
797 pop_cfun ();
800 release_profile_file_filtering ();
802 /* Drop pure/const flags from instrumented functions. */
803 if (profile_arc_flag || flag_test_coverage)
804 FOR_EACH_DEFINED_FUNCTION (node)
806 if (!gimple_has_body_p (node->decl)
807 || !(!node->clone_of
808 || node->decl != node->clone_of->decl))
809 continue;
811 /* Don't profile functions produced for builtin stuff. */
812 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
813 continue;
815 node->set_const_flag (false, false);
816 node->set_pure_flag (false, false);
819 /* Update call statements and rebuild the cgraph. */
820 FOR_EACH_DEFINED_FUNCTION (node)
822 basic_block bb;
824 if (!gimple_has_body_p (node->decl)
825 || !(!node->clone_of
826 || node->decl != node->clone_of->decl))
827 continue;
829 /* Don't profile functions produced for builtin stuff. */
830 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
831 continue;
833 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
835 FOR_EACH_BB_FN (bb, cfun)
837 gimple_stmt_iterator gsi;
838 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
840 gimple *stmt = gsi_stmt (gsi);
841 if (is_gimple_call (stmt))
842 update_stmt (stmt);
846 /* re-merge split blocks. */
847 cleanup_tree_cfg ();
848 update_ssa (TODO_update_ssa);
850 cgraph_edge::rebuild_edges ();
852 pop_cfun ();
855 handle_missing_profiles ();
857 del_node_map ();
858 return 0;
861 namespace {
863 const pass_data pass_data_ipa_tree_profile =
865 SIMPLE_IPA_PASS, /* type */
866 "profile", /* name */
867 OPTGROUP_NONE, /* optinfo_flags */
868 TV_IPA_PROFILE, /* tv_id */
869 0, /* properties_required */
870 0, /* properties_provided */
871 0, /* properties_destroyed */
872 0, /* todo_flags_start */
873 TODO_dump_symtab, /* todo_flags_finish */
876 class pass_ipa_tree_profile : public simple_ipa_opt_pass
878 public:
879 pass_ipa_tree_profile (gcc::context *ctxt)
880 : simple_ipa_opt_pass (pass_data_ipa_tree_profile, ctxt)
883 /* opt_pass methods: */
884 virtual bool gate (function *);
885 virtual unsigned int execute (function *) { return tree_profiling (); }
887 }; // class pass_ipa_tree_profile
889 bool
890 pass_ipa_tree_profile::gate (function *)
892 /* When profile instrumentation, use or test coverage shall be performed.
893 But for AutoFDO, this there is no instrumentation, thus this pass is
894 diabled. */
895 return (!in_lto_p && !flag_auto_profile
896 && (flag_branch_probabilities || flag_test_coverage
897 || profile_arc_flag));
900 } // anon namespace
902 simple_ipa_opt_pass *
903 make_pass_ipa_tree_profile (gcc::context *ctxt)
905 return new pass_ipa_tree_profile (ctxt);
908 #include "gt-tree-profile.h"