[ree] PR rtl-optimization/78038: Handle global register dataflow definitions in ree
[official-gcc.git] / gcc / tree-profile.c
blobabeee92204e227fa5752ebf5aefa9fd961286c69
1 /* Calculate branch probabilities, and basic block execution counts.
2 Copyright (C) 1990-2016 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"
54 static GTY(()) tree gcov_type_node;
55 static GTY(()) tree tree_interval_profiler_fn;
56 static GTY(()) tree tree_pow2_profiler_fn;
57 static GTY(()) tree tree_one_value_profiler_fn;
58 static GTY(()) tree tree_indirect_call_profiler_fn;
59 static GTY(()) tree tree_time_profiler_fn;
60 static GTY(()) tree tree_average_profiler_fn;
61 static GTY(()) tree tree_ior_profiler_fn;
64 static GTY(()) tree ic_void_ptr_var;
65 static GTY(()) tree ic_gcov_type_ptr_var;
66 static GTY(()) tree ptr_void;
68 /* Do initialization work for the edge profiler. */
70 /* Add code:
71 __thread gcov* __gcov_indirect_call_counters; // pointer to actual counter
72 __thread void* __gcov_indirect_call_callee; // actual callee address
73 __thread int __gcov_function_counter; // time profiler function counter
75 static void
76 init_ic_make_global_vars (void)
78 tree gcov_type_ptr;
80 ptr_void = build_pointer_type (void_type_node);
82 ic_void_ptr_var
83 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
84 get_identifier (
85 (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
86 "__gcov_indirect_call_topn_callee" :
87 "__gcov_indirect_call_callee")),
88 ptr_void);
89 TREE_PUBLIC (ic_void_ptr_var) = 1;
90 DECL_EXTERNAL (ic_void_ptr_var) = 1;
91 TREE_STATIC (ic_void_ptr_var) = 1;
92 DECL_ARTIFICIAL (ic_void_ptr_var) = 1;
93 DECL_INITIAL (ic_void_ptr_var) = NULL;
94 if (targetm.have_tls)
95 set_decl_tls_model (ic_void_ptr_var, decl_default_tls_model (ic_void_ptr_var));
97 varpool_node::finalize_decl (ic_void_ptr_var);
99 gcov_type_ptr = build_pointer_type (get_gcov_type ());
101 ic_gcov_type_ptr_var
102 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
103 get_identifier (
104 (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
105 "__gcov_indirect_call_topn_counters" :
106 "__gcov_indirect_call_counters")),
107 gcov_type_ptr);
108 TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
109 DECL_EXTERNAL (ic_gcov_type_ptr_var) = 1;
110 TREE_STATIC (ic_gcov_type_ptr_var) = 1;
111 DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1;
112 DECL_INITIAL (ic_gcov_type_ptr_var) = NULL;
113 if (targetm.have_tls)
114 set_decl_tls_model (ic_gcov_type_ptr_var, decl_default_tls_model (ic_gcov_type_ptr_var));
116 varpool_node::finalize_decl (ic_gcov_type_ptr_var);
119 /* Create the type and function decls for the interface with gcov. */
121 void
122 gimple_init_edge_profiler (void)
124 tree interval_profiler_fn_type;
125 tree pow2_profiler_fn_type;
126 tree one_value_profiler_fn_type;
127 tree gcov_type_ptr;
128 tree ic_profiler_fn_type;
129 tree average_profiler_fn_type;
130 tree time_profiler_fn_type;
131 const char *profiler_fn_name;
132 const char *fn_name;
134 if (!gcov_type_node)
136 const char *fn_suffix
137 = flag_profile_update == PROFILE_UPDATE_ATOMIC ? "_atomic" : "";
139 gcov_type_node = get_gcov_type ();
140 gcov_type_ptr = build_pointer_type (gcov_type_node);
142 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
143 interval_profiler_fn_type
144 = build_function_type_list (void_type_node,
145 gcov_type_ptr, gcov_type_node,
146 integer_type_node,
147 unsigned_type_node, NULL_TREE);
148 fn_name = concat ("__gcov_interval_profiler", fn_suffix, NULL);
149 tree_interval_profiler_fn = build_fn_decl (fn_name,
150 interval_profiler_fn_type);
151 free (CONST_CAST (char *, fn_name));
152 TREE_NOTHROW (tree_interval_profiler_fn) = 1;
153 DECL_ATTRIBUTES (tree_interval_profiler_fn)
154 = tree_cons (get_identifier ("leaf"), NULL,
155 DECL_ATTRIBUTES (tree_interval_profiler_fn));
157 /* void (*) (gcov_type *, gcov_type) */
158 pow2_profiler_fn_type
159 = build_function_type_list (void_type_node,
160 gcov_type_ptr, gcov_type_node,
161 NULL_TREE);
162 fn_name = concat ("__gcov_pow2_profiler", fn_suffix, NULL);
163 tree_pow2_profiler_fn = build_fn_decl (fn_name, pow2_profiler_fn_type);
164 free (CONST_CAST (char *, fn_name));
165 TREE_NOTHROW (tree_pow2_profiler_fn) = 1;
166 DECL_ATTRIBUTES (tree_pow2_profiler_fn)
167 = tree_cons (get_identifier ("leaf"), NULL,
168 DECL_ATTRIBUTES (tree_pow2_profiler_fn));
170 /* void (*) (gcov_type *, gcov_type) */
171 one_value_profiler_fn_type
172 = build_function_type_list (void_type_node,
173 gcov_type_ptr, gcov_type_node,
174 NULL_TREE);
175 fn_name = concat ("__gcov_one_value_profiler", fn_suffix, NULL);
176 tree_one_value_profiler_fn = build_fn_decl (fn_name,
177 one_value_profiler_fn_type);
178 free (CONST_CAST (char *, fn_name));
179 TREE_NOTHROW (tree_one_value_profiler_fn) = 1;
180 DECL_ATTRIBUTES (tree_one_value_profiler_fn)
181 = tree_cons (get_identifier ("leaf"), NULL,
182 DECL_ATTRIBUTES (tree_one_value_profiler_fn));
184 init_ic_make_global_vars ();
186 /* void (*) (gcov_type, void *) */
187 ic_profiler_fn_type
188 = build_function_type_list (void_type_node,
189 gcov_type_node,
190 ptr_void,
191 NULL_TREE);
192 profiler_fn_name = "__gcov_indirect_call_profiler_v2";
193 if (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE))
194 profiler_fn_name = "__gcov_indirect_call_topn_profiler";
196 tree_indirect_call_profiler_fn
197 = build_fn_decl (profiler_fn_name, ic_profiler_fn_type);
199 TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
200 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
201 = tree_cons (get_identifier ("leaf"), NULL,
202 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn));
204 /* void (*) (gcov_type *, gcov_type, void *) */
205 time_profiler_fn_type
206 = build_function_type_list (void_type_node,
207 gcov_type_ptr, NULL_TREE);
208 fn_name = concat ("__gcov_time_profiler", fn_suffix, NULL);
209 tree_time_profiler_fn = build_fn_decl (fn_name, time_profiler_fn_type);
210 free (CONST_CAST (char *, fn_name));
211 TREE_NOTHROW (tree_time_profiler_fn) = 1;
212 DECL_ATTRIBUTES (tree_time_profiler_fn)
213 = tree_cons (get_identifier ("leaf"), NULL,
214 DECL_ATTRIBUTES (tree_time_profiler_fn));
216 /* void (*) (gcov_type *, gcov_type) */
217 average_profiler_fn_type
218 = build_function_type_list (void_type_node,
219 gcov_type_ptr, gcov_type_node, NULL_TREE);
220 fn_name = concat ("__gcov_average_profiler", fn_suffix, NULL);
221 tree_average_profiler_fn = build_fn_decl (fn_name,
222 average_profiler_fn_type);
223 free (CONST_CAST (char *, fn_name));
224 TREE_NOTHROW (tree_average_profiler_fn) = 1;
225 DECL_ATTRIBUTES (tree_average_profiler_fn)
226 = tree_cons (get_identifier ("leaf"), NULL,
227 DECL_ATTRIBUTES (tree_average_profiler_fn));
228 fn_name = concat ("__gcov_ior_profiler", fn_suffix, NULL);
229 tree_ior_profiler_fn = build_fn_decl (fn_name, average_profiler_fn_type);
230 free (CONST_CAST (char *, fn_name));
231 TREE_NOTHROW (tree_ior_profiler_fn) = 1;
232 DECL_ATTRIBUTES (tree_ior_profiler_fn)
233 = tree_cons (get_identifier ("leaf"), NULL,
234 DECL_ATTRIBUTES (tree_ior_profiler_fn));
236 /* LTO streamer needs assembler names. Because we create these decls
237 late, we need to initialize them by hand. */
238 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn);
239 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn);
240 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn);
241 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn);
242 DECL_ASSEMBLER_NAME (tree_time_profiler_fn);
243 DECL_ASSEMBLER_NAME (tree_average_profiler_fn);
244 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
248 /* Output instructions as GIMPLE trees to increment the edge
249 execution count, and insert them on E. We rely on
250 gsi_insert_on_edge to preserve the order. */
252 void
253 gimple_gen_edge_profiler (int edgeno, edge e)
255 tree one;
257 one = build_int_cst (gcov_type_node, 1);
259 if (flag_profile_update == PROFILE_UPDATE_ATOMIC)
261 /* __atomic_fetch_add (&counter, 1, MEMMODEL_RELAXED); */
262 tree addr = tree_coverage_counter_addr (GCOV_COUNTER_ARCS, edgeno);
263 tree f = builtin_decl_explicit (LONG_LONG_TYPE_SIZE > 32
264 ? BUILT_IN_ATOMIC_FETCH_ADD_8:
265 BUILT_IN_ATOMIC_FETCH_ADD_4);
266 gcall *stmt = gimple_build_call (f, 3, addr, one,
267 build_int_cst (integer_type_node,
268 MEMMODEL_RELAXED));
269 gsi_insert_on_edge (e, stmt);
271 else
273 tree ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
274 tree gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
275 NULL, "PROF_edge_counter");
276 gassign *stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
277 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
278 NULL, "PROF_edge_counter");
279 gassign *stmt2 = gimple_build_assign (gcov_type_tmp_var, PLUS_EXPR,
280 gimple_assign_lhs (stmt1), one);
281 gassign *stmt3 = gimple_build_assign (unshare_expr (ref),
282 gimple_assign_lhs (stmt2));
283 gsi_insert_on_edge (e, stmt1);
284 gsi_insert_on_edge (e, stmt2);
285 gsi_insert_on_edge (e, stmt3);
289 /* Emits code to get VALUE to instrument at GSI, and returns the
290 variable containing the value. */
292 static tree
293 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
295 tree val = value->hvalue.value;
296 if (POINTER_TYPE_P (TREE_TYPE (val)))
297 val = fold_convert (build_nonstandard_integer_type
298 (TYPE_PRECISION (TREE_TYPE (val)), 1), val);
299 return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
300 true, NULL_TREE, true, GSI_SAME_STMT);
303 /* Output instructions as GIMPLE trees to increment the interval histogram
304 counter. VALUE is the expression whose value is profiled. TAG is the
305 tag of the section for counters, BASE is offset of the counter position. */
307 void
308 gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
310 gimple *stmt = value->hvalue.stmt;
311 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
312 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
313 gcall *call;
314 tree val;
315 tree start = build_int_cst_type (integer_type_node,
316 value->hdata.intvl.int_start);
317 tree steps = build_int_cst_type (unsigned_type_node,
318 value->hdata.intvl.steps);
320 ref_ptr = force_gimple_operand_gsi (&gsi,
321 build_addr (ref),
322 true, NULL_TREE, true, GSI_SAME_STMT);
323 val = prepare_instrumented_value (&gsi, value);
324 call = gimple_build_call (tree_interval_profiler_fn, 4,
325 ref_ptr, val, start, steps);
326 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
329 /* Output instructions as GIMPLE trees to increment the power of two histogram
330 counter. VALUE is the expression whose value is profiled. TAG is the tag
331 of the section for counters, BASE is offset of the counter position. */
333 void
334 gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
336 gimple *stmt = value->hvalue.stmt;
337 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
338 tree ref_ptr = tree_coverage_counter_addr (tag, base);
339 gcall *call;
340 tree val;
342 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
343 true, NULL_TREE, true, GSI_SAME_STMT);
344 val = prepare_instrumented_value (&gsi, value);
345 call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val);
346 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
349 /* Output instructions as GIMPLE trees for code to find the most common value.
350 VALUE is the expression whose value is profiled. TAG is the tag of the
351 section for counters, BASE is offset of the counter position. */
353 void
354 gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
356 gimple *stmt = value->hvalue.stmt;
357 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
358 tree ref_ptr = tree_coverage_counter_addr (tag, base);
359 gcall *call;
360 tree val;
362 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
363 true, NULL_TREE, true, GSI_SAME_STMT);
364 val = prepare_instrumented_value (&gsi, value);
365 call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val);
366 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
370 /* Output instructions as GIMPLE trees for code to find the most
371 common called function in indirect call.
372 VALUE is the call expression whose indirect callee is profiled.
373 TAG is the tag of the section for counters, BASE is offset of the
374 counter position. */
376 void
377 gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
379 tree tmp1;
380 gassign *stmt1, *stmt2, *stmt3;
381 gimple *stmt = value->hvalue.stmt;
382 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
383 tree ref_ptr = tree_coverage_counter_addr (tag, base);
385 if ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) &&
386 tag == GCOV_COUNTER_V_INDIR) ||
387 (!PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) &&
388 tag == GCOV_COUNTER_ICALL_TOPNV))
389 return;
391 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
392 true, NULL_TREE, true, GSI_SAME_STMT);
394 /* Insert code:
396 stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
397 stmt2: tmp1 = (void *) (indirect call argument value)
398 stmt3: __gcov_indirect_call_callee = tmp1;
401 stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr);
402 tmp1 = make_temp_ssa_name (ptr_void, NULL, "PROF");
403 stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
404 stmt3 = gimple_build_assign (ic_void_ptr_var, gimple_assign_lhs (stmt2));
406 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
407 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
408 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
412 /* Output instructions as GIMPLE trees for code to find the most
413 common called function in indirect call. Insert instructions at the
414 beginning of every possible called function.
417 void
418 gimple_gen_ic_func_profiler (void)
420 struct cgraph_node * c_node = cgraph_node::get (current_function_decl);
421 gimple_stmt_iterator gsi;
422 gcall *stmt1;
423 gassign *stmt2;
424 tree tree_uid, cur_func, void0;
426 if (c_node->only_called_directly_p ())
427 return;
429 gimple_init_edge_profiler ();
431 /* Insert code:
433 stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
434 &current_function_decl)
436 gsi = gsi_after_labels (split_edge (single_succ_edge
437 (ENTRY_BLOCK_PTR_FOR_FN (cfun))));
439 cur_func = force_gimple_operand_gsi (&gsi,
440 build_addr (current_function_decl),
441 true, NULL_TREE,
442 true, GSI_SAME_STMT);
443 tree_uid = build_int_cst
444 (gcov_type_node,
445 cgraph_node::get (current_function_decl)->profile_id);
446 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2,
447 tree_uid, cur_func);
448 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
450 /* Set __gcov_indirect_call_callee to 0,
451 so that calls from other modules won't get misattributed
452 to the last caller of the current callee. */
453 void0 = build_int_cst (build_pointer_type (void_type_node), 0);
454 stmt2 = gimple_build_assign (ic_void_ptr_var, void0);
455 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
458 /* Output instructions as GIMPLE tree at the beginning for each function.
459 TAG is the tag of the section for counters, BASE is offset of the
460 counter position and GSI is the iterator we place the counter. */
462 void
463 gimple_gen_time_profiler (unsigned tag, unsigned base,
464 gimple_stmt_iterator &gsi)
466 tree ref_ptr = tree_coverage_counter_addr (tag, base);
467 gcall *call;
469 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
470 true, NULL_TREE, true, GSI_SAME_STMT);
471 call = gimple_build_call (tree_time_profiler_fn, 1, ref_ptr);
472 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
475 /* Output instructions as GIMPLE trees to increment the average histogram
476 counter. VALUE is the expression whose value is profiled. TAG is the
477 tag of the section for counters, BASE is offset of the counter position. */
479 void
480 gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
482 gimple *stmt = value->hvalue.stmt;
483 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
484 tree ref_ptr = tree_coverage_counter_addr (tag, base);
485 gcall *call;
486 tree val;
488 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
489 true, NULL_TREE,
490 true, GSI_SAME_STMT);
491 val = prepare_instrumented_value (&gsi, value);
492 call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
493 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
496 /* Output instructions as GIMPLE trees to increment the ior histogram
497 counter. VALUE is the expression whose value is profiled. TAG is the
498 tag of the section for counters, BASE is offset of the counter position. */
500 void
501 gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
503 gimple *stmt = value->hvalue.stmt;
504 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
505 tree ref_ptr = tree_coverage_counter_addr (tag, base);
506 gcall *call;
507 tree val;
509 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
510 true, NULL_TREE, true, GSI_SAME_STMT);
511 val = prepare_instrumented_value (&gsi, value);
512 call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
513 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
516 #ifndef HAVE_sync_compare_and_swapsi
517 #define HAVE_sync_compare_and_swapsi 0
518 #endif
519 #ifndef HAVE_atomic_compare_and_swapsi
520 #define HAVE_atomic_compare_and_swapsi 0
521 #endif
523 #ifndef HAVE_sync_compare_and_swapdi
524 #define HAVE_sync_compare_and_swapdi 0
525 #endif
526 #ifndef HAVE_atomic_compare_and_swapdi
527 #define HAVE_atomic_compare_and_swapdi 0
528 #endif
530 /* Profile all functions in the callgraph. */
532 static unsigned int
533 tree_profiling (void)
535 struct cgraph_node *node;
537 /* Verify whether we can utilize atomic update operations. */
538 if (flag_profile_update == PROFILE_UPDATE_ATOMIC)
540 bool can_support = false;
541 unsigned HOST_WIDE_INT gcov_type_size
542 = tree_to_uhwi (TYPE_SIZE_UNIT (get_gcov_type ()));
543 if (gcov_type_size == 4)
544 can_support
545 = HAVE_sync_compare_and_swapsi || HAVE_atomic_compare_and_swapsi;
546 else if (gcov_type_size == 8)
547 can_support
548 = HAVE_sync_compare_and_swapdi || HAVE_atomic_compare_and_swapdi;
550 if (!can_support)
552 warning (0, "target does not support atomic profile update, "
553 "single mode is selected");
554 flag_profile_update = PROFILE_UPDATE_SINGLE;
558 /* This is a small-ipa pass that gets called only once, from
559 cgraphunit.c:ipa_passes(). */
560 gcc_assert (symtab->state == IPA_SSA);
562 init_node_map (true);
564 FOR_EACH_DEFINED_FUNCTION (node)
566 if (!gimple_has_body_p (node->decl))
567 continue;
569 /* Don't profile functions produced for builtin stuff. */
570 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
571 continue;
573 if (lookup_attribute ("no_profile_instrument_function",
574 DECL_ATTRIBUTES (node->decl)))
575 continue;
576 /* Do not instrument extern inline functions when testing coverage.
577 While this is not perfectly consistent (early inlined extern inlines
578 will get acocunted), testsuite expects that. */
579 if (DECL_EXTERNAL (node->decl)
580 && flag_test_coverage)
581 continue;
583 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
585 /* Local pure-const may imply need to fixup the cfg. */
586 if (execute_fixup_cfg () & TODO_cleanup_cfg)
587 cleanup_tree_cfg ();
589 branch_prob ();
591 if (! flag_branch_probabilities
592 && flag_profile_values)
593 gimple_gen_ic_func_profiler ();
595 if (flag_branch_probabilities
596 && flag_profile_values
597 && flag_value_profile_transformations)
598 gimple_value_profile_transformations ();
600 /* The above could hose dominator info. Currently there is
601 none coming in, this is a safety valve. It should be
602 easy to adjust it, if and when there is some. */
603 free_dominance_info (CDI_DOMINATORS);
604 free_dominance_info (CDI_POST_DOMINATORS);
605 pop_cfun ();
608 /* Drop pure/const flags from instrumented functions. */
609 if (profile_arc_flag || flag_test_coverage)
610 FOR_EACH_DEFINED_FUNCTION (node)
612 if (!gimple_has_body_p (node->decl)
613 || !(!node->clone_of
614 || node->decl != node->clone_of->decl))
615 continue;
617 /* Don't profile functions produced for builtin stuff. */
618 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
619 continue;
621 node->set_const_flag (false, false);
622 node->set_pure_flag (false, false);
625 /* Update call statements and rebuild the cgraph. */
626 FOR_EACH_DEFINED_FUNCTION (node)
628 basic_block bb;
630 if (!gimple_has_body_p (node->decl)
631 || !(!node->clone_of
632 || node->decl != node->clone_of->decl))
633 continue;
635 /* Don't profile functions produced for builtin stuff. */
636 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
637 continue;
639 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
641 FOR_EACH_BB_FN (bb, cfun)
643 gimple_stmt_iterator gsi;
644 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
646 gimple *stmt = gsi_stmt (gsi);
647 if (is_gimple_call (stmt))
648 update_stmt (stmt);
652 /* re-merge split blocks. */
653 cleanup_tree_cfg ();
654 update_ssa (TODO_update_ssa);
656 cgraph_edge::rebuild_edges ();
658 pop_cfun ();
661 handle_missing_profiles ();
663 del_node_map ();
664 return 0;
667 namespace {
669 const pass_data pass_data_ipa_tree_profile =
671 SIMPLE_IPA_PASS, /* type */
672 "profile", /* name */
673 OPTGROUP_NONE, /* optinfo_flags */
674 TV_IPA_PROFILE, /* tv_id */
675 0, /* properties_required */
676 0, /* properties_provided */
677 0, /* properties_destroyed */
678 0, /* todo_flags_start */
679 TODO_dump_symtab, /* todo_flags_finish */
682 class pass_ipa_tree_profile : public simple_ipa_opt_pass
684 public:
685 pass_ipa_tree_profile (gcc::context *ctxt)
686 : simple_ipa_opt_pass (pass_data_ipa_tree_profile, ctxt)
689 /* opt_pass methods: */
690 virtual bool gate (function *);
691 virtual unsigned int execute (function *) { return tree_profiling (); }
693 }; // class pass_ipa_tree_profile
695 bool
696 pass_ipa_tree_profile::gate (function *)
698 /* When profile instrumentation, use or test coverage shall be performed.
699 But for AutoFDO, this there is no instrumentation, thus this pass is
700 diabled. */
701 return (!in_lto_p && !flag_auto_profile
702 && (flag_branch_probabilities || flag_test_coverage
703 || profile_arc_flag));
706 } // anon namespace
708 simple_ipa_opt_pass *
709 make_pass_ipa_tree_profile (gcc::context *ctxt)
711 return new pass_ipa_tree_profile (ctxt);
714 #include "gt-tree-profile.h"