PR sanitizer/59009
[official-gcc.git] / gcc / tree-profile.c
blob9253059010831d6f6a14c5038a50110b5d76cc6d
1 /* Calculate branch probabilities, and basic block execution counts.
2 Copyright (C) 1990-2013 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 "function.h"
33 #include "basic-block.h"
34 #include "diagnostic-core.h"
35 #include "coverage.h"
36 #include "tree.h"
37 #include "gimplify.h"
38 #include "gimple-ssa.h"
39 #include "cgraph.h"
40 #include "tree-cfg.h"
41 #include "tree-ssanames.h"
42 #include "tree-into-ssa.h"
43 #include "tree-pass.h"
44 #include "value-prof.h"
45 #include "profile.h"
46 #include "target.h"
47 #include "tree-cfgcleanup.h"
49 static GTY(()) tree gcov_type_node;
50 static GTY(()) tree tree_interval_profiler_fn;
51 static GTY(()) tree tree_pow2_profiler_fn;
52 static GTY(()) tree tree_one_value_profiler_fn;
53 static GTY(()) tree tree_indirect_call_profiler_fn;
54 static GTY(()) tree tree_time_profiler_fn;
55 static GTY(()) tree tree_average_profiler_fn;
56 static GTY(()) tree tree_ior_profiler_fn;
59 static GTY(()) tree ic_void_ptr_var;
60 static GTY(()) tree ic_gcov_type_ptr_var;
61 static GTY(()) tree ptr_void;
63 /* Do initialization work for the edge profiler. */
65 /* Add code:
66 __thread gcov* __gcov_indirect_call_counters; // pointer to actual counter
67 __thread void* __gcov_indirect_call_callee; // actual callee address
68 __thread int __gcov_function_counter; // time profiler function counter
70 static void
71 init_ic_make_global_vars (void)
73 tree gcov_type_ptr;
75 ptr_void = build_pointer_type (void_type_node);
77 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
78 if (flag_lto)
80 ic_void_ptr_var
81 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
82 get_identifier ("__gcov_indirect_call_callee_ltopriv"),
83 ptr_void);
84 TREE_PUBLIC (ic_void_ptr_var) = 1;
85 DECL_COMMON (ic_void_ptr_var) = 1;
86 DECL_VISIBILITY (ic_void_ptr_var) = VISIBILITY_HIDDEN;
87 DECL_VISIBILITY_SPECIFIED (ic_void_ptr_var) = true;
89 else
91 ic_void_ptr_var
92 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
93 get_identifier ("__gcov_indirect_call_callee"),
94 ptr_void);
95 TREE_PUBLIC (ic_void_ptr_var) = 1;
96 DECL_EXTERNAL (ic_void_ptr_var) = 1;
98 TREE_STATIC (ic_void_ptr_var) = 1;
99 DECL_ARTIFICIAL (ic_void_ptr_var) = 1;
100 DECL_INITIAL (ic_void_ptr_var) = NULL;
101 if (targetm.have_tls)
102 DECL_TLS_MODEL (ic_void_ptr_var) =
103 decl_default_tls_model (ic_void_ptr_var);
105 varpool_finalize_decl (ic_void_ptr_var);
107 gcov_type_ptr = build_pointer_type (get_gcov_type ());
108 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
109 if (flag_lto)
111 ic_gcov_type_ptr_var
112 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
113 get_identifier ("__gcov_indirect_call_counters_ltopriv"),
114 gcov_type_ptr);
115 TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
116 DECL_COMMON (ic_gcov_type_ptr_var) = 1;
117 DECL_VISIBILITY (ic_gcov_type_ptr_var) = VISIBILITY_HIDDEN;
118 DECL_VISIBILITY_SPECIFIED (ic_gcov_type_ptr_var) = true;
120 else
122 ic_gcov_type_ptr_var
123 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
124 get_identifier ("__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;
129 TREE_STATIC (ic_gcov_type_ptr_var) = 1;
130 DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1;
131 DECL_INITIAL (ic_gcov_type_ptr_var) = NULL;
132 if (targetm.have_tls)
133 DECL_TLS_MODEL (ic_gcov_type_ptr_var) =
134 decl_default_tls_model (ic_gcov_type_ptr_var);
136 varpool_finalize_decl (ic_gcov_type_ptr_var);
139 /* Create the type and function decls for the interface with gcov. */
141 void
142 gimple_init_edge_profiler (void)
144 tree interval_profiler_fn_type;
145 tree pow2_profiler_fn_type;
146 tree one_value_profiler_fn_type;
147 tree gcov_type_ptr;
148 tree ic_profiler_fn_type;
149 tree average_profiler_fn_type;
150 tree time_profiler_fn_type;
152 if (!gcov_type_node)
154 gcov_type_node = get_gcov_type ();
155 gcov_type_ptr = build_pointer_type (gcov_type_node);
157 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
158 interval_profiler_fn_type
159 = build_function_type_list (void_type_node,
160 gcov_type_ptr, gcov_type_node,
161 integer_type_node,
162 unsigned_type_node, NULL_TREE);
163 tree_interval_profiler_fn
164 = build_fn_decl ("__gcov_interval_profiler",
165 interval_profiler_fn_type);
166 TREE_NOTHROW (tree_interval_profiler_fn) = 1;
167 DECL_ATTRIBUTES (tree_interval_profiler_fn)
168 = tree_cons (get_identifier ("leaf"), NULL,
169 DECL_ATTRIBUTES (tree_interval_profiler_fn));
171 /* void (*) (gcov_type *, gcov_type) */
172 pow2_profiler_fn_type
173 = build_function_type_list (void_type_node,
174 gcov_type_ptr, gcov_type_node,
175 NULL_TREE);
176 tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler",
177 pow2_profiler_fn_type);
178 TREE_NOTHROW (tree_pow2_profiler_fn) = 1;
179 DECL_ATTRIBUTES (tree_pow2_profiler_fn)
180 = tree_cons (get_identifier ("leaf"), NULL,
181 DECL_ATTRIBUTES (tree_pow2_profiler_fn));
183 /* void (*) (gcov_type *, gcov_type) */
184 one_value_profiler_fn_type
185 = build_function_type_list (void_type_node,
186 gcov_type_ptr, gcov_type_node,
187 NULL_TREE);
188 tree_one_value_profiler_fn
189 = build_fn_decl ("__gcov_one_value_profiler",
190 one_value_profiler_fn_type);
191 TREE_NOTHROW (tree_one_value_profiler_fn) = 1;
192 DECL_ATTRIBUTES (tree_one_value_profiler_fn)
193 = tree_cons (get_identifier ("leaf"), NULL,
194 DECL_ATTRIBUTES (tree_one_value_profiler_fn));
196 init_ic_make_global_vars ();
198 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
199 if (flag_lto)
201 /* void (*) (gcov_type, void *) */
202 ic_profiler_fn_type
203 = build_function_type_list (void_type_node,
204 gcov_type_ptr, gcov_type_node,
205 ptr_void, ptr_void,
206 NULL_TREE);
207 tree_indirect_call_profiler_fn
208 = build_fn_decl ("__gcov_indirect_call_profiler",
209 ic_profiler_fn_type);
211 else
213 /* void (*) (gcov_type, void *) */
214 ic_profiler_fn_type
215 = build_function_type_list (void_type_node,
216 gcov_type_node,
217 ptr_void,
218 NULL_TREE);
219 tree_indirect_call_profiler_fn
220 = build_fn_decl ("__gcov_indirect_call_profiler_v2",
221 ic_profiler_fn_type);
223 TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
224 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
225 = tree_cons (get_identifier ("leaf"), NULL,
226 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn));
228 /* void (*) (gcov_type *, gcov_type, void *) */
229 time_profiler_fn_type
230 = build_function_type_list (void_type_node,
231 gcov_type_ptr, NULL_TREE);
232 tree_time_profiler_fn
233 = build_fn_decl ("__gcov_time_profiler",
234 time_profiler_fn_type);
235 TREE_NOTHROW (tree_time_profiler_fn) = 1;
236 DECL_ATTRIBUTES (tree_time_profiler_fn)
237 = tree_cons (get_identifier ("leaf"), NULL,
238 DECL_ATTRIBUTES (tree_time_profiler_fn));
240 /* void (*) (gcov_type *, gcov_type) */
241 average_profiler_fn_type
242 = build_function_type_list (void_type_node,
243 gcov_type_ptr, gcov_type_node, NULL_TREE);
244 tree_average_profiler_fn
245 = build_fn_decl ("__gcov_average_profiler",
246 average_profiler_fn_type);
247 TREE_NOTHROW (tree_average_profiler_fn) = 1;
248 DECL_ATTRIBUTES (tree_average_profiler_fn)
249 = tree_cons (get_identifier ("leaf"), NULL,
250 DECL_ATTRIBUTES (tree_average_profiler_fn));
251 tree_ior_profiler_fn
252 = build_fn_decl ("__gcov_ior_profiler",
253 average_profiler_fn_type);
254 TREE_NOTHROW (tree_ior_profiler_fn) = 1;
255 DECL_ATTRIBUTES (tree_ior_profiler_fn)
256 = tree_cons (get_identifier ("leaf"), NULL,
257 DECL_ATTRIBUTES (tree_ior_profiler_fn));
259 /* LTO streamer needs assembler names. Because we create these decls
260 late, we need to initialize them by hand. */
261 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn);
262 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn);
263 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn);
264 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn);
265 DECL_ASSEMBLER_NAME (tree_time_profiler_fn);
266 DECL_ASSEMBLER_NAME (tree_average_profiler_fn);
267 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
271 /* Output instructions as GIMPLE trees to increment the edge
272 execution count, and insert them on E. We rely on
273 gsi_insert_on_edge to preserve the order. */
275 void
276 gimple_gen_edge_profiler (int edgeno, edge e)
278 tree ref, one, gcov_type_tmp_var;
279 gimple stmt1, stmt2, stmt3;
281 ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
282 one = build_int_cst (gcov_type_node, 1);
283 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
284 NULL, "PROF_edge_counter");
285 stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
286 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
287 NULL, "PROF_edge_counter");
288 stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, gcov_type_tmp_var,
289 gimple_assign_lhs (stmt1), one);
290 stmt3 = gimple_build_assign (unshare_expr (ref), gimple_assign_lhs (stmt2));
291 gsi_insert_on_edge (e, stmt1);
292 gsi_insert_on_edge (e, stmt2);
293 gsi_insert_on_edge (e, stmt3);
296 /* Emits code to get VALUE to instrument at GSI, and returns the
297 variable containing the value. */
299 static tree
300 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
302 tree val = value->hvalue.value;
303 if (POINTER_TYPE_P (TREE_TYPE (val)))
304 val = fold_convert (build_nonstandard_integer_type
305 (TYPE_PRECISION (TREE_TYPE (val)), 1), val);
306 return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
307 true, NULL_TREE, true, GSI_SAME_STMT);
310 /* Output instructions as GIMPLE trees to increment the interval histogram
311 counter. VALUE is the expression whose value is profiled. TAG is the
312 tag of the section for counters, BASE is offset of the counter position. */
314 void
315 gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
317 gimple stmt = value->hvalue.stmt;
318 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
319 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
320 gimple call;
321 tree val;
322 tree start = build_int_cst_type (integer_type_node,
323 value->hdata.intvl.int_start);
324 tree steps = build_int_cst_type (unsigned_type_node,
325 value->hdata.intvl.steps);
327 ref_ptr = force_gimple_operand_gsi (&gsi,
328 build_addr (ref, current_function_decl),
329 true, NULL_TREE, true, GSI_SAME_STMT);
330 val = prepare_instrumented_value (&gsi, value);
331 call = gimple_build_call (tree_interval_profiler_fn, 4,
332 ref_ptr, val, start, steps);
333 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
336 /* Output instructions as GIMPLE trees to increment the power of two histogram
337 counter. VALUE is the expression whose value is profiled. TAG is the tag
338 of the section for counters, BASE is offset of the counter position. */
340 void
341 gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
343 gimple stmt = value->hvalue.stmt;
344 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
345 tree ref_ptr = tree_coverage_counter_addr (tag, base);
346 gimple call;
347 tree val;
349 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
350 true, NULL_TREE, true, GSI_SAME_STMT);
351 val = prepare_instrumented_value (&gsi, value);
352 call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val);
353 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
356 /* Output instructions as GIMPLE trees for code to find the most common value.
357 VALUE is the expression whose value is profiled. TAG is the tag of the
358 section for counters, BASE is offset of the counter position. */
360 void
361 gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
363 gimple stmt = value->hvalue.stmt;
364 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
365 tree ref_ptr = tree_coverage_counter_addr (tag, base);
366 gimple call;
367 tree val;
369 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
370 true, NULL_TREE, true, GSI_SAME_STMT);
371 val = prepare_instrumented_value (&gsi, value);
372 call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val);
373 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
377 /* Output instructions as GIMPLE trees for code to find the most
378 common called function in indirect call.
379 VALUE is the call expression whose indirect callee is profiled.
380 TAG is the tag of the section for counters, BASE is offset of the
381 counter position. */
383 void
384 gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
386 tree tmp1;
387 gimple stmt1, stmt2, stmt3;
388 gimple stmt = value->hvalue.stmt;
389 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
390 tree ref_ptr = tree_coverage_counter_addr (tag, base);
392 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
393 true, NULL_TREE, true, GSI_SAME_STMT);
395 /* Insert code:
397 stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
398 stmt2: tmp1 = (void *) (indirect call argument value)
399 stmt3: __gcov_indirect_call_callee = tmp1;
402 stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr);
403 tmp1 = make_temp_ssa_name (ptr_void, NULL, "PROF");
404 stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
405 stmt3 = gimple_build_assign (ic_void_ptr_var, gimple_assign_lhs (stmt2));
407 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
408 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
409 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
413 /* Output instructions as GIMPLE trees for code to find the most
414 common called function in indirect call. Insert instructions at the
415 beginning of every possible called function.
418 void
419 gimple_gen_ic_func_profiler (void)
421 struct cgraph_node * c_node = cgraph_get_node (current_function_decl);
422 gimple_stmt_iterator gsi;
423 gimple stmt1, stmt2;
424 tree tree_uid, cur_func, void0;
426 if (cgraph_only_called_directly_p (c_node))
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 (ENTRY_BLOCK_PTR)));
438 cur_func = force_gimple_operand_gsi (&gsi,
439 build_addr (current_function_decl,
440 current_function_decl),
441 true, NULL_TREE,
442 true, GSI_SAME_STMT);
443 tree_uid = build_int_cst
444 (gcov_type_node, cgraph_get_node (current_function_decl)->profile_id);
445 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
446 if (flag_lto)
448 tree counter_ptr, ptr_var;
449 counter_ptr = force_gimple_operand_gsi (&gsi, ic_gcov_type_ptr_var,
450 true, NULL_TREE, true,
451 GSI_SAME_STMT);
452 ptr_var = force_gimple_operand_gsi (&gsi, ic_void_ptr_var,
453 true, NULL_TREE, true,
454 GSI_SAME_STMT);
456 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 4,
457 counter_ptr, tree_uid, cur_func, ptr_var);
459 else
461 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2,
462 tree_uid, cur_func);
464 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
466 /* Set __gcov_indirect_call_callee to 0,
467 so that calls from other modules won't get misattributed
468 to the last caller of the current callee. */
469 void0 = build_int_cst (build_pointer_type (void_type_node), 0);
470 stmt2 = gimple_build_assign (ic_void_ptr_var, void0);
471 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
474 /* Output instructions as GIMPLE tree at the beginning for each function.
475 TAG is the tag of the section for counters, BASE is offset of the
476 counter position and GSI is the iterator we place the counter. */
478 void
479 gimple_gen_time_profiler (unsigned tag, unsigned base,
480 gimple_stmt_iterator &gsi)
482 tree ref_ptr = tree_coverage_counter_addr (tag, base);
483 gimple call;
485 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
486 true, NULL_TREE, true, GSI_SAME_STMT);
487 call = gimple_build_call (tree_time_profiler_fn, 1, ref_ptr);
488 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
491 /* Output instructions as GIMPLE trees for code to find the most common value
492 of a difference between two evaluations of an expression.
493 VALUE is the expression whose value is profiled. TAG is the tag of the
494 section for counters, BASE is offset of the counter position. */
496 void
497 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
498 unsigned tag ATTRIBUTE_UNUSED,
499 unsigned base ATTRIBUTE_UNUSED)
501 /* FIXME implement this. */
502 #ifdef ENABLE_CHECKING
503 internal_error ("unimplemented functionality");
504 #endif
505 gcc_unreachable ();
508 /* Output instructions as GIMPLE trees to increment the average histogram
509 counter. VALUE is the expression whose value is profiled. TAG is the
510 tag of the section for counters, BASE is offset of the counter position. */
512 void
513 gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
515 gimple stmt = value->hvalue.stmt;
516 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
517 tree ref_ptr = tree_coverage_counter_addr (tag, base);
518 gimple call;
519 tree val;
521 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
522 true, NULL_TREE,
523 true, GSI_SAME_STMT);
524 val = prepare_instrumented_value (&gsi, value);
525 call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
526 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
529 /* Output instructions as GIMPLE trees to increment the ior histogram
530 counter. VALUE is the expression whose value is profiled. TAG is the
531 tag of the section for counters, BASE is offset of the counter position. */
533 void
534 gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
536 gimple stmt = value->hvalue.stmt;
537 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
538 tree ref_ptr = tree_coverage_counter_addr (tag, base);
539 gimple call;
540 tree val;
542 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
543 true, NULL_TREE, true, GSI_SAME_STMT);
544 val = prepare_instrumented_value (&gsi, value);
545 call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
546 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
549 /* Profile all functions in the callgraph. */
551 static unsigned int
552 tree_profiling (void)
554 struct cgraph_node *node;
556 /* This is a small-ipa pass that gets called only once, from
557 cgraphunit.c:ipa_passes(). */
558 gcc_assert (cgraph_state == CGRAPH_STATE_IPA_SSA);
560 init_node_map (true);
562 FOR_EACH_DEFINED_FUNCTION (node)
564 if (!gimple_has_body_p (node->decl))
565 continue;
567 /* Don't profile functions produced for builtin stuff. */
568 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
569 continue;
571 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
573 /* Local pure-const may imply need to fixup the cfg. */
574 if (execute_fixup_cfg () & TODO_cleanup_cfg)
575 cleanup_tree_cfg ();
577 branch_prob ();
579 if (! flag_branch_probabilities
580 && flag_profile_values)
581 gimple_gen_ic_func_profiler ();
583 if (flag_branch_probabilities
584 && flag_profile_values
585 && flag_value_profile_transformations)
586 gimple_value_profile_transformations ();
588 /* The above could hose dominator info. Currently there is
589 none coming in, this is a safety valve. It should be
590 easy to adjust it, if and when there is some. */
591 free_dominance_info (CDI_DOMINATORS);
592 free_dominance_info (CDI_POST_DOMINATORS);
593 pop_cfun ();
596 /* Drop pure/const flags from instrumented functions. */
597 FOR_EACH_DEFINED_FUNCTION (node)
599 if (!gimple_has_body_p (node->decl)
600 || !(!node->clone_of
601 || node->decl != node->clone_of->decl))
602 continue;
604 /* Don't profile functions produced for builtin stuff. */
605 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
606 continue;
608 cgraph_set_const_flag (node, false, false);
609 cgraph_set_pure_flag (node, false, false);
612 /* Update call statements and rebuild the cgraph. */
613 FOR_EACH_DEFINED_FUNCTION (node)
615 basic_block bb;
617 if (!gimple_has_body_p (node->decl)
618 || !(!node->clone_of
619 || node->decl != node->clone_of->decl))
620 continue;
622 /* Don't profile functions produced for builtin stuff. */
623 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
624 continue;
626 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
628 FOR_EACH_BB (bb)
630 gimple_stmt_iterator gsi;
631 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
633 gimple stmt = gsi_stmt (gsi);
634 if (is_gimple_call (stmt))
635 update_stmt (stmt);
639 /* re-merge split blocks. */
640 cleanup_tree_cfg ();
641 update_ssa (TODO_update_ssa);
643 rebuild_cgraph_edges ();
645 pop_cfun ();
648 handle_missing_profiles ();
650 del_node_map ();
651 return 0;
654 /* When profile instrumentation, use or test coverage shall be performed. */
656 static bool
657 gate_tree_profile_ipa (void)
659 return (!in_lto_p
660 && (flag_branch_probabilities || flag_test_coverage
661 || profile_arc_flag));
664 namespace {
666 const pass_data pass_data_ipa_tree_profile =
668 SIMPLE_IPA_PASS, /* type */
669 "profile", /* name */
670 OPTGROUP_NONE, /* optinfo_flags */
671 true, /* has_gate */
672 true, /* has_execute */
673 TV_IPA_PROFILE, /* tv_id */
674 0, /* properties_required */
675 0, /* properties_provided */
676 0, /* properties_destroyed */
677 0, /* todo_flags_start */
678 0, /* todo_flags_finish */
681 class pass_ipa_tree_profile : public simple_ipa_opt_pass
683 public:
684 pass_ipa_tree_profile (gcc::context *ctxt)
685 : simple_ipa_opt_pass (pass_data_ipa_tree_profile, ctxt)
688 /* opt_pass methods: */
689 bool gate () { return gate_tree_profile_ipa (); }
690 unsigned int execute () { return tree_profiling (); }
692 }; // class pass_ipa_tree_profile
694 } // anon namespace
696 simple_ipa_opt_pass *
697 make_pass_ipa_tree_profile (gcc::context *ctxt)
699 return new pass_ipa_tree_profile (ctxt);
702 #include "gt-tree-profile.h"