]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/tree-profile.c
[testsuite] Add missing dg-require-effective-target label_values
[thirdparty/gcc.git] / gcc / tree-profile.c
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.
7
8 This file is part of GCC.
9
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
13 version.
14
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3. If not see
22 <http://www.gnu.org/licenses/>. */
23
24 /* Generate basic block profile instrumentation and auxiliary files.
25 Tree-based version. See profile.c for overview. */
26
27 #include "config.h"
28 #include "system.h"
29 #include "coretypes.h"
30 #include "memmodel.h"
31 #include "backend.h"
32 #include "target.h"
33 #include "tree.h"
34 #include "gimple.h"
35 #include "cfghooks.h"
36 #include "tree-pass.h"
37 #include "ssa.h"
38 #include "cgraph.h"
39 #include "coverage.h"
40 #include "diagnostic-core.h"
41 #include "fold-const.h"
42 #include "varasm.h"
43 #include "tree-nested.h"
44 #include "gimplify.h"
45 #include "gimple-iterator.h"
46 #include "gimplify-me.h"
47 #include "tree-cfg.h"
48 #include "tree-into-ssa.h"
49 #include "value-prof.h"
50 #include "profile.h"
51 #include "tree-cfgcleanup.h"
52 #include "params.h"
53 #include "stringpool.h"
54 #include "attribs.h"
55 #include "tree-pretty-print.h"
56 #include "langhooks.h"
57 #include "stor-layout.h"
58 #include "xregex.h"
59
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_one_value_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;
68
69
70 static GTY(()) tree ic_tuple_var;
71 static GTY(()) tree ic_tuple_counters_field;
72 static GTY(()) tree ic_tuple_callee_field;
73
74 /* Do initialization work for the edge profiler. */
75
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
80 */
81 static void
82 init_ic_make_global_vars (void)
83 {
84 tree gcov_type_ptr;
85
86 gcov_type_ptr = build_pointer_type (get_gcov_type ());
87
88 tree tuple_type = lang_hooks.types.make_type (RECORD_TYPE);
89
90 /* callee */
91 ic_tuple_callee_field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
92 ptr_type_node);
93
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;
98
99 finish_builtin_struct (tuple_type, "indirect_call_tuple",
100 ic_tuple_counters_field, NULL_TREE);
101
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));
111 }
112
113 /* Create the type and function decls for the interface with gcov. */
114
115 void
116 gimple_init_gcov_profiler (void)
117 {
118 tree interval_profiler_fn_type;
119 tree pow2_profiler_fn_type;
120 tree one_value_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;
126
127 if (!gcov_type_node)
128 {
129 const char *fn_suffix
130 = flag_profile_update == PROFILE_UPDATE_ATOMIC ? "_atomic" : "";
131
132 gcov_type_node = get_gcov_type ();
133 gcov_type_ptr = build_pointer_type (gcov_type_node);
134
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));
149
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));
162
163 /* void (*) (gcov_type *, gcov_type) */
164 one_value_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_one_value_profiler_v2", fn_suffix, NULL);
169 tree_one_value_profiler_fn = build_fn_decl (fn_name,
170 one_value_profiler_fn_type);
171
172 TREE_NOTHROW (tree_one_value_profiler_fn) = 1;
173 DECL_ATTRIBUTES (tree_one_value_profiler_fn)
174 = tree_cons (get_identifier ("leaf"), NULL,
175 DECL_ATTRIBUTES (tree_one_value_profiler_fn));
176
177 init_ic_make_global_vars ();
178
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";
186
187 tree_indirect_call_profiler_fn
188 = build_fn_decl (profiler_fn_name, ic_profiler_fn_type);
189
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));
194
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;
204
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));
224
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_one_value_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);
233 }
234 }
235
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. */
239
240 void
241 gimple_gen_edge_profiler (int edgeno, edge e)
242 {
243 tree one;
244
245 one = build_int_cst (gcov_type_node, 1);
246
247 if (flag_profile_update == PROFILE_UPDATE_ATOMIC)
248 {
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);
258 }
259 else
260 {
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);
274 }
275 }
276
277 /* Emits code to get VALUE to instrument at GSI, and returns the
278 variable containing the value. */
279
280 static tree
281 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
282 {
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);
289 }
290
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. */
294
295 void
296 gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
297 {
298 gimple *stmt = value->hvalue.stmt;
299 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
300 tree ref = tree_coverage_counter_ref (tag, base), 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);
307
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);
315 }
316
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, BASE is offset of the counter position. */
320
321 void
322 gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
323 {
324 gimple *stmt = value->hvalue.stmt;
325 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
326 tree ref_ptr = tree_coverage_counter_addr (tag, base);
327 gcall *call;
328 tree val;
329
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);
335 }
336
337 /* Output instructions as GIMPLE trees for code to find the most common value.
338 VALUE is the expression whose value is profiled. TAG is the tag of the
339 section for counters, BASE is offset of the counter position. */
340
341 void
342 gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
343 {
344 gimple *stmt = value->hvalue.stmt;
345 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
346 tree ref_ptr = tree_coverage_counter_addr (tag, base);
347 gcall *call;
348 tree val;
349
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_one_value_profiler_fn, 2, ref_ptr, val);
354 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
355 }
356
357
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, BASE is offset of the
362 counter position. */
363
364 void
365 gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
366 {
367 tree tmp1;
368 gassign *stmt1, *stmt2, *stmt3;
369 gimple *stmt = value->hvalue.stmt;
370 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
371 tree ref_ptr = tree_coverage_counter_addr (tag, base);
372
373 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
374 true, NULL_TREE, true, GSI_SAME_STMT);
375
376 /* Insert code:
377
378 stmt1: __gcov_indirect_call.counters = get_relevant_counter_ptr ();
379 stmt2: tmp1 = (void *) (indirect call argument value)
380 stmt3: __gcov_indirect_call.callee = tmp1;
381
382 Example:
383 f_1 = foo;
384 __gcov_indirect_call.counters = &__gcov4.main[0];
385 PROF_9 = f_1;
386 __gcov_indirect_call_callee = PROF_9;
387 _4 = f_1 ();
388 */
389
390 tree gcov_type_ptr = build_pointer_type (get_gcov_type ());
391
392 tree counter_ref = build3 (COMPONENT_REF, gcov_type_ptr,
393 ic_tuple_var, ic_tuple_counters_field, NULL_TREE);
394
395 stmt1 = gimple_build_assign (counter_ref, ref_ptr);
396 tmp1 = make_temp_ssa_name (ptr_type_node, NULL, "PROF");
397 stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
398 tree callee_ref = build3 (COMPONENT_REF, ptr_type_node,
399 ic_tuple_var, ic_tuple_callee_field, NULL_TREE);
400 stmt3 = gimple_build_assign (callee_ref, tmp1);
401
402 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
403 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
404 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
405 }
406
407
408 /* Output instructions as GIMPLE trees for code to find the most
409 common called function in indirect call. Insert instructions at the
410 beginning of every possible called function.
411 */
412
413 void
414 gimple_gen_ic_func_profiler (void)
415 {
416 struct cgraph_node * c_node = cgraph_node::get (current_function_decl);
417 gcall *stmt1;
418 tree tree_uid, cur_func, void0;
419
420 if (c_node->only_called_directly_p ())
421 return;
422
423 gimple_init_gcov_profiler ();
424
425 basic_block entry = ENTRY_BLOCK_PTR_FOR_FN (cfun);
426 basic_block cond_bb = split_edge (single_succ_edge (entry));
427 basic_block update_bb = split_edge (single_succ_edge (cond_bb));
428
429 /* We need to do an extra split in order to not create an input
430 for a possible PHI node. */
431 split_edge (single_succ_edge (update_bb));
432
433 edge true_edge = single_succ_edge (cond_bb);
434 true_edge->flags = EDGE_TRUE_VALUE;
435
436 profile_probability probability;
437 if (DECL_VIRTUAL_P (current_function_decl))
438 probability = profile_probability::very_likely ();
439 else
440 probability = profile_probability::unlikely ();
441
442 true_edge->probability = probability;
443 edge e = make_edge (cond_bb, single_succ_edge (update_bb)->dest,
444 EDGE_FALSE_VALUE);
445 e->probability = true_edge->probability.invert ();
446
447 /* Insert code:
448
449 if (__gcov_indirect_call_callee != NULL)
450 __gcov_indirect_call_profiler_v3 (profile_id, &current_function_decl);
451
452 The function __gcov_indirect_call_profiler_v3 is responsible for
453 resetting __gcov_indirect_call_callee to NULL. */
454
455 gimple_stmt_iterator gsi = gsi_start_bb (cond_bb);
456 void0 = build_int_cst (ptr_type_node, 0);
457
458 tree callee_ref = build3 (COMPONENT_REF, ptr_type_node,
459 ic_tuple_var, ic_tuple_callee_field, NULL_TREE);
460
461 tree ref = force_gimple_operand_gsi (&gsi, callee_ref, true, NULL_TREE,
462 true, GSI_SAME_STMT);
463
464 gcond *cond = gimple_build_cond (NE_EXPR, ref,
465 void0, NULL, NULL);
466 gsi_insert_before (&gsi, cond, GSI_NEW_STMT);
467
468 gsi = gsi_after_labels (update_bb);
469
470 cur_func = force_gimple_operand_gsi (&gsi,
471 build_addr (current_function_decl),
472 true, NULL_TREE,
473 true, GSI_SAME_STMT);
474 tree_uid = build_int_cst
475 (gcov_type_node,
476 cgraph_node::get (current_function_decl)->profile_id);
477 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2,
478 tree_uid, cur_func);
479 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
480 }
481
482 /* Output instructions as GIMPLE tree at the beginning for each function.
483 TAG is the tag of the section for counters, BASE is offset of the
484 counter position and GSI is the iterator we place the counter. */
485
486 void
487 gimple_gen_time_profiler (unsigned tag, unsigned base)
488 {
489 tree type = get_gcov_type ();
490 basic_block entry = ENTRY_BLOCK_PTR_FOR_FN (cfun);
491 basic_block cond_bb = split_edge (single_succ_edge (entry));
492 basic_block update_bb = split_edge (single_succ_edge (cond_bb));
493
494 /* We need to do an extra split in order to not create an input
495 for a possible PHI node. */
496 split_edge (single_succ_edge (update_bb));
497
498 edge true_edge = single_succ_edge (cond_bb);
499 true_edge->flags = EDGE_TRUE_VALUE;
500 true_edge->probability = profile_probability::unlikely ();
501 edge e
502 = make_edge (cond_bb, single_succ_edge (update_bb)->dest, EDGE_FALSE_VALUE);
503 e->probability = true_edge->probability.invert ();
504
505 gimple_stmt_iterator gsi = gsi_start_bb (cond_bb);
506 tree original_ref = tree_coverage_counter_ref (tag, base);
507 tree ref = force_gimple_operand_gsi (&gsi, original_ref, true, NULL_TREE,
508 true, GSI_SAME_STMT);
509 tree one = build_int_cst (type, 1);
510
511 /* Emit: if (counters[0] != 0). */
512 gcond *cond = gimple_build_cond (EQ_EXPR, ref, build_int_cst (type, 0),
513 NULL, NULL);
514 gsi_insert_before (&gsi, cond, GSI_NEW_STMT);
515
516 gsi = gsi_start_bb (update_bb);
517
518 /* Emit: counters[0] = ++__gcov_time_profiler_counter. */
519 if (flag_profile_update == PROFILE_UPDATE_ATOMIC)
520 {
521 tree ptr = make_temp_ssa_name (build_pointer_type (type), NULL,
522 "time_profiler_counter_ptr");
523 tree addr = build1 (ADDR_EXPR, TREE_TYPE (ptr),
524 tree_time_profiler_counter);
525 gassign *assign = gimple_build_assign (ptr, NOP_EXPR, addr);
526 gsi_insert_before (&gsi, assign, GSI_NEW_STMT);
527 tree f = builtin_decl_explicit (LONG_LONG_TYPE_SIZE > 32
528 ? BUILT_IN_ATOMIC_ADD_FETCH_8:
529 BUILT_IN_ATOMIC_ADD_FETCH_4);
530 gcall *stmt = gimple_build_call (f, 3, ptr, one,
531 build_int_cst (integer_type_node,
532 MEMMODEL_RELAXED));
533 tree result_type = TREE_TYPE (TREE_TYPE (f));
534 tree tmp = make_temp_ssa_name (result_type, NULL, "time_profile");
535 gimple_set_lhs (stmt, tmp);
536 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
537 tmp = make_temp_ssa_name (type, NULL, "time_profile");
538 assign = gimple_build_assign (tmp, NOP_EXPR,
539 gimple_call_lhs (stmt));
540 gsi_insert_after (&gsi, assign, GSI_NEW_STMT);
541 assign = gimple_build_assign (original_ref, tmp);
542 gsi_insert_after (&gsi, assign, GSI_NEW_STMT);
543 }
544 else
545 {
546 tree tmp = make_temp_ssa_name (type, NULL, "time_profile");
547 gassign *assign = gimple_build_assign (tmp, tree_time_profiler_counter);
548 gsi_insert_before (&gsi, assign, GSI_NEW_STMT);
549
550 tmp = make_temp_ssa_name (type, NULL, "time_profile");
551 assign = gimple_build_assign (tmp, PLUS_EXPR, gimple_assign_lhs (assign),
552 one);
553 gsi_insert_after (&gsi, assign, GSI_NEW_STMT);
554 assign = gimple_build_assign (original_ref, tmp);
555 gsi_insert_after (&gsi, assign, GSI_NEW_STMT);
556 assign = gimple_build_assign (tree_time_profiler_counter, tmp);
557 gsi_insert_after (&gsi, assign, GSI_NEW_STMT);
558 }
559 }
560
561 /* Output instructions as GIMPLE trees to increment the average histogram
562 counter. VALUE is the expression whose value is profiled. TAG is the
563 tag of the section for counters, BASE is offset of the counter position. */
564
565 void
566 gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
567 {
568 gimple *stmt = value->hvalue.stmt;
569 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
570 tree ref_ptr = tree_coverage_counter_addr (tag, base);
571 gcall *call;
572 tree val;
573
574 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
575 true, NULL_TREE,
576 true, GSI_SAME_STMT);
577 val = prepare_instrumented_value (&gsi, value);
578 call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
579 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
580 }
581
582 /* Output instructions as GIMPLE trees to increment the ior histogram
583 counter. VALUE is the expression whose value is profiled. TAG is the
584 tag of the section for counters, BASE is offset of the counter position. */
585
586 void
587 gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
588 {
589 gimple *stmt = value->hvalue.stmt;
590 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
591 tree ref_ptr = tree_coverage_counter_addr (tag, base);
592 gcall *call;
593 tree val;
594
595 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
596 true, NULL_TREE, true, GSI_SAME_STMT);
597 val = prepare_instrumented_value (&gsi, value);
598 call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
599 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
600 }
601
602 static vec<regex_t> profile_filter_files;
603 static vec<regex_t> profile_exclude_files;
604
605 /* Parse list of provided REGEX (separated with semi-collon) and
606 create expressions (of type regex_t) and save them into V vector.
607 If there is a regular expression parsing error, error message is
608 printed for FLAG_NAME. */
609
610 static void
611 parse_profile_filter (const char *regex, vec<regex_t> *v,
612 const char *flag_name)
613 {
614 v->create (4);
615 if (regex != NULL)
616 {
617 char *str = xstrdup (regex);
618 for (char *p = strtok (str, ";"); p != NULL; p = strtok (NULL, ";"))
619 {
620 regex_t r;
621 if (regcomp (&r, p, REG_EXTENDED | REG_NOSUB) != 0)
622 {
623 error ("invalid regular expression %qs in %qs",
624 p, flag_name);
625 return;
626 }
627
628 v->safe_push (r);
629 }
630 }
631 }
632
633 /* Parse values of -fprofile-filter-files and -fprofile-exclude-files
634 options. */
635
636 static void
637 parse_profile_file_filtering ()
638 {
639 parse_profile_filter (flag_profile_filter_files, &profile_filter_files,
640 "-fprofile-filter-files");
641 parse_profile_filter (flag_profile_exclude_files, &profile_exclude_files,
642 "-fprofile-exclude-files");
643 }
644
645 /* Parse vectors of regular expressions. */
646
647 static void
648 release_profile_file_filtering ()
649 {
650 profile_filter_files.release ();
651 profile_exclude_files.release ();
652 }
653
654 /* Return true when FILENAME should be instrumented based on
655 -fprofile-filter-files and -fprofile-exclude-files options. */
656
657 static bool
658 include_source_file_for_profile (const char *filename)
659 {
660 /* First check whether file is included in flag_profile_exclude_files. */
661 for (unsigned i = 0; i < profile_exclude_files.length (); i++)
662 if (regexec (&profile_exclude_files[i],
663 filename, 0, NULL, 0) == REG_NOERROR)
664 return false;
665
666 /* For non-empty flag_profile_filter_files include only files matching a
667 regex in the flag. */
668 if (profile_filter_files.is_empty ())
669 return true;
670
671 for (unsigned i = 0; i < profile_filter_files.length (); i++)
672 if (regexec (&profile_filter_files[i], filename, 0, NULL, 0) == REG_NOERROR)
673 return true;
674
675 return false;
676 }
677
678 #ifndef HAVE_sync_compare_and_swapsi
679 #define HAVE_sync_compare_and_swapsi 0
680 #endif
681 #ifndef HAVE_atomic_compare_and_swapsi
682 #define HAVE_atomic_compare_and_swapsi 0
683 #endif
684
685 #ifndef HAVE_sync_compare_and_swapdi
686 #define HAVE_sync_compare_and_swapdi 0
687 #endif
688 #ifndef HAVE_atomic_compare_and_swapdi
689 #define HAVE_atomic_compare_and_swapdi 0
690 #endif
691
692 /* Profile all functions in the callgraph. */
693
694 static unsigned int
695 tree_profiling (void)
696 {
697 struct cgraph_node *node;
698
699 /* Verify whether we can utilize atomic update operations. */
700 bool can_support_atomic = false;
701 unsigned HOST_WIDE_INT gcov_type_size
702 = tree_to_uhwi (TYPE_SIZE_UNIT (get_gcov_type ()));
703 if (gcov_type_size == 4)
704 can_support_atomic
705 = HAVE_sync_compare_and_swapsi || HAVE_atomic_compare_and_swapsi;
706 else if (gcov_type_size == 8)
707 can_support_atomic
708 = HAVE_sync_compare_and_swapdi || HAVE_atomic_compare_and_swapdi;
709
710 if (flag_profile_update == PROFILE_UPDATE_ATOMIC
711 && !can_support_atomic)
712 {
713 warning (0, "target does not support atomic profile update, "
714 "single mode is selected");
715 flag_profile_update = PROFILE_UPDATE_SINGLE;
716 }
717 else if (flag_profile_update == PROFILE_UPDATE_PREFER_ATOMIC)
718 flag_profile_update = can_support_atomic
719 ? PROFILE_UPDATE_ATOMIC : PROFILE_UPDATE_SINGLE;
720
721 /* This is a small-ipa pass that gets called only once, from
722 cgraphunit.c:ipa_passes(). */
723 gcc_assert (symtab->state == IPA_SSA);
724
725 init_node_map (true);
726 parse_profile_file_filtering ();
727
728 FOR_EACH_DEFINED_FUNCTION (node)
729 {
730 bool thunk = false;
731 if (!gimple_has_body_p (node->decl) && !node->thunk.thunk_p)
732 continue;
733
734 /* Don't profile functions produced for builtin stuff. */
735 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
736 continue;
737
738 if (lookup_attribute ("no_profile_instrument_function",
739 DECL_ATTRIBUTES (node->decl)))
740 continue;
741 /* Do not instrument extern inline functions when testing coverage.
742 While this is not perfectly consistent (early inlined extern inlines
743 will get acocunted), testsuite expects that. */
744 if (DECL_EXTERNAL (node->decl)
745 && flag_test_coverage)
746 continue;
747
748 const char *file = LOCATION_FILE (DECL_SOURCE_LOCATION (node->decl));
749 if (!include_source_file_for_profile (file))
750 continue;
751
752 if (node->thunk.thunk_p)
753 {
754 /* We cannot expand variadic thunks to Gimple. */
755 if (stdarg_p (TREE_TYPE (node->decl)))
756 continue;
757 thunk = true;
758 /* When generate profile, expand thunk to gimple so it can be
759 instrumented same way as other functions. */
760 if (profile_arc_flag)
761 node->expand_thunk (false, true);
762 /* Read cgraph profile but keep function as thunk at profile-use
763 time. */
764 else
765 {
766 read_thunk_profile (node);
767 continue;
768 }
769 }
770
771 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
772
773 if (dump_file)
774 dump_function_header (dump_file, cfun->decl, dump_flags);
775
776 /* Local pure-const may imply need to fixup the cfg. */
777 if (gimple_has_body_p (node->decl)
778 && (execute_fixup_cfg () & TODO_cleanup_cfg))
779 cleanup_tree_cfg ();
780
781 branch_prob (thunk);
782
783 if (! flag_branch_probabilities
784 && flag_profile_values)
785 gimple_gen_ic_func_profiler ();
786
787 if (flag_branch_probabilities
788 && !thunk
789 && flag_profile_values
790 && flag_value_profile_transformations)
791 gimple_value_profile_transformations ();
792
793 /* The above could hose dominator info. Currently there is
794 none coming in, this is a safety valve. It should be
795 easy to adjust it, if and when there is some. */
796 free_dominance_info (CDI_DOMINATORS);
797 free_dominance_info (CDI_POST_DOMINATORS);
798 pop_cfun ();
799 }
800
801 release_profile_file_filtering ();
802
803 /* Drop pure/const flags from instrumented functions. */
804 if (profile_arc_flag || flag_test_coverage)
805 FOR_EACH_DEFINED_FUNCTION (node)
806 {
807 if (!gimple_has_body_p (node->decl)
808 || !(!node->clone_of
809 || node->decl != node->clone_of->decl))
810 continue;
811
812 /* Don't profile functions produced for builtin stuff. */
813 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
814 continue;
815
816 node->set_const_flag (false, false);
817 node->set_pure_flag (false, false);
818 }
819
820 /* Update call statements and rebuild the cgraph. */
821 FOR_EACH_DEFINED_FUNCTION (node)
822 {
823 basic_block bb;
824
825 if (!gimple_has_body_p (node->decl)
826 || !(!node->clone_of
827 || node->decl != node->clone_of->decl))
828 continue;
829
830 /* Don't profile functions produced for builtin stuff. */
831 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
832 continue;
833
834 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
835
836 FOR_EACH_BB_FN (bb, cfun)
837 {
838 gimple_stmt_iterator gsi;
839 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
840 {
841 gimple *stmt = gsi_stmt (gsi);
842 if (is_gimple_call (stmt))
843 update_stmt (stmt);
844 }
845 }
846
847 /* re-merge split blocks. */
848 cleanup_tree_cfg ();
849 update_ssa (TODO_update_ssa);
850
851 cgraph_edge::rebuild_edges ();
852
853 pop_cfun ();
854 }
855
856 handle_missing_profiles ();
857
858 del_node_map ();
859 return 0;
860 }
861
862 namespace {
863
864 const pass_data pass_data_ipa_tree_profile =
865 {
866 SIMPLE_IPA_PASS, /* type */
867 "profile", /* name */
868 OPTGROUP_NONE, /* optinfo_flags */
869 TV_IPA_PROFILE, /* tv_id */
870 0, /* properties_required */
871 0, /* properties_provided */
872 0, /* properties_destroyed */
873 0, /* todo_flags_start */
874 TODO_dump_symtab, /* todo_flags_finish */
875 };
876
877 class pass_ipa_tree_profile : public simple_ipa_opt_pass
878 {
879 public:
880 pass_ipa_tree_profile (gcc::context *ctxt)
881 : simple_ipa_opt_pass (pass_data_ipa_tree_profile, ctxt)
882 {}
883
884 /* opt_pass methods: */
885 virtual bool gate (function *);
886 virtual unsigned int execute (function *) { return tree_profiling (); }
887
888 }; // class pass_ipa_tree_profile
889
890 bool
891 pass_ipa_tree_profile::gate (function *)
892 {
893 /* When profile instrumentation, use or test coverage shall be performed.
894 But for AutoFDO, this there is no instrumentation, thus this pass is
895 diabled. */
896 return (!in_lto_p && !flag_auto_profile
897 && (flag_branch_probabilities || flag_test_coverage
898 || profile_arc_flag));
899 }
900
901 } // anon namespace
902
903 simple_ipa_opt_pass *
904 make_pass_ipa_tree_profile (gcc::context *ctxt)
905 {
906 return new pass_ipa_tree_profile (ctxt);
907 }
908
909 #include "gt-tree-profile.h"