Cherry-pick fprofile-generate-atomic from google/gcc-4_9
[official-gcc.git] / gcc / tree-profile.c
blob740f7ab7d5a56d06c195dfe93cba81ae0ebb3955
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 "backend.h"
31 #include "target.h"
32 #include "tree.h"
33 #include "gimple.h"
34 #include "cfghooks.h"
35 #include "tree-pass.h"
36 #include "ssa.h"
37 #include "cgraph.h"
38 #include "coverage.h"
39 #include "diagnostic-core.h"
40 #include "fold-const.h"
41 #include "varasm.h"
42 #include "tree-nested.h"
43 #include "gimplify.h"
44 #include "gimple-iterator.h"
45 #include "gimplify-me.h"
46 #include "tree-cfg.h"
47 #include "tree-into-ssa.h"
48 #include "value-prof.h"
49 #include "profile.h"
50 #include "tree-cfgcleanup.h"
51 #include "params.h"
53 static GTY(()) tree gcov_type_node;
54 static GTY(()) tree tree_interval_profiler_fn;
55 static GTY(()) tree tree_pow2_profiler_fn;
56 static GTY(()) tree tree_one_value_profiler_fn;
57 static GTY(()) tree tree_indirect_call_profiler_fn;
58 static GTY(()) tree tree_time_profiler_fn;
59 static GTY(()) tree tree_average_profiler_fn;
60 static GTY(()) tree tree_ior_profiler_fn;
63 static GTY(()) tree ic_void_ptr_var;
64 static GTY(()) tree ic_gcov_type_ptr_var;
65 static GTY(()) tree ptr_void;
67 /* Do initialization work for the edge profiler. */
69 /* Add code:
70 __thread gcov* __gcov_indirect_call_counters; // pointer to actual counter
71 __thread void* __gcov_indirect_call_callee; // actual callee address
72 __thread int __gcov_function_counter; // time profiler function counter
74 static void
75 init_ic_make_global_vars (void)
77 tree gcov_type_ptr;
79 ptr_void = build_pointer_type (void_type_node);
81 ic_void_ptr_var
82 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
83 get_identifier (
84 (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
85 "__gcov_indirect_call_topn_callee" :
86 "__gcov_indirect_call_callee")),
87 ptr_void);
88 TREE_PUBLIC (ic_void_ptr_var) = 1;
89 DECL_EXTERNAL (ic_void_ptr_var) = 1;
90 TREE_STATIC (ic_void_ptr_var) = 1;
91 DECL_ARTIFICIAL (ic_void_ptr_var) = 1;
92 DECL_INITIAL (ic_void_ptr_var) = NULL;
93 if (targetm.have_tls)
94 set_decl_tls_model (ic_void_ptr_var, decl_default_tls_model (ic_void_ptr_var));
96 varpool_node::finalize_decl (ic_void_ptr_var);
98 gcov_type_ptr = build_pointer_type (get_gcov_type ());
100 ic_gcov_type_ptr_var
101 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
102 get_identifier (
103 (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
104 "__gcov_indirect_call_topn_counters" :
105 "__gcov_indirect_call_counters")),
106 gcov_type_ptr);
107 TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
108 DECL_EXTERNAL (ic_gcov_type_ptr_var) = 1;
109 TREE_STATIC (ic_gcov_type_ptr_var) = 1;
110 DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1;
111 DECL_INITIAL (ic_gcov_type_ptr_var) = NULL;
112 if (targetm.have_tls)
113 set_decl_tls_model (ic_gcov_type_ptr_var, decl_default_tls_model (ic_gcov_type_ptr_var));
115 varpool_node::finalize_decl (ic_gcov_type_ptr_var);
118 /* Create the type and function decls for the interface with gcov. */
120 void
121 gimple_init_edge_profiler (void)
123 tree interval_profiler_fn_type;
124 tree pow2_profiler_fn_type;
125 tree one_value_profiler_fn_type;
126 tree gcov_type_ptr;
127 tree ic_profiler_fn_type;
128 tree average_profiler_fn_type;
129 tree time_profiler_fn_type;
130 const char *profiler_fn_name;
132 if (!gcov_type_node)
134 gcov_type_node = get_gcov_type ();
135 gcov_type_ptr = build_pointer_type (gcov_type_node);
137 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
138 interval_profiler_fn_type
139 = build_function_type_list (void_type_node,
140 gcov_type_ptr, gcov_type_node,
141 integer_type_node,
142 unsigned_type_node, NULL_TREE);
143 tree_interval_profiler_fn
144 = build_fn_decl ("__gcov_interval_profiler",
145 interval_profiler_fn_type);
146 TREE_NOTHROW (tree_interval_profiler_fn) = 1;
147 DECL_ATTRIBUTES (tree_interval_profiler_fn)
148 = tree_cons (get_identifier ("leaf"), NULL,
149 DECL_ATTRIBUTES (tree_interval_profiler_fn));
151 /* void (*) (gcov_type *, gcov_type) */
152 pow2_profiler_fn_type
153 = build_function_type_list (void_type_node,
154 gcov_type_ptr, gcov_type_node,
155 NULL_TREE);
156 tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler",
157 pow2_profiler_fn_type);
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 one_value_profiler_fn_type
165 = build_function_type_list (void_type_node,
166 gcov_type_ptr, gcov_type_node,
167 NULL_TREE);
168 tree_one_value_profiler_fn
169 = build_fn_decl ("__gcov_one_value_profiler",
170 one_value_profiler_fn_type);
171 TREE_NOTHROW (tree_one_value_profiler_fn) = 1;
172 DECL_ATTRIBUTES (tree_one_value_profiler_fn)
173 = tree_cons (get_identifier ("leaf"), NULL,
174 DECL_ATTRIBUTES (tree_one_value_profiler_fn));
176 init_ic_make_global_vars ();
178 /* void (*) (gcov_type, void *) */
179 ic_profiler_fn_type
180 = build_function_type_list (void_type_node,
181 gcov_type_node,
182 ptr_void,
183 NULL_TREE);
184 profiler_fn_name = "__gcov_indirect_call_profiler_v2";
185 if (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE))
186 profiler_fn_name = "__gcov_indirect_call_topn_profiler";
188 tree_indirect_call_profiler_fn
189 = build_fn_decl (profiler_fn_name, ic_profiler_fn_type);
191 TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
192 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
193 = tree_cons (get_identifier ("leaf"), NULL,
194 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn));
196 /* void (*) (gcov_type *, gcov_type, void *) */
197 time_profiler_fn_type
198 = build_function_type_list (void_type_node,
199 gcov_type_ptr, NULL_TREE);
200 tree_time_profiler_fn
201 = build_fn_decl ("__gcov_time_profiler",
202 time_profiler_fn_type);
203 TREE_NOTHROW (tree_time_profiler_fn) = 1;
204 DECL_ATTRIBUTES (tree_time_profiler_fn)
205 = tree_cons (get_identifier ("leaf"), NULL,
206 DECL_ATTRIBUTES (tree_time_profiler_fn));
208 /* void (*) (gcov_type *, gcov_type) */
209 average_profiler_fn_type
210 = build_function_type_list (void_type_node,
211 gcov_type_ptr, gcov_type_node, NULL_TREE);
212 tree_average_profiler_fn
213 = build_fn_decl ("__gcov_average_profiler",
214 average_profiler_fn_type);
215 TREE_NOTHROW (tree_average_profiler_fn) = 1;
216 DECL_ATTRIBUTES (tree_average_profiler_fn)
217 = tree_cons (get_identifier ("leaf"), NULL,
218 DECL_ATTRIBUTES (tree_average_profiler_fn));
219 tree_ior_profiler_fn
220 = build_fn_decl ("__gcov_ior_profiler",
221 average_profiler_fn_type);
222 TREE_NOTHROW (tree_ior_profiler_fn) = 1;
223 DECL_ATTRIBUTES (tree_ior_profiler_fn)
224 = tree_cons (get_identifier ("leaf"), NULL,
225 DECL_ATTRIBUTES (tree_ior_profiler_fn));
227 /* LTO streamer needs assembler names. Because we create these decls
228 late, we need to initialize them by hand. */
229 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn);
230 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn);
231 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn);
232 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn);
233 DECL_ASSEMBLER_NAME (tree_time_profiler_fn);
234 DECL_ASSEMBLER_NAME (tree_average_profiler_fn);
235 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
239 /* Output instructions as GIMPLE trees to increment the edge
240 execution count, and insert them on E. We rely on
241 gsi_insert_on_edge to preserve the order. */
243 void
244 gimple_gen_edge_profiler (int edgeno, edge e)
246 tree one;
248 one = build_int_cst (gcov_type_node, 1);
250 if (flag_profile_update == PROFILE_UPDATE_ATOMIC)
252 /* __atomic_fetch_add (&counter, 1, MEMMODEL_RELAXED); */
253 tree addr = tree_coverage_counter_addr (GCOV_COUNTER_ARCS, edgeno);
254 gcall *stmt
255 = gimple_build_call (builtin_decl_explicit (GCOV_TYPE_ATOMIC_FETCH_ADD),
256 3, addr, one,
257 build_int_cst (integer_type_node,
258 MEMMODEL_RELAXED));
259 gsi_insert_on_edge (e, stmt);
261 else
263 tree ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
264 tree gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
265 NULL, "PROF_edge_counter");
266 gassign *stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
267 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
268 NULL, "PROF_edge_counter");
269 gassign *stmt2 = gimple_build_assign (gcov_type_tmp_var, PLUS_EXPR,
270 gimple_assign_lhs (stmt1), one);
271 gassign *stmt3 = gimple_build_assign (unshare_expr (ref),
272 gimple_assign_lhs (stmt2));
273 gsi_insert_on_edge (e, stmt1);
274 gsi_insert_on_edge (e, stmt2);
275 gsi_insert_on_edge (e, stmt3);
279 /* Emits code to get VALUE to instrument at GSI, and returns the
280 variable containing the value. */
282 static tree
283 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
285 tree val = value->hvalue.value;
286 if (POINTER_TYPE_P (TREE_TYPE (val)))
287 val = fold_convert (build_nonstandard_integer_type
288 (TYPE_PRECISION (TREE_TYPE (val)), 1), val);
289 return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
290 true, NULL_TREE, true, GSI_SAME_STMT);
293 /* Output instructions as GIMPLE trees to increment the interval histogram
294 counter. VALUE is the expression whose value is profiled. TAG is the
295 tag of the section for counters, BASE is offset of the counter position. */
297 void
298 gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
300 gimple *stmt = value->hvalue.stmt;
301 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
302 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
303 gcall *call;
304 tree val;
305 tree start = build_int_cst_type (integer_type_node,
306 value->hdata.intvl.int_start);
307 tree steps = build_int_cst_type (unsigned_type_node,
308 value->hdata.intvl.steps);
310 ref_ptr = force_gimple_operand_gsi (&gsi,
311 build_addr (ref),
312 true, NULL_TREE, true, GSI_SAME_STMT);
313 val = prepare_instrumented_value (&gsi, value);
314 call = gimple_build_call (tree_interval_profiler_fn, 4,
315 ref_ptr, val, start, steps);
316 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
319 /* Output instructions as GIMPLE trees to increment the power of two histogram
320 counter. VALUE is the expression whose value is profiled. TAG is the tag
321 of the section for counters, BASE is offset of the counter position. */
323 void
324 gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
326 gimple *stmt = value->hvalue.stmt;
327 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
328 tree ref_ptr = tree_coverage_counter_addr (tag, base);
329 gcall *call;
330 tree val;
332 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
333 true, NULL_TREE, true, GSI_SAME_STMT);
334 val = prepare_instrumented_value (&gsi, value);
335 call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val);
336 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
339 /* Output instructions as GIMPLE trees for code to find the most common value.
340 VALUE is the expression whose value is profiled. TAG is the tag of the
341 section for counters, BASE is offset of the counter position. */
343 void
344 gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
346 gimple *stmt = value->hvalue.stmt;
347 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
348 tree ref_ptr = tree_coverage_counter_addr (tag, base);
349 gcall *call;
350 tree val;
352 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
353 true, NULL_TREE, true, GSI_SAME_STMT);
354 val = prepare_instrumented_value (&gsi, value);
355 call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val);
356 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
360 /* Output instructions as GIMPLE trees for code to find the most
361 common called function in indirect call.
362 VALUE is the call expression whose indirect callee is profiled.
363 TAG is the tag of the section for counters, BASE is offset of the
364 counter position. */
366 void
367 gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
369 tree tmp1;
370 gassign *stmt1, *stmt2, *stmt3;
371 gimple *stmt = value->hvalue.stmt;
372 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
373 tree ref_ptr = tree_coverage_counter_addr (tag, base);
375 if ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) &&
376 tag == GCOV_COUNTER_V_INDIR) ||
377 (!PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) &&
378 tag == GCOV_COUNTER_ICALL_TOPNV))
379 return;
381 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
382 true, NULL_TREE, true, GSI_SAME_STMT);
384 /* Insert code:
386 stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
387 stmt2: tmp1 = (void *) (indirect call argument value)
388 stmt3: __gcov_indirect_call_callee = tmp1;
391 stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr);
392 tmp1 = make_temp_ssa_name (ptr_void, NULL, "PROF");
393 stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
394 stmt3 = gimple_build_assign (ic_void_ptr_var, gimple_assign_lhs (stmt2));
396 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
397 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
398 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
402 /* Output instructions as GIMPLE trees for code to find the most
403 common called function in indirect call. Insert instructions at the
404 beginning of every possible called function.
407 void
408 gimple_gen_ic_func_profiler (void)
410 struct cgraph_node * c_node = cgraph_node::get (current_function_decl);
411 gimple_stmt_iterator gsi;
412 gcall *stmt1;
413 gassign *stmt2;
414 tree tree_uid, cur_func, void0;
416 if (c_node->only_called_directly_p ())
417 return;
419 gimple_init_edge_profiler ();
421 /* Insert code:
423 stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
424 &current_function_decl)
426 gsi = gsi_after_labels (split_edge (single_succ_edge
427 (ENTRY_BLOCK_PTR_FOR_FN (cfun))));
429 cur_func = force_gimple_operand_gsi (&gsi,
430 build_addr (current_function_decl),
431 true, NULL_TREE,
432 true, GSI_SAME_STMT);
433 tree_uid = build_int_cst
434 (gcov_type_node,
435 cgraph_node::get (current_function_decl)->profile_id);
436 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2,
437 tree_uid, cur_func);
438 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
440 /* Set __gcov_indirect_call_callee to 0,
441 so that calls from other modules won't get misattributed
442 to the last caller of the current callee. */
443 void0 = build_int_cst (build_pointer_type (void_type_node), 0);
444 stmt2 = gimple_build_assign (ic_void_ptr_var, void0);
445 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
448 /* Output instructions as GIMPLE tree at the beginning for each function.
449 TAG is the tag of the section for counters, BASE is offset of the
450 counter position and GSI is the iterator we place the counter. */
452 void
453 gimple_gen_time_profiler (unsigned tag, unsigned base,
454 gimple_stmt_iterator &gsi)
456 tree ref_ptr = tree_coverage_counter_addr (tag, base);
457 gcall *call;
459 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
460 true, NULL_TREE, true, GSI_SAME_STMT);
461 call = gimple_build_call (tree_time_profiler_fn, 1, ref_ptr);
462 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
465 /* Output instructions as GIMPLE trees for code to find the most common value
466 of a difference between two evaluations of an expression.
467 VALUE is the expression whose value is profiled. TAG is the tag of the
468 section for counters, BASE is offset of the counter position. */
470 void
471 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
472 unsigned tag ATTRIBUTE_UNUSED,
473 unsigned base ATTRIBUTE_UNUSED)
475 /* FIXME implement this. */
476 if (flag_checking)
477 internal_error ("unimplemented functionality");
478 gcc_unreachable ();
481 /* Output instructions as GIMPLE trees to increment the average histogram
482 counter. VALUE is the expression whose value is profiled. TAG is the
483 tag of the section for counters, BASE is offset of the counter position. */
485 void
486 gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
488 gimple *stmt = value->hvalue.stmt;
489 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
490 tree ref_ptr = tree_coverage_counter_addr (tag, base);
491 gcall *call;
492 tree val;
494 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
495 true, NULL_TREE,
496 true, GSI_SAME_STMT);
497 val = prepare_instrumented_value (&gsi, value);
498 call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
499 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
502 /* Output instructions as GIMPLE trees to increment the ior histogram
503 counter. VALUE is the expression whose value is profiled. TAG is the
504 tag of the section for counters, BASE is offset of the counter position. */
506 void
507 gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
509 gimple *stmt = value->hvalue.stmt;
510 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
511 tree ref_ptr = tree_coverage_counter_addr (tag, base);
512 gcall *call;
513 tree val;
515 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
516 true, NULL_TREE, true, GSI_SAME_STMT);
517 val = prepare_instrumented_value (&gsi, value);
518 call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
519 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
522 /* Profile all functions in the callgraph. */
524 static unsigned int
525 tree_profiling (void)
527 struct cgraph_node *node;
529 /* This is a small-ipa pass that gets called only once, from
530 cgraphunit.c:ipa_passes(). */
531 gcc_assert (symtab->state == IPA_SSA);
533 init_node_map (true);
535 FOR_EACH_DEFINED_FUNCTION (node)
537 if (!gimple_has_body_p (node->decl))
538 continue;
540 /* Don't profile functions produced for builtin stuff. */
541 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
542 continue;
544 if (lookup_attribute ("no_profile_instrument_function",
545 DECL_ATTRIBUTES (node->decl)))
546 continue;
547 /* Do not instrument extern inline functions when testing coverage.
548 While this is not perfectly consistent (early inlined extern inlines
549 will get acocunted), testsuite expects that. */
550 if (DECL_EXTERNAL (node->decl)
551 && flag_test_coverage)
552 continue;
554 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
556 /* Local pure-const may imply need to fixup the cfg. */
557 if (execute_fixup_cfg () & TODO_cleanup_cfg)
558 cleanup_tree_cfg ();
560 branch_prob ();
562 if (! flag_branch_probabilities
563 && flag_profile_values)
564 gimple_gen_ic_func_profiler ();
566 if (flag_branch_probabilities
567 && flag_profile_values
568 && flag_value_profile_transformations)
569 gimple_value_profile_transformations ();
571 /* The above could hose dominator info. Currently there is
572 none coming in, this is a safety valve. It should be
573 easy to adjust it, if and when there is some. */
574 free_dominance_info (CDI_DOMINATORS);
575 free_dominance_info (CDI_POST_DOMINATORS);
576 pop_cfun ();
579 /* Drop pure/const flags from instrumented functions. */
580 if (profile_arc_flag || flag_test_coverage)
581 FOR_EACH_DEFINED_FUNCTION (node)
583 if (!gimple_has_body_p (node->decl)
584 || !(!node->clone_of
585 || node->decl != node->clone_of->decl))
586 continue;
588 /* Don't profile functions produced for builtin stuff. */
589 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
590 continue;
592 node->set_const_flag (false, false);
593 node->set_pure_flag (false, false);
596 /* Update call statements and rebuild the cgraph. */
597 FOR_EACH_DEFINED_FUNCTION (node)
599 basic_block bb;
601 if (!gimple_has_body_p (node->decl)
602 || !(!node->clone_of
603 || node->decl != node->clone_of->decl))
604 continue;
606 /* Don't profile functions produced for builtin stuff. */
607 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
608 continue;
610 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
612 FOR_EACH_BB_FN (bb, cfun)
614 gimple_stmt_iterator gsi;
615 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
617 gimple *stmt = gsi_stmt (gsi);
618 if (is_gimple_call (stmt))
619 update_stmt (stmt);
623 /* re-merge split blocks. */
624 cleanup_tree_cfg ();
625 update_ssa (TODO_update_ssa);
627 cgraph_edge::rebuild_edges ();
629 pop_cfun ();
632 handle_missing_profiles ();
634 del_node_map ();
635 return 0;
638 namespace {
640 const pass_data pass_data_ipa_tree_profile =
642 SIMPLE_IPA_PASS, /* type */
643 "profile", /* name */
644 OPTGROUP_NONE, /* optinfo_flags */
645 TV_IPA_PROFILE, /* tv_id */
646 0, /* properties_required */
647 0, /* properties_provided */
648 0, /* properties_destroyed */
649 0, /* todo_flags_start */
650 TODO_dump_symtab, /* todo_flags_finish */
653 class pass_ipa_tree_profile : public simple_ipa_opt_pass
655 public:
656 pass_ipa_tree_profile (gcc::context *ctxt)
657 : simple_ipa_opt_pass (pass_data_ipa_tree_profile, ctxt)
660 /* opt_pass methods: */
661 virtual bool gate (function *);
662 virtual unsigned int execute (function *) { return tree_profiling (); }
664 }; // class pass_ipa_tree_profile
666 bool
667 pass_ipa_tree_profile::gate (function *)
669 /* When profile instrumentation, use or test coverage shall be performed.
670 But for AutoFDO, this there is no instrumentation, thus this pass is
671 diabled. */
672 return (!in_lto_p && !flag_auto_profile
673 && (flag_branch_probabilities || flag_test_coverage
674 || profile_arc_flag));
677 } // anon namespace
679 simple_ipa_opt_pass *
680 make_pass_ipa_tree_profile (gcc::context *ctxt)
682 return new pass_ipa_tree_profile (ctxt);
685 #include "gt-tree-profile.h"