Implement TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS hook.
[official-gcc.git] / gcc / tree-profile.c
blob377ab0d27508323899d2db98dc9c9d4e7f30eaa5
1 /* Calculate branch probabilities, and basic block execution counts.
2 Copyright (C) 1990-2015 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 "tm.h"
31 #include "flags.h"
32 #include "hard-reg-set.h"
33 #include "input.h"
34 #include "function.h"
35 #include "predict.h"
36 #include "dominance.h"
37 #include "cfg.h"
38 #include "basic-block.h"
39 #include "diagnostic-core.h"
40 #include "coverage.h"
41 #include "input.h"
42 #include "alias.h"
43 #include "symtab.h"
44 #include "tree.h"
45 #include "fold-const.h"
46 #include "tree-ssa-alias.h"
47 #include "internal-fn.h"
48 #include "gimple-expr.h"
49 #include "is-a.h"
50 #include "gimple.h"
51 #include "varasm.h"
52 #include "tree-nested.h"
53 #include "gimplify.h"
54 #include "gimple-iterator.h"
55 #include "gimplify-me.h"
56 #include "gimple-ssa.h"
57 #include "plugin-api.h"
58 #include "ipa-ref.h"
59 #include "cgraph.h"
60 #include "tree-cfg.h"
61 #include "stringpool.h"
62 #include "tree-ssanames.h"
63 #include "tree-into-ssa.h"
64 #include "tree-pass.h"
65 #include "value-prof.h"
66 #include "profile.h"
67 #include "target.h"
68 #include "tree-cfgcleanup.h"
69 #include "tree-nested.h"
70 #include "params.h"
72 static GTY(()) tree gcov_type_node;
73 static GTY(()) tree tree_interval_profiler_fn;
74 static GTY(()) tree tree_pow2_profiler_fn;
75 static GTY(()) tree tree_one_value_profiler_fn;
76 static GTY(()) tree tree_indirect_call_profiler_fn;
77 static GTY(()) tree tree_time_profiler_fn;
78 static GTY(()) tree tree_average_profiler_fn;
79 static GTY(()) tree tree_ior_profiler_fn;
82 static GTY(()) tree ic_void_ptr_var;
83 static GTY(()) tree ic_gcov_type_ptr_var;
84 static GTY(()) tree ptr_void;
86 /* Do initialization work for the edge profiler. */
88 /* Add code:
89 __thread gcov* __gcov_indirect_call_counters; // pointer to actual counter
90 __thread void* __gcov_indirect_call_callee; // actual callee address
91 __thread int __gcov_function_counter; // time profiler function counter
93 static void
94 init_ic_make_global_vars (void)
96 tree gcov_type_ptr;
98 ptr_void = build_pointer_type (void_type_node);
100 ic_void_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_callee" :
105 "__gcov_indirect_call_callee")),
106 ptr_void);
107 TREE_PUBLIC (ic_void_ptr_var) = 1;
108 DECL_EXTERNAL (ic_void_ptr_var) = 1;
109 TREE_STATIC (ic_void_ptr_var) = 1;
110 DECL_ARTIFICIAL (ic_void_ptr_var) = 1;
111 DECL_INITIAL (ic_void_ptr_var) = NULL;
112 if (targetm.have_tls)
113 set_decl_tls_model (ic_void_ptr_var, decl_default_tls_model (ic_void_ptr_var));
115 varpool_node::finalize_decl (ic_void_ptr_var);
117 gcov_type_ptr = build_pointer_type (get_gcov_type ());
119 ic_gcov_type_ptr_var
120 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
121 get_identifier (
122 (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
123 "__gcov_indirect_call_topn_counters" :
124 "__gcov_indirect_call_counters")),
125 gcov_type_ptr);
126 TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
127 DECL_EXTERNAL (ic_gcov_type_ptr_var) = 1;
128 TREE_STATIC (ic_gcov_type_ptr_var) = 1;
129 DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1;
130 DECL_INITIAL (ic_gcov_type_ptr_var) = NULL;
131 if (targetm.have_tls)
132 set_decl_tls_model (ic_gcov_type_ptr_var, decl_default_tls_model (ic_gcov_type_ptr_var));
134 varpool_node::finalize_decl (ic_gcov_type_ptr_var);
137 /* Create the type and function decls for the interface with gcov. */
139 void
140 gimple_init_edge_profiler (void)
142 tree interval_profiler_fn_type;
143 tree pow2_profiler_fn_type;
144 tree one_value_profiler_fn_type;
145 tree gcov_type_ptr;
146 tree ic_profiler_fn_type;
147 tree average_profiler_fn_type;
148 tree time_profiler_fn_type;
150 if (!gcov_type_node)
152 gcov_type_node = get_gcov_type ();
153 gcov_type_ptr = build_pointer_type (gcov_type_node);
155 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
156 interval_profiler_fn_type
157 = build_function_type_list (void_type_node,
158 gcov_type_ptr, gcov_type_node,
159 integer_type_node,
160 unsigned_type_node, NULL_TREE);
161 tree_interval_profiler_fn
162 = build_fn_decl ("__gcov_interval_profiler",
163 interval_profiler_fn_type);
164 TREE_NOTHROW (tree_interval_profiler_fn) = 1;
165 DECL_ATTRIBUTES (tree_interval_profiler_fn)
166 = tree_cons (get_identifier ("leaf"), NULL,
167 DECL_ATTRIBUTES (tree_interval_profiler_fn));
169 /* void (*) (gcov_type *, gcov_type) */
170 pow2_profiler_fn_type
171 = build_function_type_list (void_type_node,
172 gcov_type_ptr, gcov_type_node,
173 NULL_TREE);
174 tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler",
175 pow2_profiler_fn_type);
176 TREE_NOTHROW (tree_pow2_profiler_fn) = 1;
177 DECL_ATTRIBUTES (tree_pow2_profiler_fn)
178 = tree_cons (get_identifier ("leaf"), NULL,
179 DECL_ATTRIBUTES (tree_pow2_profiler_fn));
181 /* void (*) (gcov_type *, gcov_type) */
182 one_value_profiler_fn_type
183 = build_function_type_list (void_type_node,
184 gcov_type_ptr, gcov_type_node,
185 NULL_TREE);
186 tree_one_value_profiler_fn
187 = build_fn_decl ("__gcov_one_value_profiler",
188 one_value_profiler_fn_type);
189 TREE_NOTHROW (tree_one_value_profiler_fn) = 1;
190 DECL_ATTRIBUTES (tree_one_value_profiler_fn)
191 = tree_cons (get_identifier ("leaf"), NULL,
192 DECL_ATTRIBUTES (tree_one_value_profiler_fn));
194 init_ic_make_global_vars ();
196 /* void (*) (gcov_type, void *) */
197 ic_profiler_fn_type
198 = build_function_type_list (void_type_node,
199 gcov_type_node,
200 ptr_void,
201 NULL_TREE);
202 tree_indirect_call_profiler_fn
203 = build_fn_decl ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
204 "__gcov_indirect_call_topn_profiler":
205 "__gcov_indirect_call_profiler_v2"),
206 ic_profiler_fn_type);
208 TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
209 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
210 = tree_cons (get_identifier ("leaf"), NULL,
211 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn));
213 /* void (*) (gcov_type *, gcov_type, void *) */
214 time_profiler_fn_type
215 = build_function_type_list (void_type_node,
216 gcov_type_ptr, NULL_TREE);
217 tree_time_profiler_fn
218 = build_fn_decl ("__gcov_time_profiler",
219 time_profiler_fn_type);
220 TREE_NOTHROW (tree_time_profiler_fn) = 1;
221 DECL_ATTRIBUTES (tree_time_profiler_fn)
222 = tree_cons (get_identifier ("leaf"), NULL,
223 DECL_ATTRIBUTES (tree_time_profiler_fn));
225 /* void (*) (gcov_type *, gcov_type) */
226 average_profiler_fn_type
227 = build_function_type_list (void_type_node,
228 gcov_type_ptr, gcov_type_node, NULL_TREE);
229 tree_average_profiler_fn
230 = build_fn_decl ("__gcov_average_profiler",
231 average_profiler_fn_type);
232 TREE_NOTHROW (tree_average_profiler_fn) = 1;
233 DECL_ATTRIBUTES (tree_average_profiler_fn)
234 = tree_cons (get_identifier ("leaf"), NULL,
235 DECL_ATTRIBUTES (tree_average_profiler_fn));
236 tree_ior_profiler_fn
237 = build_fn_decl ("__gcov_ior_profiler",
238 average_profiler_fn_type);
239 TREE_NOTHROW (tree_ior_profiler_fn) = 1;
240 DECL_ATTRIBUTES (tree_ior_profiler_fn)
241 = tree_cons (get_identifier ("leaf"), NULL,
242 DECL_ATTRIBUTES (tree_ior_profiler_fn));
244 /* LTO streamer needs assembler names. Because we create these decls
245 late, we need to initialize them by hand. */
246 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn);
247 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn);
248 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn);
249 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn);
250 DECL_ASSEMBLER_NAME (tree_time_profiler_fn);
251 DECL_ASSEMBLER_NAME (tree_average_profiler_fn);
252 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
256 /* Output instructions as GIMPLE trees to increment the edge
257 execution count, and insert them on E. We rely on
258 gsi_insert_on_edge to preserve the order. */
260 void
261 gimple_gen_edge_profiler (int edgeno, edge e)
263 tree ref, one, gcov_type_tmp_var;
264 gassign *stmt1, *stmt2, *stmt3;
266 ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
267 one = build_int_cst (gcov_type_node, 1);
268 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
269 NULL, "PROF_edge_counter");
270 stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
271 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
272 NULL, "PROF_edge_counter");
273 stmt2 = gimple_build_assign (gcov_type_tmp_var, PLUS_EXPR,
274 gimple_assign_lhs (stmt1), one);
275 stmt3 = gimple_build_assign (unshare_expr (ref), gimple_assign_lhs (stmt2));
276 gsi_insert_on_edge (e, stmt1);
277 gsi_insert_on_edge (e, stmt2);
278 gsi_insert_on_edge (e, stmt3);
281 /* Emits code to get VALUE to instrument at GSI, and returns the
282 variable containing the value. */
284 static tree
285 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
287 tree val = value->hvalue.value;
288 if (POINTER_TYPE_P (TREE_TYPE (val)))
289 val = fold_convert (build_nonstandard_integer_type
290 (TYPE_PRECISION (TREE_TYPE (val)), 1), val);
291 return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
292 true, NULL_TREE, true, GSI_SAME_STMT);
295 /* Output instructions as GIMPLE trees to increment the interval histogram
296 counter. VALUE is the expression whose value is profiled. TAG is the
297 tag of the section for counters, BASE is offset of the counter position. */
299 void
300 gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
302 gimple stmt = value->hvalue.stmt;
303 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
304 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
305 gcall *call;
306 tree val;
307 tree start = build_int_cst_type (integer_type_node,
308 value->hdata.intvl.int_start);
309 tree steps = build_int_cst_type (unsigned_type_node,
310 value->hdata.intvl.steps);
312 ref_ptr = force_gimple_operand_gsi (&gsi,
313 build_addr (ref, current_function_decl),
314 true, NULL_TREE, true, GSI_SAME_STMT);
315 val = prepare_instrumented_value (&gsi, value);
316 call = gimple_build_call (tree_interval_profiler_fn, 4,
317 ref_ptr, val, start, steps);
318 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
321 /* Output instructions as GIMPLE trees to increment the power of two histogram
322 counter. VALUE is the expression whose value is profiled. TAG is the tag
323 of the section for counters, BASE is offset of the counter position. */
325 void
326 gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
328 gimple stmt = value->hvalue.stmt;
329 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
330 tree ref_ptr = tree_coverage_counter_addr (tag, base);
331 gcall *call;
332 tree val;
334 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
335 true, NULL_TREE, true, GSI_SAME_STMT);
336 val = prepare_instrumented_value (&gsi, value);
337 call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val);
338 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
341 /* Output instructions as GIMPLE trees for code to find the most common value.
342 VALUE is the expression whose value is profiled. TAG is the tag of the
343 section for counters, BASE is offset of the counter position. */
345 void
346 gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
348 gimple stmt = value->hvalue.stmt;
349 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
350 tree ref_ptr = tree_coverage_counter_addr (tag, base);
351 gcall *call;
352 tree val;
354 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
355 true, NULL_TREE, true, GSI_SAME_STMT);
356 val = prepare_instrumented_value (&gsi, value);
357 call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val);
358 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
362 /* Output instructions as GIMPLE trees for code to find the most
363 common called function in indirect call.
364 VALUE is the call expression whose indirect callee is profiled.
365 TAG is the tag of the section for counters, BASE is offset of the
366 counter position. */
368 void
369 gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
371 tree tmp1;
372 gassign *stmt1, *stmt2, *stmt3;
373 gimple stmt = value->hvalue.stmt;
374 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
375 tree ref_ptr = tree_coverage_counter_addr (tag, base);
377 if ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) &&
378 tag == GCOV_COUNTER_V_INDIR) ||
379 (!PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) &&
380 tag == GCOV_COUNTER_ICALL_TOPNV))
381 return;
383 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
384 true, NULL_TREE, true, GSI_SAME_STMT);
386 /* Insert code:
388 stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
389 stmt2: tmp1 = (void *) (indirect call argument value)
390 stmt3: __gcov_indirect_call_callee = tmp1;
393 stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr);
394 tmp1 = make_temp_ssa_name (ptr_void, NULL, "PROF");
395 stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
396 stmt3 = gimple_build_assign (ic_void_ptr_var, gimple_assign_lhs (stmt2));
398 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
399 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
400 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
404 /* Output instructions as GIMPLE trees for code to find the most
405 common called function in indirect call. Insert instructions at the
406 beginning of every possible called function.
409 void
410 gimple_gen_ic_func_profiler (void)
412 struct cgraph_node * c_node = cgraph_node::get (current_function_decl);
413 gimple_stmt_iterator gsi;
414 gcall *stmt1;
415 gassign *stmt2;
416 tree tree_uid, cur_func, void0;
418 if (c_node->only_called_directly_p ())
419 return;
421 gimple_init_edge_profiler ();
423 /* Insert code:
425 stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
426 &current_function_decl)
428 gsi = gsi_after_labels (split_edge (single_succ_edge
429 (ENTRY_BLOCK_PTR_FOR_FN (cfun))));
431 cur_func = force_gimple_operand_gsi (&gsi,
432 build_addr (current_function_decl,
433 current_function_decl),
434 true, NULL_TREE,
435 true, GSI_SAME_STMT);
436 tree_uid = build_int_cst
437 (gcov_type_node,
438 cgraph_node::get (current_function_decl)->profile_id);
439 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2,
440 tree_uid, cur_func);
441 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
443 /* Set __gcov_indirect_call_callee to 0,
444 so that calls from other modules won't get misattributed
445 to the last caller of the current callee. */
446 void0 = build_int_cst (build_pointer_type (void_type_node), 0);
447 stmt2 = gimple_build_assign (ic_void_ptr_var, void0);
448 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
451 /* Output instructions as GIMPLE tree at the beginning for each function.
452 TAG is the tag of the section for counters, BASE is offset of the
453 counter position and GSI is the iterator we place the counter. */
455 void
456 gimple_gen_time_profiler (unsigned tag, unsigned base,
457 gimple_stmt_iterator &gsi)
459 tree ref_ptr = tree_coverage_counter_addr (tag, base);
460 gcall *call;
462 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
463 true, NULL_TREE, true, GSI_SAME_STMT);
464 call = gimple_build_call (tree_time_profiler_fn, 1, ref_ptr);
465 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
468 /* Output instructions as GIMPLE trees for code to find the most common value
469 of a difference between two evaluations of an expression.
470 VALUE is the expression whose value is profiled. TAG is the tag of the
471 section for counters, BASE is offset of the counter position. */
473 void
474 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
475 unsigned tag ATTRIBUTE_UNUSED,
476 unsigned base ATTRIBUTE_UNUSED)
478 /* FIXME implement this. */
479 #ifdef ENABLE_CHECKING
480 internal_error ("unimplemented functionality");
481 #endif
482 gcc_unreachable ();
485 /* Output instructions as GIMPLE trees to increment the average histogram
486 counter. VALUE is the expression whose value is profiled. TAG is the
487 tag of the section for counters, BASE is offset of the counter position. */
489 void
490 gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
492 gimple stmt = value->hvalue.stmt;
493 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
494 tree ref_ptr = tree_coverage_counter_addr (tag, base);
495 gcall *call;
496 tree val;
498 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
499 true, NULL_TREE,
500 true, GSI_SAME_STMT);
501 val = prepare_instrumented_value (&gsi, value);
502 call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
503 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
506 /* Output instructions as GIMPLE trees to increment the ior histogram
507 counter. VALUE is the expression whose value is profiled. TAG is the
508 tag of the section for counters, BASE is offset of the counter position. */
510 void
511 gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
513 gimple stmt = value->hvalue.stmt;
514 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
515 tree ref_ptr = tree_coverage_counter_addr (tag, base);
516 gcall *call;
517 tree val;
519 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
520 true, NULL_TREE, true, GSI_SAME_STMT);
521 val = prepare_instrumented_value (&gsi, value);
522 call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
523 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
526 /* Profile all functions in the callgraph. */
528 static unsigned int
529 tree_profiling (void)
531 struct cgraph_node *node;
533 /* This is a small-ipa pass that gets called only once, from
534 cgraphunit.c:ipa_passes(). */
535 gcc_assert (symtab->state == IPA_SSA);
537 init_node_map (true);
539 FOR_EACH_DEFINED_FUNCTION (node)
541 if (!gimple_has_body_p (node->decl))
542 continue;
544 /* Don't profile functions produced for builtin stuff. */
545 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
546 continue;
548 /* Do not instrument extern inline functions when testing coverage.
549 While this is not perfectly consistent (early inlined extern inlines
550 will get acocunted), testsuite expects that. */
551 if (DECL_EXTERNAL (node->decl)
552 && flag_test_coverage)
553 continue;
555 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
557 /* Local pure-const may imply need to fixup the cfg. */
558 if (execute_fixup_cfg () & TODO_cleanup_cfg)
559 cleanup_tree_cfg ();
561 branch_prob ();
563 if (! flag_branch_probabilities
564 && flag_profile_values)
565 gimple_gen_ic_func_profiler ();
567 if (flag_branch_probabilities
568 && flag_profile_values
569 && flag_value_profile_transformations)
570 gimple_value_profile_transformations ();
572 /* The above could hose dominator info. Currently there is
573 none coming in, this is a safety valve. It should be
574 easy to adjust it, if and when there is some. */
575 free_dominance_info (CDI_DOMINATORS);
576 free_dominance_info (CDI_POST_DOMINATORS);
577 pop_cfun ();
580 /* Drop pure/const flags from instrumented functions. */
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 0, /* 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"