gcc/c-family/
[official-gcc.git] / gcc / tree-profile.c
blob132ce0d4d13957c9bf0b02d053d81b44cd7bcffb
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 "gimple.h"
38 #include "gimplify.h"
39 #include "gimple-iterator.h"
40 #include "gimplify-me.h"
41 #include "gimple-ssa.h"
42 #include "cgraph.h"
43 #include "tree-cfg.h"
44 #include "tree-ssanames.h"
45 #include "tree-into-ssa.h"
46 #include "tree-pass.h"
47 #include "value-prof.h"
48 #include "profile.h"
49 #include "target.h"
50 #include "tree-cfgcleanup.h"
51 #include "tree-nested.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 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
82 if (flag_lto)
84 ic_void_ptr_var
85 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
86 get_identifier ("__gcov_indirect_call_callee_ltopriv"),
87 ptr_void);
88 TREE_PUBLIC (ic_void_ptr_var) = 1;
89 DECL_COMMON (ic_void_ptr_var) = 1;
90 DECL_VISIBILITY (ic_void_ptr_var) = VISIBILITY_HIDDEN;
91 DECL_VISIBILITY_SPECIFIED (ic_void_ptr_var) = true;
93 else
95 ic_void_ptr_var
96 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
97 get_identifier ("__gcov_indirect_call_callee"),
98 ptr_void);
99 TREE_PUBLIC (ic_void_ptr_var) = 1;
100 DECL_EXTERNAL (ic_void_ptr_var) = 1;
102 TREE_STATIC (ic_void_ptr_var) = 1;
103 DECL_ARTIFICIAL (ic_void_ptr_var) = 1;
104 DECL_INITIAL (ic_void_ptr_var) = NULL;
105 if (targetm.have_tls)
106 DECL_TLS_MODEL (ic_void_ptr_var) =
107 decl_default_tls_model (ic_void_ptr_var);
109 varpool_finalize_decl (ic_void_ptr_var);
111 gcov_type_ptr = build_pointer_type (get_gcov_type ());
112 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
113 if (flag_lto)
115 ic_gcov_type_ptr_var
116 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
117 get_identifier ("__gcov_indirect_call_counters_ltopriv"),
118 gcov_type_ptr);
119 TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
120 DECL_COMMON (ic_gcov_type_ptr_var) = 1;
121 DECL_VISIBILITY (ic_gcov_type_ptr_var) = VISIBILITY_HIDDEN;
122 DECL_VISIBILITY_SPECIFIED (ic_gcov_type_ptr_var) = true;
124 else
126 ic_gcov_type_ptr_var
127 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
128 get_identifier ("__gcov_indirect_call_counters"),
129 gcov_type_ptr);
130 TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
131 DECL_EXTERNAL (ic_gcov_type_ptr_var) = 1;
133 TREE_STATIC (ic_gcov_type_ptr_var) = 1;
134 DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1;
135 DECL_INITIAL (ic_gcov_type_ptr_var) = NULL;
136 if (targetm.have_tls)
137 DECL_TLS_MODEL (ic_gcov_type_ptr_var) =
138 decl_default_tls_model (ic_gcov_type_ptr_var);
140 varpool_finalize_decl (ic_gcov_type_ptr_var);
143 /* Create the type and function decls for the interface with gcov. */
145 void
146 gimple_init_edge_profiler (void)
148 tree interval_profiler_fn_type;
149 tree pow2_profiler_fn_type;
150 tree one_value_profiler_fn_type;
151 tree gcov_type_ptr;
152 tree ic_profiler_fn_type;
153 tree average_profiler_fn_type;
154 tree time_profiler_fn_type;
156 if (!gcov_type_node)
158 gcov_type_node = get_gcov_type ();
159 gcov_type_ptr = build_pointer_type (gcov_type_node);
161 /* void (*) (gcov_type *, gcov_type, int, unsigned) */
162 interval_profiler_fn_type
163 = build_function_type_list (void_type_node,
164 gcov_type_ptr, gcov_type_node,
165 integer_type_node,
166 unsigned_type_node, NULL_TREE);
167 tree_interval_profiler_fn
168 = build_fn_decl ("__gcov_interval_profiler",
169 interval_profiler_fn_type);
170 TREE_NOTHROW (tree_interval_profiler_fn) = 1;
171 DECL_ATTRIBUTES (tree_interval_profiler_fn)
172 = tree_cons (get_identifier ("leaf"), NULL,
173 DECL_ATTRIBUTES (tree_interval_profiler_fn));
175 /* void (*) (gcov_type *, gcov_type) */
176 pow2_profiler_fn_type
177 = build_function_type_list (void_type_node,
178 gcov_type_ptr, gcov_type_node,
179 NULL_TREE);
180 tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler",
181 pow2_profiler_fn_type);
182 TREE_NOTHROW (tree_pow2_profiler_fn) = 1;
183 DECL_ATTRIBUTES (tree_pow2_profiler_fn)
184 = tree_cons (get_identifier ("leaf"), NULL,
185 DECL_ATTRIBUTES (tree_pow2_profiler_fn));
187 /* void (*) (gcov_type *, gcov_type) */
188 one_value_profiler_fn_type
189 = build_function_type_list (void_type_node,
190 gcov_type_ptr, gcov_type_node,
191 NULL_TREE);
192 tree_one_value_profiler_fn
193 = build_fn_decl ("__gcov_one_value_profiler",
194 one_value_profiler_fn_type);
195 TREE_NOTHROW (tree_one_value_profiler_fn) = 1;
196 DECL_ATTRIBUTES (tree_one_value_profiler_fn)
197 = tree_cons (get_identifier ("leaf"), NULL,
198 DECL_ATTRIBUTES (tree_one_value_profiler_fn));
200 init_ic_make_global_vars ();
202 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
203 if (flag_lto)
205 /* void (*) (gcov_type, void *) */
206 ic_profiler_fn_type
207 = build_function_type_list (void_type_node,
208 gcov_type_ptr, gcov_type_node,
209 ptr_void, ptr_void,
210 NULL_TREE);
211 tree_indirect_call_profiler_fn
212 = build_fn_decl ("__gcov_indirect_call_profiler",
213 ic_profiler_fn_type);
215 else
217 /* void (*) (gcov_type, void *) */
218 ic_profiler_fn_type
219 = build_function_type_list (void_type_node,
220 gcov_type_node,
221 ptr_void,
222 NULL_TREE);
223 tree_indirect_call_profiler_fn
224 = build_fn_decl ("__gcov_indirect_call_profiler_v2",
225 ic_profiler_fn_type);
227 TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
228 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
229 = tree_cons (get_identifier ("leaf"), NULL,
230 DECL_ATTRIBUTES (tree_indirect_call_profiler_fn));
232 /* void (*) (gcov_type *, gcov_type, void *) */
233 time_profiler_fn_type
234 = build_function_type_list (void_type_node,
235 gcov_type_ptr, NULL_TREE);
236 tree_time_profiler_fn
237 = build_fn_decl ("__gcov_time_profiler",
238 time_profiler_fn_type);
239 TREE_NOTHROW (tree_time_profiler_fn) = 1;
240 DECL_ATTRIBUTES (tree_time_profiler_fn)
241 = tree_cons (get_identifier ("leaf"), NULL,
242 DECL_ATTRIBUTES (tree_time_profiler_fn));
244 /* void (*) (gcov_type *, gcov_type) */
245 average_profiler_fn_type
246 = build_function_type_list (void_type_node,
247 gcov_type_ptr, gcov_type_node, NULL_TREE);
248 tree_average_profiler_fn
249 = build_fn_decl ("__gcov_average_profiler",
250 average_profiler_fn_type);
251 TREE_NOTHROW (tree_average_profiler_fn) = 1;
252 DECL_ATTRIBUTES (tree_average_profiler_fn)
253 = tree_cons (get_identifier ("leaf"), NULL,
254 DECL_ATTRIBUTES (tree_average_profiler_fn));
255 tree_ior_profiler_fn
256 = build_fn_decl ("__gcov_ior_profiler",
257 average_profiler_fn_type);
258 TREE_NOTHROW (tree_ior_profiler_fn) = 1;
259 DECL_ATTRIBUTES (tree_ior_profiler_fn)
260 = tree_cons (get_identifier ("leaf"), NULL,
261 DECL_ATTRIBUTES (tree_ior_profiler_fn));
263 /* LTO streamer needs assembler names. Because we create these decls
264 late, we need to initialize them by hand. */
265 DECL_ASSEMBLER_NAME (tree_interval_profiler_fn);
266 DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn);
267 DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn);
268 DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn);
269 DECL_ASSEMBLER_NAME (tree_time_profiler_fn);
270 DECL_ASSEMBLER_NAME (tree_average_profiler_fn);
271 DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
275 /* Output instructions as GIMPLE trees to increment the edge
276 execution count, and insert them on E. We rely on
277 gsi_insert_on_edge to preserve the order. */
279 void
280 gimple_gen_edge_profiler (int edgeno, edge e)
282 tree ref, one, gcov_type_tmp_var;
283 gimple stmt1, stmt2, stmt3;
285 ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
286 one = build_int_cst (gcov_type_node, 1);
287 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
288 NULL, "PROF_edge_counter");
289 stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
290 gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
291 NULL, "PROF_edge_counter");
292 stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, gcov_type_tmp_var,
293 gimple_assign_lhs (stmt1), one);
294 stmt3 = gimple_build_assign (unshare_expr (ref), gimple_assign_lhs (stmt2));
295 gsi_insert_on_edge (e, stmt1);
296 gsi_insert_on_edge (e, stmt2);
297 gsi_insert_on_edge (e, stmt3);
300 /* Emits code to get VALUE to instrument at GSI, and returns the
301 variable containing the value. */
303 static tree
304 prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
306 tree val = value->hvalue.value;
307 if (POINTER_TYPE_P (TREE_TYPE (val)))
308 val = fold_convert (build_nonstandard_integer_type
309 (TYPE_PRECISION (TREE_TYPE (val)), 1), val);
310 return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
311 true, NULL_TREE, true, GSI_SAME_STMT);
314 /* Output instructions as GIMPLE trees to increment the interval histogram
315 counter. VALUE is the expression whose value is profiled. TAG is the
316 tag of the section for counters, BASE is offset of the counter position. */
318 void
319 gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
321 gimple stmt = value->hvalue.stmt;
322 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
323 tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
324 gimple call;
325 tree val;
326 tree start = build_int_cst_type (integer_type_node,
327 value->hdata.intvl.int_start);
328 tree steps = build_int_cst_type (unsigned_type_node,
329 value->hdata.intvl.steps);
331 ref_ptr = force_gimple_operand_gsi (&gsi,
332 build_addr (ref, current_function_decl),
333 true, NULL_TREE, true, GSI_SAME_STMT);
334 val = prepare_instrumented_value (&gsi, value);
335 call = gimple_build_call (tree_interval_profiler_fn, 4,
336 ref_ptr, val, start, steps);
337 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
340 /* Output instructions as GIMPLE trees to increment the power of two histogram
341 counter. VALUE is the expression whose value is profiled. TAG is the tag
342 of the section for counters, BASE is offset of the counter position. */
344 void
345 gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
347 gimple stmt = value->hvalue.stmt;
348 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
349 tree ref_ptr = tree_coverage_counter_addr (tag, base);
350 gimple call;
351 tree val;
353 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
354 true, NULL_TREE, true, GSI_SAME_STMT);
355 val = prepare_instrumented_value (&gsi, value);
356 call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val);
357 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
360 /* Output instructions as GIMPLE trees for code to find the most common value.
361 VALUE is the expression whose value is profiled. TAG is the tag of the
362 section for counters, BASE is offset of the counter position. */
364 void
365 gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
367 gimple stmt = value->hvalue.stmt;
368 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
369 tree ref_ptr = tree_coverage_counter_addr (tag, base);
370 gimple call;
371 tree val;
373 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
374 true, NULL_TREE, true, GSI_SAME_STMT);
375 val = prepare_instrumented_value (&gsi, value);
376 call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val);
377 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
381 /* Output instructions as GIMPLE trees for code to find the most
382 common called function in indirect call.
383 VALUE is the call expression whose indirect callee is profiled.
384 TAG is the tag of the section for counters, BASE is offset of the
385 counter position. */
387 void
388 gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
390 tree tmp1;
391 gimple stmt1, stmt2, stmt3;
392 gimple stmt = value->hvalue.stmt;
393 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
394 tree ref_ptr = tree_coverage_counter_addr (tag, base);
396 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
397 true, NULL_TREE, true, GSI_SAME_STMT);
399 /* Insert code:
401 stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
402 stmt2: tmp1 = (void *) (indirect call argument value)
403 stmt3: __gcov_indirect_call_callee = tmp1;
406 stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr);
407 tmp1 = make_temp_ssa_name (ptr_void, NULL, "PROF");
408 stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
409 stmt3 = gimple_build_assign (ic_void_ptr_var, gimple_assign_lhs (stmt2));
411 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
412 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
413 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
417 /* Output instructions as GIMPLE trees for code to find the most
418 common called function in indirect call. Insert instructions at the
419 beginning of every possible called function.
422 void
423 gimple_gen_ic_func_profiler (void)
425 struct cgraph_node * c_node = cgraph_get_node (current_function_decl);
426 gimple_stmt_iterator gsi;
427 gimple stmt1, stmt2;
428 tree tree_uid, cur_func, void0;
430 if (cgraph_only_called_directly_p (c_node))
431 return;
433 gimple_init_edge_profiler ();
435 /* Insert code:
437 stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
438 &current_function_decl)
440 gsi = gsi_after_labels (split_edge (single_succ_edge (ENTRY_BLOCK_PTR)));
442 cur_func = force_gimple_operand_gsi (&gsi,
443 build_addr (current_function_decl,
444 current_function_decl),
445 true, NULL_TREE,
446 true, GSI_SAME_STMT);
447 tree_uid = build_int_cst
448 (gcov_type_node, cgraph_get_node (current_function_decl)->profile_id);
449 /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
450 if (flag_lto)
452 tree counter_ptr, ptr_var;
453 counter_ptr = force_gimple_operand_gsi (&gsi, ic_gcov_type_ptr_var,
454 true, NULL_TREE, true,
455 GSI_SAME_STMT);
456 ptr_var = force_gimple_operand_gsi (&gsi, ic_void_ptr_var,
457 true, NULL_TREE, true,
458 GSI_SAME_STMT);
460 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 4,
461 counter_ptr, tree_uid, cur_func, ptr_var);
463 else
465 stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2,
466 tree_uid, cur_func);
468 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
470 /* Set __gcov_indirect_call_callee to 0,
471 so that calls from other modules won't get misattributed
472 to the last caller of the current callee. */
473 void0 = build_int_cst (build_pointer_type (void_type_node), 0);
474 stmt2 = gimple_build_assign (ic_void_ptr_var, void0);
475 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
478 /* Output instructions as GIMPLE tree at the beginning for each function.
479 TAG is the tag of the section for counters, BASE is offset of the
480 counter position and GSI is the iterator we place the counter. */
482 void
483 gimple_gen_time_profiler (unsigned tag, unsigned base,
484 gimple_stmt_iterator &gsi)
486 tree ref_ptr = tree_coverage_counter_addr (tag, base);
487 gimple call;
489 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
490 true, NULL_TREE, true, GSI_SAME_STMT);
491 call = gimple_build_call (tree_time_profiler_fn, 1, ref_ptr);
492 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
495 /* Output instructions as GIMPLE trees for code to find the most common value
496 of a difference between two evaluations of an expression.
497 VALUE is the expression whose value is profiled. TAG is the tag of the
498 section for counters, BASE is offset of the counter position. */
500 void
501 gimple_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
502 unsigned tag ATTRIBUTE_UNUSED,
503 unsigned base ATTRIBUTE_UNUSED)
505 /* FIXME implement this. */
506 #ifdef ENABLE_CHECKING
507 internal_error ("unimplemented functionality");
508 #endif
509 gcc_unreachable ();
512 /* Output instructions as GIMPLE trees to increment the average histogram
513 counter. VALUE is the expression whose value is profiled. TAG is the
514 tag of the section for counters, BASE is offset of the counter position. */
516 void
517 gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
519 gimple stmt = value->hvalue.stmt;
520 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
521 tree ref_ptr = tree_coverage_counter_addr (tag, base);
522 gimple call;
523 tree val;
525 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
526 true, NULL_TREE,
527 true, GSI_SAME_STMT);
528 val = prepare_instrumented_value (&gsi, value);
529 call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
530 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
533 /* Output instructions as GIMPLE trees to increment the ior histogram
534 counter. VALUE is the expression whose value is profiled. TAG is the
535 tag of the section for counters, BASE is offset of the counter position. */
537 void
538 gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
540 gimple stmt = value->hvalue.stmt;
541 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
542 tree ref_ptr = tree_coverage_counter_addr (tag, base);
543 gimple call;
544 tree val;
546 ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
547 true, NULL_TREE, true, GSI_SAME_STMT);
548 val = prepare_instrumented_value (&gsi, value);
549 call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
550 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
553 /* Profile all functions in the callgraph. */
555 static unsigned int
556 tree_profiling (void)
558 struct cgraph_node *node;
560 /* This is a small-ipa pass that gets called only once, from
561 cgraphunit.c:ipa_passes(). */
562 gcc_assert (cgraph_state == CGRAPH_STATE_IPA_SSA);
564 init_node_map (true);
566 FOR_EACH_DEFINED_FUNCTION (node)
568 if (!gimple_has_body_p (node->decl))
569 continue;
571 /* Don't profile functions produced for builtin stuff. */
572 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
573 continue;
575 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
577 /* Local pure-const may imply need to fixup the cfg. */
578 if (execute_fixup_cfg () & TODO_cleanup_cfg)
579 cleanup_tree_cfg ();
581 branch_prob ();
583 if (! flag_branch_probabilities
584 && flag_profile_values)
585 gimple_gen_ic_func_profiler ();
587 if (flag_branch_probabilities
588 && flag_profile_values
589 && flag_value_profile_transformations)
590 gimple_value_profile_transformations ();
592 /* The above could hose dominator info. Currently there is
593 none coming in, this is a safety valve. It should be
594 easy to adjust it, if and when there is some. */
595 free_dominance_info (CDI_DOMINATORS);
596 free_dominance_info (CDI_POST_DOMINATORS);
597 pop_cfun ();
600 /* Drop pure/const flags from instrumented functions. */
601 FOR_EACH_DEFINED_FUNCTION (node)
603 if (!gimple_has_body_p (node->decl)
604 || !(!node->clone_of
605 || node->decl != node->clone_of->decl))
606 continue;
608 /* Don't profile functions produced for builtin stuff. */
609 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
610 continue;
612 cgraph_set_const_flag (node, false, false);
613 cgraph_set_pure_flag (node, false, false);
616 /* Update call statements and rebuild the cgraph. */
617 FOR_EACH_DEFINED_FUNCTION (node)
619 basic_block bb;
621 if (!gimple_has_body_p (node->decl)
622 || !(!node->clone_of
623 || node->decl != node->clone_of->decl))
624 continue;
626 /* Don't profile functions produced for builtin stuff. */
627 if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
628 continue;
630 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
632 FOR_EACH_BB (bb)
634 gimple_stmt_iterator gsi;
635 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
637 gimple stmt = gsi_stmt (gsi);
638 if (is_gimple_call (stmt))
639 update_stmt (stmt);
643 /* re-merge split blocks. */
644 cleanup_tree_cfg ();
645 update_ssa (TODO_update_ssa);
647 rebuild_cgraph_edges ();
649 pop_cfun ();
652 handle_missing_profiles ();
654 del_node_map ();
655 return 0;
658 /* When profile instrumentation, use or test coverage shall be performed. */
660 static bool
661 gate_tree_profile_ipa (void)
663 return (!in_lto_p
664 && (flag_branch_probabilities || flag_test_coverage
665 || profile_arc_flag));
668 namespace {
670 const pass_data pass_data_ipa_tree_profile =
672 SIMPLE_IPA_PASS, /* type */
673 "profile", /* name */
674 OPTGROUP_NONE, /* optinfo_flags */
675 true, /* has_gate */
676 true, /* has_execute */
677 TV_IPA_PROFILE, /* tv_id */
678 0, /* properties_required */
679 0, /* properties_provided */
680 0, /* properties_destroyed */
681 0, /* todo_flags_start */
682 0, /* todo_flags_finish */
685 class pass_ipa_tree_profile : public simple_ipa_opt_pass
687 public:
688 pass_ipa_tree_profile (gcc::context *ctxt)
689 : simple_ipa_opt_pass (pass_data_ipa_tree_profile, ctxt)
692 /* opt_pass methods: */
693 bool gate () { return gate_tree_profile_ipa (); }
694 unsigned int execute () { return tree_profiling (); }
696 }; // class pass_ipa_tree_profile
698 } // anon namespace
700 simple_ipa_opt_pass *
701 make_pass_ipa_tree_profile (gcc::context *ctxt)
703 return new pass_ipa_tree_profile (ctxt);
706 #include "gt-tree-profile.h"